From 02db0e0edae180925da0b1911aa47520bdd70755 Mon Sep 17 00:00:00 2001 From: "michal.szwaj" Date: Sun, 11 Feb 2018 20:39:49 +0100 Subject: [PATCH] Initial commit --- .gitignore | 4 + CMakeLists.txt | 73 ++ assets/ico_androidauto.png | Bin 0 -> 4365 bytes assets/ico_info.png | Bin 0 -> 438 bytes assets/ico_setting.png | Bin 0 -> 3584 bytes assets/ico_warning.png | Bin 0 -> 751 bytes assets/resources.qrc | 8 + cmake_modules/Findlibusb-1.0.cmake | 98 +++ include/f1x/openauto/Common/Log.hpp | 23 + .../Configuration/BluetootAdapterType.hpp | 40 + .../autoapp/Configuration/Configuration.hpp | 113 +++ .../Configuration/HandednessOfTrafficType.hpp | 39 + .../autoapp/Configuration/IConfiguration.hpp | 75 ++ .../autoapp/Projection/AndroidAutoEntity.hpp | 78 ++ .../Projection/AndroidAutoEntityFactory.hpp | 55 ++ .../autoapp/Projection/AudioInput.hpp | 73 ++ .../autoapp/Projection/AudioInputService.hpp | 65 ++ .../autoapp/Projection/AudioOutput.hpp | 67 ++ .../autoapp/Projection/AudioService.hpp | 65 ++ .../autoapp/Projection/BluetoothService.hpp | 56 ++ .../Projection/DummyBluetoothDevice.hpp | 45 + .../autoapp/Projection/IAndroidAutoEntity.hpp | 47 ++ .../IAndroidAutoEntityEventHandler.hpp | 42 + .../Projection/IAndroidAutoEntityFactory.hpp | 44 + .../autoapp/Projection/IAudioInput.hpp | 56 ++ .../autoapp/Projection/IAudioOutput.hpp | 53 ++ .../autoapp/Projection/IBluetoothDevice.hpp | 48 ++ .../autoapp/Projection/IInputDevice.hpp | 53 ++ .../Projection/IInputDeviceEventHandler.hpp | 44 + .../openauto/autoapp/Projection/IService.hpp | 51 ++ .../autoapp/Projection/IServiceFactory.hpp | 44 + .../autoapp/Projection/IVideoOutput.hpp | 56 ++ .../autoapp/Projection/InputDevice.hpp | 66 ++ .../autoapp/Projection/InputEvent.hpp | 66 ++ .../autoapp/Projection/InputService.hpp | 65 ++ .../Projection/LocalBluetoothDevice.hpp | 68 ++ .../autoapp/Projection/MediaAudioService.hpp | 42 + .../autoapp/Projection/OMXVideoOutput.hpp | 72 ++ .../autoapp/Projection/QtVideoOutput.hpp | 67 ++ .../Projection/RemoteBluetoothDevice.hpp | 50 ++ .../autoapp/Projection/SensorService.hpp | 56 ++ .../autoapp/Projection/SequentialBuffer.hpp | 60 ++ .../autoapp/Projection/ServiceFactory.hpp | 51 ++ .../Projection/ServiceFinishPromise.hpp | 37 + .../autoapp/Projection/SpeechAudioService.hpp | 42 + .../autoapp/Projection/SystemAudioService.hpp | 42 + .../autoapp/Projection/VideoOutput.hpp | 49 ++ .../autoapp/Projection/VideoService.hpp | 68 ++ .../f1x/openauto/autoapp/UI/MainWindow.hpp | 56 ++ .../openauto/autoapp/UI/SettingsWindow.hpp | 69 ++ include/f1x/openauto/autoapp/USB/USBApp.hpp | 63 ++ include/f1x/openauto/autoapp/USB/USBMain.hpp | 68 ++ src/autoapp/Configuration/Configuration.cpp | 273 +++++++ src/autoapp/Main.cpp | 39 + src/autoapp/Projection/AndroidAutoEntity.cpp | 249 ++++++ .../Projection/AndroidAutoEntityFactory.cpp | 61 ++ src/autoapp/Projection/AudioInput.cpp | 172 ++++ src/autoapp/Projection/AudioInputService.cpp | 208 +++++ src/autoapp/Projection/AudioOutput.cpp | 102 +++ src/autoapp/Projection/AudioService.cpp | 176 ++++ src/autoapp/Projection/BluetoothService.cpp | 111 +++ .../Projection/DummyBluetoothDevice.cpp | 58 ++ src/autoapp/Projection/InputDevice.cpp | 233 ++++++ src/autoapp/Projection/InputService.cpp | 195 +++++ .../Projection/LocalBluetoothDevice.cpp | 184 +++++ src/autoapp/Projection/MediaAudioService.cpp | 40 + src/autoapp/Projection/OMXVideoOutput.cpp | 271 ++++++ src/autoapp/Projection/QtVideoOutput.cpp | 99 +++ .../Projection/RemoteBluetoothDevice.cpp | 64 ++ src/autoapp/Projection/SensorService.cpp | 124 +++ src/autoapp/Projection/SequentialBuffer.cpp | 106 +++ src/autoapp/Projection/ServiceFactory.cpp | 141 ++++ src/autoapp/Projection/SpeechAudioService.cpp | 40 + src/autoapp/Projection/SystemAudioService.cpp | 40 + src/autoapp/Projection/VideoOutput.cpp | 54 ++ src/autoapp/Projection/VideoService.cpp | 178 ++++ src/autoapp/UI/MainWindow.cpp | 48 ++ src/autoapp/UI/SettingsWindow.cpp | 242 ++++++ src/autoapp/UI/mainwindow.ui | 207 +++++ src/autoapp/UI/settingswindow.ui | 768 ++++++++++++++++++ src/autoapp/USB/USBApp.cpp | 124 +++ src/autoapp/USB/USBMain.cpp | 105 +++ 82 files changed, 7384 insertions(+) create mode 100644 .gitignore create mode 100644 CMakeLists.txt create mode 100755 assets/ico_androidauto.png create mode 100755 assets/ico_info.png create mode 100755 assets/ico_setting.png create mode 100755 assets/ico_warning.png create mode 100644 assets/resources.qrc create mode 100644 cmake_modules/Findlibusb-1.0.cmake create mode 100644 include/f1x/openauto/Common/Log.hpp create mode 100644 include/f1x/openauto/autoapp/Configuration/BluetootAdapterType.hpp create mode 100644 include/f1x/openauto/autoapp/Configuration/Configuration.hpp create mode 100644 include/f1x/openauto/autoapp/Configuration/HandednessOfTrafficType.hpp create mode 100644 include/f1x/openauto/autoapp/Configuration/IConfiguration.hpp create mode 100644 include/f1x/openauto/autoapp/Projection/AndroidAutoEntity.hpp create mode 100644 include/f1x/openauto/autoapp/Projection/AndroidAutoEntityFactory.hpp create mode 100644 include/f1x/openauto/autoapp/Projection/AudioInput.hpp create mode 100644 include/f1x/openauto/autoapp/Projection/AudioInputService.hpp create mode 100644 include/f1x/openauto/autoapp/Projection/AudioOutput.hpp create mode 100644 include/f1x/openauto/autoapp/Projection/AudioService.hpp create mode 100644 include/f1x/openauto/autoapp/Projection/BluetoothService.hpp create mode 100644 include/f1x/openauto/autoapp/Projection/DummyBluetoothDevice.hpp create mode 100644 include/f1x/openauto/autoapp/Projection/IAndroidAutoEntity.hpp create mode 100644 include/f1x/openauto/autoapp/Projection/IAndroidAutoEntityEventHandler.hpp create mode 100644 include/f1x/openauto/autoapp/Projection/IAndroidAutoEntityFactory.hpp create mode 100644 include/f1x/openauto/autoapp/Projection/IAudioInput.hpp create mode 100644 include/f1x/openauto/autoapp/Projection/IAudioOutput.hpp create mode 100644 include/f1x/openauto/autoapp/Projection/IBluetoothDevice.hpp create mode 100644 include/f1x/openauto/autoapp/Projection/IInputDevice.hpp create mode 100644 include/f1x/openauto/autoapp/Projection/IInputDeviceEventHandler.hpp create mode 100644 include/f1x/openauto/autoapp/Projection/IService.hpp create mode 100644 include/f1x/openauto/autoapp/Projection/IServiceFactory.hpp create mode 100644 include/f1x/openauto/autoapp/Projection/IVideoOutput.hpp create mode 100644 include/f1x/openauto/autoapp/Projection/InputDevice.hpp create mode 100644 include/f1x/openauto/autoapp/Projection/InputEvent.hpp create mode 100644 include/f1x/openauto/autoapp/Projection/InputService.hpp create mode 100644 include/f1x/openauto/autoapp/Projection/LocalBluetoothDevice.hpp create mode 100644 include/f1x/openauto/autoapp/Projection/MediaAudioService.hpp create mode 100644 include/f1x/openauto/autoapp/Projection/OMXVideoOutput.hpp create mode 100644 include/f1x/openauto/autoapp/Projection/QtVideoOutput.hpp create mode 100644 include/f1x/openauto/autoapp/Projection/RemoteBluetoothDevice.hpp create mode 100644 include/f1x/openauto/autoapp/Projection/SensorService.hpp create mode 100644 include/f1x/openauto/autoapp/Projection/SequentialBuffer.hpp create mode 100644 include/f1x/openauto/autoapp/Projection/ServiceFactory.hpp create mode 100644 include/f1x/openauto/autoapp/Projection/ServiceFinishPromise.hpp create mode 100644 include/f1x/openauto/autoapp/Projection/SpeechAudioService.hpp create mode 100644 include/f1x/openauto/autoapp/Projection/SystemAudioService.hpp create mode 100644 include/f1x/openauto/autoapp/Projection/VideoOutput.hpp create mode 100644 include/f1x/openauto/autoapp/Projection/VideoService.hpp create mode 100644 include/f1x/openauto/autoapp/UI/MainWindow.hpp create mode 100644 include/f1x/openauto/autoapp/UI/SettingsWindow.hpp create mode 100644 include/f1x/openauto/autoapp/USB/USBApp.hpp create mode 100644 include/f1x/openauto/autoapp/USB/USBMain.hpp create mode 100644 src/autoapp/Configuration/Configuration.cpp create mode 100644 src/autoapp/Main.cpp create mode 100644 src/autoapp/Projection/AndroidAutoEntity.cpp create mode 100644 src/autoapp/Projection/AndroidAutoEntityFactory.cpp create mode 100644 src/autoapp/Projection/AudioInput.cpp create mode 100644 src/autoapp/Projection/AudioInputService.cpp create mode 100644 src/autoapp/Projection/AudioOutput.cpp create mode 100644 src/autoapp/Projection/AudioService.cpp create mode 100644 src/autoapp/Projection/BluetoothService.cpp create mode 100644 src/autoapp/Projection/DummyBluetoothDevice.cpp create mode 100644 src/autoapp/Projection/InputDevice.cpp create mode 100644 src/autoapp/Projection/InputService.cpp create mode 100644 src/autoapp/Projection/LocalBluetoothDevice.cpp create mode 100644 src/autoapp/Projection/MediaAudioService.cpp create mode 100644 src/autoapp/Projection/OMXVideoOutput.cpp create mode 100644 src/autoapp/Projection/QtVideoOutput.cpp create mode 100644 src/autoapp/Projection/RemoteBluetoothDevice.cpp create mode 100644 src/autoapp/Projection/SensorService.cpp create mode 100644 src/autoapp/Projection/SequentialBuffer.cpp create mode 100644 src/autoapp/Projection/ServiceFactory.cpp create mode 100644 src/autoapp/Projection/SpeechAudioService.cpp create mode 100644 src/autoapp/Projection/SystemAudioService.cpp create mode 100644 src/autoapp/Projection/VideoOutput.cpp create mode 100644 src/autoapp/Projection/VideoService.cpp create mode 100644 src/autoapp/UI/MainWindow.cpp create mode 100644 src/autoapp/UI/SettingsWindow.cpp create mode 100644 src/autoapp/UI/mainwindow.ui create mode 100644 src/autoapp/UI/settingswindow.ui create mode 100644 src/autoapp/USB/USBApp.cpp create mode 100644 src/autoapp/USB/USBMain.cpp diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..7e47c61 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +# Add any directories, files, or patterns you don't want to be tracked by version control +lib/ +bin/ +CMakeLists.txt.user \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..399e9d7 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,73 @@ +cmake_minimum_required(VERSION 3.5.1) +project(openauto CXX) + +set(CMAKE_AUTOMOC ON) +set(CMAKE_AUTOUIC ON) +set(CMAKE_AUTORCC ON) +set(base_directory ${CMAKE_CURRENT_SOURCE_DIR}) +set(resources_directory ${base_directory}/assets) +set(sources_directory ${base_directory}/src) +set(include_directory ${base_directory}/include) + +set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${base_directory}/lib) +set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${base_directory}/lib) + +set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${base_directory}/bin) +set(EXECUTABLE_OUTPUT_PATH ${base_directory}/bin) + +set(Boost_USE_STATIC_LIBS OFF) +set(Boost_USE_MULTITHREADED ON) +set(Boost_USE_STATIC_RUNTIME OFF) + +set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake_modules/") +SET(CMAKE_CXX_STANDARD 14) +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS_INIT} -Wall -pedantic -fPIC") +set(CMAKE_CXX_FLAGS_DEBUG "-g -O0") +set(CMAKE_CXX_FLAGS_RELEASE "-g -O3") + +add_definitions(-DBOOST_ALL_DYN_LINK) + +find_package(Boost REQUIRED COMPONENTS system log OPTIONAL_COMPONENTS unit_test_framework) +find_package(libusb-1.0 REQUIRED) +find_package(Qt5 COMPONENTS Multimedia MultimediaWidgets Bluetooth) +find_package(Protobuf REQUIRED) + +if(RPI3_BUILD) + add_definitions(-DUSE_OMX -DOMX_SKIP64BIT) + set(BCM_HOST_LIBRARIES "/opt/vc/lib/libbcm_host.so") + set(BCM_HOST_INCLUDE_DIRS "/opt/vc/include") + set(ILCLIENT_INCLUDE_DIRS "/opt/vc/src/hello_pi/libs/ilclient") + set(ILCLIENT_LIBRARIES "/opt/vc/src/hello_pi/libs/ilclient/libilclient.a;/opt/vc/lib/libvcos.so;/opt/vc/lib/libvcilcs.a;/opt/vc/lib/libvchiq_arm.so") +endif(RPI3_BUILD) + +include_directories(${CMAKE_CURRENT_BINARY_DIR} + ${Qt5Multimedia_INCLUDE_DIRS} + ${Qt5MultimediaWidgets_INCLUDE_DIRS} + ${Qt5Widgets_INCLUDE_DIRS} + ${Qt5Bluetooth_INCLUDE_DIRS} + ${Boost_INCLUDE_DIRS} + ${LIBUSB_1_INCLUDE_DIRS} + ${PROTOBUF_INCLUDE_DIR} + ${AASDK_PROTO_INCLUDE_DIRS} + ${AASDK_INCLUDE_DIRS} + ${BCM_HOST_INCLUDE_DIRS} + ${ILCLIENT_INCLUDE_DIRS} + ${include_directory}) + +link_directories(${CMAKE_LIBRARY_OUTPUT_DIRECTORY}) + +set(autoapp_sources_directory ${sources_directory}/autoapp) +file(GLOB_RECURSE source_files ${autoapp_sources_directory}/*.ui ${autoapp_sources_directory}/*.cpp ${include_directory}/*.hpp ${resources_directory}/*.qrc) + +add_executable(autoapp ${source_files}) +target_link_libraries(autoapp + ${Boost_LIBRARIES} + ${Qt5Multimedia_LIBRARIES} + ${Qt5MultimediaWidgets_LIBRARIES} + ${Qt5Bluetooth_LIBRARIES} + ${LIBUSB_1_LIBRARIES} + ${PROTOBUF_LIBRARIES} + ${BCM_HOST_LIBRARIES} + ${ILCLIENT_LIBRARIES} + ${AASDK_PROTO_LIBRARIES} + ${AASDK_LIBRARIES}) diff --git a/assets/ico_androidauto.png b/assets/ico_androidauto.png new file mode 100755 index 0000000000000000000000000000000000000000..9c205151c9f46204ee20611a8eacbc73d4c560d0 GIT binary patch literal 4365 zcmV+o5%TVdP)Wz@?|hqiBG(*}7%gnKSAf z$C+t$y0c-m8|A+~l=gtJ1zsRj8=X*Ik9-imp5k`~kp>!QYKYL45)F3r*8*6G-UYzp6Ox0f|cKmM^b^cP|dDoeNj>mlguO3t&uDtq%RSbGJ1z0H~;IP6Kc$Y4~eT ztgQNkM~ba6(IjKc%4K;M032B5N&}E!<$FJX>yj4ei0&wV_3#a83Q9=%4Nh=83P4Wc zuuee`HkEE^kkbGRBeS+d`aQ(?_W=Aw($hVnA4sxvLmGf#-U+r%XC@#a+=| z(*O=`1IHc!-%a$qL@MDC&fTl4+I>3l-YeZJx}qLXTH{62`f?Cx!Dy5}W~*bgm_+7j zTvLjYtqtEy0E%n9IJ7?6?F8R;`F)>W0f543(=hW2f^fwt$W`rq9l%4QJ&)@gwhS`_ z0~8c*Q*d5=;Njwp-&hKAS9^;9+-2lk4uA--2z;pN;lv)E=swT(!_&TTLD*I61>;QC zp}!4|N+VWkmM~f>3%Tlz-U)D5;GEyGmGE z4uc61-Ba;e^FIT?S3fGdx+%!D?SPX54;oc|TS&vIQadtC0(c~a1!IKjo3qe*x(BD) z+6{REV{CQNOJCZqS_+!>!XG0_RM~R?t~D}-q5~CKGJd!q2fd0O1%;sK9P=m3czB*2 z7yJR7^L4>MYBbgEv~31}h5I_M&Me4P<1GS569BdAq3mQBWVhX@cLOA?NJ{WVOo z3=W_*pkv8Lt>{%boK`ama>^7dj(*(&S(f@tSm#*uVH?f|b?BTU$6-f)rejo(sw(P+hBYNMSB(d_YP=4e^M5jG zAw3Gmty8U-=9C6eJ6&Yq4vFD`A`5~c9Rd;By1H?ub#&R0D2Y#cwjIp8Y5*XP#{d)< z3%ndtZ48?i<{+T*A=(iGEjyrbJUYjYMbpd(s2pa-5D0~Fwyk3{fw_Pr>2ds|o}^75 zO>7Es*LbIKjw1jhBj*QIj$KRhQJQn{e7Y!#XgPiyq9|VU-H}ceKlr#E#0ZQ4;)G0x z6&VhDq=|HC(KJ1{mKtWHvrl-+<=z9`35~KEyfSV00X_2>jjknJ|e%KR+MA zg&6^ldThv%S>zZZNQ@z@C}{8WgC{^ojIjqjbxmszRJpikoL1G13jj^)%Q1WFAsHM` z8689C9CLC_m@~-)of|nHD9jY`ooi&MIv@}M1PCA~VFf)sfrLO11mVe&t&LXiIIXHn zIsmR(Z;U`608nUjobHg0=WfY`Hiq>JL6zfQZ*U+(WPJgf2#gT|!63T2x)UnmB}v)< z0G{p1-*Gc8+~%tBP65aN0?0RVey_^0`Q~ig>$W4T4v)Y{K{$R413o{i;K%>f4XYFZ zf)Rm51FRq@G`_JH_)E{^++DqrWoOoxc?7Fb49e!@kS4piib z@MKHScvSiQ>`ze?1OlN;nP~b`qfy* zDaw?vXr>iv0`u&N`iI7W`FRqG9AaGgh|v%c7-LX14WZt^h*V92@PhNXPndU=JGB6C z*T(mAEeBwDrBk=U@gt8D7Ae8dG>Vop2gg6mvml^FvzsV@u~@(eP&5tUPr(+G!UFD`z|4 z4`>N?3Pxu=1fW|1ZoO7OzEuGASALw1A|Hfw9l>Edfq*>l$U3Id+J-9&fUDYzqig4( z_?17)1geL@S#ga6Rpky$u?wR-Z}gYTHW7a4lA!Z`mfsIb4S)zh)pUdvb(nxm&zEgG zn0qKX$9=^BXpRP6BJmR#+|NY-CRqejl{ukbhMQM(;LZXO1vb`K4^ZSrG$M!~@My87 zY8rxJ<)T|AB8alIFC{3bxW;=QfCWYaP)AtD18y6#%xu)txJIi4kpWLu$oRi5fH8m* zK_!9!f=>Nr*@(b7M`#F7AfnlGUjJ(S6$QXu+u)$celC-d^A!%b93nQ}n2R3e^6i;W zbl}Fxgf+7S1hhWd;nbHE4FFo_P*rUx`+3?^*EIRE15mQPF_!b+3gA0qx%kU>OoHDR zj`Hy+J&24YaRlI80C?Cf!YoECpU3Kh0b@r#BLWnzLm31D5lsfsJpfQ{FfBC%z~MDz zF%EdouoY??i)L6*lqnichIL&xYGepBn%abKe30N|P!LP*lKT13O zET2cyRf+~^opY!IL73yIYhDZh)1Uur{3_vo`?=}?+-9gd$pME*_|wV)^eXz8t@zaG z(+O3=BRA`S$Noph7j2Q>(NFm?HL(HlA)2}NYio1Pk7%m4pnSQzeP=Eu-vefEiSOt7 zwo&EBxWDH1JoF?%`N@)A6<9Ni!6Xb#JA-3A#amGvdenu9XciOLlAXDPvQaGRN(caV zZ6gk@jqm5$Iu_3TR-OsPSyFN|mqh-WVFzx=B`6qzcKQ)T|7?wepo8MKK}0*;TN;ZR z*OZ_v!P&Ef0BBlQ77M)F!C`oE)Wm?tug`>8Oi~Y!k~g6z5U{$4;1v6m&xqp6C&Hjq zIoisOdW;^WB#Xtg6-fM5X$ezMNwwDw;Cn_NQ0G8Jt_gDuPO=Z}0NijbFx36cv;*_A zfv`>&)g?6OFHU{R(t{ey4Cq1D-A?$SguH z!_f|>z6KtrfoZW0SOv!BjYk@4*wg|l$Iln$pui>$PTx{Wc(gt8bQuuVMy8#?%I`mh zrfDqc00hJ8c>tZGrwL%1L&WXVtO%*8|4waH2g);nVka(I2t1f}hLO%dApB|40XV*C zUNEF6JB$>e>*qL;ZAtzbFnye=II93WGLu7Mm!_S;g?T6#`p+X9E83F^K>p7o)m_Wc zqt6CIp})~Ijbhc}rKB)J!qURTCfP^Zh%?C&1VKnT02&A8WdYNz00{z^z#uXPVhkii z<_f6aKS2&N;&2FnW7?(Q^FMd9JHcW>#jFEXxoCA%4tQMP|Uk4vq(Z z*VE{fSqLDaSk6fV;!#iF9N|zn)Efxy?09P7FRy*^k2v+y#9wzeuFKQAeeJ6Sfo%_I z-0+1cx@<&I6m)j_aQ^&x-rCyk4TXYrT|GT-TTLd1Y%;BsMCto>r+rq2(*d)^0znYK zIX4UjkAk3T{KaBd$z$WCBSU)0-TdEZePZOd0`rhx^ar&g0HzzZLRp62@5j-jU!%Lb z8;YW=3kHLqOOn{KY}s;O|6}Xx>$5aXn<>lk9fBZiHk(bz&(DW!lA&qZnA%Mu!|cK$ zw|}fUxhx*w^K~F2BMUxX$KwE=AI&uwBj`FuC=@~<5WuNZr_UZgezL`4G4EQweEGk{ zj@z?m50)-nI^f*FpVimb|12C1FV4-&Ey&Ew$d@G+J0OQy>t0_t>$PZI35TCk=-FGD03zF^uU0uE`UDsn9bZM~CbzMg|97cC{H;x@Uex|jxt=Vig z?OL{MS#|8V4?p}6cinYYQtxXBirS!R+F#mi*5cgU+$miQY!bq z)|+p>nQO6F9+D*a4vW=to73Tt9Zq{ZrH#!yGsd84TGMBreO|h%Y86je0QTe9iaYf8VO>`V>(V z%S2IpR+6Ohtn5tW<>f(96|}c@ptY^-#NtJZrlq6@?AWmbxw*Ntc=2Msd-v|Qrca-~ z(zJU(DfS^uBpCMa71aT7- zl?+v=;3Tymje@-ny(yQbI<(((&pqdN&$)-6K`&7}1MC6Iz?`~GfJ@+jz<<%pg%V}r z5U2rFB$bkD7mAKupiKqX0iKECb6sO-ofBX-3nv|y`sxw@Q&-p2KfmN|8;Q~3p{*Q{mo@lK6_rP1j7?*WyTKQ}Mr^Y`G?7PwHmN2$ zNE4g11Fc}2emH4(i2`jcC((YWWyXl|(6kB>D&malO9-n}FdBemlc)y{-&sfG%K0gP#otHtD&K zKkbfzj_Z|yl|V;?&qo5ijkJN@N=&ZoQV4C<2J}W~ehu&=CBy4s?on3+cn&}E4E z02|Y!1@u@p8fwm}ty8kZ{1VV_xY>D1ir-ZAF$cI7xB-}AxWC=Ni@;W3y^^95=zAWp z!t~+{_K|e~xCdApL(`M={&_br+492Q3#`)y+`bsvzgJ1|blj7$~IhB|Q-^`pk z^?#KZ7Lyf$wq*mH$jcGd;#f}PNdPueAeA(;wu&6r`v^Zkqd;REQBs_f8x5e($#V+6 zhQ=IQ&LG>4pl*DJNrBqvQBt($$`26G0#SYCrxQj1eYPB3)-7qr^;Q7$3O)~tr<4@) zvwnODBLt_&cQ{%U^eZWb*zUBP0P_LvEcpEu+?hmhNGT!{OMKyeJppW1QfzPZh$8S% zV+%07;Q5#EijrbR6EwUUxE>gWc1uUOJ194~atChp`tg1Hoxl^oHhs>Y75r_Df$uGt zKPaX-vmDp^5ZI<^->G@g@3`JCYti3`1_*hd-woWRr05%j`TKwgp;{AYTK0xu zKKStj3yf+2$MuE+C!<)l+TdGQsQu<`0^mvD*@(vaP$k7FQySp+Eu1no6wHri6KL8+ zJ*lm1Sp#SlG#=Pr@FSC$034`ys%W?cIIi~(;PQ+U;u!D}unRZ@ybF8+e60U{Byc7$ z5f}qp0$c~2mGODMp`^GXk_OOceF6MAqmzFYcma4?Nf9X?QNLff2lzhObzaQ|Hr4VG zG};3G3!IT9i3gS`Db@r}Agv(ShU0o2z(c^L8KTK?CB^WjjX?c~F)PgP1}@U-Zq2~| zG;yO=)y5hn#bv-nn0W(W183CBZ&1&|T#|vwDc~w4#r61M+p*^J3ADXi_jxt&K?dlw zxG4c}TyJs)CiRGtVl41_+>Eay2s@M%V}M7}POMryt)&4*rF0$@ZMlzAQvBRD<7)|m z9?SW9Y?YMKZe%k8a4@Bl*rB8tmD2IOugA6{rL_AXv;gR|EGJVofelKEYtovxZ@_o2 zq__s(gO?_pR8kyl)(CtsMH5)9q?nVm%5P#zm=ipWqyRN}*~kxI>N$6-D?gJV<&NvE z2kuCC7zqCB^&1=PVlF!F(mf2%x7KV>xnomd@rG$NT&bw0A9ca9r;Y za9#{ePl}p_w3T-O_r*k~*;&X48pR#}Zi%V+$h>GJL&#lm7%xhS*YddfwMyQhAIO?E zrtiWJ4{sV#ABL3ibN!jdMff*uv03E$?>FJ!=?~Ld@PEKgCB^gAzl}i)Oab1Cfp$Zp z1inPo0Jq05fj5*CyJKYhT*vhmQ74!~GiWEU3|M7a5OiC+9oO55`Jj^9f%Ud*fN60! zEn?dHXE?5R6hBHf4ACzIR_brAjY$i{kq0mmPoi!CZ(%qOU!z>S5y$x?u%N|emMbY1 z#xOS1N9ebe6jLGzK)_?wiC-P#TB=?~=rIhSV}jidFa-!Q#R(CB-U(uHfqu zrv17+UI$+byc*Lub9o&M$p?hY#eV{Bq_H9(q%rf+0U>2g^dm}&HvD8lhZ7jkjfSId z7vkp#G=&#T#s%uR-k1QL4+D!eua77xil9)NE5B-NsR#;<>IZl+27+{$4hz?en-!s(`(?ZI*jZ7kZ1T^!2S9g*NNxh2wggG5{LkzO|rxH(^ooAwc*ve&4Txrmr%Nz3pd;gzeYJRm90SFW^ zdH_E=NE{bQ=Q*zTa1K@f!^D#vqyp@7TyI{GM@DUcz}vxD_)m~WTcFwb_~}>kp!&xF z?^)=s54crH(G%8?4XXjpc3kgo`02++TcX|TwTdWaiTRoduUqP}4d~WcNZMN30;(#7 z_TiT)wTTgq>ut+Hnz(KFCE;yi7Jlu8ek)ETf)PLoGNxf3YZUYhvRyy zGsyhaDPTS{s3cm?2KYsa=-HtYFQ?ij2yC0{fsPant*famz;V4X`1N?whV5ys84x%r zZNsl6ls25NGnR(Z0Ao|S$foMV%i~fwwsCrFQ&UR2Z#A<8e3a5jl<*%@yf@%1N^(mG zsQicZIe#SSt&ZLsS^%QvowbZ7bne}$wgn;3*Hk@*Co*s(-P5cQ_*e#n;5=ZvzG0gZ zw;%-CzF7CUop{{4rm?u`Q-G4equv-2L8ub~_Y<&E0 zl@w(q#RetC4C0F*${Q-cJ|)F;{F~4rz=|f@Sfr#lWlR9H5G)6_g!pL>FiJ`BK+u*@ zQcTviL?HzAnZI92F*$hOp`=)#4b|>2nnOwPtFRr07Jv|yM2`SBC@H>DTQE>qc@ine zjhAA)tE8AzNao)u##wjrlEZ032Xu2r)BAl(EM8b?4;Jy$0z!b(Q&=;z;nQ5AwOBF zw~{bzTNQwaw$2;CElP?5N%0`*YuN+(;lgYhKSSFRmiY;92VrcTgVnY2ivI&GJ9U>i6#^Xq0000Dw!Am?eJBh#Hb&h<9B$^Yu!!+Fm6Kj-Z^aEL?1fbS{* zB~Op96toRsXs!Mc>u#j#RwMNSs4UQ<_L7`3kgei{7P& z%-sWt06;RyY?X6>JHDrn_LV>-$G)ps;C@IbCwx~=?i+yt zdKw;qlBXUp7_rE|Teywoya+F&c7}zUnISV@`9HGr;1pDW{ylVAO5lBrooWo2uStPy zeJ2lKr#)J?2uq$murMhBr6$2z*r3cnX4rhLA+S25Tpl#|1$BN~Qr0%tyCc}%5%aCG h)@LH@3WxYV@CW1QvN@AKdz%0N002ovPDHLkV1k;aM9BaE literal 0 HcmV?d00001 diff --git a/assets/resources.qrc b/assets/resources.qrc new file mode 100644 index 0000000..1070e2d --- /dev/null +++ b/assets/resources.qrc @@ -0,0 +1,8 @@ + + + ico_androidauto.png + ico_warning.png + ico_setting.png + ico_info.png + + diff --git a/cmake_modules/Findlibusb-1.0.cmake b/cmake_modules/Findlibusb-1.0.cmake new file mode 100644 index 0000000..ec40055 --- /dev/null +++ b/cmake_modules/Findlibusb-1.0.cmake @@ -0,0 +1,98 @@ +# - Try to find libusb-1.0 +# Once done this will define +# +# LIBUSB_1_FOUND - system has libusb +# LIBUSB_1_INCLUDE_DIRS - the libusb include directory +# LIBUSB_1_LIBRARIES - Link these to use libusb +# LIBUSB_1_DEFINITIONS - Compiler switches required for using libusb +# +# Adapted from cmake-modules Google Code project +# +# Copyright (c) 2006 Andreas Schneider +# +# (Changes for libusb) Copyright (c) 2008 Kyle Machulis +# +# Redistribution and use is allowed according to the terms of the New BSD license. +# +# CMake-Modules Project New BSD License +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright notice, this +# list of conditions and the following disclaimer. +# +# * Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# * Neither the name of the CMake-Modules Project nor the names of its +# contributors may be used to endorse or promote products derived from this +# software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +# ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# + + +if (LIBUSB_1_LIBRARIES AND LIBUSB_1_INCLUDE_DIRS) + # in cache already + set(LIBUSB_FOUND TRUE) +else (LIBUSB_1_LIBRARIES AND LIBUSB_1_INCLUDE_DIRS) + find_path(LIBUSB_1_INCLUDE_DIR + NAMES + libusb.h + PATHS + /usr/include + /usr/local/include + /opt/local/include + /sw/include + PATH_SUFFIXES + libusb-1.0 + ) + + find_library(LIBUSB_1_LIBRARY + NAMES + usb-1.0 usb + PATHS + /usr/lib + /usr/local/lib + /opt/local/lib + /sw/lib + ) + + set(LIBUSB_1_INCLUDE_DIRS + ${LIBUSB_1_INCLUDE_DIR} + ) + set(LIBUSB_1_LIBRARIES + ${LIBUSB_1_LIBRARY} +) + + if (LIBUSB_1_INCLUDE_DIRS AND LIBUSB_1_LIBRARIES) + set(LIBUSB_1_FOUND TRUE) + endif (LIBUSB_1_INCLUDE_DIRS AND LIBUSB_1_LIBRARIES) + + if (LIBUSB_1_FOUND) + if (NOT libusb_1_FIND_QUIETLY) + message(STATUS "Found libusb-1.0:") + message(STATUS " - Includes: ${LIBUSB_1_INCLUDE_DIRS}") + message(STATUS " - Libraries: ${LIBUSB_1_LIBRARIES}") + endif (NOT libusb_1_FIND_QUIETLY) + else (LIBUSB_1_FOUND) + if (libusb_1_FIND_REQUIRED) + message(FATAL_ERROR "Could not find libusb") + endif (libusb_1_FIND_REQUIRED) + endif (LIBUSB_1_FOUND) + + # show the LIBUSB_1_INCLUDE_DIRS and LIBUSB_1_LIBRARIES variables only in the advanced view + mark_as_advanced(LIBUSB_1_INCLUDE_DIRS LIBUSB_1_LIBRARIES) + +endif (LIBUSB_1_LIBRARIES AND LIBUSB_1_INCLUDE_DIRS) diff --git a/include/f1x/openauto/Common/Log.hpp b/include/f1x/openauto/Common/Log.hpp new file mode 100644 index 0000000..f0f544a --- /dev/null +++ b/include/f1x/openauto/Common/Log.hpp @@ -0,0 +1,23 @@ +/* +* This file is part of openauto project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* openauto is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 3 of the License, or +* (at your option) any later version. + +* openauto is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with openauto. If not, see . +*/ + +#pragma once + +#include + +#define OPENAUTO_LOG(severity) BOOST_LOG_TRIVIAL(severity) << "[AaApp] " diff --git a/include/f1x/openauto/autoapp/Configuration/BluetootAdapterType.hpp b/include/f1x/openauto/autoapp/Configuration/BluetootAdapterType.hpp new file mode 100644 index 0000000..8185411 --- /dev/null +++ b/include/f1x/openauto/autoapp/Configuration/BluetootAdapterType.hpp @@ -0,0 +1,40 @@ +/* +* This file is part of openauto project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* openauto is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 3 of the License, or +* (at your option) any later version. + +* openauto is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with openauto. If not, see . +*/ + +#pragma once + +namespace f1x +{ +namespace openauto +{ +namespace autoapp +{ +namespace configuration +{ + +enum class BluetoothAdapterType +{ + NONE, + LOCAL, + REMOTE +}; + +} +} +} +} diff --git a/include/f1x/openauto/autoapp/Configuration/Configuration.hpp b/include/f1x/openauto/autoapp/Configuration/Configuration.hpp new file mode 100644 index 0000000..eb489c7 --- /dev/null +++ b/include/f1x/openauto/autoapp/Configuration/Configuration.hpp @@ -0,0 +1,113 @@ +/* +* This file is part of openauto project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* openauto is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 3 of the License, or +* (at your option) any later version. + +* openauto is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with openauto. If not, see . +*/ + +#pragma once + +#include +#include + +namespace f1x +{ +namespace openauto +{ +namespace autoapp +{ +namespace configuration +{ + +class Configuration: public IConfiguration +{ +public: + Configuration(); + + void load() override; + void reset() override; + void save() override; + + void setHandednessOfTrafficType(HandednessOfTrafficType value) override; + HandednessOfTrafficType getHandednessOfTrafficType() const override; + void showClock(bool value) override; + bool showClock() const override; + + aasdk::proto::enums::VideoFPS::Enum getVideoFPS() const override; + void setVideoFPS(aasdk::proto::enums::VideoFPS::Enum value) override; + aasdk::proto::enums::VideoResolution::Enum getVideoResolution() const override; + void setVideoResolution(aasdk::proto::enums::VideoResolution::Enum value) override; + size_t getScreenDPI() const override; + void setScreenDPI(size_t value) override; + + bool getTouchscreenEnabled() const override; + void setTouchscreenEnabled(bool value) override; + ButtonCodes getButtonCodes() const override; + void setButtonCodes(const ButtonCodes& value) override; + + BluetoothAdapterType getBluetoothAdapterType() const override; + void setBluetoothAdapterType(BluetoothAdapterType value) override; + std::string getBluetoothRemoteAdapterAddress() const override; + void setBluetoothRemoteAdapterAddress(const std::string& value) override; + +private: + void readButtonCodes(boost::property_tree::ptree& iniConfig); + void insertButtonCode(boost::property_tree::ptree& iniConfig, const std::string& buttonCodeKey, aasdk::proto::enums::ButtonCode::Enum buttonCode); + void writeButtonCodes(boost::property_tree::ptree& iniConfig); + + HandednessOfTrafficType handednessOfTrafficType_; + bool showClock_; + aasdk::proto::enums::VideoFPS::Enum videoFPS_; + aasdk::proto::enums::VideoResolution::Enum videoResolution_; + size_t screenDPI_; + bool enableTouchscreen_; + ButtonCodes buttonCodes_; + BluetoothAdapterType bluetoothAdapterType_; + std::string bluetoothRemoteAdapterAddress_; + + static const std::string cConfigFileName; + + static const std::string cGeneralShowClockKey; + static const std::string cGeneralHandednessOfTrafficTypeKey; + + static const std::string cVideoFPSKey; + static const std::string cVideoResolutionKey; + static const std::string cVideoScreenDPIKey; + + static const std::string cBluetoothAdapterTypeKey; + static const std::string cBluetoothRemoteAdapterAddressKey; + + static const std::string cInputEnableTouchscreenKey; + static const std::string cInputPlayButtonKey; + static const std::string cInputPauseButtonKey; + static const std::string cInputTogglePlayButtonKey; + static const std::string cInputNextTrackButtonKey; + static const std::string cInputPreviousTrackButtonKey; + static const std::string cInputHomeButtonKey; + static const std::string cInputPhoneButtonKey; + static const std::string cInputCallEndButtonKey; + static const std::string cInputVoiceCommandButtonKey; + static const std::string cInputLeftButtonKey; + static const std::string cInputRightButtonKey; + static const std::string cInputUpButtonKey; + static const std::string cInputDownButtonKey; + static const std::string cInputScrollWheelButtonKey; + static const std::string cInputBackButtonKey; + static const std::string cInputEnterButtonKey; +}; + +} +} +} +} diff --git a/include/f1x/openauto/autoapp/Configuration/HandednessOfTrafficType.hpp b/include/f1x/openauto/autoapp/Configuration/HandednessOfTrafficType.hpp new file mode 100644 index 0000000..e71c6c5 --- /dev/null +++ b/include/f1x/openauto/autoapp/Configuration/HandednessOfTrafficType.hpp @@ -0,0 +1,39 @@ +/* +* This file is part of openauto project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* openauto is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 3 of the License, or +* (at your option) any later version. + +* openauto is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with openauto. If not, see . +*/ + +#pragma once + +namespace f1x +{ +namespace openauto +{ +namespace autoapp +{ +namespace configuration +{ + +enum class HandednessOfTrafficType +{ + LEFT_HAND_DRIVE, + RIGHT_HAND_DRIVE +}; + +} +} +} +} diff --git a/include/f1x/openauto/autoapp/Configuration/IConfiguration.hpp b/include/f1x/openauto/autoapp/Configuration/IConfiguration.hpp new file mode 100644 index 0000000..666ae56 --- /dev/null +++ b/include/f1x/openauto/autoapp/Configuration/IConfiguration.hpp @@ -0,0 +1,75 @@ +/* +* This file is part of openauto project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* openauto is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 3 of the License, or +* (at your option) any later version. + +* openauto is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with openauto. If not, see . +*/ + +#pragma once + +#include +#include +#include +#include +#include +#include + +namespace f1x +{ +namespace openauto +{ +namespace autoapp +{ +namespace configuration +{ + +class IConfiguration +{ +public: + typedef std::shared_ptr Pointer; + typedef std::vector ButtonCodes; + + virtual ~IConfiguration() = default; + + virtual void load() = 0; + virtual void reset() = 0; + virtual void save() = 0; + + virtual void setHandednessOfTrafficType(HandednessOfTrafficType value) = 0; + virtual HandednessOfTrafficType getHandednessOfTrafficType() const = 0; + virtual void showClock(bool value) = 0; + virtual bool showClock() const = 0; + + virtual aasdk::proto::enums::VideoFPS::Enum getVideoFPS() const = 0; + virtual void setVideoFPS(aasdk::proto::enums::VideoFPS::Enum value) = 0; + virtual aasdk::proto::enums::VideoResolution::Enum getVideoResolution() const = 0; + virtual void setVideoResolution(aasdk::proto::enums::VideoResolution::Enum value) = 0; + virtual size_t getScreenDPI() const = 0; + virtual void setScreenDPI(size_t value) = 0; + + virtual bool getTouchscreenEnabled() const = 0; + virtual void setTouchscreenEnabled(bool value) = 0; + virtual ButtonCodes getButtonCodes() const = 0; + virtual void setButtonCodes(const ButtonCodes& value) = 0; + + virtual BluetoothAdapterType getBluetoothAdapterType() const = 0; + virtual void setBluetoothAdapterType(BluetoothAdapterType value) = 0; + virtual std::string getBluetoothRemoteAdapterAddress() const = 0; + virtual void setBluetoothRemoteAdapterAddress(const std::string& value) = 0; +}; + +} +} +} +} diff --git a/include/f1x/openauto/autoapp/Projection/AndroidAutoEntity.hpp b/include/f1x/openauto/autoapp/Projection/AndroidAutoEntity.hpp new file mode 100644 index 0000000..9ebae20 --- /dev/null +++ b/include/f1x/openauto/autoapp/Projection/AndroidAutoEntity.hpp @@ -0,0 +1,78 @@ +/* +* This file is part of openauto project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* openauto is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 3 of the License, or +* (at your option) any later version. + +* openauto is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with openauto. If not, see . +*/ + +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace f1x +{ +namespace openauto +{ +namespace autoapp +{ +namespace projection +{ + +class AndroidAutoEntity: public IAndroidAutoEntity, public aasdk::channel::control::IControlServiceChannelEventHandler, public std::enable_shared_from_this +{ +public: + AndroidAutoEntity(boost::asio::io_service& ioService, + aasdk::messenger::ICryptor::Pointer cryptor, + aasdk::transport::ITransport::Pointer transport, + configuration::IConfiguration::Pointer configuration, + IServiceFactory& serviceFactory); + ~AndroidAutoEntity() override; + + void start(IAndroidAutoEntityEventHandler& eventHandler) override; + void stop() override; + void onVersionResponse(uint16_t majorCode, uint16_t minorCode, aasdk::proto::enums::VersionResponseStatus::Enum status) override; + void onHandshake(const aasdk::common::DataConstBuffer& payload) override; + void onServiceDiscoveryRequest(const aasdk::proto::messages::ServiceDiscoveryRequest& request) override; + void onAudioFocusRequest(const aasdk::proto::messages::AudioFocusRequest& request) override; + void onShutdownRequest(const aasdk::proto::messages::ShutdownRequest& request) override; + void onShutdownResponse(const aasdk::proto::messages::ShutdownResponse& response) override; + void onNavigationFocusRequest(const aasdk::proto::messages::NavigationFocusRequest& request) override; + void onChannelError(const aasdk::error::Error& e) override; + +private: + using std::enable_shared_from_this::shared_from_this; + void handleStop(); + + boost::asio::io_service::strand strand_; + aasdk::messenger::ICryptor::Pointer cryptor_; + aasdk::transport::ITransport::Pointer transport_; + configuration::IConfiguration::Pointer configuration_; + IServiceFactory& serviceFactory_; + aasdk::messenger::IMessenger::Pointer messenger_; + aasdk::channel::control::ControlServiceChannel::Pointer controlServiceChannel_; + ServiceList serviceList_; + IAndroidAutoEntityEventHandler* eventHandler_; +}; + +} +} +} +} diff --git a/include/f1x/openauto/autoapp/Projection/AndroidAutoEntityFactory.hpp b/include/f1x/openauto/autoapp/Projection/AndroidAutoEntityFactory.hpp new file mode 100644 index 0000000..aa3017c --- /dev/null +++ b/include/f1x/openauto/autoapp/Projection/AndroidAutoEntityFactory.hpp @@ -0,0 +1,55 @@ +/* +* This file is part of openauto project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* openauto is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 3 of the License, or +* (at your option) any later version. + +* openauto is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with openauto. If not, see . +*/ + +#pragma once + +#include +#include +#include +#include + +namespace f1x +{ +namespace openauto +{ +namespace autoapp +{ +namespace projection +{ + +class AndroidAutoEntityFactory: public IAndroidAutoEntityFactory +{ +public: + AndroidAutoEntityFactory(aasdk::usb::IUSBWrapper& usbWrapper, + boost::asio::io_service& ioService, + configuration::IConfiguration::Pointer configuration, + IServiceFactory& serviceFactory); + + IAndroidAutoEntity::Pointer create(aasdk::usb::DeviceHandle deviceHandle) override; + +private: + aasdk::usb::IUSBWrapper& usbWrapper_; + boost::asio::io_service& ioService_; + configuration::IConfiguration::Pointer configuration_; + IServiceFactory& serviceFactory_; +}; + +} +} +} +} diff --git a/include/f1x/openauto/autoapp/Projection/AudioInput.hpp b/include/f1x/openauto/autoapp/Projection/AudioInput.hpp new file mode 100644 index 0000000..1dd7db0 --- /dev/null +++ b/include/f1x/openauto/autoapp/Projection/AudioInput.hpp @@ -0,0 +1,73 @@ +/* +* This file is part of openauto project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* openauto is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 3 of the License, or +* (at your option) any later version. + +* openauto is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with openauto. If not, see . +*/ + +#pragma once + +#include +#include +#include +#include + +namespace f1x +{ +namespace openauto +{ +namespace autoapp +{ +namespace projection +{ + +class AudioInput: public QObject, public IAudioInput +{ + Q_OBJECT +public: + AudioInput(uint32_t channelCount, uint32_t sampleSize, uint32_t sampleRate); + + bool open() override; + bool isActive() const override; + void read(ReadPromise::Pointer promise) override; + void start(StartPromise::Pointer promise) override; + void stop() override; + uint32_t getSampleSize() const override; + uint32_t getChannelCount() const override; + uint32_t getSampleRate() const override; + +signals: + void startRecording(StartPromise::Pointer promise); + void stopRecording(); + +private slots: + void createAudioInput(); + void onStartRecording(StartPromise::Pointer promise); + void onStopRecording(); + void onReadyRead(); + +private: + QAudioFormat audioFormat_; + QIODevice* ioDevice_; + std::unique_ptr audioInput_; + ReadPromise::Pointer readPromise_; + mutable std::mutex mutex_; + + static constexpr size_t cSampleSize = 2056; +}; + +} +} +} +} diff --git a/include/f1x/openauto/autoapp/Projection/AudioInputService.hpp b/include/f1x/openauto/autoapp/Projection/AudioInputService.hpp new file mode 100644 index 0000000..6fea293 --- /dev/null +++ b/include/f1x/openauto/autoapp/Projection/AudioInputService.hpp @@ -0,0 +1,65 @@ +/* +* This file is part of openauto project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* openauto is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 3 of the License, or +* (at your option) any later version. + +* openauto is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with openauto. If not, see . +*/ + +#pragma once + +#include +#include +#include + +namespace f1x +{ +namespace openauto +{ +namespace autoapp +{ +namespace projection +{ + +class AudioInputService: public aasdk::channel::av::IAVInputServiceChannelEventHandler, public IService, public std::enable_shared_from_this +{ +public: + typedef std::shared_ptr Pointer; + + AudioInputService(boost::asio::io_service& ioService, aasdk::messenger::IMessenger::Pointer messenger, IAudioInput::Pointer audioInput); + + void start() override; + void stop() override; + void fillFeatures(aasdk::proto::messages::ServiceDiscoveryResponse& response) override; + void onChannelOpenRequest(const aasdk::proto::messages::ChannelOpenRequest& request) override; + void onAVChannelSetupRequest(const aasdk::proto::messages::AVChannelSetupRequest& request) override; + void onAVInputOpenRequest(const aasdk::proto::messages::AVInputOpenRequest& request) override; + void onAVMediaAckIndication(const aasdk::proto::messages::AVMediaAckIndication& indication) override; + void onChannelError(const aasdk::error::Error& e) override; + +private: + using std::enable_shared_from_this::shared_from_this; + void onAudioInputOpenSucceed(); + void onAudioInputDataReady(aasdk::common::Data data); + void readAudioInput(); + + boost::asio::io_service::strand strand_; + aasdk::channel::av::AVInputServiceChannel::Pointer channel_; + IAudioInput::Pointer audioInput_; + int32_t session_; +}; + +} +} +} +} diff --git a/include/f1x/openauto/autoapp/Projection/AudioOutput.hpp b/include/f1x/openauto/autoapp/Projection/AudioOutput.hpp new file mode 100644 index 0000000..aa868b4 --- /dev/null +++ b/include/f1x/openauto/autoapp/Projection/AudioOutput.hpp @@ -0,0 +1,67 @@ +/* +* This file is part of openauto project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* openauto is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 3 of the License, or +* (at your option) any later version. + +* openauto is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with openauto. If not, see . +*/ + +#pragma once + +#include +#include +#include +#include + +namespace f1x +{ +namespace openauto +{ +namespace autoapp +{ +namespace projection +{ + +class AudioOutput: public QObject, public IAudioOutput +{ + Q_OBJECT + +public: + AudioOutput(uint32_t channelCount, uint32_t sampleSize, uint32_t sampleRate); + bool open() override; + void write(const aasdk::common::DataConstBuffer& buffer) override; + void start() override; + void stop() override; + uint32_t getSampleSize() const override; + uint32_t getChannelCount() const override; + uint32_t getSampleRate() const override; + +signals: + void startPlayback(); + void stopPlayback(); + +protected slots: + void createAudioOutput(); + void onStartPlayback(); + void onStopPlayback(); + +private: + QAudioFormat audioFormat_; + SequentialBuffer audioBuffer_; + std::unique_ptr audioOutput_; +}; + +} +} +} +} diff --git a/include/f1x/openauto/autoapp/Projection/AudioService.hpp b/include/f1x/openauto/autoapp/Projection/AudioService.hpp new file mode 100644 index 0000000..82e1d5d --- /dev/null +++ b/include/f1x/openauto/autoapp/Projection/AudioService.hpp @@ -0,0 +1,65 @@ +/* +* This file is part of openauto project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* openauto is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 3 of the License, or +* (at your option) any later version. + +* openauto is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with openauto. If not, see . +*/ + +#pragma once + +#include +#include +#include +#include + +namespace f1x +{ +namespace openauto +{ +namespace autoapp +{ +namespace projection +{ + +class AudioService: public aasdk::channel::av::IAudioServiceChannelEventHandler, public IService, public std::enable_shared_from_this +{ +public: + typedef std::shared_ptr Pointer; + + AudioService(boost::asio::io_service& ioService, aasdk::channel::av::IAudioServiceChannel::Pointer channel, IAudioOutput::Pointer audioOutput); + + void start() override; + void stop() override; + void fillFeatures(aasdk::proto::messages::ServiceDiscoveryResponse& response) override; + void onChannelOpenRequest(const aasdk::proto::messages::ChannelOpenRequest& request) override; + void onAVChannelSetupRequest(const aasdk::proto::messages::AVChannelSetupRequest& request) override; + void onAVChannelStartIndication(const aasdk::proto::messages::AVChannelStartIndication& indication) override; + void onAVChannelStopIndication(const aasdk::proto::messages::AVChannelStopIndication& indication) override; + void onAVMediaWithTimestampIndication(aasdk::messenger::Timestamp::ValueType timestamp, const aasdk::common::DataConstBuffer& buffer) override; + void onAVMediaIndication(const aasdk::common::DataConstBuffer& buffer) override; + void onChannelError(const aasdk::error::Error& e) override; + +protected: + using std::enable_shared_from_this::shared_from_this; + + boost::asio::io_service::strand strand_; + aasdk::channel::av::IAudioServiceChannel::Pointer channel_; + IAudioOutput::Pointer audioOutput_; + int32_t session_; +}; + +} +} +} +} diff --git a/include/f1x/openauto/autoapp/Projection/BluetoothService.hpp b/include/f1x/openauto/autoapp/Projection/BluetoothService.hpp new file mode 100644 index 0000000..ddb1730 --- /dev/null +++ b/include/f1x/openauto/autoapp/Projection/BluetoothService.hpp @@ -0,0 +1,56 @@ +/* +* This file is part of openauto project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* openauto is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 3 of the License, or +* (at your option) any later version. + +* openauto is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with openauto. If not, see . +*/ + +#pragma once + +#include +#include +#include + +namespace f1x +{ +namespace openauto +{ +namespace autoapp +{ +namespace projection +{ + +class BluetoothService: public aasdk::channel::bluetooth::IBluetoothServiceChannelEventHandler, public IService, public std::enable_shared_from_this +{ +public: + BluetoothService(boost::asio::io_service& ioService, aasdk::messenger::IMessenger::Pointer messenger, IBluetoothDevice::Pointer bluetoothDevice); + void start() override; + void stop() override; + void fillFeatures(aasdk::proto::messages::ServiceDiscoveryResponse& response) override; + void onChannelOpenRequest(const aasdk::proto::messages::ChannelOpenRequest& request) override; + void onBluetoothPairingRequest(const aasdk::proto::messages::BluetoothPairingRequest& request) override; + void onChannelError(const aasdk::error::Error& e) override; + +private: + using std::enable_shared_from_this::shared_from_this; + + boost::asio::io_service::strand strand_; + aasdk::channel::bluetooth::BluetoothServiceChannel::Pointer channel_; + IBluetoothDevice::Pointer bluetoothDevice_; +}; + +} +} +} +} diff --git a/include/f1x/openauto/autoapp/Projection/DummyBluetoothDevice.hpp b/include/f1x/openauto/autoapp/Projection/DummyBluetoothDevice.hpp new file mode 100644 index 0000000..7dd8717 --- /dev/null +++ b/include/f1x/openauto/autoapp/Projection/DummyBluetoothDevice.hpp @@ -0,0 +1,45 @@ +/* +* This file is part of openauto project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* openauto is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 3 of the License, or +* (at your option) any later version. + +* openauto is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with openauto. If not, see . +*/ + +#pragma once + +#include + +namespace f1x +{ +namespace openauto +{ +namespace autoapp +{ +namespace projection +{ + +class DummyBluetoothDevice: public IBluetoothDevice +{ +public: + void stop() override; + bool isPaired(const std::string& address) const override; + void pair(const std::string& address, PairingPromise::Pointer promise) override; + std::string getLocalAddress() const override; + bool isAvailable() const override; +}; + +} +} +} +} diff --git a/include/f1x/openauto/autoapp/Projection/IAndroidAutoEntity.hpp b/include/f1x/openauto/autoapp/Projection/IAndroidAutoEntity.hpp new file mode 100644 index 0000000..1d249e7 --- /dev/null +++ b/include/f1x/openauto/autoapp/Projection/IAndroidAutoEntity.hpp @@ -0,0 +1,47 @@ +/* +* This file is part of openauto project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* openauto is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 3 of the License, or +* (at your option) any later version. + +* openauto is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with openauto. If not, see . +*/ + +#pragma once + +#include +#include + +namespace f1x +{ +namespace openauto +{ +namespace autoapp +{ +namespace projection +{ + +class IAndroidAutoEntity +{ +public: + typedef std::shared_ptr Pointer; + + virtual ~IAndroidAutoEntity() = default; + + virtual void start(IAndroidAutoEntityEventHandler& eventHandler) = 0; + virtual void stop() = 0; +}; + +} +} +} +} diff --git a/include/f1x/openauto/autoapp/Projection/IAndroidAutoEntityEventHandler.hpp b/include/f1x/openauto/autoapp/Projection/IAndroidAutoEntityEventHandler.hpp new file mode 100644 index 0000000..2a244c1 --- /dev/null +++ b/include/f1x/openauto/autoapp/Projection/IAndroidAutoEntityEventHandler.hpp @@ -0,0 +1,42 @@ +/* +* This file is part of openauto project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* openauto is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 3 of the License, or +* (at your option) any later version. + +* openauto is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with openauto. If not, see . +*/ + +#pragma once + +#include + +namespace f1x +{ +namespace openauto +{ +namespace autoapp +{ +namespace projection +{ + +class IAndroidAutoEntityEventHandler +{ +public: + virtual ~IAndroidAutoEntityEventHandler() = default; + virtual void onAndroidAutoQuit() = 0; +}; + +} +} +} +} diff --git a/include/f1x/openauto/autoapp/Projection/IAndroidAutoEntityFactory.hpp b/include/f1x/openauto/autoapp/Projection/IAndroidAutoEntityFactory.hpp new file mode 100644 index 0000000..ab51c4f --- /dev/null +++ b/include/f1x/openauto/autoapp/Projection/IAndroidAutoEntityFactory.hpp @@ -0,0 +1,44 @@ +/* +* This file is part of openauto project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* openauto is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 3 of the License, or +* (at your option) any later version. + +* openauto is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with openauto. If not, see . +*/ + +#pragma once + +#include +#include + +namespace f1x +{ +namespace openauto +{ +namespace autoapp +{ +namespace projection +{ + +class IAndroidAutoEntityFactory +{ +public: + virtual ~IAndroidAutoEntityFactory() = default; + + virtual IAndroidAutoEntity::Pointer create(aasdk::usb::DeviceHandle deviceHandle) = 0; +}; + +} +} +} +} diff --git a/include/f1x/openauto/autoapp/Projection/IAudioInput.hpp b/include/f1x/openauto/autoapp/Projection/IAudioInput.hpp new file mode 100644 index 0000000..67c3373 --- /dev/null +++ b/include/f1x/openauto/autoapp/Projection/IAudioInput.hpp @@ -0,0 +1,56 @@ +/* +* This file is part of openauto project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* openauto is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 3 of the License, or +* (at your option) any later version. + +* openauto is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with openauto. If not, see . +*/ + +#pragma once + +#include +#include +#include + +namespace f1x +{ +namespace openauto +{ +namespace autoapp +{ +namespace projection +{ + +class IAudioInput +{ +public: + typedef aasdk::io::Promise StartPromise; + typedef aasdk::io::Promise ReadPromise; + typedef std::shared_ptr Pointer; + + virtual ~IAudioInput() = default; + + virtual bool open() = 0; + virtual bool isActive() const = 0; + virtual void read(ReadPromise::Pointer promise) = 0; + virtual void start(StartPromise::Pointer promise) = 0; + virtual void stop() = 0; + virtual uint32_t getSampleSize() const = 0; + virtual uint32_t getChannelCount() const = 0; + virtual uint32_t getSampleRate() const = 0; +}; + +} +} +} +} diff --git a/include/f1x/openauto/autoapp/Projection/IAudioOutput.hpp b/include/f1x/openauto/autoapp/Projection/IAudioOutput.hpp new file mode 100644 index 0000000..4940962 --- /dev/null +++ b/include/f1x/openauto/autoapp/Projection/IAudioOutput.hpp @@ -0,0 +1,53 @@ +/* +* This file is part of openauto project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* openauto is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 3 of the License, or +* (at your option) any later version. + +* openauto is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with openauto. If not, see . +*/ + +#pragma once + +#include +#include + +namespace f1x +{ +namespace openauto +{ +namespace autoapp +{ +namespace projection +{ + +class IAudioOutput +{ +public: + typedef std::shared_ptr Pointer; + + IAudioOutput() = default; + virtual ~IAudioOutput() = default; + + virtual bool open() = 0; + virtual void write(const aasdk::common::DataConstBuffer& buffer) = 0; + virtual void start() = 0; + virtual void stop() = 0; + virtual uint32_t getSampleSize() const = 0; + virtual uint32_t getChannelCount() const = 0; + virtual uint32_t getSampleRate() const = 0; +}; + +} +} +} +} diff --git a/include/f1x/openauto/autoapp/Projection/IBluetoothDevice.hpp b/include/f1x/openauto/autoapp/Projection/IBluetoothDevice.hpp new file mode 100644 index 0000000..2d151fd --- /dev/null +++ b/include/f1x/openauto/autoapp/Projection/IBluetoothDevice.hpp @@ -0,0 +1,48 @@ +/* +* This file is part of openauto project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* openauto is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 3 of the License, or +* (at your option) any later version. + +* openauto is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with openauto. If not, see . +*/ + +#include + +#pragma once + +namespace f1x +{ +namespace openauto +{ +namespace autoapp +{ +namespace projection +{ + +class IBluetoothDevice +{ +public: + typedef aasdk::io::Promise PairingPromise; + typedef std::shared_ptr Pointer; + + virtual void stop() = 0; + virtual bool isPaired(const std::string& address) const = 0; + virtual void pair(const std::string& address, PairingPromise::Pointer promise) = 0; + virtual std::string getLocalAddress() const = 0; + virtual bool isAvailable() const = 0; +}; + +} +} +} +} diff --git a/include/f1x/openauto/autoapp/Projection/IInputDevice.hpp b/include/f1x/openauto/autoapp/Projection/IInputDevice.hpp new file mode 100644 index 0000000..663fbbd --- /dev/null +++ b/include/f1x/openauto/autoapp/Projection/IInputDevice.hpp @@ -0,0 +1,53 @@ +/* +* This file is part of openauto project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* openauto is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 3 of the License, or +* (at your option) any later version. + +* openauto is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with openauto. If not, see . +*/ + +#pragma once + +#include +#include +#include + +namespace f1x +{ +namespace openauto +{ +namespace autoapp +{ +namespace projection +{ + +class IInputDeviceEventHandler; + +class IInputDevice +{ +public: + typedef std::shared_ptr Pointer; + typedef std::vector ButtonCodes; + + virtual ~IInputDevice() = default; + virtual void start(IInputDeviceEventHandler& eventHandler) = 0; + virtual void stop() = 0; + virtual ButtonCodes getSupportedButtonCodes() const = 0; + virtual bool hasTouchscreen() const = 0; + virtual QRect getTouchscreenGeometry() const = 0; +}; + +} +} +} +} diff --git a/include/f1x/openauto/autoapp/Projection/IInputDeviceEventHandler.hpp b/include/f1x/openauto/autoapp/Projection/IInputDeviceEventHandler.hpp new file mode 100644 index 0000000..9521253 --- /dev/null +++ b/include/f1x/openauto/autoapp/Projection/IInputDeviceEventHandler.hpp @@ -0,0 +1,44 @@ +/* +* This file is part of openauto project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* openauto is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 3 of the License, or +* (at your option) any later version. + +* openauto is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with openauto. If not, see . +*/ + +#pragma once + +#include + +namespace f1x +{ +namespace openauto +{ +namespace autoapp +{ +namespace projection +{ + +class IInputDeviceEventHandler +{ +public: + virtual ~IInputDeviceEventHandler() = default; + + virtual void onButtonEvent(const ButtonEvent& event) = 0; + virtual void onTouchEvent(const TouchEvent& event) = 0; +}; + +} +} +} +} diff --git a/include/f1x/openauto/autoapp/Projection/IService.hpp b/include/f1x/openauto/autoapp/Projection/IService.hpp new file mode 100644 index 0000000..cd7c762 --- /dev/null +++ b/include/f1x/openauto/autoapp/Projection/IService.hpp @@ -0,0 +1,51 @@ +/* +* This file is part of openauto project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* openauto is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 3 of the License, or +* (at your option) any later version. + +* openauto is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with openauto. If not, see . +*/ + +#pragma once + +#include +#include +#include + +namespace f1x +{ +namespace openauto +{ +namespace autoapp +{ +namespace projection +{ + +class IService +{ +public: + typedef std::shared_ptr Pointer; + + virtual ~IService() = default; + + virtual void start() = 0; + virtual void stop() = 0; + virtual void fillFeatures(aasdk::proto::messages::ServiceDiscoveryResponse& response) = 0; +}; + +typedef std::vector ServiceList; + +} +} +} +} diff --git a/include/f1x/openauto/autoapp/Projection/IServiceFactory.hpp b/include/f1x/openauto/autoapp/Projection/IServiceFactory.hpp new file mode 100644 index 0000000..4d1563c --- /dev/null +++ b/include/f1x/openauto/autoapp/Projection/IServiceFactory.hpp @@ -0,0 +1,44 @@ +/* +* This file is part of openauto project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* openauto is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 3 of the License, or +* (at your option) any later version. + +* openauto is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with openauto. If not, see . +*/ + +#pragma once + +#include +#include + +namespace f1x +{ +namespace openauto +{ +namespace autoapp +{ +namespace projection +{ + +class IServiceFactory +{ +public: + virtual ~IServiceFactory() = default; + + virtual ServiceList create(aasdk::messenger::IMessenger::Pointer messenger) = 0; +}; + +} +} +} +} diff --git a/include/f1x/openauto/autoapp/Projection/IVideoOutput.hpp b/include/f1x/openauto/autoapp/Projection/IVideoOutput.hpp new file mode 100644 index 0000000..8a65d85 --- /dev/null +++ b/include/f1x/openauto/autoapp/Projection/IVideoOutput.hpp @@ -0,0 +1,56 @@ +/* +* This file is part of openauto project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* openauto is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 3 of the License, or +* (at your option) any later version. + +* openauto is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with openauto. If not, see . +*/ + +#pragma once + +#include +#include +#include +#include + +namespace f1x +{ +namespace openauto +{ +namespace autoapp +{ +namespace projection +{ + +class IVideoOutput +{ +public: + typedef std::shared_ptr Pointer; + + IVideoOutput() = default; + virtual ~IVideoOutput() = default; + + virtual bool open() = 0; + virtual bool init() = 0; + virtual void write(uint64_t timestamp, const aasdk::common::DataConstBuffer& buffer) = 0; + virtual void stop() = 0; + virtual bool isActive() const = 0; + virtual aasdk::proto::enums::VideoFPS::Enum getVideoFPS() const = 0; + virtual aasdk::proto::enums::VideoResolution::Enum getVideoResolution() const = 0; + virtual size_t getScreenDPI() const = 0; +}; + +} +} +} +} diff --git a/include/f1x/openauto/autoapp/Projection/InputDevice.hpp b/include/f1x/openauto/autoapp/Projection/InputDevice.hpp new file mode 100644 index 0000000..b6197a1 --- /dev/null +++ b/include/f1x/openauto/autoapp/Projection/InputDevice.hpp @@ -0,0 +1,66 @@ +/* +* This file is part of openauto project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* openauto is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 3 of the License, or +* (at your option) any later version. + +* openauto is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with openauto. If not, see . +*/ + +#pragma once + +#include +#include +#include +#include + +namespace f1x +{ +namespace openauto +{ +namespace autoapp +{ +namespace projection +{ + +class InputDevice: public QObject, public IInputDevice, boost::noncopyable +{ + Q_OBJECT + +public: + InputDevice(QObject& parent, configuration::IConfiguration::Pointer configuration, const QRect& touchscreenGeometry, const QRect& videoGeometry); + + void start(IInputDeviceEventHandler& eventHandler) override; + void stop() override; + ButtonCodes getSupportedButtonCodes() const override; + bool eventFilter(QObject* obj, QEvent* event) override; + bool hasTouchscreen() const override; + QRect getTouchscreenGeometry() const override; + +private: + void setVideoGeometry(); + bool handleKeyEvent(QEvent* event, QKeyEvent* key); + void dispatchKeyEvent(ButtonEvent event); + bool handleTouchEvent(QEvent* event); + + QObject& parent_; + configuration::IConfiguration::Pointer configuration_; + QRect touchscreenGeometry_; + QRect displayGeometry_; + IInputDeviceEventHandler* eventHandler_; + std::mutex mutex_; +}; + +} +} +} +} diff --git a/include/f1x/openauto/autoapp/Projection/InputEvent.hpp b/include/f1x/openauto/autoapp/Projection/InputEvent.hpp new file mode 100644 index 0000000..fe22064 --- /dev/null +++ b/include/f1x/openauto/autoapp/Projection/InputEvent.hpp @@ -0,0 +1,66 @@ +/* +* This file is part of openauto project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* openauto is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 3 of the License, or +* (at your option) any later version. + +* openauto is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with openauto. If not, see . +*/ + +#pragma once + +#include +#include +#include + +namespace f1x +{ +namespace openauto +{ +namespace autoapp +{ +namespace projection +{ + +enum class ButtonEventType +{ + NONE, + PRESS, + RELEASE +}; + +enum class WheelDirection +{ + NONE, + LEFT, + RIGHT +}; + +struct ButtonEvent +{ + ButtonEventType type; + WheelDirection wheelDirection; + aasdk::proto::enums::ButtonCode::Enum code; +}; + +struct TouchEvent +{ + aasdk::proto::enums::TouchAction::Enum type; + uint32_t x; + uint32_t y; + uint32_t pointerId; +}; + +} +} +} +} diff --git a/include/f1x/openauto/autoapp/Projection/InputService.hpp b/include/f1x/openauto/autoapp/Projection/InputService.hpp new file mode 100644 index 0000000..cb6c5e4 --- /dev/null +++ b/include/f1x/openauto/autoapp/Projection/InputService.hpp @@ -0,0 +1,65 @@ +/* +* This file is part of openauto project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* openauto is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 3 of the License, or +* (at your option) any later version. + +* openauto is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with openauto. If not, see . +*/ + +#pragma once + +#include +#include +#include +#include +#include + +namespace f1x +{ +namespace openauto +{ +namespace autoapp +{ +namespace projection +{ + +class InputService: + public aasdk::channel::input::IInputServiceChannelEventHandler, + public IService, + public IInputDeviceEventHandler, + public std::enable_shared_from_this +{ +public: + InputService(boost::asio::io_service& ioService, aasdk::messenger::IMessenger::Pointer messenger, IInputDevice::Pointer inputDevice); + + void start() override; + void stop() override; + void fillFeatures(aasdk::proto::messages::ServiceDiscoveryResponse& response) override; + void onChannelOpenRequest(const aasdk::proto::messages::ChannelOpenRequest& request) override; + void onBindingRequest(const aasdk::proto::messages::BindingRequest& request) override; + void onChannelError(const aasdk::error::Error& e) override; + void onButtonEvent(const ButtonEvent& event) override; + void onTouchEvent(const TouchEvent& event) override; + +private: + using std::enable_shared_from_this::shared_from_this; + + boost::asio::io_service::strand strand_; + aasdk::channel::input::InputServiceChannel::Pointer channel_; + IInputDevice::Pointer inputDevice_; +}; + +} +} +} +} diff --git a/include/f1x/openauto/autoapp/Projection/LocalBluetoothDevice.hpp b/include/f1x/openauto/autoapp/Projection/LocalBluetoothDevice.hpp new file mode 100644 index 0000000..ed62749 --- /dev/null +++ b/include/f1x/openauto/autoapp/Projection/LocalBluetoothDevice.hpp @@ -0,0 +1,68 @@ +/* +* This file is part of openauto project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* openauto is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 3 of the License, or +* (at your option) any later version. + +* openauto is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with openauto. If not, see . +*/ + +#include +#include + +#pragma once + +namespace f1x +{ +namespace openauto +{ +namespace autoapp +{ +namespace projection +{ + +class LocalBluetoothDevice: public QObject, public IBluetoothDevice +{ + Q_OBJECT + +public: + LocalBluetoothDevice(); + + void stop() override; + bool isPaired(const std::string& address) const override; + void pair(const std::string& address, PairingPromise::Pointer promise) override; + std::string getLocalAddress() const override; + bool isAvailable() const override; + +signals: + void startPairing(const QString& address, PairingPromise::Pointer promise); + +private slots: + void createBluetoothLocalDevice(); + void onStartPairing(const QString& address, PairingPromise::Pointer promise); + void onPairingDisplayConfirmation(const QBluetoothAddress &address, QString pin); + void onPairingDisplayPinCode(const QBluetoothAddress &address, QString pin); + void onPairingFinished(const QBluetoothAddress &address, QBluetoothLocalDevice::Pairing pairing); + void onError(QBluetoothLocalDevice::Error error); + void onHostModeStateChanged(QBluetoothLocalDevice::HostMode state); + +private: + mutable std::mutex mutex_; + std::unique_ptr localDevice_; + PairingPromise::Pointer pairingPromise_; + QBluetoothAddress pairingAddress_; +}; + +} +} +} +} diff --git a/include/f1x/openauto/autoapp/Projection/MediaAudioService.hpp b/include/f1x/openauto/autoapp/Projection/MediaAudioService.hpp new file mode 100644 index 0000000..447952f --- /dev/null +++ b/include/f1x/openauto/autoapp/Projection/MediaAudioService.hpp @@ -0,0 +1,42 @@ +/* +* This file is part of openauto project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* openauto is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 3 of the License, or +* (at your option) any later version. + +* openauto is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with openauto. If not, see . +*/ + +#pragma once + +#include +#include + +namespace f1x +{ +namespace openauto +{ +namespace autoapp +{ +namespace projection +{ + +class MediaAudioService: public AudioService +{ +public: + MediaAudioService(boost::asio::io_service& ioService, aasdk::messenger::IMessenger::Pointer messenger, IAudioOutput::Pointer audioOutput); +}; + +} +} +} +} diff --git a/include/f1x/openauto/autoapp/Projection/OMXVideoOutput.hpp b/include/f1x/openauto/autoapp/Projection/OMXVideoOutput.hpp new file mode 100644 index 0000000..bb4406f --- /dev/null +++ b/include/f1x/openauto/autoapp/Projection/OMXVideoOutput.hpp @@ -0,0 +1,72 @@ +/* +* This file is part of openauto project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* openauto is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 3 of the License, or +* (at your option) any later version. + +* openauto is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with openauto. If not, see . +*/ + +#ifdef USE_OMX +#pragma once + +extern "C" +{ +#include +} + +#include +#include +#include +#include +#include + +namespace f1x +{ +namespace openauto +{ +namespace autoapp +{ +namespace projection +{ + +class OMXVideoOutput: public VideoOutput +{ +public: + OMXVideoOutput(configuration::IConfiguration::Pointer configuration); + + bool open() override; + bool init() override; + void write(uint64_t timestamp, const aasdk::common::DataConstBuffer& buffer) override; + void stop() override; + bool isActive() const override; + +private: + bool createComponents(); + bool initClock(); + bool setupTunnels(); + bool enablePortBuffers(); + + mutable std::mutex mutex_; + bool isActive_; + bool portSettingsChanged_; + ILCLIENT_T* client_; + COMPONENT_T* components_[5]; + TUNNEL_T tunnels_[4]; +}; + +} +} +} +} + +#endif diff --git a/include/f1x/openauto/autoapp/Projection/QtVideoOutput.hpp b/include/f1x/openauto/autoapp/Projection/QtVideoOutput.hpp new file mode 100644 index 0000000..1333a5a --- /dev/null +++ b/include/f1x/openauto/autoapp/Projection/QtVideoOutput.hpp @@ -0,0 +1,67 @@ +/* +* This file is part of openauto project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* openauto is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 3 of the License, or +* (at your option) any later version. + +* openauto is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with openauto. If not, see . +*/ + +#pragma once + +#include +#include +#include +#include +#include + +namespace f1x +{ +namespace openauto +{ +namespace autoapp +{ +namespace projection +{ + +class QtVideoOutput: public QObject, public VideoOutput, boost::noncopyable +{ + Q_OBJECT + +public: + QtVideoOutput(configuration::IConfiguration::Pointer configuration); + bool open() override; + bool init() override; + void write(uint64_t timestamp, const aasdk::common::DataConstBuffer& buffer) override; + void stop() override; + bool isActive() const override; + +signals: + void startPlayback(); + void stopPlayback(); + +protected slots: + void createVideoOutput(); + void onStartPlayback(); + void onStopPlayback(); + +private: + SequentialBuffer videoBuffer_; + std::unique_ptr videoWidget_; + std::unique_ptr mediaPlayer_; + mutable std::mutex mutex_; +}; + +} +} +} +} diff --git a/include/f1x/openauto/autoapp/Projection/RemoteBluetoothDevice.hpp b/include/f1x/openauto/autoapp/Projection/RemoteBluetoothDevice.hpp new file mode 100644 index 0000000..692241c --- /dev/null +++ b/include/f1x/openauto/autoapp/Projection/RemoteBluetoothDevice.hpp @@ -0,0 +1,50 @@ +/* +* This file is part of openauto project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* openauto is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 3 of the License, or +* (at your option) any later version. + +* openauto is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with openauto. If not, see . +*/ + +#pragma once + +#include + +namespace f1x +{ +namespace openauto +{ +namespace autoapp +{ +namespace projection +{ + +class RemoteBluetoothDevice: public IBluetoothDevice +{ +public: + RemoteBluetoothDevice(const std::string& address); + + void stop() override; + bool isPaired(const std::string& address) const override; + void pair(const std::string& address, PairingPromise::Pointer promise) override; + std::string getLocalAddress() const override; + bool isAvailable() const override; + +private: + std::string address_; +}; + +} +} +} +} diff --git a/include/f1x/openauto/autoapp/Projection/SensorService.hpp b/include/f1x/openauto/autoapp/Projection/SensorService.hpp new file mode 100644 index 0000000..53d6b20 --- /dev/null +++ b/include/f1x/openauto/autoapp/Projection/SensorService.hpp @@ -0,0 +1,56 @@ +/* +* This file is part of openauto project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* openauto is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 3 of the License, or +* (at your option) any later version. + +* openauto is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with openauto. If not, see . +*/ + +#pragma once + +#include +#include + +namespace f1x +{ +namespace openauto +{ +namespace autoapp +{ +namespace projection +{ + +class SensorService: public aasdk::channel::sensor::ISensorServiceChannelEventHandler, public IService, public std::enable_shared_from_this +{ +public: + SensorService(boost::asio::io_service& ioService, aasdk::messenger::IMessenger::Pointer messenger); + + void start() override; + void stop() override; + void fillFeatures(aasdk::proto::messages::ServiceDiscoveryResponse& response) override; + void onChannelOpenRequest(const aasdk::proto::messages::ChannelOpenRequest& request) override; + void onSensorStartRequest(const aasdk::proto::messages::SensorStartRequestMessage& request) override; + void onChannelError(const aasdk::error::Error& e) override; + +private: + using std::enable_shared_from_this::shared_from_this; + void sendDrivingStatusUnrestricted(); + + boost::asio::io_service::strand strand_; + aasdk::channel::sensor::SensorServiceChannel::Pointer channel_; +}; + +} +} +} +} diff --git a/include/f1x/openauto/autoapp/Projection/SequentialBuffer.hpp b/include/f1x/openauto/autoapp/Projection/SequentialBuffer.hpp new file mode 100644 index 0000000..361f808 --- /dev/null +++ b/include/f1x/openauto/autoapp/Projection/SequentialBuffer.hpp @@ -0,0 +1,60 @@ +/* +* This file is part of openauto project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* openauto is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 3 of the License, or +* (at your option) any later version. + +* openauto is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with openauto. If not, see . +*/ + +#pragma once + +#include +#include +#include +#include + +namespace f1x +{ +namespace openauto +{ +namespace autoapp +{ +namespace projection +{ + +class SequentialBuffer: public QIODevice +{ +public: + SequentialBuffer(); + bool isSequential() const override; + qint64 size() const override; + qint64 pos() const override; + bool seek(qint64 pos) override; + bool atEnd() const override; + bool reset() override; + bool canReadLine() const override; + qint64 bytesAvailable() const override; + +protected: + qint64 readData(char *data, qint64 maxlen) override; + qint64 writeData(const char *data, qint64 len) override; + +private: + boost::circular_buffer data_; + mutable std::mutex mutex_; +}; + +} +} +} +} diff --git a/include/f1x/openauto/autoapp/Projection/ServiceFactory.hpp b/include/f1x/openauto/autoapp/Projection/ServiceFactory.hpp new file mode 100644 index 0000000..0d929b6 --- /dev/null +++ b/include/f1x/openauto/autoapp/Projection/ServiceFactory.hpp @@ -0,0 +1,51 @@ +/* +* This file is part of openauto project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* openauto is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 3 of the License, or +* (at your option) any later version. + +* openauto is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with openauto. If not, see . +*/ + +#pragma once + +#include +#include + +namespace f1x +{ +namespace openauto +{ +namespace autoapp +{ +namespace projection +{ + +class ServiceFactory: public IServiceFactory +{ +public: + ServiceFactory(boost::asio::io_service& ioService, configuration::IConfiguration::Pointer configuration); + ServiceList create(aasdk::messenger::IMessenger::Pointer messenger) override; + +private: + IService::Pointer createVideoService(aasdk::messenger::IMessenger::Pointer messenger); + IService::Pointer createBluetoothService(aasdk::messenger::IMessenger::Pointer messenger); + IService::Pointer createInputService(aasdk::messenger::IMessenger::Pointer messenger); + + boost::asio::io_service& ioService_; + configuration::IConfiguration::Pointer configuration_; +}; + +} +} +} +} diff --git a/include/f1x/openauto/autoapp/Projection/ServiceFinishPromise.hpp b/include/f1x/openauto/autoapp/Projection/ServiceFinishPromise.hpp new file mode 100644 index 0000000..6b09835 --- /dev/null +++ b/include/f1x/openauto/autoapp/Projection/ServiceFinishPromise.hpp @@ -0,0 +1,37 @@ +/* +* This file is part of openauto project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* openauto is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 3 of the License, or +* (at your option) any later version. + +* openauto is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with openauto. If not, see . +*/ + +#pragma once + +#include + +namespace f1x +{ +namespace openauto +{ +namespace autoapp +{ +namespace projection +{ + +typedef aasdk::io::Promise ServiceFinishPromise; + +} +} +} +} diff --git a/include/f1x/openauto/autoapp/Projection/SpeechAudioService.hpp b/include/f1x/openauto/autoapp/Projection/SpeechAudioService.hpp new file mode 100644 index 0000000..6d3cf0b --- /dev/null +++ b/include/f1x/openauto/autoapp/Projection/SpeechAudioService.hpp @@ -0,0 +1,42 @@ +/* +* This file is part of openauto project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* openauto is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 3 of the License, or +* (at your option) any later version. + +* openauto is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with openauto. If not, see . +*/ + +#pragma once + +#include +#include + +namespace f1x +{ +namespace openauto +{ +namespace autoapp +{ +namespace projection +{ + +class SpeechAudioService: public AudioService +{ +public: + SpeechAudioService(boost::asio::io_service& ioService, aasdk::messenger::IMessenger::Pointer messenger, IAudioOutput::Pointer audioOutput); +}; + +} +} +} +} diff --git a/include/f1x/openauto/autoapp/Projection/SystemAudioService.hpp b/include/f1x/openauto/autoapp/Projection/SystemAudioService.hpp new file mode 100644 index 0000000..e33fdff --- /dev/null +++ b/include/f1x/openauto/autoapp/Projection/SystemAudioService.hpp @@ -0,0 +1,42 @@ +/* +* This file is part of openauto project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* openauto is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 3 of the License, or +* (at your option) any later version. + +* openauto is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with openauto. If not, see . +*/ + +#pragma once + +#include +#include + +namespace f1x +{ +namespace openauto +{ +namespace autoapp +{ +namespace projection +{ + +class SystemAudioService: public AudioService +{ +public: + SystemAudioService(boost::asio::io_service& ioService, aasdk::messenger::IMessenger::Pointer messenger, IAudioOutput::Pointer audioOutput); +}; + +} +} +} +} diff --git a/include/f1x/openauto/autoapp/Projection/VideoOutput.hpp b/include/f1x/openauto/autoapp/Projection/VideoOutput.hpp new file mode 100644 index 0000000..7cfac93 --- /dev/null +++ b/include/f1x/openauto/autoapp/Projection/VideoOutput.hpp @@ -0,0 +1,49 @@ +/* +* This file is part of openauto project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* openauto is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 3 of the License, or +* (at your option) any later version. + +* openauto is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with openauto. If not, see . +*/ + +#pragma once + +#include +#include + +namespace f1x +{ +namespace openauto +{ +namespace autoapp +{ +namespace projection +{ + +class VideoOutput: public IVideoOutput +{ +public: + VideoOutput(configuration::IConfiguration::Pointer configuration); + + aasdk::proto::enums::VideoFPS::Enum getVideoFPS() const override; + aasdk::proto::enums::VideoResolution::Enum getVideoResolution() const override; + size_t getScreenDPI() const override; + +protected: + configuration::IConfiguration::Pointer configuration_; +}; + +} +} +} +} diff --git a/include/f1x/openauto/autoapp/Projection/VideoService.hpp b/include/f1x/openauto/autoapp/Projection/VideoService.hpp new file mode 100644 index 0000000..7896beb --- /dev/null +++ b/include/f1x/openauto/autoapp/Projection/VideoService.hpp @@ -0,0 +1,68 @@ +/* +* This file is part of openauto project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* openauto is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 3 of the License, or +* (at your option) any later version. + +* openauto is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with openauto. If not, see . +*/ + +#pragma once + +#include +#include +#include +#include +#include +#include + +namespace f1x +{ +namespace openauto +{ +namespace autoapp +{ +namespace projection +{ + +class VideoService: public aasdk::channel::av::IVideoServiceChannelEventHandler, public IService, public std::enable_shared_from_this +{ +public: + typedef std::shared_ptr Pointer; + + VideoService(boost::asio::io_service& ioService, aasdk::messenger::IMessenger::Pointer messenger, IVideoOutput::Pointer videoOutput); + + void start() override; + void stop() override; + void fillFeatures(aasdk::proto::messages::ServiceDiscoveryResponse& response) override; + void onChannelOpenRequest(const aasdk::proto::messages::ChannelOpenRequest& request) override; + void onAVChannelSetupRequest(const aasdk::proto::messages::AVChannelSetupRequest& request) override; + void onAVChannelStartIndication(const aasdk::proto::messages::AVChannelStartIndication& indication) override; + void onAVMediaWithTimestampIndication(aasdk::messenger::Timestamp::ValueType timestamp, const aasdk::common::DataConstBuffer& buffer) override; + void onAVMediaIndication(const aasdk::common::DataConstBuffer& buffer) override; + void onVideoFocusRequest(const aasdk::proto::messages::VideoFocusRequest& request) override; + void onChannelError(const aasdk::error::Error& e) override; + +private: + using std::enable_shared_from_this::shared_from_this; + void sendVideoFocusIndication(); + + boost::asio::io_service::strand strand_; + aasdk::channel::av::VideoServiceChannel::Pointer channel_; + IVideoOutput::Pointer videoOutput_; + int32_t session_; +}; + +} +} +} +} diff --git a/include/f1x/openauto/autoapp/UI/MainWindow.hpp b/include/f1x/openauto/autoapp/UI/MainWindow.hpp new file mode 100644 index 0000000..3227837 --- /dev/null +++ b/include/f1x/openauto/autoapp/UI/MainWindow.hpp @@ -0,0 +1,56 @@ +/* +* This file is part of openauto project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* openauto is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 3 of the License, or +* (at your option) any later version. + +* openauto is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with openauto. If not, see . +*/ + +#pragma once + +#include +#include + +namespace Ui +{ +class MainWindow; +} + +namespace f1x +{ +namespace openauto +{ +namespace autoapp +{ +namespace ui +{ + +class MainWindow : public QMainWindow +{ + Q_OBJECT +public: + explicit MainWindow(QWidget *parent = nullptr); + ~MainWindow() override; + +signals: + void exit(); + void openSettings(); + +private: + Ui::MainWindow* ui_; +}; + +} +} +} +} diff --git a/include/f1x/openauto/autoapp/UI/SettingsWindow.hpp b/include/f1x/openauto/autoapp/UI/SettingsWindow.hpp new file mode 100644 index 0000000..058b1de --- /dev/null +++ b/include/f1x/openauto/autoapp/UI/SettingsWindow.hpp @@ -0,0 +1,69 @@ +/* +* This file is part of openauto project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* openauto is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 3 of the License, or +* (at your option) any later version. + +* openauto is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with openauto. If not, see . +*/ + +#pragma once + +#include +#include +#include + +class QCheckBox; + +namespace Ui +{ +class SettingsWindow; +} + +namespace f1x +{ +namespace openauto +{ +namespace autoapp +{ +namespace ui +{ + +class SettingsWindow : public QWidget +{ + Q_OBJECT +public: + explicit SettingsWindow(configuration::IConfiguration::Pointer configuration, QWidget *parent = nullptr); + ~SettingsWindow() override; + +private slots: + void onSave(); + void onResetToDefaults(); + void onUpdateScreenDPI(int value); + void onShowBindings(); + +private: + void showEvent(QShowEvent* event); + void load(); + void loadButtonCheckBoxes(); + void saveButtonCheckBoxes(); + void saveButtonCheckBox(const QCheckBox* checkBox, configuration::IConfiguration::ButtonCodes& buttonCodes, aasdk::proto::enums::ButtonCode::Enum buttonCode); + void setButtonCheckBoxes(bool value); + + Ui::SettingsWindow* ui_; + configuration::IConfiguration::Pointer configuration_; +}; + +} +} +} +} diff --git a/include/f1x/openauto/autoapp/USB/USBApp.hpp b/include/f1x/openauto/autoapp/USB/USBApp.hpp new file mode 100644 index 0000000..76c6955 --- /dev/null +++ b/include/f1x/openauto/autoapp/USB/USBApp.hpp @@ -0,0 +1,63 @@ +/* +* This file is part of openauto project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* openauto is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 3 of the License, or +* (at your option) any later version. + +* openauto is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with openauto. If not, see . +*/ + +#pragma once + +#include +#include +#include + +namespace f1x +{ +namespace openauto +{ +namespace autoapp +{ +namespace usb +{ + +class USBApp: public projection::IAndroidAutoEntityEventHandler, public std::enable_shared_from_this +{ +public: + typedef std::shared_ptr Pointer; + + USBApp(boost::asio::io_service& ioService, projection::IAndroidAutoEntityFactory& androidAutoEntityFactory, aasdk::usb::IUSBHub::Pointer usbHub); + + void start(); + void stop(); + void onAndroidAutoQuit() override; + +private: + using std::enable_shared_from_this::shared_from_this; + + void waitForDevice(); + void aoapDeviceHandler(aasdk::usb::DeviceHandle deviceHandle); + void onUSBHubError(const aasdk::error::Error& error); + + boost::asio::io_service& ioService_; + boost::asio::io_service::strand strand_; + projection::IAndroidAutoEntityFactory& androidAutoEntityFactory_; + aasdk::usb::IUSBHub::Pointer usbHub_; + projection::IAndroidAutoEntity::Pointer androidAutoEntity_; + bool isStopped_; +}; + +} +} +} +} diff --git a/include/f1x/openauto/autoapp/USB/USBMain.hpp b/include/f1x/openauto/autoapp/USB/USBMain.hpp new file mode 100644 index 0000000..481d84b --- /dev/null +++ b/include/f1x/openauto/autoapp/USB/USBMain.hpp @@ -0,0 +1,68 @@ +/* +* This file is part of openauto project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* openauto is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 3 of the License, or +* (at your option) any later version. + +* openauto is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with openauto. If not, see . +*/ + +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace f1x +{ +namespace openauto +{ +namespace autoapp +{ +namespace usb +{ + +class USBMain +{ +public: + USBMain(libusb_context* context); + + int exec(int argc, char* argv[]); + +private: + typedef std::vector ThreadPool; + + void startUSBWorkers(); + void startIOServiceWorkers(); + + libusb_context* usbContext_; + aasdk::usb::USBWrapper usbWrapper_; + boost::asio::io_service ioService_; + aasdk::usb::AccessoryModeQueryFactory queryFactory_; + aasdk::usb::AccessoryModeQueryChainFactory queryChainFactory_; + configuration::IConfiguration::Pointer configuration_; + projection::ServiceFactory serviceFactory_; + projection::AndroidAutoEntityFactory androidAutoEntityFactory_; + autoapp::usb::USBApp::Pointer usbApp_; + ThreadPool threadPool_; +}; + +} +} +} +} diff --git a/src/autoapp/Configuration/Configuration.cpp b/src/autoapp/Configuration/Configuration.cpp new file mode 100644 index 0000000..ec1b67c --- /dev/null +++ b/src/autoapp/Configuration/Configuration.cpp @@ -0,0 +1,273 @@ +/* +* This file is part of openauto project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* openauto is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 3 of the License, or +* (at your option) any later version. + +* openauto is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with openauto. If not, see . +*/ + +#include +#include + +namespace f1x +{ +namespace openauto +{ +namespace autoapp +{ +namespace configuration +{ + +const std::string Configuration::cConfigFileName = "configuration.ini"; + +const std::string Configuration::cGeneralShowClockKey = "General.ShowClock"; +const std::string Configuration::cGeneralHandednessOfTrafficTypeKey = "General.HandednessOfTrafficType"; + +const std::string Configuration::cVideoFPSKey = "Video.FPS"; +const std::string Configuration::cVideoResolutionKey = "Video.Resolution"; +const std::string Configuration::cVideoScreenDPIKey = "Video.ScreenDPI"; + +const std::string Configuration::cBluetoothAdapterTypeKey = "Bluetooth.AdapterType"; +const std::string Configuration::cBluetoothRemoteAdapterAddressKey = "Bluetooth.RemoteAdapterAddress"; + +const std::string Configuration::cInputEnableTouchscreenKey = "Input.EnableTouchscreen"; +const std::string Configuration::cInputPlayButtonKey = "Input.PlayButton"; +const std::string Configuration::cInputPauseButtonKey = "Input.PauseButton"; +const std::string Configuration::cInputTogglePlayButtonKey = "Input.TogglePlayButton"; +const std::string Configuration::cInputNextTrackButtonKey = "Input.NextTrackButton"; +const std::string Configuration::cInputPreviousTrackButtonKey = "Input.PreviousTrackButton"; +const std::string Configuration::cInputHomeButtonKey = "Input.HomeButton"; +const std::string Configuration::cInputPhoneButtonKey = "Input.PhoneButton"; +const std::string Configuration::cInputCallEndButtonKey = "Input.CallEndButton"; +const std::string Configuration::cInputVoiceCommandButtonKey = "Input.VoiceCommandButton"; +const std::string Configuration::cInputLeftButtonKey = "Input.LeftButton"; +const std::string Configuration::cInputRightButtonKey = "Input.RightButton"; +const std::string Configuration::cInputUpButtonKey = "Input.UpButton"; +const std::string Configuration::cInputDownButtonKey = "Input.DownButton"; +const std::string Configuration::cInputScrollWheelButtonKey = "Input.ScrollWheelButton"; +const std::string Configuration::cInputBackButtonKey = "Input.BackButton"; +const std::string Configuration::cInputEnterButtonKey = "Input.EnterButton"; + +Configuration::Configuration() +{ + this->load(); +} + +void Configuration::load() +{ + boost::property_tree::ptree iniConfig; + + try + { + boost::property_tree::ini_parser::read_ini(cConfigFileName, iniConfig); + + handednessOfTrafficType_ = static_cast(iniConfig.get(cGeneralHandednessOfTrafficTypeKey, + static_cast(HandednessOfTrafficType::LEFT_HAND_DRIVE))); + showClock_ = iniConfig.get(cGeneralShowClockKey, true); + + videoFPS_ = static_cast(iniConfig.get(cVideoFPSKey, + aasdk::proto::enums::VideoFPS::_60)); + + videoResolution_ = static_cast(iniConfig.get(cVideoResolutionKey, + aasdk::proto::enums::VideoResolution::_480p)); + screenDPI_ = iniConfig.get(cVideoScreenDPIKey, 140); + + enableTouchscreen_ = iniConfig.get(cInputEnableTouchscreenKey, true); + this->readButtonCodes(iniConfig); + + bluetoothAdapterType_ = static_cast(iniConfig.get(cBluetoothAdapterTypeKey, + static_cast(BluetoothAdapterType::NONE))); + + bluetoothRemoteAdapterAddress_ = iniConfig.get(cBluetoothRemoteAdapterAddressKey, ""); + } + catch(const boost::property_tree::ini_parser_error& e) + { + OPENAUTO_LOG(warning) << "[Configuration] failed to read configuration file: " << cConfigFileName + << ", error: " << e.what(); + this->reset(); + } +} + +void Configuration::reset() +{ + handednessOfTrafficType_ = HandednessOfTrafficType::LEFT_HAND_DRIVE; + showClock_ = true; + videoFPS_ = aasdk::proto::enums::VideoFPS::_60; + videoResolution_ = aasdk::proto::enums::VideoResolution::_480p; + screenDPI_ = 140; + enableTouchscreen_ = true; + buttonCodes_.clear(); + bluetoothAdapterType_ = BluetoothAdapterType::NONE; + bluetoothRemoteAdapterAddress_ = ""; +} + +void Configuration::save() +{ + boost::property_tree::ptree iniConfig; + iniConfig.put(cGeneralHandednessOfTrafficTypeKey, static_cast(handednessOfTrafficType_)); + iniConfig.put(cGeneralShowClockKey, showClock_); + + iniConfig.put(cVideoFPSKey, static_cast(videoFPS_)); + iniConfig.put(cVideoResolutionKey, static_cast(videoResolution_)); + iniConfig.put(cVideoScreenDPIKey, screenDPI_); + + iniConfig.put(cInputEnableTouchscreenKey, enableTouchscreen_); + this->writeButtonCodes(iniConfig); + + iniConfig.put(cBluetoothAdapterTypeKey, static_cast(bluetoothAdapterType_)); + iniConfig.put(cBluetoothRemoteAdapterAddressKey, bluetoothRemoteAdapterAddress_); + boost::property_tree::ini_parser::write_ini(cConfigFileName, iniConfig); +} + +void Configuration::setHandednessOfTrafficType(HandednessOfTrafficType value) +{ + handednessOfTrafficType_ = value; +} + +HandednessOfTrafficType Configuration::getHandednessOfTrafficType() const +{ + return handednessOfTrafficType_; +} + +void Configuration::showClock(bool value) +{ + showClock_ = value; +} + +bool Configuration::showClock() const +{ + return showClock_; +} + +aasdk::proto::enums::VideoFPS::Enum Configuration::getVideoFPS() const +{ + return videoFPS_; +} + +void Configuration::setVideoFPS(aasdk::proto::enums::VideoFPS::Enum value) +{ + videoFPS_ = value; +} + +aasdk::proto::enums::VideoResolution::Enum Configuration::getVideoResolution() const +{ + return videoResolution_; +} + +void Configuration::setVideoResolution(aasdk::proto::enums::VideoResolution::Enum value) +{ + videoResolution_ = value; +} + +size_t Configuration::getScreenDPI() const +{ + return screenDPI_; +} + +void Configuration::setScreenDPI(size_t value) +{ + screenDPI_ = value; +} + +bool Configuration::getTouchscreenEnabled() const +{ + return enableTouchscreen_; +} + +void Configuration::setTouchscreenEnabled(bool value) +{ + enableTouchscreen_ = value; +} + +Configuration::ButtonCodes Configuration::getButtonCodes() const +{ + return buttonCodes_; +} + +void Configuration::setButtonCodes(const ButtonCodes& value) +{ + buttonCodes_ = value; +} + +BluetoothAdapterType Configuration::getBluetoothAdapterType() const +{ + return bluetoothAdapterType_; +} + +void Configuration::setBluetoothAdapterType(BluetoothAdapterType value) +{ + bluetoothAdapterType_ = value; +} + +std::string Configuration::getBluetoothRemoteAdapterAddress() const +{ + return bluetoothRemoteAdapterAddress_; +} + +void Configuration::setBluetoothRemoteAdapterAddress(const std::string& value) +{ + bluetoothRemoteAdapterAddress_ = value; +} + +void Configuration::readButtonCodes(boost::property_tree::ptree& iniConfig) +{ + this->insertButtonCode(iniConfig, cInputPlayButtonKey, aasdk::proto::enums::ButtonCode::PLAY); + this->insertButtonCode(iniConfig, cInputPauseButtonKey, aasdk::proto::enums::ButtonCode::PAUSE); + this->insertButtonCode(iniConfig, cInputTogglePlayButtonKey, aasdk::proto::enums::ButtonCode::TOGGLE_PLAY); + this->insertButtonCode(iniConfig, cInputNextTrackButtonKey, aasdk::proto::enums::ButtonCode::NEXT); + this->insertButtonCode(iniConfig, cInputPreviousTrackButtonKey, aasdk::proto::enums::ButtonCode::PREV); + this->insertButtonCode(iniConfig, cInputHomeButtonKey, aasdk::proto::enums::ButtonCode::HOME); + this->insertButtonCode(iniConfig, cInputPhoneButtonKey, aasdk::proto::enums::ButtonCode::PHONE); + this->insertButtonCode(iniConfig, cInputCallEndButtonKey, aasdk::proto::enums::ButtonCode::CALL_END); + this->insertButtonCode(iniConfig, cInputVoiceCommandButtonKey, aasdk::proto::enums::ButtonCode::MICROPHONE_1); + this->insertButtonCode(iniConfig, cInputLeftButtonKey, aasdk::proto::enums::ButtonCode::LEFT); + this->insertButtonCode(iniConfig, cInputRightButtonKey, aasdk::proto::enums::ButtonCode::RIGHT); + this->insertButtonCode(iniConfig, cInputUpButtonKey, aasdk::proto::enums::ButtonCode::UP); + this->insertButtonCode(iniConfig, cInputDownButtonKey, aasdk::proto::enums::ButtonCode::DOWN); + this->insertButtonCode(iniConfig, cInputScrollWheelButtonKey, aasdk::proto::enums::ButtonCode::SCROLL_WHEEL); + this->insertButtonCode(iniConfig, cInputBackButtonKey, aasdk::proto::enums::ButtonCode::BACK); + this->insertButtonCode(iniConfig, cInputEnterButtonKey, aasdk::proto::enums::ButtonCode::ENTER); +} + +void Configuration::insertButtonCode(boost::property_tree::ptree& iniConfig, const std::string& buttonCodeKey, aasdk::proto::enums::ButtonCode::Enum buttonCode) +{ + if(iniConfig.get(buttonCodeKey, false)) + { + buttonCodes_.push_back(buttonCode); + } +} + +void Configuration::writeButtonCodes(boost::property_tree::ptree& iniConfig) +{ + iniConfig.put(cInputPlayButtonKey, std::find(buttonCodes_.begin(), buttonCodes_.end(), aasdk::proto::enums::ButtonCode::PLAY) != buttonCodes_.end()); + iniConfig.put(cInputPauseButtonKey, std::find(buttonCodes_.begin(), buttonCodes_.end(), aasdk::proto::enums::ButtonCode::PAUSE) != buttonCodes_.end()); + iniConfig.put(cInputTogglePlayButtonKey, std::find(buttonCodes_.begin(), buttonCodes_.end(), aasdk::proto::enums::ButtonCode::TOGGLE_PLAY) != buttonCodes_.end()); + iniConfig.put(cInputNextTrackButtonKey, std::find(buttonCodes_.begin(), buttonCodes_.end(), aasdk::proto::enums::ButtonCode::NEXT) != buttonCodes_.end()); + iniConfig.put(cInputPreviousTrackButtonKey, std::find(buttonCodes_.begin(), buttonCodes_.end(), aasdk::proto::enums::ButtonCode::PREV) != buttonCodes_.end()); + iniConfig.put(cInputHomeButtonKey, std::find(buttonCodes_.begin(), buttonCodes_.end(), aasdk::proto::enums::ButtonCode::HOME) != buttonCodes_.end()); + iniConfig.put(cInputPhoneButtonKey, std::find(buttonCodes_.begin(), buttonCodes_.end(), aasdk::proto::enums::ButtonCode::PHONE) != buttonCodes_.end()); + iniConfig.put(cInputCallEndButtonKey, std::find(buttonCodes_.begin(), buttonCodes_.end(), aasdk::proto::enums::ButtonCode::CALL_END) != buttonCodes_.end()); + iniConfig.put(cInputVoiceCommandButtonKey, std::find(buttonCodes_.begin(), buttonCodes_.end(), aasdk::proto::enums::ButtonCode::MICROPHONE_1) != buttonCodes_.end()); + iniConfig.put(cInputLeftButtonKey, std::find(buttonCodes_.begin(), buttonCodes_.end(), aasdk::proto::enums::ButtonCode::LEFT) != buttonCodes_.end()); + iniConfig.put(cInputRightButtonKey, std::find(buttonCodes_.begin(), buttonCodes_.end(), aasdk::proto::enums::ButtonCode::RIGHT) != buttonCodes_.end()); + iniConfig.put(cInputUpButtonKey, std::find(buttonCodes_.begin(), buttonCodes_.end(), aasdk::proto::enums::ButtonCode::UP) != buttonCodes_.end()); + iniConfig.put(cInputDownButtonKey, std::find(buttonCodes_.begin(), buttonCodes_.end(), aasdk::proto::enums::ButtonCode::DOWN) != buttonCodes_.end()); + iniConfig.put(cInputScrollWheelButtonKey, std::find(buttonCodes_.begin(), buttonCodes_.end(), aasdk::proto::enums::ButtonCode::SCROLL_WHEEL) != buttonCodes_.end()); + iniConfig.put(cInputBackButtonKey, std::find(buttonCodes_.begin(), buttonCodes_.end(), aasdk::proto::enums::ButtonCode::BACK) != buttonCodes_.end()); + iniConfig.put(cInputEnterButtonKey, std::find(buttonCodes_.begin(), buttonCodes_.end(), aasdk::proto::enums::ButtonCode::ENTER) != buttonCodes_.end()); +} + +} +} +} +} diff --git a/src/autoapp/Main.cpp b/src/autoapp/Main.cpp new file mode 100644 index 0000000..0f7783a --- /dev/null +++ b/src/autoapp/Main.cpp @@ -0,0 +1,39 @@ +/* +* This file is part of openauto project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* openauto is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 3 of the License, or +* (at your option) any later version. + +* openauto is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with openauto. If not, see . +*/ + +#include +#include + +namespace aasdk = f1x::aasdk; +namespace autoapp = f1x::openauto::autoapp; + +int main(int argc, char* argv[]) +{ + libusb_context* context; + if(libusb_init(&context) != 0) + { + OPENAUTO_LOG(error) << "[OpenAuto] libusb init failed."; + return 1; + } + + autoapp::usb::USBMain main(context); + auto result = main.exec(argc, argv); + + libusb_exit(context); + return result; +} diff --git a/src/autoapp/Projection/AndroidAutoEntity.cpp b/src/autoapp/Projection/AndroidAutoEntity.cpp new file mode 100644 index 0000000..91205a6 --- /dev/null +++ b/src/autoapp/Projection/AndroidAutoEntity.cpp @@ -0,0 +1,249 @@ +/* +* This file is part of openauto project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* openauto is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 3 of the License, or +* (at your option) any later version. + +* openauto is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with openauto. If not, see . +*/ + +#include +#include +#include +#include +#include + +namespace f1x +{ +namespace openauto +{ +namespace autoapp +{ +namespace projection +{ + +AndroidAutoEntity::AndroidAutoEntity(boost::asio::io_service& ioService, + aasdk::messenger::ICryptor::Pointer cryptor, + aasdk::transport::ITransport::Pointer transport, + configuration::IConfiguration::Pointer configuration, + IServiceFactory& serviceFactory) + : strand_(ioService) + , cryptor_(std::move(cryptor)) + , transport_(std::move(transport)) + , configuration_(std::move(configuration)) + , serviceFactory_(serviceFactory) + , messenger_(std::make_shared(ioService, + std::make_shared(ioService, transport_, cryptor_), + std::make_shared(ioService, transport_, cryptor_))) + , controlServiceChannel_(std::make_shared(strand_, messenger_)) + , eventHandler_(nullptr) +{ +} + +AndroidAutoEntity::~AndroidAutoEntity() +{ + OPENAUTO_LOG(debug) << "[AndroidAutoEntity] destroy."; +} + +void AndroidAutoEntity::start(IAndroidAutoEntityEventHandler& eventHandler) +{ + strand_.dispatch([this, self = this->shared_from_this(), eventHandler = &eventHandler]() { + OPENAUTO_LOG(info) << "[AndroidAutoEntity] start."; + eventHandler_ = eventHandler; + + cryptor_->init(); + + serviceList_ = serviceFactory_.create(messenger_); + std::for_each(serviceList_.begin(), serviceList_.end(), std::bind(&IService::start, std::placeholders::_1)); + + controlServiceChannel_->receive(this->shared_from_this()); + auto versionRequestPromise = aasdk::channel::SendPromise::defer(strand_); + versionRequestPromise->then([]() {}, std::bind(&AndroidAutoEntity::onChannelError, this->shared_from_this(), std::placeholders::_1)); + controlServiceChannel_->sendVersionRequest(std::move(versionRequestPromise)); + }); +} + +void AndroidAutoEntity::stop() +{ + strand_.dispatch([this, self = this->shared_from_this()]() { + OPENAUTO_LOG(info) << "[AndroidAutoEntity] stop."; + this->handleStop(); + }); +} + +void AndroidAutoEntity::onVersionResponse(uint16_t majorCode, uint16_t minorCode, aasdk::proto::enums::VersionResponseStatus::Enum status) +{ + OPENAUTO_LOG(info) << "[AndroidAutoEntity] version response, version: " << majorCode + << "." << minorCode + << ", status: " << status; + + if(status == aasdk::proto::enums::VersionResponseStatus::MISMATCH) + { + OPENAUTO_LOG(error) << "[AndroidAutoEntity] version mismatch."; + eventHandler_->onAndroidAutoQuit(); + } + else + { + OPENAUTO_LOG(info) << "[AndroidAutoEntity] Begin handshake."; + + try + { + cryptor_->doHandshake(); + + auto handshakePromise = aasdk::channel::SendPromise::defer(strand_); + handshakePromise->then([]() {}, std::bind(&AndroidAutoEntity::onChannelError, this->shared_from_this(), std::placeholders::_1)); + controlServiceChannel_->sendHandshake(cryptor_->readHandshakeBuffer(), std::move(handshakePromise)); + controlServiceChannel_->receive(this->shared_from_this()); + } + catch(const aasdk::error::Error& e) + { + this->onChannelError(e); + } + } +} + +void AndroidAutoEntity::onHandshake(const aasdk::common::DataConstBuffer& payload) +{ + OPENAUTO_LOG(info) << "[AndroidAutoEntity] Handshake, size: " << payload.size; + + try + { + cryptor_->writeHandshakeBuffer(payload); + + if(!cryptor_->doHandshake()) + { + OPENAUTO_LOG(info) << "[AndroidAutoEntity] continue handshake."; + + auto handshakePromise = aasdk::channel::SendPromise::defer(strand_); + handshakePromise->then([]() {}, std::bind(&AndroidAutoEntity::onChannelError, this->shared_from_this(), std::placeholders::_1)); + controlServiceChannel_->sendHandshake(cryptor_->readHandshakeBuffer(), std::move(handshakePromise)); + } + else + { + OPENAUTO_LOG(info) << "[AndroidAutoEntity] Auth completed."; + + aasdk::proto::messages::AuthCompleteIndication authCompleteIndication; + authCompleteIndication.set_status(aasdk::proto::enums::Status::OK); + + auto authCompletePromise = aasdk::channel::SendPromise::defer(strand_); + authCompletePromise->then([]() {}, std::bind(&AndroidAutoEntity::onChannelError, this->shared_from_this(), std::placeholders::_1)); + controlServiceChannel_->sendAuthComplete(authCompleteIndication, std::move(authCompletePromise)); + } + + controlServiceChannel_->receive(this->shared_from_this()); + } + catch(const aasdk::error::Error& e) + { + this->onChannelError(e); + } +} + +void AndroidAutoEntity::onServiceDiscoveryRequest(const aasdk::proto::messages::ServiceDiscoveryRequest& request) +{ + OPENAUTO_LOG(info) << "[AndroidAutoEntity] Discovery request, device name: " << request.device_name() + << ", brand: " << request.device_brand(); + + aasdk::proto::messages::ServiceDiscoveryResponse serviceDiscoveryResponse; + serviceDiscoveryResponse.mutable_channels()->Reserve(256); + serviceDiscoveryResponse.set_head_unit_name("OpenAuto"); + serviceDiscoveryResponse.set_car_model("Universal"); + serviceDiscoveryResponse.set_car_year("2018"); + serviceDiscoveryResponse.set_car_serial("20180301"); + serviceDiscoveryResponse.set_left_hand_drive_vehicle(configuration_->getHandednessOfTrafficType() == configuration::HandednessOfTrafficType::LEFT_HAND_DRIVE); + serviceDiscoveryResponse.set_headunit_manufacturer("f1x"); + serviceDiscoveryResponse.set_headunit_model("OpenAuto Autoapp"); + serviceDiscoveryResponse.set_sw_build("1"); + serviceDiscoveryResponse.set_sw_version("1.0"); + serviceDiscoveryResponse.set_can_play_native_media_during_vr(false); + serviceDiscoveryResponse.set_hide_clock(!configuration_->showClock()); + + std::for_each(serviceList_.begin(), serviceList_.end(), std::bind(&IService::fillFeatures, std::placeholders::_1, std::ref(serviceDiscoveryResponse))); + + auto promise = aasdk::channel::SendPromise::defer(strand_); + promise->then([]() {}, std::bind(&AndroidAutoEntity::onChannelError, this->shared_from_this(), std::placeholders::_1)); + controlServiceChannel_->sendServiceDiscoveryResponse(serviceDiscoveryResponse, std::move(promise)); + controlServiceChannel_->receive(this->shared_from_this()); +} + +void AndroidAutoEntity::onAudioFocusRequest(const aasdk::proto::messages::AudioFocusRequest& request) +{ + OPENAUTO_LOG(info) << "[AndroidAutoEntity] requested audio focus, type: " << request.audio_focus_type(); + + aasdk::proto::enums::AudioFocusState::Enum audioFocusState = + request.audio_focus_type() == aasdk::proto::enums::AudioFocusType::RELEASE ? aasdk::proto::enums::AudioFocusState::LOSS + : aasdk::proto::enums::AudioFocusState::GAIN; + + OPENAUTO_LOG(info) << "[AndroidAutoEntity] audio focus state: " << audioFocusState; + + aasdk::proto::messages::AudioFocusResponse response; + response.set_audio_focus_state(audioFocusState); + + auto promise = aasdk::channel::SendPromise::defer(strand_); + promise->then([]() {}, std::bind(&AndroidAutoEntity::onChannelError, this->shared_from_this(), std::placeholders::_1)); + controlServiceChannel_->sendAudioFocusResponse(response, std::move(promise)); + controlServiceChannel_->receive(this->shared_from_this()); +} + +void AndroidAutoEntity::onShutdownRequest(const aasdk::proto::messages::ShutdownRequest& request) +{ + OPENAUTO_LOG(info) << "[AndroidAutoEntity] Shutdown request, reason: " << request.reason(); + + aasdk::proto::messages::ShutdownResponse response; + auto promise = aasdk::channel::SendPromise::defer(strand_); + promise->then([this, self = this->shared_from_this()]() { + eventHandler_->onAndroidAutoQuit(); + }, + std::bind(&AndroidAutoEntity::onChannelError, this->shared_from_this(), std::placeholders::_1)); + + controlServiceChannel_->sendShutdownResponse(response, std::move(promise)); + controlServiceChannel_->receive(this->shared_from_this()); +} + +void AndroidAutoEntity::onShutdownResponse(const aasdk::proto::messages::ShutdownResponse&) +{ + OPENAUTO_LOG(info) << "[AndroidAutoEntity] Shutdown response "; + eventHandler_->onAndroidAutoQuit(); +} + +void AndroidAutoEntity::onNavigationFocusRequest(const aasdk::proto::messages::NavigationFocusRequest& request) +{ + OPENAUTO_LOG(info) << "[AndroidAutoEntity] navigation focus request, type: " << request.type(); + + aasdk::proto::messages::NavigationFocusResponse response; + response.set_type(2); + + auto promise = aasdk::channel::SendPromise::defer(strand_); + promise->then([]() {}, std::bind(&AndroidAutoEntity::onChannelError, this->shared_from_this(), std::placeholders::_1)); + controlServiceChannel_->sendNavigationFocusResponse(response, std::move(promise)); + controlServiceChannel_->receive(this->shared_from_this()); +} + +void AndroidAutoEntity::onChannelError(const aasdk::error::Error& e) +{ + OPENAUTO_LOG(error) << "[AndroidAutoEntity] channel error: " << e.what(); + eventHandler_->onAndroidAutoQuit(); +} + +void AndroidAutoEntity::handleStop() +{ + std::for_each(serviceList_.begin(), serviceList_.end(), std::bind(&IService::stop, std::placeholders::_1)); + + messenger_->stop(); + cryptor_->deinit(); + transport_->stop(); + eventHandler_ = nullptr; +} + +} +} +} +} diff --git a/src/autoapp/Projection/AndroidAutoEntityFactory.cpp b/src/autoapp/Projection/AndroidAutoEntityFactory.cpp new file mode 100644 index 0000000..612b818 --- /dev/null +++ b/src/autoapp/Projection/AndroidAutoEntityFactory.cpp @@ -0,0 +1,61 @@ +/* +* This file is part of openauto project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* openauto is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 3 of the License, or +* (at your option) any later version. + +* openauto is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with openauto. If not, see . +*/ + +#include +#include +#include +#include +#include +#include + +namespace f1x +{ +namespace openauto +{ +namespace autoapp +{ +namespace projection +{ + +AndroidAutoEntityFactory::AndroidAutoEntityFactory(aasdk::usb::IUSBWrapper& usbWrapper, + boost::asio::io_service& ioService, + configuration::IConfiguration::Pointer configuration, + IServiceFactory& serviceFactory) + : usbWrapper_(usbWrapper) + , ioService_(ioService) + , configuration_(std::move(configuration)) + , serviceFactory_(serviceFactory) +{ + +} + +IAndroidAutoEntity::Pointer AndroidAutoEntityFactory::create(aasdk::usb::DeviceHandle deviceHandle) +{ + auto aoapDevice(aasdk::usb::AOAPDevice::create(usbWrapper_, ioService_, deviceHandle)); + auto transport(std::make_shared(ioService_, aoapDevice)); + + auto sslWrapper(std::make_shared()); + auto cryptor(std::make_shared(std::move(sslWrapper))); + + return std::make_shared(ioService_, std::move(cryptor), std::move(transport), configuration_, serviceFactory_); +} + +} +} +} +} diff --git a/src/autoapp/Projection/AudioInput.cpp b/src/autoapp/Projection/AudioInput.cpp new file mode 100644 index 0000000..4fbe1ff --- /dev/null +++ b/src/autoapp/Projection/AudioInput.cpp @@ -0,0 +1,172 @@ +/* +* This file is part of openauto project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* openauto is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 3 of the License, or +* (at your option) any later version. + +* openauto is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with openauto. If not, see . +*/ + +#include +#include +#include + +namespace f1x +{ +namespace openauto +{ +namespace autoapp +{ +namespace projection +{ + +AudioInput::AudioInput(uint32_t channelCount, uint32_t sampleSize, uint32_t sampleRate) + : ioDevice_(nullptr) +{ + qRegisterMetaType("StartPromise::Pointer"); + + audioFormat_.setChannelCount(channelCount); + audioFormat_.setSampleRate(sampleRate); + audioFormat_.setSampleSize(sampleSize); + audioFormat_.setCodec("audio/pcm"); + audioFormat_.setByteOrder(QAudioFormat::LittleEndian); + audioFormat_.setSampleType(QAudioFormat::SignedInt); + + this->moveToThread(QApplication::instance()->thread()); + connect(this, &AudioInput::startRecording, this, &AudioInput::onStartRecording, Qt::QueuedConnection); + connect(this, &AudioInput::stopRecording, this, &AudioInput::onStopRecording, Qt::QueuedConnection); + QMetaObject::invokeMethod(this, "createAudioInput", Qt::BlockingQueuedConnection); +} + +void AudioInput::createAudioInput() +{ + OPENAUTO_LOG(debug) << "[AudioInput] create."; + audioInput_ = (std::make_unique(QAudioDeviceInfo::defaultInputDevice(), audioFormat_)); +} + +bool AudioInput::open() +{ + std::lock_guard lock(mutex_); + + return ioDevice_ == nullptr; +} + +bool AudioInput::isActive() const +{ + std::lock_guard lock(mutex_); + + return ioDevice_ != nullptr; +} + +void AudioInput::read(ReadPromise::Pointer promise) +{ + std::lock_guard lock(mutex_); + + if(ioDevice_ == nullptr) + { + promise->reject(); + } + else if(readPromise_ != nullptr) + { + promise->reject(); + } + else + { + readPromise_ = std::move(promise); + } +} + +void AudioInput::start(StartPromise::Pointer promise) +{ + emit startRecording(std::move(promise)); +} + +void AudioInput::stop() +{ + emit stopRecording(); +} + +uint32_t AudioInput::getSampleSize() const +{ + std::lock_guard lock(mutex_); + return audioFormat_.sampleSize(); +} + +uint32_t AudioInput::getChannelCount() const +{ + std::lock_guard lock(mutex_); + return audioFormat_.channelCount(); +} + +uint32_t AudioInput::getSampleRate() const +{ + std::lock_guard lock(mutex_); + return audioFormat_.sampleRate(); +} + +void AudioInput::onStartRecording(StartPromise::Pointer promise) +{ + ioDevice_ = audioInput_->start(); + + if(ioDevice_ != nullptr) + { + connect(ioDevice_, &QIODevice::readyRead, this, &AudioInput::onReadyRead, Qt::QueuedConnection); + promise->resolve(); + } + else + { + promise->reject(); + } +} + +void AudioInput::onStopRecording() +{ + if(readPromise_ != nullptr) + { + readPromise_->reject(); + readPromise_.reset(); + } + + ioDevice_->reset(); + ioDevice_->disconnect(); + audioInput_->stop(); + ioDevice_ = nullptr; +} + +void AudioInput::onReadyRead() +{ + if(readPromise_ == nullptr) + { + return; + } + + aasdk::common::Data data(cSampleSize, 0); + aasdk::common::DataBuffer buffer(data); + auto readSize = ioDevice_->read(reinterpret_cast(buffer.data), buffer.size); + + if(readSize != -1) + { + data.resize(readSize); + readPromise_->resolve(std::move(data)); + readPromise_.reset(); + } + else + { + readPromise_->reject(); + readPromise_.reset(); + } +} + +} +} +} +} diff --git a/src/autoapp/Projection/AudioInputService.cpp b/src/autoapp/Projection/AudioInputService.cpp new file mode 100644 index 0000000..527c842 --- /dev/null +++ b/src/autoapp/Projection/AudioInputService.cpp @@ -0,0 +1,208 @@ +/* +* This file is part of openauto project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* openauto is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 3 of the License, or +* (at your option) any later version. + +* openauto is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with openauto. If not, see . +*/ + +#include +#include +#include + +namespace f1x +{ +namespace openauto +{ +namespace autoapp +{ +namespace projection +{ + +AudioInputService::AudioInputService(boost::asio::io_service& ioService, aasdk::messenger::IMessenger::Pointer messenger, IAudioInput::Pointer audioInput) + : strand_(ioService) + , channel_(std::make_shared(strand_, std::move(messenger))) + , audioInput_(std::move(audioInput)) + , session_(0) +{ + +} + +void AudioInputService::start() +{ + strand_.dispatch([this, self = this->shared_from_this()]() { + OPENAUTO_LOG(info) << "[AudioInputService] start."; + channel_->receive(this->shared_from_this()); + }); +} + +void AudioInputService::stop() +{ + strand_.dispatch([this, self = this->shared_from_this()]() { + OPENAUTO_LOG(info) << "[AudioInputService] stop."; + + if(audioInput_->isActive()) + { + audioInput_->stop(); + } + }); +} + +void AudioInputService::fillFeatures(aasdk::proto::messages::ServiceDiscoveryResponse& response) +{ + OPENAUTO_LOG(info) << "[AudioInputService] fill features."; + + auto* channelDescriptor = response.add_channels(); + channelDescriptor->set_channel_id(static_cast(channel_->getId())); + + auto* avInputChannel = channelDescriptor->mutable_av_input_channel(); + avInputChannel->set_stream_type(aasdk::proto::enums::AVStreamType::AUDIO); + + auto audioConfig = avInputChannel->mutable_audio_config(); + audioConfig->set_sample_rate(audioInput_->getSampleRate()); + audioConfig->set_bit_depth(audioInput_->getSampleSize()); + audioConfig->set_channel_count(audioInput_->getChannelCount()); +} + +void AudioInputService::onChannelOpenRequest(const aasdk::proto::messages::ChannelOpenRequest& request) +{ + OPENAUTO_LOG(info) << "[AudioInputService] open request, priority: " << request.priority(); + const aasdk::proto::enums::Status::Enum status = audioInput_->open() ? aasdk::proto::enums::Status::OK : aasdk::proto::enums::Status::FAIL; + OPENAUTO_LOG(info) << "[AudioInputService] open status: " << status; + + aasdk::proto::messages::ChannelOpenResponse response; + response.set_status(status); + + auto promise = aasdk::channel::SendPromise::defer(strand_); + promise->then([]() {}, std::bind(&AudioInputService::onChannelError, this->shared_from_this(), std::placeholders::_1)); + channel_->sendChannelOpenResponse(response, std::move(promise)); + + channel_->receive(this->shared_from_this()); +} + +void AudioInputService::onAVChannelSetupRequest(const aasdk::proto::messages::AVChannelSetupRequest& request) +{ + OPENAUTO_LOG(info) << "[AudioInputService] setup request, config index: " << request.config_index(); + const aasdk::proto::enums::AVChannelSetupStatus::Enum status = aasdk::proto::enums::AVChannelSetupStatus::OK; + OPENAUTO_LOG(info) << "[AudioInputService] setup status: " << status; + + + aasdk::proto::messages::AVChannelSetupResponse response; + response.set_media_status(status); + response.set_max_unacked(1); + response.add_configs(0); + + auto promise = aasdk::channel::SendPromise::defer(strand_); + promise->then([]() {}, std::bind(&AudioInputService::onChannelError, this->shared_from_this(), std::placeholders::_1)); + channel_->sendAVChannelSetupResponse(response, std::move(promise)); + + channel_->receive(this->shared_from_this()); +} + +void AudioInputService::onAVInputOpenRequest(const aasdk::proto::messages::AVInputOpenRequest& request) +{ + OPENAUTO_LOG(info) << "[AudioInputService] input open request, open: " << request.open() + << ", anc: " << request.anc() + << ", ec: " << request.ec() + << ", max unacked: " << request.max_unacked(); + + if(request.open()) + { + auto startPromise = IAudioInput::StartPromise::defer(strand_); + startPromise->then(std::bind(&AudioInputService::onAudioInputOpenSucceed, this->shared_from_this()), + [this, self = this->shared_from_this()]() { + OPENAUTO_LOG(error) << "[AudioInputService] audio input open failed."; + + aasdk::proto::messages::AVInputOpenResponse response; + response.set_session(session_); + response.set_value(1); + + auto sendPromise = aasdk::channel::SendPromise::defer(strand_); + sendPromise->then([]() {}, std::bind(&AudioInputService::onChannelError, this->shared_from_this(), std::placeholders::_1)); + channel_->sendAVInputOpenResponse(response, std::move(sendPromise)); + }); + + audioInput_->start(std::move(startPromise)); + } + else + { + audioInput_->stop(); + + aasdk::proto::messages::AVInputOpenResponse response; + response.set_session(session_); + response.set_value(0); + + auto sendPromise = aasdk::channel::SendPromise::defer(strand_); + sendPromise->then([]() {}, std::bind(&AudioInputService::onChannelError, this->shared_from_this(), std::placeholders::_1)); + channel_->sendAVInputOpenResponse(response, std::move(sendPromise)); + } + + channel_->receive(this->shared_from_this()); +} + +void AudioInputService::onAVMediaAckIndication(const aasdk::proto::messages::AVMediaAckIndication&) +{ + channel_->receive(this->shared_from_this()); +} + +void AudioInputService::onChannelError(const aasdk::error::Error& e) +{ + OPENAUTO_LOG(error) << "[AudioInputService] channel error: " << e.what(); +} + +void AudioInputService::onAudioInputOpenSucceed() +{ + OPENAUTO_LOG(info) << "[AudioInputService] audio input open succeed."; + + aasdk::proto::messages::AVInputOpenResponse response; + response.set_session(session_); + response.set_value(0); + + auto sendPromise = aasdk::channel::SendPromise::defer(strand_); + sendPromise->then([]() {}, std::bind(&AudioInputService::onChannelError, this->shared_from_this(), std::placeholders::_1)); + channel_->sendAVInputOpenResponse(response, std::move(sendPromise)); + + this->readAudioInput(); +} + +void AudioInputService::onAudioInputDataReady(aasdk::common::Data data) +{ + auto sendPromise = aasdk::channel::SendPromise::defer(strand_); + sendPromise->then(std::bind(&AudioInputService::readAudioInput, this->shared_from_this()), + std::bind(&AudioInputService::onChannelError, this->shared_from_this(), std::placeholders::_1)); + + + timespec tp; + clock_gettime(CLOCK_REALTIME, &tp); + auto timestamp = tp.tv_sec * 1000000 + tp.tv_nsec / 1000; + channel_->sendAVMediaWithTimestampIndication(timestamp, std::move(data), std::move(sendPromise)); +} + +void AudioInputService::readAudioInput() +{ + if(audioInput_->isActive()) + { + auto readPromise = IAudioInput::ReadPromise::defer(strand_); + readPromise->then(std::bind(&AudioInputService::onAudioInputDataReady, this->shared_from_this(), std::placeholders::_1), + [this, self = this->shared_from_this()]() { + OPENAUTO_LOG(info) << "[AudioInputService] audio input read rejected."; + }); + + audioInput_->read(std::move(readPromise)); + } +} + +} +} +} +} diff --git a/src/autoapp/Projection/AudioOutput.cpp b/src/autoapp/Projection/AudioOutput.cpp new file mode 100644 index 0000000..924953c --- /dev/null +++ b/src/autoapp/Projection/AudioOutput.cpp @@ -0,0 +1,102 @@ +/* +* This file is part of openauto project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* openauto is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 3 of the License, or +* (at your option) any later version. + +* openauto is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with openauto. If not, see . +*/ + +#include +#include +#include + +namespace f1x +{ +namespace openauto +{ +namespace autoapp +{ +namespace projection +{ + +AudioOutput::AudioOutput(uint32_t channelCount, uint32_t sampleSize, uint32_t sampleRate) +{ + audioFormat_.setChannelCount(channelCount); + audioFormat_.setSampleRate(sampleRate); + audioFormat_.setSampleSize(sampleSize); + audioFormat_.setCodec("audio/pcm"); + audioFormat_.setByteOrder(QAudioFormat::LittleEndian); + audioFormat_.setSampleType(QAudioFormat::SignedInt); + + this->moveToThread(QApplication::instance()->thread()); + connect(this, &AudioOutput::startPlayback, this, &AudioOutput::onStartPlayback); + connect(this, &AudioOutput::stopPlayback, this, &AudioOutput::onStopPlayback); + + QMetaObject::invokeMethod(this, "createAudioOutput", Qt::BlockingQueuedConnection); +} + +void AudioOutput::createAudioOutput() +{ + OPENAUTO_LOG(debug) << "[AudioOutput] create."; + audioOutput_ = std::make_unique(QAudioDeviceInfo::defaultOutputDevice(), audioFormat_); +} + +bool AudioOutput::open() +{ + return audioBuffer_.open(QIODevice::ReadWrite); +} + +void AudioOutput::write(const aasdk::common::DataConstBuffer& buffer) +{ + audioBuffer_.write(reinterpret_cast(buffer.cdata), buffer.size); +} + +void AudioOutput::start() +{ + emit startPlayback(); +} + +void AudioOutput::stop() +{ + emit stopPlayback(); +} + +uint32_t AudioOutput::getSampleSize() const +{ + return audioFormat_.sampleSize(); +} + +uint32_t AudioOutput::getChannelCount() const +{ + return audioFormat_.channelCount(); +} + +uint32_t AudioOutput::getSampleRate() const +{ + return audioFormat_.sampleRate(); +} + +void AudioOutput::onStartPlayback() +{ + audioOutput_->start(&audioBuffer_); +} + +void AudioOutput::onStopPlayback() +{ + audioOutput_->suspend(); +} + +} +} +} +} diff --git a/src/autoapp/Projection/AudioService.cpp b/src/autoapp/Projection/AudioService.cpp new file mode 100644 index 0000000..c2df8f2 --- /dev/null +++ b/src/autoapp/Projection/AudioService.cpp @@ -0,0 +1,176 @@ +/* +* This file is part of openauto project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* openauto is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 3 of the License, or +* (at your option) any later version. + +* openauto is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with openauto. If not, see . +*/ + +#include +#include + +namespace f1x +{ +namespace openauto +{ +namespace autoapp +{ +namespace projection +{ + +AudioService::AudioService(boost::asio::io_service& ioService, aasdk::channel::av::IAudioServiceChannel::Pointer channel, IAudioOutput::Pointer audioOutput) + : strand_(ioService) + , channel_(std::move(channel)) + , audioOutput_(std::move(audioOutput)) + , session_(-1) +{ + +} + +void AudioService::start() +{ + strand_.dispatch([this, self = this->shared_from_this()]() { + OPENAUTO_LOG(info) << "[AudioService] start, channel: " << aasdk::messenger::channelIdToString(channel_->getId()); + channel_->receive(this->shared_from_this()); + }); +} + +void AudioService::stop() +{ + strand_.dispatch([this, self = this->shared_from_this()]() { + OPENAUTO_LOG(info) << "[AudioService] stop, channel: " << aasdk::messenger::channelIdToString(channel_->getId()); + audioOutput_->stop(); + }); +} + +void AudioService::fillFeatures(aasdk::proto::messages::ServiceDiscoveryResponse& response) +{ + OPENAUTO_LOG(info) << "[AudioService] fill features, channel: " << aasdk::messenger::channelIdToString(channel_->getId()); + + auto* channelDescriptor = response.add_channels(); + channelDescriptor->set_channel_id(static_cast(channel_->getId())); + + auto* audioChannel = channelDescriptor->mutable_av_channel(); + audioChannel->set_stream_type(aasdk::proto::enums::AVStreamType::AUDIO); + + switch(channel_->getId()) + { + case aasdk::messenger::ChannelId::SYSTEM_AUDIO: + audioChannel->set_audio_type(aasdk::proto::enums::AudioType::SYSTEM); + break; + + case aasdk::messenger::ChannelId::MEDIA_AUDIO: + audioChannel->set_audio_type(aasdk::proto::enums::AudioType::MEDIA); + break; + + case aasdk::messenger::ChannelId::SPEECH_AUDIO: + audioChannel->set_audio_type(aasdk::proto::enums::AudioType::SPEECH); + break; + default: + break; + } + + audioChannel->set_available_while_in_call(true); + + auto* audioConfig = audioChannel->add_audio_configs(); + audioConfig->set_sample_rate(audioOutput_->getSampleRate()); + audioConfig->set_bit_depth(audioOutput_->getSampleSize()); + audioConfig->set_channel_count(audioOutput_->getChannelCount()); +} + +void AudioService::onChannelOpenRequest(const aasdk::proto::messages::ChannelOpenRequest& request) +{ + OPENAUTO_LOG(info) << "[AudioService] open request" + << ", channel: " << aasdk::messenger::channelIdToString(channel_->getId()) + << ", priority: " << request.priority(); + const aasdk::proto::enums::Status::Enum status = audioOutput_->open() ? aasdk::proto::enums::Status::OK : aasdk::proto::enums::Status::FAIL; + OPENAUTO_LOG(info) << "[AudioService] open status: " << status + << ", channel: " << aasdk::messenger::channelIdToString(channel_->getId()); + + aasdk::proto::messages::ChannelOpenResponse response; + response.set_status(status); + + auto promise = aasdk::channel::SendPromise::defer(strand_); + promise->then([]() {}, std::bind(&AudioService::onChannelError, this->shared_from_this(), std::placeholders::_1)); + channel_->sendChannelOpenResponse(response, std::move(promise)); + channel_->receive(this->shared_from_this()); +} + +void AudioService::onAVChannelSetupRequest(const aasdk::proto::messages::AVChannelSetupRequest& request) +{ + OPENAUTO_LOG(info) << "[AudioService] setup request" + << ", channel: " << aasdk::messenger::channelIdToString(channel_->getId()) + << ", config index: " << request.config_index(); + const aasdk::proto::enums::AVChannelSetupStatus::Enum status = aasdk::proto::enums::AVChannelSetupStatus::OK; + OPENAUTO_LOG(info) << "[AudioService] setup status: " << status + << ", channel: " << aasdk::messenger::channelIdToString(channel_->getId()); + + aasdk::proto::messages::AVChannelSetupResponse response; + response.set_media_status(status); + response.set_max_unacked(1); + response.add_configs(0); + + auto promise = aasdk::channel::SendPromise::defer(strand_); + promise->then([]() {}, std::bind(&AudioService::onChannelError, this->shared_from_this(), std::placeholders::_1)); + channel_->sendAVChannelSetupResponse(response, std::move(promise)); + channel_->receive(this->shared_from_this()); +} + +void AudioService::onAVChannelStartIndication(const aasdk::proto::messages::AVChannelStartIndication& indication) +{ + OPENAUTO_LOG(info) << "[AudioService] start indication" + << ", channel: " << aasdk::messenger::channelIdToString(channel_->getId()) + << ", session: " << indication.session(); + session_ = indication.session(); + audioOutput_->start(); + channel_->receive(this->shared_from_this()); +} + +void AudioService::onAVChannelStopIndication(const aasdk::proto::messages::AVChannelStopIndication& indication) +{ + OPENAUTO_LOG(info) << "[AudioService] stop indication" + << ", channel: " << aasdk::messenger::channelIdToString(channel_->getId()) + << ", session: " << session_; + session_ = -1; + audioOutput_->stop(); + channel_->receive(this->shared_from_this()); +} + +void AudioService::onAVMediaWithTimestampIndication(aasdk::messenger::Timestamp::ValueType, const aasdk::common::DataConstBuffer& buffer) +{ + this->onAVMediaIndication(buffer); +} + +void AudioService::onAVMediaIndication(const aasdk::common::DataConstBuffer& buffer) +{ + audioOutput_->write(buffer); + aasdk::proto::messages::AVMediaAckIndication indication; + indication.set_session(session_); + indication.set_value(1); + + auto promise = aasdk::channel::SendPromise::defer(strand_); + promise->then([]() {}, std::bind(&AudioService::onChannelError, this->shared_from_this(), std::placeholders::_1)); + channel_->sendAVMediaAckIndication(indication, std::move(promise)); + channel_->receive(this->shared_from_this()); +} + +void AudioService::onChannelError(const aasdk::error::Error& e) +{ + OPENAUTO_LOG(error) << "[AudioService] channel error: " << e.what() + << ", channel: " << aasdk::messenger::channelIdToString(channel_->getId()); +} + +} +} +} +} diff --git a/src/autoapp/Projection/BluetoothService.cpp b/src/autoapp/Projection/BluetoothService.cpp new file mode 100644 index 0000000..c8712a5 --- /dev/null +++ b/src/autoapp/Projection/BluetoothService.cpp @@ -0,0 +1,111 @@ +/* +* This file is part of openauto project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* openauto is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 3 of the License, or +* (at your option) any later version. + +* openauto is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with openauto. If not, see . +*/ + +#include +#include + +namespace f1x +{ +namespace openauto +{ +namespace autoapp +{ +namespace projection +{ + +BluetoothService::BluetoothService(boost::asio::io_service& ioService, aasdk::messenger::IMessenger::Pointer messenger, IBluetoothDevice::Pointer bluetoothDevice) + : strand_(ioService) + , channel_(std::make_shared(strand_, std::move(messenger))) + , bluetoothDevice_(std::move(bluetoothDevice)) +{ + +} + +void BluetoothService::start() +{ + strand_.dispatch([this, self = this->shared_from_this()]() { + OPENAUTO_LOG(info) << "[BluetoothService] start."; + channel_->receive(this->shared_from_this()); + }); +} + +void BluetoothService::stop() +{ + strand_.dispatch([this, self = this->shared_from_this()]() { + OPENAUTO_LOG(info) << "[BluetoothService] stop."; + bluetoothDevice_->stop(); + }); +} + +void BluetoothService::fillFeatures(aasdk::proto::messages::ServiceDiscoveryResponse& response) +{ + OPENAUTO_LOG(info) << "[BluetoothService] fill features"; + + if(bluetoothDevice_->isAvailable()) + { + OPENAUTO_LOG(info) << "[BluetoothService] sending local adapter adress: " << bluetoothDevice_->getLocalAddress(); + + auto* channelDescriptor = response.add_channels(); + channelDescriptor->set_channel_id(static_cast(channel_->getId())); + auto bluetoothChannel = channelDescriptor->mutable_bluetooth_channel(); + bluetoothChannel->set_adapter_address(bluetoothDevice_->getLocalAddress()); + } +} + +void BluetoothService::onChannelOpenRequest(const aasdk::proto::messages::ChannelOpenRequest& request) +{ + OPENAUTO_LOG(info) << "[BluetoothService] open request, priority: " << request.priority(); + const aasdk::proto::enums::Status::Enum status = aasdk::proto::enums::Status::OK; + OPENAUTO_LOG(info) << "[BluetoothService] open status: " << status; + + aasdk::proto::messages::ChannelOpenResponse response; + response.set_status(status); + + auto promise = aasdk::channel::SendPromise::defer(strand_); + promise->then([]() {}, std::bind(&BluetoothService::onChannelError, this->shared_from_this(), std::placeholders::_1)); + channel_->sendChannelOpenResponse(response, std::move(promise)); + + channel_->receive(this->shared_from_this()); +} + +void BluetoothService::onBluetoothPairingRequest(const aasdk::proto::messages::BluetoothPairingRequest& request) +{ + OPENAUTO_LOG(info) << "[BluetoothService] pairing request, address: " << request.phone_address(); + + aasdk::proto::messages::BluetoothPairingResponse response; + + const auto isPaired = bluetoothDevice_->isPaired(request.phone_address()); + response.set_already_paired(isPaired); + response.set_status(isPaired ? aasdk::proto::enums::BluetoothPairingStatus::OK : aasdk::proto::enums::BluetoothPairingStatus::FAIL); + + auto promise = aasdk::channel::SendPromise::defer(strand_); + promise->then([]() {}, std::bind(&BluetoothService::onChannelError, this->shared_from_this(), std::placeholders::_1)); + channel_->sendBluetoothPairingResponse(response, std::move(promise)); + + channel_->receive(this->shared_from_this()); +} + +void BluetoothService::onChannelError(const aasdk::error::Error& e) +{ + OPENAUTO_LOG(error) << "[BluetoothService] channel error: " << e.what(); +} + +} +} +} +} diff --git a/src/autoapp/Projection/DummyBluetoothDevice.cpp b/src/autoapp/Projection/DummyBluetoothDevice.cpp new file mode 100644 index 0000000..cf45ac4 --- /dev/null +++ b/src/autoapp/Projection/DummyBluetoothDevice.cpp @@ -0,0 +1,58 @@ +/* +* This file is part of openauto project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* openauto is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 3 of the License, or +* (at your option) any later version. + +* openauto is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with openauto. If not, see . +*/ + +#include + +namespace f1x +{ +namespace openauto +{ +namespace autoapp +{ +namespace projection +{ + +void DummyBluetoothDevice::stop() +{ + +} + +bool DummyBluetoothDevice::isPaired(const std::string&) const +{ + return false; +} + +void DummyBluetoothDevice::pair(const std::string&, PairingPromise::Pointer promise) +{ + promise->reject(); +} + +std::string DummyBluetoothDevice::getLocalAddress() const +{ + return ""; +} + +bool DummyBluetoothDevice::isAvailable() const +{ + return false; +} + +} +} +} +} diff --git a/src/autoapp/Projection/InputDevice.cpp b/src/autoapp/Projection/InputDevice.cpp new file mode 100644 index 0000000..52c2f1a --- /dev/null +++ b/src/autoapp/Projection/InputDevice.cpp @@ -0,0 +1,233 @@ +/* +* This file is part of openauto project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* openauto is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 3 of the License, or +* (at your option) any later version. + +* openauto is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with openauto. If not, see . +*/ + +#include +#include +#include + +namespace f1x +{ +namespace openauto +{ +namespace autoapp +{ +namespace projection +{ + +InputDevice::InputDevice(QObject& parent, configuration::IConfiguration::Pointer configuration, const QRect& touchscreenGeometry, const QRect& displayGeometry) + : parent_(parent) + , configuration_(std::move(configuration)) + , touchscreenGeometry_(touchscreenGeometry) + , displayGeometry_(displayGeometry) + , eventHandler_(nullptr) +{ + this->moveToThread(parent.thread()); +} + +void InputDevice::start(IInputDeviceEventHandler& eventHandler) +{ + std::lock_guard lock(mutex_); + + OPENAUTO_LOG(info) << "[InputDevice] start."; + eventHandler_ = &eventHandler; + parent_.installEventFilter(this); +} + +void InputDevice::stop() +{ + std::lock_guard lock(mutex_); + + OPENAUTO_LOG(info) << "[InputDevice] stop."; + parent_.removeEventFilter(this); + eventHandler_ = nullptr; +} + +bool InputDevice::eventFilter(QObject* obj, QEvent* event) +{ + std::lock_guard lock(mutex_); + + if(eventHandler_ != nullptr) + { + if(event->type() == QEvent::KeyPress || event->type() == QEvent::KeyRelease) + { + QKeyEvent* key = static_cast(event); + if(!key->isAutoRepeat()) + { + return this->handleKeyEvent(event, key); + } + } + else if(event->type() == QEvent::MouseButtonPress || event->type() == QEvent::MouseButtonRelease || event->type() == QEvent::MouseMove) + { + return this->handleTouchEvent(event); + } + } + + return QObject::eventFilter(obj, event); +} + +bool InputDevice::handleKeyEvent(QEvent* event, QKeyEvent* key) +{ + auto eventType = event->type() == QEvent::KeyPress ? ButtonEventType::PRESS : ButtonEventType::RELEASE; + aasdk::proto::enums::ButtonCode::Enum buttonCode; + WheelDirection wheelDirection = WheelDirection::NONE; + + switch(key->key()) + { + case Qt::Key_Return: + case Qt::Key_Enter: + buttonCode = aasdk::proto::enums::ButtonCode::ENTER; + break; + + case Qt::Key_Left: + buttonCode = aasdk::proto::enums::ButtonCode::LEFT; + break; + + case Qt::Key_Right: + buttonCode = aasdk::proto::enums::ButtonCode::RIGHT; + break; + + case Qt::Key_Up: + buttonCode = aasdk::proto::enums::ButtonCode::UP; + break; + + case Qt::Key_Down: + buttonCode = aasdk::proto::enums::ButtonCode::DOWN; + break; + + case Qt::Key_Escape: + buttonCode = aasdk::proto::enums::ButtonCode::BACK; + break; + + case Qt::Key_H: + buttonCode = aasdk::proto::enums::ButtonCode::HOME; + break; + + case Qt::Key_P: + buttonCode = aasdk::proto::enums::ButtonCode::PHONE; + break; + + case Qt::Key_O: + buttonCode = aasdk::proto::enums::ButtonCode::CALL_END; + break; + + case Qt::Key_X: + buttonCode = aasdk::proto::enums::ButtonCode::PLAY; + break; + + case Qt::Key_C: + buttonCode = aasdk::proto::enums::ButtonCode::PAUSE; + break; + + case Qt::Key_V: + buttonCode = aasdk::proto::enums::ButtonCode::PREV; + break; + + case Qt::Key_B: + buttonCode = aasdk::proto::enums::ButtonCode::TOGGLE_PLAY; + break; + + case Qt::Key_N: + buttonCode = aasdk::proto::enums::ButtonCode::NEXT; + break; + + case Qt::Key_M: + buttonCode = aasdk::proto::enums::ButtonCode::MICROPHONE_1; + break; + + case Qt::Key_1: + wheelDirection = WheelDirection::LEFT; + eventType = ButtonEventType::NONE; + buttonCode = aasdk::proto::enums::ButtonCode::SCROLL_WHEEL; + break; + + case Qt::Key_2: + wheelDirection = WheelDirection::RIGHT; + eventType = ButtonEventType::NONE; + buttonCode = aasdk::proto::enums::ButtonCode::SCROLL_WHEEL; + break; + + default: + return false; + } + + const auto& buttonCodes = this->getSupportedButtonCodes(); + if(std::find(buttonCodes.begin(), buttonCodes.end(), buttonCode) != buttonCodes.end()) + { + if(buttonCode != aasdk::proto::enums::ButtonCode::SCROLL_WHEEL || event->type() == QEvent::KeyRelease) + { + eventHandler_->onButtonEvent({eventType, wheelDirection, buttonCode}); + } + } + + return true; +} + +bool InputDevice::handleTouchEvent(QEvent* event) +{ + if(!configuration_->getTouchscreenEnabled()) + { + return false; + } + + aasdk::proto::enums::TouchAction::Enum type; + + switch(event->type()) + { + case QEvent::MouseButtonPress: + type = aasdk::proto::enums::TouchAction::PRESS; + break; + case QEvent::MouseButtonRelease: + type = aasdk::proto::enums::TouchAction::RELEASE; + break; + case QEvent::MouseMove: + type = aasdk::proto::enums::TouchAction::DRAG; + break; + default: + return false; + }; + + QMouseEvent* mouse = static_cast(event); + if(event->type() == QEvent::MouseButtonRelease || mouse->buttons().testFlag(Qt::LeftButton)) + { + 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}); + } + + return true; +} + +bool InputDevice::hasTouchscreen() const +{ + return configuration_->getTouchscreenEnabled(); +} + +QRect InputDevice::getTouchscreenGeometry() const +{ + return touchscreenGeometry_; +} + +IInputDevice::ButtonCodes InputDevice::getSupportedButtonCodes() const +{ + return configuration_->getButtonCodes(); +} + +} +} +} +} diff --git a/src/autoapp/Projection/InputService.cpp b/src/autoapp/Projection/InputService.cpp new file mode 100644 index 0000000..65f8c81 --- /dev/null +++ b/src/autoapp/Projection/InputService.cpp @@ -0,0 +1,195 @@ +/* +* This file is part of openauto project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* openauto is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 3 of the License, or +* (at your option) any later version. + +* openauto is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with openauto. If not, see . +*/ + +#include +#include +#include + +namespace f1x +{ +namespace openauto +{ +namespace autoapp +{ +namespace projection +{ + +InputService::InputService(boost::asio::io_service& ioService, aasdk::messenger::IMessenger::Pointer messenger, IInputDevice::Pointer inputDevice) + : strand_(ioService) + , channel_(std::make_shared(strand_, std::move(messenger))) + , inputDevice_(std::move(inputDevice)) +{ + +} + +void InputService::start() +{ + strand_.dispatch([this, self = this->shared_from_this()]() { + OPENAUTO_LOG(info) << "[InputService] start."; + channel_->receive(this->shared_from_this()); + }); +} + +void InputService::stop() +{ + strand_.dispatch([this, self = this->shared_from_this()]() { + OPENAUTO_LOG(info) << "[InputService] stop."; + inputDevice_->stop(); + }); +} + +void InputService::fillFeatures(aasdk::proto::messages::ServiceDiscoveryResponse& response) +{ + OPENAUTO_LOG(info) << "[InputService] fill features."; + + auto* channelDescriptor = response.add_channels(); + channelDescriptor->set_channel_id(static_cast(channel_->getId())); + + auto* inputChannel = channelDescriptor->mutable_input_channel(); + + const auto& supportedButtonCodes = inputDevice_->getSupportedButtonCodes(); + + for(const auto& buttonCode : supportedButtonCodes) + { + inputChannel->add_supported_keycodes(buttonCode); + } + + if(inputDevice_->hasTouchscreen()) + { + const auto& touchscreenSurface = inputDevice_->getTouchscreenGeometry(); + auto touchscreenConfig = inputChannel->mutable_touch_screen_config(); + + touchscreenConfig->set_width(touchscreenSurface.width()); + touchscreenConfig->set_height(touchscreenSurface.height()); + } +} + +void InputService::onChannelOpenRequest(const aasdk::proto::messages::ChannelOpenRequest& request) +{ + OPENAUTO_LOG(info) << "[InputService] open request, priority: " << request.priority(); + const aasdk::proto::enums::Status::Enum status = aasdk::proto::enums::Status::OK; + OPENAUTO_LOG(info) << "[InputService] open status: " << status; + + aasdk::proto::messages::ChannelOpenResponse response; + response.set_status(status); + + auto promise = aasdk::channel::SendPromise::defer(strand_); + promise->then([]() {}, std::bind(&InputService::onChannelError, this->shared_from_this(), std::placeholders::_1)); + channel_->sendChannelOpenResponse(response, std::move(promise)); + + channel_->receive(this->shared_from_this()); +} + +void InputService::onBindingRequest(const aasdk::proto::messages::BindingRequest& request) +{ + OPENAUTO_LOG(info) << "[InputService] binding request, scan codes count: " << request.scan_codes_size(); + + aasdk::proto::enums::Status::Enum status = aasdk::proto::enums::Status::OK; + const auto& supportedButtonCodes = inputDevice_->getSupportedButtonCodes(); + + for(int i = 0; i < request.scan_codes_size(); ++i) + { + if(std::find(supportedButtonCodes.begin(), supportedButtonCodes.end(), request.scan_codes(i)) == supportedButtonCodes.end()) + { + OPENAUTO_LOG(error) << "[InputService] binding request, scan code: " << request.scan_codes(i) + << " is not supported."; + + status = aasdk::proto::enums::Status::FAIL; + break; + } + } + + aasdk::proto::messages::BindingResponse response; + response.set_status(status); + + if(status == aasdk::proto::enums::Status::OK) + { + inputDevice_->start(*this); + } + + OPENAUTO_LOG(info) << "[InputService] binding request, status: " << status; + + auto promise = aasdk::channel::SendPromise::defer(strand_); + promise->then([]() {}, std::bind(&InputService::onChannelError, this->shared_from_this(), std::placeholders::_1)); + channel_->sendBindingResponse(response, std::move(promise)); + channel_->receive(this->shared_from_this()); +} + +void InputService::onChannelError(const aasdk::error::Error& e) +{ + OPENAUTO_LOG(error) << "[SensorService] channel error: " << e.what(); +} + +void InputService::onButtonEvent(const ButtonEvent& event) +{ + timespec tp; + clock_gettime(CLOCK_REALTIME, &tp); + auto timestamp = tp.tv_sec * 1000000 + tp.tv_nsec / 1000; + + strand_.dispatch([this, self = this->shared_from_this(), event = std::move(event), timestamp]() { + aasdk::proto::messages::InputEventIndication inputEventIndication; + inputEventIndication.set_timestamp(timestamp); + + if(event.code == aasdk::proto::enums::ButtonCode::SCROLL_WHEEL) + { + auto relativeEvent = inputEventIndication.mutable_relative_input_event()->add_relative_input_events(); + relativeEvent->set_delta(event.wheelDirection == WheelDirection::LEFT ? -1 : 1); + relativeEvent->set_scan_code(event.code); + } + else + { + auto buttonEvent = inputEventIndication.mutable_button_event()->add_button_events(); + buttonEvent->set_meta(0); + buttonEvent->set_is_pressed(event.type == ButtonEventType::PRESS); + buttonEvent->set_long_press(false); + buttonEvent->set_scan_code(event.code); + } + + auto promise = aasdk::channel::SendPromise::defer(strand_); + promise->then([]() {}, std::bind(&InputService::onChannelError, this->shared_from_this(), std::placeholders::_1)); + channel_->sendInputEventIndication(inputEventIndication, std::move(promise)); + }); +} + +void InputService::onTouchEvent(const TouchEvent& event) +{ + timespec tp; + clock_gettime(CLOCK_REALTIME, &tp); + auto timestamp = tp.tv_sec * 1000000 + tp.tv_nsec / 1000; + + strand_.dispatch([this, self = this->shared_from_this(), event = std::move(event), timestamp]() { + aasdk::proto::messages::InputEventIndication inputEventIndication; + inputEventIndication.set_timestamp(timestamp); + + auto touchEvent = inputEventIndication.mutable_touch_event(); + touchEvent->set_touch_action(event.type); + auto touchLocation = touchEvent->add_touch_location(); + touchLocation->set_x(event.x); + touchLocation->set_y(event.y); + touchLocation->set_pointer_id(0); + + auto promise = aasdk::channel::SendPromise::defer(strand_); + promise->then([]() {}, std::bind(&InputService::onChannelError, this->shared_from_this(), std::placeholders::_1)); + channel_->sendInputEventIndication(inputEventIndication, std::move(promise)); + }); +} + +} +} +} +} diff --git a/src/autoapp/Projection/LocalBluetoothDevice.cpp b/src/autoapp/Projection/LocalBluetoothDevice.cpp new file mode 100644 index 0000000..5c7060e --- /dev/null +++ b/src/autoapp/Projection/LocalBluetoothDevice.cpp @@ -0,0 +1,184 @@ +/* +* This file is part of openauto project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* openauto is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 3 of the License, or +* (at your option) any later version. + +* openauto is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with openauto. If not, see . +*/ + +#include +#include +#include + +namespace f1x +{ +namespace openauto +{ +namespace autoapp +{ +namespace projection +{ + +LocalBluetoothDevice::LocalBluetoothDevice() +{ + qRegisterMetaType("PairingPromise::Pointer"); + + this->moveToThread(QApplication::instance()->thread()); + connect(this, &LocalBluetoothDevice::startPairing, this, &LocalBluetoothDevice::onStartPairing, Qt::QueuedConnection); + QMetaObject::invokeMethod(this, "createBluetoothLocalDevice", Qt::BlockingQueuedConnection); +} + +void LocalBluetoothDevice::createBluetoothLocalDevice() +{ + OPENAUTO_LOG(debug) << "[LocalBluetoothDevice] create."; + + localDevice_ = std::make_unique(QBluetoothAddress()); + + connect(localDevice_.get(), &QBluetoothLocalDevice::pairingDisplayConfirmation, this, &LocalBluetoothDevice::onPairingDisplayConfirmation); + connect(localDevice_.get(), &QBluetoothLocalDevice::pairingDisplayPinCode, this, &LocalBluetoothDevice::onPairingDisplayPinCode); + connect(localDevice_.get(), &QBluetoothLocalDevice::pairingFinished, this, &LocalBluetoothDevice::onPairingFinished); + connect(localDevice_.get(), &QBluetoothLocalDevice::error, this, &LocalBluetoothDevice::onError); + connect(localDevice_.get(), &QBluetoothLocalDevice::hostModeStateChanged, this, &LocalBluetoothDevice::onHostModeStateChanged); + localDevice_->setHostMode(QBluetoothLocalDevice::HostDiscoverable); +} + +void LocalBluetoothDevice::stop() +{ + std::lock_guard lock(mutex_); + + if(pairingPromise_ != nullptr) + { + pairingPromise_->reject(); + pairingPromise_.reset(); + pairingAddress_ = QBluetoothAddress(); + } +} + +bool LocalBluetoothDevice::isPaired(const std::string& address) const +{ + std::lock_guard lock(mutex_); + + return localDevice_->pairingStatus(QBluetoothAddress(QString::fromStdString(address))) != QBluetoothLocalDevice::Unpaired; +} + +void LocalBluetoothDevice::pair(const std::string& address, PairingPromise::Pointer promise) +{ + emit startPairing(QString::fromStdString(address), std::move(promise)); +} + +std::string LocalBluetoothDevice::getLocalAddress() const +{ + std::lock_guard lock(mutex_); + return localDevice_->isValid() ? localDevice_->address().toString().toStdString() : ""; +} + +bool LocalBluetoothDevice::isAvailable() const +{ + std::lock_guard lock(mutex_); + return localDevice_->isValid(); +} + +void LocalBluetoothDevice::onStartPairing(const QString& address, PairingPromise::Pointer promise) +{ + OPENAUTO_LOG(debug) << "[LocalBluetoothDevice] onStartPairing, address: " << address.toStdString(); + + std::lock_guard lock(mutex_); + + if(!localDevice_->isValid()) + { + promise->reject(); + } + else + { + if(pairingPromise_ != nullptr) + { + pairingPromise_->reject(); + } + + pairingAddress_ = QBluetoothAddress(address); + pairingPromise_ = std::move(promise); + localDevice_->requestPairing(pairingAddress_, QBluetoothLocalDevice::AuthorizedPaired); + } +} + +void LocalBluetoothDevice::onPairingDisplayConfirmation(const QBluetoothAddress &address, QString pin) +{ + OPENAUTO_LOG(debug) << "[LocalBluetoothDevice] onPairingDisplayConfirmation, address: " << address.toString().toStdString() + << ", pin: " << pin.toStdString(); + + std::lock_guard lock(mutex_); + localDevice_->pairingConfirmation(address == pairingAddress_); +} + +void LocalBluetoothDevice::onPairingDisplayPinCode(const QBluetoothAddress &address, QString pin) +{ + OPENAUTO_LOG(debug) << "[LocalBluetoothDevice] onPairingDisplayPinCode, address: " << address.toString().toStdString() + << ", pin: " << pin.toStdString(); + + std::lock_guard lock(mutex_); + localDevice_->pairingConfirmation(address == pairingAddress_); +} + +void LocalBluetoothDevice::onPairingFinished(const QBluetoothAddress &address, QBluetoothLocalDevice::Pairing pairing) +{ + OPENAUTO_LOG(debug) << "[LocalBluetoothDevice] onPairingDisplayPinCode, address: " << address.toString().toStdString() + << ", pin: " << pairing; + + std::lock_guard lock(mutex_); + + if(address == pairingAddress_) + { + if(pairing != QBluetoothLocalDevice::Unpaired) + { + pairingPromise_->resolve(); + } + else + { + pairingPromise_->reject(); + } + + pairingPromise_.reset(); + pairingAddress_ = QBluetoothAddress(); + } +} + +void LocalBluetoothDevice::onError(QBluetoothLocalDevice::Error error) +{ + OPENAUTO_LOG(debug) << "[LocalBluetoothDevice] onError, error: " << error; + + std::lock_guard lock(mutex_); + + if(pairingPromise_ != nullptr) + { + pairingPromise_->reject(); + pairingPromise_.reset(); + pairingAddress_ = QBluetoothAddress(); + } +} + +void LocalBluetoothDevice::onHostModeStateChanged(QBluetoothLocalDevice::HostMode state) +{ + std::lock_guard lock(mutex_); + + if(state == QBluetoothLocalDevice::HostPoweredOff && pairingPromise_ != nullptr) + { + pairingPromise_->reject(); + pairingPromise_.reset(); + pairingAddress_ = QBluetoothAddress(); + } +} + +} +} +} +} diff --git a/src/autoapp/Projection/MediaAudioService.cpp b/src/autoapp/Projection/MediaAudioService.cpp new file mode 100644 index 0000000..be7e9f7 --- /dev/null +++ b/src/autoapp/Projection/MediaAudioService.cpp @@ -0,0 +1,40 @@ +/* +* This file is part of openauto project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* openauto is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 3 of the License, or +* (at your option) any later version. + +* openauto is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with openauto. If not, see . +*/ + +#include +#include + +namespace f1x +{ +namespace openauto +{ +namespace autoapp +{ +namespace projection +{ + +MediaAudioService::MediaAudioService(boost::asio::io_service& ioService, aasdk::messenger::IMessenger::Pointer messenger, IAudioOutput::Pointer audioOutput) + : AudioService(ioService, std::make_shared(strand_, std::move(messenger)), std::move(audioOutput)) +{ + +} + +} +} +} +} diff --git a/src/autoapp/Projection/OMXVideoOutput.cpp b/src/autoapp/Projection/OMXVideoOutput.cpp new file mode 100644 index 0000000..259b0c0 --- /dev/null +++ b/src/autoapp/Projection/OMXVideoOutput.cpp @@ -0,0 +1,271 @@ +/* +* This file is part of openauto project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* openauto is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 3 of the License, or +* (at your option) any later version. + +* openauto is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with openauto. If not, see . +*/ + +#ifdef USE_OMX + +extern "C" +{ +#include +} + +#include +#include +#include + +namespace f1x +{ +namespace openauto +{ +namespace autoapp +{ +namespace projection +{ + +namespace VideoComponent +{ + static constexpr uint32_t DECODER = 0; + static constexpr uint32_t RENDERER = 1; + static constexpr uint32_t CLOCK = 2; + static constexpr uint32_t SCHEDULER = 3; +} + +OMXVideoOutput::OMXVideoOutput(configuration::IConfiguration::Pointer configuration) + : VideoOutput(std::move(configuration)) + , isActive_(false) + , portSettingsChanged_(false) + , client_(nullptr) +{ + memset(components_, 0, sizeof(components_)); + memset(tunnels_, 0, sizeof(tunnels_)); +} + +bool OMXVideoOutput::open() +{ + std::lock_guard lock(mutex_); + + OPENAUTO_LOG(info) << "[OMXVideoOutput] open."; + + bcm_host_init(); + if(OMX_Init() != OMX_ErrorNone) + { + OPENAUTO_LOG(error) << "[OMXVideoOutput] omx init failed."; + return false; + } + + client_ = ilclient_init(); + if(client_ == nullptr) + { + OPENAUTO_LOG(error) << "[OMXVideoOutput] ilclient init failed."; + return false; + } + + if(!this->createComponents()) + { + return false; + } + + if(!this->setupTunnels()) + { + OPENAUTO_LOG(error) << "[OMXVideoOutput] setup tunnels failed."; + return false; + } + + ilclient_change_component_state(components_[VideoComponent::CLOCK], OMX_StateExecuting); + ilclient_change_component_state(components_[VideoComponent::DECODER], OMX_StateIdle); + + if(!this->enablePortBuffers()) + { + OPENAUTO_LOG(error) << "[OMXVideoOutput] enable port buffers failed."; + return false; + } + + isActive_ = true; + return true; +} + +bool OMXVideoOutput::init() +{ + std::lock_guard lock(mutex_); + + OPENAUTO_LOG(info) << "[OMXVideoOutput] init, state: " << isActive_; + ilclient_change_component_state(components_[VideoComponent::DECODER], OMX_StateExecuting); + return true; +} + +void OMXVideoOutput::write(uint64_t timestamp, const aasdk::common::DataConstBuffer& buffer) +{ + std::lock_guard lock(mutex_); + + size_t writeSize = 0; + + while(isActive_ && writeSize < buffer.size) + { + OMX_BUFFERHEADERTYPE* buf = ilclient_get_input_buffer(components_[VideoComponent::DECODER], 130, 1); + + if(buf == nullptr) + { + break; + } + else + { + aasdk::common::DataConstBuffer currentBuffer(buffer.cdata, buffer.size, writeSize); + buf->nFilledLen = std::min(buf->nAllocLen, currentBuffer.size); + memcpy(buf->pBuffer, ¤tBuffer.cdata[0], buf->nFilledLen); + buf->nTimeStamp = omx_ticks_from_s64(timestamp / 1000000); + buf->nOffset = 0; + + writeSize += buf->nFilledLen; + + if(timestamp == 0) + { + buf->nFlags = OMX_BUFFERFLAG_STARTTIME; + } + + if(!portSettingsChanged_ && ilclient_remove_event(components_[VideoComponent::DECODER], OMX_EventPortSettingsChanged, 131, 0, 0, 1) == 0) + { + portSettingsChanged_ = true; + + if(ilclient_setup_tunnel(&tunnels_[0], 0, 0) != 0) + { + break; + } + + ilclient_change_component_state(components_[VideoComponent::SCHEDULER], OMX_StateExecuting); + if(ilclient_setup_tunnel(&tunnels_[1], 0, 1000) != 0) + { + break; + } + + ilclient_change_component_state(components_[VideoComponent::RENDERER], OMX_StateExecuting); + } + + if(OMX_EmptyThisBuffer(ILC_GET_HANDLE(components_[VideoComponent::DECODER]), buf) != OMX_ErrorNone) + { + break; + } + } + } +} + +void OMXVideoOutput::stop() +{ + OPENAUTO_LOG(info) << "[OMXVideoOutput] stop."; + + std::lock_guard lock(mutex_); + + if(isActive_) + { + isActive_ = false; + + ilclient_disable_tunnel(&tunnels_[0]); + ilclient_disable_tunnel(&tunnels_[1]); + ilclient_disable_tunnel(&tunnels_[2]); + ilclient_disable_port_buffers(components_[VideoComponent::DECODER], 130, NULL, NULL, NULL); + ilclient_teardown_tunnels(tunnels_); + + ilclient_state_transition(components_, OMX_StateIdle); + ilclient_state_transition(components_, OMX_StateLoaded); + + ilclient_cleanup_components(components_); + OMX_Deinit(); + ilclient_destroy(client_); + } +} + +bool OMXVideoOutput::isActive() const +{ + std::lock_guard lock(mutex_); + + return isActive_; +} + +bool OMXVideoOutput::createComponents() +{ + if(ilclient_create_component(client_, &components_[VideoComponent::DECODER], "video_decode", static_cast(ILCLIENT_DISABLE_ALL_PORTS | ILCLIENT_ENABLE_INPUT_BUFFERS)) != 0) + { + OPENAUTO_LOG(error) << "[OMXVideoOutput] video decode component creation failed."; + return false; + } + + if(ilclient_create_component(client_, &components_[VideoComponent::RENDERER], "video_render", ILCLIENT_DISABLE_ALL_PORTS) != 0) + { + OPENAUTO_LOG(error) << "[OMXVideoOutput] video renderer component creation failed."; + return false; + } + + if(ilclient_create_component(client_, &components_[VideoComponent::CLOCK], "clock", ILCLIENT_DISABLE_ALL_PORTS) != 0) + { + OPENAUTO_LOG(error) << "[OMXVideoOutput] clock component creation failed."; + return false; + } + + if(!this->initClock()) + { + OPENAUTO_LOG(error) << "[OMXVideoOutput] clock init failed."; + return false; + } + + if(ilclient_create_component(client_, &components_[VideoComponent::SCHEDULER], "video_scheduler", ILCLIENT_DISABLE_ALL_PORTS) != 0) + { + OPENAUTO_LOG(error) << "[OMXVideoOutput] video scheduler component creation failed."; + return false; + } + + return true; +} + +bool OMXVideoOutput::initClock() +{ + OMX_TIME_CONFIG_CLOCKSTATETYPE cstate; + memset(&cstate, 0, sizeof(cstate)); + cstate.nSize = sizeof(cstate); + cstate.nVersion.nVersion = OMX_VERSION; + cstate.eState = OMX_TIME_ClockStateWaitingForStartTime; + cstate.nWaitMask = 1; + + return OMX_SetParameter(ILC_GET_HANDLE(components_[VideoComponent::CLOCK]), OMX_IndexConfigTimeClockState, &cstate) == OMX_ErrorNone; +} + +bool OMXVideoOutput::setupTunnels() +{ + set_tunnel(&tunnels_[0], components_[VideoComponent::DECODER], 131, components_[VideoComponent::SCHEDULER], 10); + set_tunnel(&tunnels_[1], components_[VideoComponent::SCHEDULER], 11, components_[VideoComponent::RENDERER], 90); + set_tunnel(&tunnels_[2], components_[VideoComponent::CLOCK], 80, components_[VideoComponent::SCHEDULER], 12); + + return ilclient_setup_tunnel(&tunnels_[2], 0, 0) == 0; +} + +bool OMXVideoOutput::enablePortBuffers() +{ + OMX_VIDEO_PARAM_PORTFORMATTYPE format; + memset(&format, 0, sizeof(OMX_VIDEO_PARAM_PORTFORMATTYPE)); + format.nSize = sizeof(OMX_VIDEO_PARAM_PORTFORMATTYPE); + format.nVersion.nVersion = OMX_VERSION; + format.nPortIndex = 130; + format.eCompressionFormat = OMX_VIDEO_CodingAVC; + + return OMX_SetParameter(ILC_GET_HANDLE(components_[VideoComponent::DECODER]), OMX_IndexParamVideoPortFormat, &format) == OMX_ErrorNone && + ilclient_enable_port_buffers(components_[VideoComponent::DECODER], 130, NULL, NULL, NULL) == 0; +} + +} +} +} +} + +#endif diff --git a/src/autoapp/Projection/QtVideoOutput.cpp b/src/autoapp/Projection/QtVideoOutput.cpp new file mode 100644 index 0000000..c108ebc --- /dev/null +++ b/src/autoapp/Projection/QtVideoOutput.cpp @@ -0,0 +1,99 @@ +/* +* This file is part of openauto project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* openauto is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 3 of the License, or +* (at your option) any later version. + +* openauto is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with openauto. If not, see . +*/ + +#include +#include +#include + +namespace f1x +{ +namespace openauto +{ +namespace autoapp +{ +namespace projection +{ + +QtVideoOutput::QtVideoOutput(configuration::IConfiguration::Pointer configuration) + : VideoOutput(std::move(configuration)) +{ + this->moveToThread(QApplication::instance()->thread()); + connect(this, &QtVideoOutput::startPlayback, this, &QtVideoOutput::onStartPlayback, Qt::QueuedConnection); + connect(this, &QtVideoOutput::stopPlayback, this, &QtVideoOutput::onStopPlayback, Qt::QueuedConnection); + + QMetaObject::invokeMethod(this, "createVideoOutput", Qt::BlockingQueuedConnection); +} + +void QtVideoOutput::createVideoOutput() +{ + OPENAUTO_LOG(debug) << "[QtVideoOutput] create."; + videoWidget_ = std::make_unique(); + mediaPlayer_ = std::make_unique(nullptr, QMediaPlayer::StreamPlayback); +} + + +bool QtVideoOutput::open() +{ + std::lock_guard lock(mutex_); + return videoBuffer_.open(QIODevice::ReadWrite); +} + +bool QtVideoOutput::init() +{ + emit startPlayback(); + return true; +} + +bool QtVideoOutput::isActive() const +{ + std::lock_guard lock(mutex_); + return videoWidget_ != nullptr && videoWidget_->isVisible(); +} + +void QtVideoOutput::stop() +{ + emit stopPlayback(); +} + +void QtVideoOutput::write(uint64_t, const aasdk::common::DataConstBuffer& buffer) +{ + std::lock_guard lock(mutex_); + videoBuffer_.write(reinterpret_cast(buffer.cdata), buffer.size); +} + +void QtVideoOutput::onStartPlayback() +{ + videoWidget_->setFocus(); + videoWidget_->setFullScreen(true); + videoWidget_->show(); + + mediaPlayer_->setVideoOutput(videoWidget_.get()); + mediaPlayer_->setMedia(QMediaContent(), &videoBuffer_); + mediaPlayer_->play(); +} + +void QtVideoOutput::onStopPlayback() +{ + videoWidget_->hide(); + mediaPlayer_->stop(); +} + +} +} +} +} diff --git a/src/autoapp/Projection/RemoteBluetoothDevice.cpp b/src/autoapp/Projection/RemoteBluetoothDevice.cpp new file mode 100644 index 0000000..b86c96f --- /dev/null +++ b/src/autoapp/Projection/RemoteBluetoothDevice.cpp @@ -0,0 +1,64 @@ +/* +* This file is part of openauto project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* openauto is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 3 of the License, or +* (at your option) any later version. + +* openauto is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with openauto. If not, see . +*/ + +#include + +namespace f1x +{ +namespace openauto +{ +namespace autoapp +{ +namespace projection +{ + +RemoteBluetoothDevice::RemoteBluetoothDevice(const std::string& address) + : address_(address) +{ + +} + +void RemoteBluetoothDevice::stop() +{ + +} + +bool RemoteBluetoothDevice::isPaired(const std::string&) const +{ + return true; +} + +void RemoteBluetoothDevice::pair(const std::string&, PairingPromise::Pointer promise) +{ + promise->resolve(); +} + +std::string RemoteBluetoothDevice::getLocalAddress() const +{ + return address_; +} + +bool RemoteBluetoothDevice::isAvailable() const +{ + return true; +} + +} +} +} +} diff --git a/src/autoapp/Projection/SensorService.cpp b/src/autoapp/Projection/SensorService.cpp new file mode 100644 index 0000000..b333fd7 --- /dev/null +++ b/src/autoapp/Projection/SensorService.cpp @@ -0,0 +1,124 @@ +/* +* This file is part of openauto project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* openauto is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 3 of the License, or +* (at your option) any later version. + +* openauto is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with openauto. If not, see . +*/ + +#include +#include +#include + +namespace f1x +{ +namespace openauto +{ +namespace autoapp +{ +namespace projection +{ + +SensorService::SensorService(boost::asio::io_service& ioService, aasdk::messenger::IMessenger::Pointer messenger) + : strand_(ioService) + , channel_(std::make_shared(strand_, std::move(messenger))) +{ + +} + +void SensorService::start() +{ + strand_.dispatch([this, self = this->shared_from_this()]() { + OPENAUTO_LOG(info) << "[SensorService] start."; + channel_->receive(this->shared_from_this()); + }); +} + +void SensorService::stop() +{ + strand_.dispatch([this, self = this->shared_from_this()]() { + OPENAUTO_LOG(info) << "[SensorService] stop."; + }); +} + +void SensorService::fillFeatures(aasdk::proto::messages::ServiceDiscoveryResponse& response) +{ + OPENAUTO_LOG(info) << "[SensorService] fill features."; + + auto* channelDescriptor = response.add_channels(); + channelDescriptor->set_channel_id(static_cast(channel_->getId())); + + auto* sensorChannel = channelDescriptor->mutable_sensor_channel(); + sensorChannel->add_sensors()->set_type(aasdk::proto::enums::SensorType::DRIVING_STATUS); + //sensorChannel->add_sensors()->set_type(aasdk::proto::enums::SensorType::LOCATION); + //sensorChannel->add_sensors()->set_type(aasdk::proto::enums::SensorType::NIGHT_DATA); +} + +void SensorService::onChannelOpenRequest(const aasdk::proto::messages::ChannelOpenRequest& request) +{ + OPENAUTO_LOG(info) << "[SensorService] open request, priority: " << request.priority(); + const aasdk::proto::enums::Status::Enum status = aasdk::proto::enums::Status::OK; + OPENAUTO_LOG(info) << "[SensorService] open status: " << status; + + aasdk::proto::messages::ChannelOpenResponse response; + response.set_status(status); + + auto promise = aasdk::channel::SendPromise::defer(strand_); + promise->then([]() {}, std::bind(&SensorService::onChannelError, this->shared_from_this(), std::placeholders::_1)); + channel_->sendChannelOpenResponse(response, std::move(promise)); + + channel_->receive(this->shared_from_this()); +} + +void SensorService::onSensorStartRequest(const aasdk::proto::messages::SensorStartRequestMessage& request) +{ + OPENAUTO_LOG(info) << "[SensorService] sensor start request, type: " << request.sensor_type(); + + aasdk::proto::messages::SensorStartResponseMessage response; + response.set_status(aasdk::proto::enums::Status::OK); + + auto promise = aasdk::channel::SendPromise::defer(strand_); + + if(request.sensor_type() == aasdk::proto::enums::SensorType::DRIVING_STATUS) + { + promise->then(std::bind(&SensorService::sendDrivingStatusUnrestricted, this->shared_from_this()), + std::bind(&SensorService::onChannelError, this->shared_from_this(), std::placeholders::_1)); + } + else + { + promise->then([]() {}, std::bind(&SensorService::onChannelError, this->shared_from_this(), std::placeholders::_1)); + } + + channel_->sendSensorStartResponse(response, std::move(promise)); + channel_->receive(this->shared_from_this()); +} + +void SensorService::sendDrivingStatusUnrestricted() +{ + aasdk::proto::messages::SensorEventIndication indication; + indication.add_driving_status()->set_status(aasdk::proto::enums::DrivingStatus::UNRESTRICTED); + + auto promise = aasdk::channel::SendPromise::defer(strand_); + promise->then([]() {}, std::bind(&SensorService::onChannelError, this->shared_from_this(), std::placeholders::_1)); + channel_->sendSensorEventIndication(indication, std::move(promise)); +} + +void SensorService::onChannelError(const aasdk::error::Error& e) +{ + OPENAUTO_LOG(error) << "[SensorService] channel error: " << e.what(); +} + +} +} +} +} diff --git a/src/autoapp/Projection/SequentialBuffer.cpp b/src/autoapp/Projection/SequentialBuffer.cpp new file mode 100644 index 0000000..e4a2911 --- /dev/null +++ b/src/autoapp/Projection/SequentialBuffer.cpp @@ -0,0 +1,106 @@ +/* +* This file is part of openauto project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* openauto is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 3 of the License, or +* (at your option) any later version. + +* openauto is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with openauto. If not, see . +*/ + +#include + +namespace f1x +{ +namespace openauto +{ +namespace autoapp +{ +namespace projection +{ + +SequentialBuffer::SequentialBuffer() + : data_(aasdk::common::cStaticDataSize) +{ +} + +bool SequentialBuffer::isSequential() const +{ + return true; +} + +qint64 SequentialBuffer::readData(char *data, qint64 maxlen) +{ + std::lock_guard lock(mutex_); + + if(data_.empty()) + { + return 0; + } + + const auto len = std::min(maxlen, data_.size()); + std::copy(data_.begin(), data_.begin() + len, data); + data_.erase(data_.begin(), data_.begin() + len); + return len; +} + +qint64 SequentialBuffer::writeData(const char *data, qint64 len) +{ + std::lock_guard lock(mutex_); + + data_.insert(data_.end(), data, data + len); + emit readyRead(); + return len; +} + +qint64 SequentialBuffer::size() const +{ + return this->bytesAvailable(); +} + +qint64 SequentialBuffer::pos() const +{ + return 0; +} + + +bool SequentialBuffer::seek(qint64) +{ + return false; +} + +bool SequentialBuffer::atEnd() const +{ + return false; +} + +bool SequentialBuffer::reset() +{ + data_.clear(); + return true; +} + +qint64 SequentialBuffer::bytesAvailable() const +{ + std::lock_guard lock(mutex_); + + return QIODevice::bytesAvailable() + std::max(1, data_.size()); +} + +bool SequentialBuffer::canReadLine() const +{ + return true; +} + +} +} +} +} diff --git a/src/autoapp/Projection/ServiceFactory.cpp b/src/autoapp/Projection/ServiceFactory.cpp new file mode 100644 index 0000000..410263c --- /dev/null +++ b/src/autoapp/Projection/ServiceFactory.cpp @@ -0,0 +1,141 @@ +/* +* This file is part of openauto project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* openauto is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 3 of the License, or +* (at your option) any later version. + +* openauto is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with openauto. If not, see . +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace f1x +{ +namespace openauto +{ +namespace autoapp +{ +namespace projection +{ + +ServiceFactory::ServiceFactory(boost::asio::io_service& ioService, configuration::IConfiguration::Pointer configuration) + : ioService_(ioService) + , configuration_(std::move(configuration)) +{ + +} + +ServiceList ServiceFactory::create(aasdk::messenger::IMessenger::Pointer messenger) +{ + ServiceList serviceList; + + IAudioInput::Pointer audioInput(new AudioInput(1, 16, 16000), std::bind(&QObject::deleteLater, std::placeholders::_1)); + serviceList.emplace_back(std::make_shared(ioService_, messenger, std::move(audioInput))); + + IAudioOutput::Pointer mediaAudioOutput(new AudioOutput(2, 16, 48000), std::bind(&QObject::deleteLater, std::placeholders::_1)); + serviceList.emplace_back(std::make_shared(ioService_, messenger, std::move(mediaAudioOutput))); + + IAudioOutput::Pointer speechAudioOutput(new AudioOutput(1, 16, 16000), std::bind(&QObject::deleteLater, std::placeholders::_1)); + serviceList.emplace_back(std::make_shared(ioService_, messenger, std::move(speechAudioOutput))); + + IAudioOutput::Pointer systemAudioOutput(new AudioOutput(1, 16, 16000), std::bind(&QObject::deleteLater, std::placeholders::_1)); + serviceList.emplace_back(std::make_shared(ioService_, messenger, std::move(systemAudioOutput))); + + serviceList.emplace_back(std::make_shared(ioService_, messenger)); + serviceList.emplace_back(this->createVideoService(messenger)); + serviceList.emplace_back(this->createBluetoothService(messenger)); + serviceList.emplace_back(this->createInputService(messenger)); + + return serviceList; +} + +IService::Pointer ServiceFactory::createVideoService(aasdk::messenger::IMessenger::Pointer messenger) +{ +#ifdef USE_OMX + IVideoOutput::Pointer videoOutput(std::make_shared(configuration_)); +#else + IVideoOutput::Pointer videoOutput(new QtVideoOutput(configuration_), std::bind(&QObject::deleteLater, std::placeholders::_1)); +#endif + return std::make_shared(ioService_, messenger, std::move(videoOutput)); +} + +IService::Pointer ServiceFactory::createBluetoothService(aasdk::messenger::IMessenger::Pointer messenger) +{ + IBluetoothDevice::Pointer bluetoothDevice; + switch(configuration_->getBluetoothAdapterType()) + { + case configuration::BluetoothAdapterType::LOCAL: + bluetoothDevice = IBluetoothDevice::Pointer(new LocalBluetoothDevice(), std::bind(&QObject::deleteLater, std::placeholders::_1)); + break; + + case configuration::BluetoothAdapterType::REMOTE: + bluetoothDevice = std::make_shared(configuration_->getBluetoothRemoteAdapterAddress()); + break; + + default: + bluetoothDevice = std::make_shared(); + break; + } + + return std::make_shared(ioService_, messenger, std::move(bluetoothDevice)); +} + +IService::Pointer ServiceFactory::createInputService(aasdk::messenger::IMessenger::Pointer messenger) +{ + QRect videoGeometry; + switch(configuration_->getVideoResolution()) + { + case aasdk::proto::enums::VideoResolution::_720p: + videoGeometry = QRect(0, 0, 1280, 720); + break; + + case aasdk::proto::enums::VideoResolution::_1080p: + videoGeometry = QRect(0, 0, 1920, 1080); + break; + + default: + videoGeometry = QRect(0, 0, 800, 480); + break; + } + + QScreen* screen = QGuiApplication::primaryScreen(); + QRect screenGeometry = screen == nullptr ? QRect(0, 0, 1, 1) : screen->geometry(); + IInputDevice::Pointer inputDevice(std::make_shared(*QApplication::instance(), configuration_, std::move(screenGeometry), std::move(videoGeometry))); + + return std::make_shared(ioService_, messenger, std::move(inputDevice)); +} + +} +} +} +} diff --git a/src/autoapp/Projection/SpeechAudioService.cpp b/src/autoapp/Projection/SpeechAudioService.cpp new file mode 100644 index 0000000..f170346 --- /dev/null +++ b/src/autoapp/Projection/SpeechAudioService.cpp @@ -0,0 +1,40 @@ +/* +* This file is part of openauto project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* openauto is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 3 of the License, or +* (at your option) any later version. + +* openauto is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with openauto. If not, see . +*/ + +#include +#include + +namespace f1x +{ +namespace openauto +{ +namespace autoapp +{ +namespace projection +{ + +SpeechAudioService::SpeechAudioService(boost::asio::io_service& ioService, aasdk::messenger::IMessenger::Pointer messenger, IAudioOutput::Pointer audioOutput) + : AudioService(ioService, std::make_shared(strand_, std::move(messenger)), std::move(audioOutput)) +{ + +} + +} +} +} +} diff --git a/src/autoapp/Projection/SystemAudioService.cpp b/src/autoapp/Projection/SystemAudioService.cpp new file mode 100644 index 0000000..1acedf6 --- /dev/null +++ b/src/autoapp/Projection/SystemAudioService.cpp @@ -0,0 +1,40 @@ +/* +* This file is part of openauto project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* openauto is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 3 of the License, or +* (at your option) any later version. + +* openauto is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with openauto. If not, see . +*/ + +#include +#include + +namespace f1x +{ +namespace openauto +{ +namespace autoapp +{ +namespace projection +{ + +SystemAudioService::SystemAudioService(boost::asio::io_service& ioService, aasdk::messenger::IMessenger::Pointer messenger, IAudioOutput::Pointer audioOutput) + : AudioService(ioService, std::make_shared(strand_, std::move(messenger)), std::move(audioOutput)) +{ + +} + +} +} +} +} diff --git a/src/autoapp/Projection/VideoOutput.cpp b/src/autoapp/Projection/VideoOutput.cpp new file mode 100644 index 0000000..1b0c4e4 --- /dev/null +++ b/src/autoapp/Projection/VideoOutput.cpp @@ -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 . +*/ + +#include + +namespace f1x +{ +namespace openauto +{ +namespace autoapp +{ +namespace projection +{ + +VideoOutput::VideoOutput(configuration::IConfiguration::Pointer configuration) + : configuration_(std::move(configuration)) +{ + +} + +aasdk::proto::enums::VideoFPS::Enum VideoOutput::getVideoFPS() const +{ + return configuration_->getVideoFPS(); +} + +aasdk::proto::enums::VideoResolution::Enum VideoOutput::getVideoResolution() const +{ + return configuration_->getVideoResolution(); +} + +size_t VideoOutput::getScreenDPI() const +{ + return configuration_->getScreenDPI(); +} + +} +} +} +} diff --git a/src/autoapp/Projection/VideoService.cpp b/src/autoapp/Projection/VideoService.cpp new file mode 100644 index 0000000..251e037 --- /dev/null +++ b/src/autoapp/Projection/VideoService.cpp @@ -0,0 +1,178 @@ +/* +* This file is part of openauto project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* openauto is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 3 of the License, or +* (at your option) any later version. + +* openauto is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with openauto. If not, see . +*/ + +#include +#include + +namespace f1x +{ +namespace openauto +{ +namespace autoapp +{ +namespace projection +{ + +VideoService::VideoService(boost::asio::io_service& ioService, aasdk::messenger::IMessenger::Pointer messenger, IVideoOutput::Pointer videoOutput) + : strand_(ioService) + , channel_(std::make_shared(strand_, std::move(messenger))) + , videoOutput_(std::move(videoOutput)) + , session_(-1) +{ + +} + +void VideoService::start() +{ + strand_.dispatch([this, self = this->shared_from_this()]() { + OPENAUTO_LOG(info) << "[VideoService] start."; + channel_->receive(this->shared_from_this()); + }); +} + +void VideoService::stop() +{ + strand_.dispatch([this, self = this->shared_from_this()]() { + OPENAUTO_LOG(info) << "[VideoService] stop."; + videoOutput_->stop(); + }); +} + +void VideoService::onChannelOpenRequest(const aasdk::proto::messages::ChannelOpenRequest& request) +{ + OPENAUTO_LOG(info) << "[VideoService] open request, priority: " << request.priority(); + const aasdk::proto::enums::Status::Enum status = videoOutput_->open() ? aasdk::proto::enums::Status::OK : aasdk::proto::enums::Status::FAIL; + OPENAUTO_LOG(info) << "[VideoService] open status: " << status; + + aasdk::proto::messages::ChannelOpenResponse response; + response.set_status(status); + + auto promise = aasdk::channel::SendPromise::defer(strand_); + promise->then([]() {}, std::bind(&VideoService::onChannelError, this->shared_from_this(), std::placeholders::_1)); + channel_->sendChannelOpenResponse(response, std::move(promise)); + + channel_->receive(this->shared_from_this()); +} + +void VideoService::onAVChannelSetupRequest(const aasdk::proto::messages::AVChannelSetupRequest& request) +{ + OPENAUTO_LOG(info) << "[VideoService] setup request, config index: " << request.config_index(); + const aasdk::proto::enums::AVChannelSetupStatus::Enum status = videoOutput_->init() ? aasdk::proto::enums::AVChannelSetupStatus::OK : aasdk::proto::enums::AVChannelSetupStatus::FAIL; + OPENAUTO_LOG(info) << "[VideoService] setup status: " << status; + + aasdk::proto::messages::AVChannelSetupResponse response; + response.set_media_status(status); + response.set_max_unacked(1); + response.add_configs(0); + + auto promise = aasdk::channel::SendPromise::defer(strand_); + promise->then(std::bind(&VideoService::sendVideoFocusIndication, this->shared_from_this()), + std::bind(&VideoService::onChannelError, this->shared_from_this(), std::placeholders::_1)); + channel_->sendAVChannelSetupResponse(response, std::move(promise)); + channel_->receive(this->shared_from_this()); +} + +void VideoService::onAVChannelStartIndication(const aasdk::proto::messages::AVChannelStartIndication& indication) +{ + OPENAUTO_LOG(info) << "[VideoService] start indication, session: " << indication.session(); + session_ = indication.session(); + + channel_->receive(this->shared_from_this()); +} + +void VideoService::onAVMediaWithTimestampIndication(aasdk::messenger::Timestamp::ValueType timestamp, const aasdk::common::DataConstBuffer& buffer) +{ + videoOutput_->write(timestamp, buffer); + + aasdk::proto::messages::AVMediaAckIndication indication; + indication.set_session(session_); + indication.set_value(1); + + auto promise = aasdk::channel::SendPromise::defer(strand_); + promise->then([]() {}, std::bind(&VideoService::onChannelError, this->shared_from_this(), std::placeholders::_1)); + channel_->sendAVMediaAckIndication(indication, std::move(promise)); + + channel_->receive(this->shared_from_this()); +} + +void VideoService::onAVMediaIndication(const aasdk::common::DataConstBuffer& buffer) +{ + videoOutput_->write(0, buffer); + + aasdk::proto::messages::AVMediaAckIndication indication; + indication.set_session(session_); + indication.set_value(1); + + auto promise = aasdk::channel::SendPromise::defer(strand_); + promise->then([]() {}, std::bind(&VideoService::onChannelError, this->shared_from_this(), std::placeholders::_1)); + channel_->sendAVMediaAckIndication(indication, std::move(promise)); + + channel_->receive(this->shared_from_this()); +} + +void VideoService::onChannelError(const aasdk::error::Error& e) +{ + OPENAUTO_LOG(error) << "[VideoService] channel error: " << e.what(); +} + +void VideoService::fillFeatures(aasdk::proto::messages::ServiceDiscoveryResponse& response) +{ + OPENAUTO_LOG(info) << "[VideoService] fill features."; + + auto* channelDescriptor = response.add_channels(); + channelDescriptor->set_channel_id(static_cast(channel_->getId())); + + auto* videoChannel = channelDescriptor->mutable_av_channel(); + videoChannel->set_stream_type(aasdk::proto::enums::AVStreamType::VIDEO); + videoChannel->set_available_while_in_call(true); + + auto* videoConfig1 = videoChannel->add_video_configs(); + videoConfig1->set_video_resolution(videoOutput_->getVideoResolution()); + videoConfig1->set_video_fps(videoOutput_->getVideoFPS()); + videoConfig1->set_margin_height(0); + videoConfig1->set_margin_width(0); + videoConfig1->set_dpi(videoOutput_->getScreenDPI()); +} + +void VideoService::onVideoFocusRequest(const aasdk::proto::messages::VideoFocusRequest& request) +{ + OPENAUTO_LOG(info) << "[VideoService] video focus request, display index: " << request.disp_index() + << ", focus mode: " << request.focus_mode() + << ", focus reason: " << request.focus_reason(); + + this->sendVideoFocusIndication(); + channel_->receive(this->shared_from_this()); +} + +void VideoService::sendVideoFocusIndication() +{ + OPENAUTO_LOG(info) << "[VideoService] video focus indication."; + + aasdk::proto::messages::VideoFocusIndication videoFocusIndication; + videoFocusIndication.set_focus_mode(aasdk::proto::enums::VideoFocusMode::FOCUSED); + videoFocusIndication.set_unrequested(false); + + auto promise = aasdk::channel::SendPromise::defer(strand_); + promise->then([]() {}, std::bind(&VideoService::onChannelError, this->shared_from_this(), std::placeholders::_1)); + channel_->sendVideoFocusIndication(videoFocusIndication, std::move(promise)); +} + +} +} +} +} diff --git a/src/autoapp/UI/MainWindow.cpp b/src/autoapp/UI/MainWindow.cpp new file mode 100644 index 0000000..d3d8be7 --- /dev/null +++ b/src/autoapp/UI/MainWindow.cpp @@ -0,0 +1,48 @@ +/* +* This file is part of openauto project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* openauto is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 3 of the License, or +* (at your option) any later version. + +* openauto is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with openauto. If not, see . +*/ + +#include +#include "ui_mainwindow.h" + +namespace f1x +{ +namespace openauto +{ +namespace autoapp +{ +namespace ui +{ + +MainWindow::MainWindow(QWidget *parent) + : QMainWindow(parent) + , ui_(new Ui::MainWindow) +{ + ui_->setupUi(this); + connect(ui_->pushButtonSettings, &QPushButton::clicked, this, &MainWindow::openSettings); + connect(ui_->pushButtonExit, &QPushButton::clicked, this, &MainWindow::exit); +} + +MainWindow::~MainWindow() +{ + delete ui_; +} + +} +} +} +} diff --git a/src/autoapp/UI/SettingsWindow.cpp b/src/autoapp/UI/SettingsWindow.cpp new file mode 100644 index 0000000..06777b1 --- /dev/null +++ b/src/autoapp/UI/SettingsWindow.cpp @@ -0,0 +1,242 @@ +/* +* This file is part of openauto project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* openauto is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 3 of the License, or +* (at your option) any later version. + +* openauto is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with openauto. If not, see . +*/ + +#include +#include +#include "ui_settingswindow.h" + +namespace f1x +{ +namespace openauto +{ +namespace autoapp +{ +namespace ui +{ + +SettingsWindow::SettingsWindow(configuration::IConfiguration::Pointer configuration, QWidget *parent) + : QWidget(parent) + , ui_(new Ui::SettingsWindow) + , configuration_(std::move(configuration)) +{ + ui_->setupUi(this); + connect(ui_->pushButtonCancel, &QPushButton::clicked, this, &SettingsWindow::close); + connect(ui_->pushButtonSave, &QPushButton::clicked, this, &SettingsWindow::onSave); + connect(ui_->horizontalSliderScreenDPI, &QSlider::valueChanged, this, &SettingsWindow::onUpdateScreenDPI); + connect(ui_->radioButtonUseExternalBluetoothAdapter, &QRadioButton::clicked, [&](bool checked) { ui_->lineEditExternalBluetoothAdapterAddress->setEnabled(checked); }); + connect(ui_->radioButtonDisableBluetooth, &QRadioButton::clicked, [&]() { ui_->lineEditExternalBluetoothAdapterAddress->setEnabled(false); }); + connect(ui_->radioButtonUseLocalBluetoothAdapter, &QRadioButton::clicked, [&]() { ui_->lineEditExternalBluetoothAdapterAddress->setEnabled(false); }); + connect(ui_->pushButtonClearSelection, &QPushButton::clicked, std::bind(&SettingsWindow::setButtonCheckBoxes, this, false)); + connect(ui_->pushButtonSelectAll, &QPushButton::clicked, std::bind(&SettingsWindow::setButtonCheckBoxes, this, true)); + connect(ui_->pushButtonResetToDefaults, &QPushButton::clicked, this, &SettingsWindow::onResetToDefaults); + connect(ui_->pushButtonShowBindings, &QPushButton::clicked, this, &SettingsWindow::onShowBindings); +} + +SettingsWindow::~SettingsWindow() +{ + delete ui_; +} + +void SettingsWindow::onSave() +{ + configuration_->setHandednessOfTrafficType(ui_->radioButtonLeftHandDrive->isChecked() ? configuration::HandednessOfTrafficType::LEFT_HAND_DRIVE : configuration::HandednessOfTrafficType::RIGHT_HAND_DRIVE); + configuration_->showClock(ui_->checkBoxShowClock->isChecked()); + configuration_->setVideoFPS(ui_->radioButton30FPS->isChecked() ? aasdk::proto::enums::VideoFPS::_30 : aasdk::proto::enums::VideoFPS::_60); + + if(ui_->radioButton480p->isChecked()) + { + configuration_->setVideoResolution(aasdk::proto::enums::VideoResolution::_480p); + } + else if(ui_->radioButton720p->isChecked()) + { + configuration_->setVideoResolution(aasdk::proto::enums::VideoResolution::_720p); + } + else if(ui_->radioButton1080p->isChecked()) + { + configuration_->setVideoResolution(aasdk::proto::enums::VideoResolution::_1080p); + } + + configuration_->setScreenDPI(static_cast(ui_->horizontalSliderScreenDPI->value())); + configuration_->setTouchscreenEnabled(ui_->checkBoxEnableTouchscreen->isChecked()); + this->saveButtonCheckBoxes(); + + if(ui_->radioButtonDisableBluetooth->isChecked()) + { + configuration_->setBluetoothAdapterType(configuration::BluetoothAdapterType::NONE); + } + else if(ui_->radioButtonUseLocalBluetoothAdapter->isChecked()) + { + configuration_->setBluetoothAdapterType(configuration::BluetoothAdapterType::LOCAL); + } + else if(ui_->radioButtonUseExternalBluetoothAdapter->isChecked()) + { + configuration_->setBluetoothAdapterType(configuration::BluetoothAdapterType::REMOTE); + } + + configuration_->setBluetoothRemoteAdapterAddress(ui_->lineEditExternalBluetoothAdapterAddress->text().toStdString()); + + configuration_->save(); + this->close(); +} + +void SettingsWindow::onResetToDefaults() +{ + QMessageBox confirmationMessage(QMessageBox::Question, "Confirmation", "Are you sure you want to reset settings?", QMessageBox::Yes | QMessageBox::Cancel); + confirmationMessage.setWindowFlags(Qt::WindowStaysOnTopHint); + if(confirmationMessage.exec() == QMessageBox::Yes) + { + configuration_->reset(); + this->load(); + } +} + +void SettingsWindow::showEvent(QShowEvent* event) +{ + QWidget::showEvent(event); + this->load(); +} + +void SettingsWindow::load() +{ + ui_->radioButtonLeftHandDrive->setChecked(configuration_->getHandednessOfTrafficType() == configuration::HandednessOfTrafficType::LEFT_HAND_DRIVE); + ui_->radioButtonRightHandDrive->setChecked(configuration_->getHandednessOfTrafficType() == configuration::HandednessOfTrafficType::RIGHT_HAND_DRIVE); + ui_->checkBoxShowClock->setChecked(configuration_->showClock()); + + ui_->radioButton30FPS->setChecked(configuration_->getVideoFPS() == aasdk::proto::enums::VideoFPS::_30); + ui_->radioButton60FPS->setChecked(configuration_->getVideoFPS() == aasdk::proto::enums::VideoFPS::_60); + + ui_->radioButton480p->setChecked(configuration_->getVideoResolution() == aasdk::proto::enums::VideoResolution::_480p); + ui_->radioButton720p->setChecked(configuration_->getVideoResolution() == aasdk::proto::enums::VideoResolution::_720p); + ui_->radioButton1080p->setChecked(configuration_->getVideoResolution() == aasdk::proto::enums::VideoResolution::_1080p); + ui_->horizontalSliderScreenDPI->setValue(static_cast(configuration_->getScreenDPI())); + + ui_->checkBoxEnableTouchscreen->setChecked(configuration_->getTouchscreenEnabled()); + this->loadButtonCheckBoxes(); + + ui_->radioButtonDisableBluetooth->setChecked(configuration_->getBluetoothAdapterType() == configuration::BluetoothAdapterType::NONE); + ui_->radioButtonUseLocalBluetoothAdapter->setChecked(configuration_->getBluetoothAdapterType() == configuration::BluetoothAdapterType::LOCAL); + ui_->radioButtonUseExternalBluetoothAdapter->setChecked(configuration_->getBluetoothAdapterType() == configuration::BluetoothAdapterType::REMOTE); + ui_->lineEditExternalBluetoothAdapterAddress->setEnabled(configuration_->getBluetoothAdapterType() == configuration::BluetoothAdapterType::REMOTE); + ui_->lineEditExternalBluetoothAdapterAddress->setText(QString::fromStdString(configuration_->getBluetoothRemoteAdapterAddress())); +} + +void SettingsWindow::loadButtonCheckBoxes() +{ + const auto& buttonCodes = configuration_->getButtonCodes(); + ui_->checkBoxPlayButton->setChecked(std::find(buttonCodes.begin(), buttonCodes.end(), aasdk::proto::enums::ButtonCode::PLAY) != buttonCodes.end()); + ui_->checkBoxPauseButton->setChecked(std::find(buttonCodes.begin(), buttonCodes.end(), aasdk::proto::enums::ButtonCode::PAUSE) != buttonCodes.end()); + ui_->checkBoxTogglePlayButton->setChecked(std::find(buttonCodes.begin(), buttonCodes.end(), aasdk::proto::enums::ButtonCode::TOGGLE_PLAY) != buttonCodes.end()); + ui_->checkBoxNextTrackButton->setChecked(std::find(buttonCodes.begin(), buttonCodes.end(), aasdk::proto::enums::ButtonCode::NEXT) != buttonCodes.end()); + ui_->checkBoxPreviousTrackButton->setChecked(std::find(buttonCodes.begin(), buttonCodes.end(), aasdk::proto::enums::ButtonCode::PREV) != buttonCodes.end()); + ui_->checkBoxHomeButton->setChecked(std::find(buttonCodes.begin(), buttonCodes.end(), aasdk::proto::enums::ButtonCode::HOME) != buttonCodes.end()); + ui_->checkBoxPhoneButton->setChecked(std::find(buttonCodes.begin(), buttonCodes.end(), aasdk::proto::enums::ButtonCode::PHONE) != buttonCodes.end()); + ui_->checkBoxCallEndButton->setChecked(std::find(buttonCodes.begin(), buttonCodes.end(), aasdk::proto::enums::ButtonCode::CALL_END) != buttonCodes.end()); + ui_->checkBoxVoiceCommandButton->setChecked(std::find(buttonCodes.begin(), buttonCodes.end(), aasdk::proto::enums::ButtonCode::MICROPHONE_1) != buttonCodes.end()); + ui_->checkBoxLeftButton->setChecked(std::find(buttonCodes.begin(), buttonCodes.end(), aasdk::proto::enums::ButtonCode::LEFT) != buttonCodes.end()); + ui_->checkBoxRightButton->setChecked(std::find(buttonCodes.begin(), buttonCodes.end(), aasdk::proto::enums::ButtonCode::RIGHT) != buttonCodes.end()); + ui_->checkBoxUpButton->setChecked(std::find(buttonCodes.begin(), buttonCodes.end(), aasdk::proto::enums::ButtonCode::UP) != buttonCodes.end()); + ui_->checkBoxDownButton->setChecked(std::find(buttonCodes.begin(), buttonCodes.end(), aasdk::proto::enums::ButtonCode::DOWN) != buttonCodes.end()); + ui_->checkBoxScrollWheelButton->setChecked(std::find(buttonCodes.begin(), buttonCodes.end(), aasdk::proto::enums::ButtonCode::SCROLL_WHEEL) != buttonCodes.end()); + ui_->checkBoxBackButton->setChecked(std::find(buttonCodes.begin(), buttonCodes.end(), aasdk::proto::enums::ButtonCode::BACK) != buttonCodes.end()); + ui_->checkBoxEnterButton->setChecked(std::find(buttonCodes.begin(), buttonCodes.end(), aasdk::proto::enums::ButtonCode::ENTER) != buttonCodes.end()); +} + +void SettingsWindow::setButtonCheckBoxes(bool value) +{ + ui_->checkBoxPlayButton->setChecked(value); + ui_->checkBoxPauseButton->setChecked(value); + ui_->checkBoxTogglePlayButton->setChecked(value); + ui_->checkBoxNextTrackButton->setChecked(value); + ui_->checkBoxPreviousTrackButton->setChecked(value); + ui_->checkBoxHomeButton->setChecked(value); + ui_->checkBoxPhoneButton->setChecked(value); + ui_->checkBoxCallEndButton->setChecked(value); + ui_->checkBoxVoiceCommandButton->setChecked(value); + ui_->checkBoxLeftButton->setChecked(value); + ui_->checkBoxRightButton->setChecked(value); + ui_->checkBoxUpButton->setChecked(value); + ui_->checkBoxDownButton->setChecked(value); + ui_->checkBoxScrollWheelButton->setChecked(value); + ui_->checkBoxBackButton->setChecked(value); + ui_->checkBoxEnterButton->setChecked(value); +} + +void SettingsWindow::saveButtonCheckBoxes() +{ + configuration::IConfiguration::ButtonCodes buttonCodes; + this->saveButtonCheckBox(ui_->checkBoxPlayButton, buttonCodes, aasdk::proto::enums::ButtonCode::PLAY); + this->saveButtonCheckBox(ui_->checkBoxPauseButton, buttonCodes, aasdk::proto::enums::ButtonCode::PAUSE); + this->saveButtonCheckBox(ui_->checkBoxTogglePlayButton, buttonCodes, aasdk::proto::enums::ButtonCode::TOGGLE_PLAY); + this->saveButtonCheckBox(ui_->checkBoxNextTrackButton, buttonCodes, aasdk::proto::enums::ButtonCode::NEXT); + this->saveButtonCheckBox(ui_->checkBoxPreviousTrackButton, buttonCodes, aasdk::proto::enums::ButtonCode::PREV); + this->saveButtonCheckBox(ui_->checkBoxHomeButton, buttonCodes, aasdk::proto::enums::ButtonCode::HOME); + this->saveButtonCheckBox(ui_->checkBoxPhoneButton, buttonCodes, aasdk::proto::enums::ButtonCode::PHONE); + this->saveButtonCheckBox(ui_->checkBoxCallEndButton, buttonCodes, aasdk::proto::enums::ButtonCode::CALL_END); + this->saveButtonCheckBox(ui_->checkBoxVoiceCommandButton, buttonCodes, aasdk::proto::enums::ButtonCode::MICROPHONE_1); + this->saveButtonCheckBox(ui_->checkBoxLeftButton, buttonCodes, aasdk::proto::enums::ButtonCode::LEFT); + this->saveButtonCheckBox(ui_->checkBoxRightButton, buttonCodes, aasdk::proto::enums::ButtonCode::RIGHT); + this->saveButtonCheckBox(ui_->checkBoxUpButton, buttonCodes, aasdk::proto::enums::ButtonCode::UP); + this->saveButtonCheckBox(ui_->checkBoxDownButton, buttonCodes, aasdk::proto::enums::ButtonCode::DOWN); + this->saveButtonCheckBox(ui_->checkBoxScrollWheelButton, buttonCodes, aasdk::proto::enums::ButtonCode::SCROLL_WHEEL); + this->saveButtonCheckBox(ui_->checkBoxBackButton, buttonCodes, aasdk::proto::enums::ButtonCode::BACK); + this->saveButtonCheckBox(ui_->checkBoxEnterButton, buttonCodes, aasdk::proto::enums::ButtonCode::ENTER); + configuration_->setButtonCodes(buttonCodes); +} + +void SettingsWindow::saveButtonCheckBox(const QCheckBox* checkBox, configuration::IConfiguration::ButtonCodes& buttonCodes, aasdk::proto::enums::ButtonCode::Enum buttonCode) +{ + if(checkBox->isChecked()) + { + buttonCodes.push_back(buttonCode); + } +} + +void SettingsWindow::onUpdateScreenDPI(int value) +{ + ui_->labelScreenDPIValue->setText(QString::number(value)); +} + +void SettingsWindow::onShowBindings() +{ + const QString message = QString("Enter -> [Enter] \n") + + QString("Left -> [Left] \n") + + QString("Right -> [Right] \n") + + QString("Up -> [Up] \n") + + QString("Down -> [Down] \n") + + QString("Back -> [Esc] \n") + + QString("Home -> [H] \n") + + QString("Phone -> [P] \n") + + QString("Call end -> [O] \n") + + QString("Play -> [X] \n") + + QString("Pause -> [C] \n") + + QString("Previous track -> [V] \n") + + QString("Next track -> [N] \n") + + QString("Toggle play -> [B] \n") + + QString("Voice command -> [M] \n") + + QString("Wheel left -> [1] \n") + + QString("Wheel right -> [2]"); + + QMessageBox confirmationMessage(QMessageBox::Information, "Information", message, QMessageBox::Ok); + confirmationMessage.setWindowFlags(Qt::WindowStaysOnTopHint); + confirmationMessage.exec(); +} + +} +} +} +} diff --git a/src/autoapp/UI/mainwindow.ui b/src/autoapp/UI/mainwindow.ui new file mode 100644 index 0000000..d184cf1 --- /dev/null +++ b/src/autoapp/UI/mainwindow.ui @@ -0,0 +1,207 @@ + + + MainWindow + + + + 0 + 0 + 800 + 480 + + + + MainWindow + + + background-color: rgb(46, 52, 54); +color: rgb(238, 238, 236); + + + + + + 290 + 30 + 281 + 41 + + + + <html><head/><body><p><span style=" font-size:22pt; font-weight:600; font-style:italic; color:#3465a4;">Waiting for device...</span></p></body></html> + + + + + + 180 + 20 + 101 + 101 + + + + <html><head/><body><p><img src=":/ico_androidauto.png"/></p></body></html> + + + + + + 630 + 340 + 161 + 41 + + + + Settings + + + true + + + false + + + + + + 630 + 390 + 161 + 41 + + + + Exit + + + true + + + + + + 340 + 70 + 301 + 31 + + + + <html><head/><body><p><span style=" font-style:italic; color:#eeeeec;">Plug in your device to start AndroidAuto (tm).</span></p></body></html> + + + + + + 10 + 410 + 271 + 21 + + + + <html><head/><body><p><a href="https://github.com/f1xpl/openauto"><span style=" text-decoration: underline; color:#007af4;">https://github.com/f1xpl/openauto</span></a></p></body></html> + + + + + + 30 + 170 + 31 + 41 + + + + <html><head/><body><p><img src=":/ico_warning.png"/></p></body></html> + + + + + + 80 + 130 + 531 + 101 + + + + <html><head/><body><p align="center"><span style=" color:#ef2929;">WARNING!</span></p><p><span style=" color:#ef2929;">Distraction may cause accidents. Do not attempt to operate while driving. Always concentrate on driving and obey Traffic Regulations. You assume total responsibility and risk for using this software.</span></p></body></html> + + + true + + + + + + 80 + 240 + 531 + 121 + + + + <html><head/><body><p><span style=" color:#ef2929;">This software is not certified by Google Inc. It is created for R&amp;D purposes and may not work as expected by the original authors. Do not use while driving.</span></p><p><span style=" color:#ef2929;">You use this software at your own risk.</span></p></body></html> + + + true + + + + + + 30 + 270 + 31 + 41 + + + + <html><head/><body><p><img src=":/ico_warning.png"/></p></body></html> + + + + + + 220 + 376 + 21 + 21 + + + + <html><head/><body><p><img src=":/ico_info.png"/></p></body></html> + + + + + + 250 + 370 + 361 + 31 + + + + <html><head/><body><p><span style=" font-style:italic;">AndroidAuto is registered trademark of Google Inc.</span></p></body></html> + + + + + + + 0 + 0 + 800 + 22 + + + + + + + + diff --git a/src/autoapp/UI/settingswindow.ui b/src/autoapp/UI/settingswindow.ui new file mode 100644 index 0000000..59f14db --- /dev/null +++ b/src/autoapp/UI/settingswindow.ui @@ -0,0 +1,768 @@ + + + SettingsWindow + + + + 0 + 0 + 800 + 480 + + + + + 800 + 480 + + + + + 800 + 480 + + + + Form + + + background-color: rgb(46, 52, 54); +color: rgb(238, 238, 236); + + + + + 630 + 430 + 161 + 41 + + + + Save + + + true + + + + + + 630 + 330 + 161 + 41 + + + + Cancel + + + true + + + false + + + + + + 0 + 0 + 621 + 481 + + + + 0 + + + + General + + + + + 0 + 10 + 621 + 91 + + + + Handedness of traffic + + + + + 10 + 30 + 141 + 23 + + + + Left-hand drive + + + + + + 10 + 60 + 151 + 23 + + + + Right-hand drive + + + + + + + 10 + 110 + 111 + 23 + + + + Show clock + + + + + + Video + + + + + 0 + 130 + 621 + 211 + + + + Resolution + + + + + 10 + 30 + 112 + 23 + + + + 480p + + + + + + 10 + 70 + 112 + 23 + + + + 720p + + + + + + 10 + 110 + 112 + 23 + + + + 1080p + + + + + + 50 + 150 + 551 + 51 + + + + <html><head/><body><p align="justify"><span style=" font-style:italic;">720p and 1080p must be activated in hidden Developer settings of Android Auto application.</span></p></body></html> + + + true + + + + + + 10 + 150 + 41 + 51 + + + + <html><head/><body><p align="justify"><img src=":/ico_warning.png"/></p></body></html> + + + + + + + 0 + 10 + 621 + 101 + + + + Frame rate + + + + + 10 + 70 + 112 + 23 + + + + 60 FPS + + + + + + 10 + 30 + 112 + 23 + + + + 30 FPS + + + + + + + 20 + 390 + 531 + 31 + + + + 999 + + + Qt::Horizontal + + + + + + 20 + 360 + 91 + 17 + + + + Screen DPI + + + + + + 570 + 380 + 41 + 51 + + + + 999 + + + + + + Input + + + + + 0 + 10 + 161 + 23 + + + + Enable touchscreen + + + + + + 0 + 70 + 621 + 381 + + + + QAbstractItemView::MultiSelection + + + + + + 10 + 50 + 67 + 17 + + + + Buttons + + + + + + 20 + 80 + 92 + 23 + + + + Play + + + + + + 20 + 120 + 92 + 23 + + + + Pause + + + + + + 20 + 160 + 111 + 23 + + + + Toggle play + + + + + + 20 + 200 + 92 + 23 + + + + Next track + + + + + + 20 + 240 + 121 + 23 + + + + Previous track + + + + + + 20 + 280 + 92 + 23 + + + + Home + + + + + + 200 + 320 + 92 + 23 + + + + Back + + + + + + 200 + 360 + 92 + 23 + + + + Enter + + + + + + 20 + 320 + 92 + 23 + + + + Phone + + + + + + 20 + 360 + 92 + 23 + + + + Call end + + + + + + 200 + 80 + 141 + 23 + + + + Voice command + + + + + + 200 + 120 + 92 + 23 + + + + Left + + + + + + 200 + 160 + 92 + 23 + + + + Right + + + + + + 200 + 200 + 92 + 23 + + + + Up + + + + + + 200 + 240 + 92 + 23 + + + + Down + + + + + + 200 + 280 + 111 + 23 + + + + Scroll wheel + + + + + + 490 + 80 + 121 + 41 + + + + Select all + + + true + + + + + + 490 + 140 + 121 + 41 + + + + Clear selection + + + true + + + + + + 490 + 200 + 121 + 41 + + + + Show bindings + + + true + + + + + + Bluetooth + + + + + 0 + 10 + 621 + 441 + + + + Bluetooth adapter + + + + + 20 + 30 + 171 + 23 + + + + Disable bluetooth + + + + + + 20 + 90 + 171 + 23 + + + + Use external adapter + + + + + + 130 + 120 + 231 + 31 + + + + + + + 60 + 120 + 67 + 31 + + + + Address: + + + + + + 180 + 160 + 271 + 31 + + + + <html><head/><body><p><span style=" font-size:10pt; font-style:italic; color:#babdb6;">Provide address in format AA:BB:CC:DD:EE:FF.</span></p></body></html> + + + + + + 150 + 160 + 21 + 31 + + + + <html><head/><body><p><img src=":/ico_info.png"/></p></body></html> + + + + + + 20 + 60 + 151 + 23 + + + + Use local adapter + + + + + + 10 + 206 + 31 + 41 + + + + <html><head/><body><p><img src=":/ico_warning.png"/></p></body></html> + + + + + + 50 + 210 + 501 + 31 + + + + In order to use bluetooth features please remember to pair your device. + + + + + + + + + 650 + 80 + 131 + 151 + + + + <html><head/><body><p><img src=":/ico_setting.png"/></p></body></html> + + + + + + 630 + 380 + 161 + 41 + + + + Reset to defaults + + + true + + + + + + diff --git a/src/autoapp/USB/USBApp.cpp b/src/autoapp/USB/USBApp.cpp new file mode 100644 index 0000000..05101b2 --- /dev/null +++ b/src/autoapp/USB/USBApp.cpp @@ -0,0 +1,124 @@ +/* +* This file is part of openauto project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* openauto is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 3 of the License, or +* (at your option) any later version. + +* openauto is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with openauto. If not, see . +*/ + +#include +#include +#include + +namespace f1x +{ +namespace openauto +{ +namespace autoapp +{ +namespace usb +{ + +USBApp::USBApp(boost::asio::io_service& ioService, projection::IAndroidAutoEntityFactory& androidAutoEntityFactory, aasdk::usb::IUSBHub::Pointer usbHub) + : ioService_(ioService) + , strand_(ioService_) + , androidAutoEntityFactory_(androidAutoEntityFactory) + , usbHub_(std::move(usbHub)) + , isStopped_(false) +{ + +} + +void USBApp::start() +{ + strand_.dispatch([this, self = this->shared_from_this()]() { + this->waitForDevice(); + }); +} + +void USBApp::stop() +{ + strand_.dispatch([this, self = this->shared_from_this()]() { + isStopped_ = true; + usbHub_->cancel(); + + if(androidAutoEntity_ != nullptr) + { + androidAutoEntity_->stop(); + } + }); +} + +void USBApp::aoapDeviceHandler(aasdk::usb::DeviceHandle deviceHandle) +{ + OPENAUTO_LOG(info) << "[USBApp] Device connected."; + + if(androidAutoEntity_ == nullptr) + { + try + { + //std::this_thread::sleep_for(std::chrono::seconds(10)); + androidAutoEntity_ = androidAutoEntityFactory_.create(std::move(deviceHandle)); + androidAutoEntity_->start(*this); + } + catch(const aasdk::error::Error& error) + { + OPENAUTO_LOG(error) << "[USBApp] AndroidAutoEntity create error: " << error.what(); + } + } + else + { + OPENAUTO_LOG(warning) << "[USBApp] android auto entity is still running."; + } +} + +void USBApp::waitForDevice() +{ + OPENAUTO_LOG(info) << "[USBApp] Waiting for device..."; + + auto promise = aasdk::usb::IUSBHub::Promise::defer(strand_); + promise->then(std::bind(&USBApp::aoapDeviceHandler, this->shared_from_this(), std::placeholders::_1), + std::bind(&USBApp::onUSBHubError, this->shared_from_this(), std::placeholders::_1)); + usbHub_->start(std::move(promise)); +} + +void USBApp::onAndroidAutoQuit() +{ + strand_.dispatch([this, self = this->shared_from_this()]() { + OPENAUTO_LOG(info) << "[USBApp] quit."; + + androidAutoEntity_->stop(); + androidAutoEntity_.reset(); + + if(!isStopped_) + { + this->waitForDevice(); + } + }); +} + +void USBApp::onUSBHubError(const aasdk::error::Error& error) +{ + OPENAUTO_LOG(error) << "[USBApp] usb hub error: " << error.what(); + + if(error.getCode() == aasdk::error::ErrorCode::OPERATION_ABORTED || + error.getCode() == aasdk::error::ErrorCode::OPERATION_IN_PROGRESS) + { + this->waitForDevice(); + } +} + +} +} +} +} diff --git a/src/autoapp/USB/USBMain.cpp b/src/autoapp/USB/USBMain.cpp new file mode 100644 index 0000000..7561e45 --- /dev/null +++ b/src/autoapp/USB/USBMain.cpp @@ -0,0 +1,105 @@ +/* +* This file is part of openauto project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* openauto is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 3 of the License, or +* (at your option) any later version. + +* openauto is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with openauto. If not, see . +*/ + +#include +#include +#include +#include +#include +#include +#include + +namespace f1x +{ +namespace openauto +{ +namespace autoapp +{ +namespace usb +{ + +USBMain::USBMain(libusb_context* context) + : usbContext_(context) + , usbWrapper_(usbContext_) + , queryFactory_(usbWrapper_, ioService_) + , queryChainFactory_(usbWrapper_, ioService_, queryFactory_) + , configuration_(std::make_shared()) + , serviceFactory_(ioService_, configuration_) + , androidAutoEntityFactory_(usbWrapper_, ioService_, configuration_, serviceFactory_) +{ + aasdk::usb::IUSBHub::Pointer usbHub(std::make_shared(usbWrapper_, ioService_, queryChainFactory_)); + usbApp_ = std::make_shared(ioService_, androidAutoEntityFactory_, std::move(usbHub)); +} + +int USBMain::exec(int argc, char* argv[]) +{ + QApplication qApplication(argc, argv); + qApplication.setOverrideCursor(Qt::BlankCursor); + + ui::MainWindow mainWindow; + mainWindow.setWindowFlags(Qt::WindowStaysOnTopHint); + ui::SettingsWindow settingsWindow(configuration_); + settingsWindow.setWindowFlags(Qt::WindowStaysOnTopHint); + + QObject::connect(&mainWindow, &ui::MainWindow::exit, []() { std::exit(0); }); + QObject::connect(&mainWindow, &ui::MainWindow::openSettings, &settingsWindow, &ui::SettingsWindow::showFullScreen); + mainWindow.showFullScreen(); + + boost::asio::io_service::work work(ioService_); + + this->startIOServiceWorkers(); + this->startUSBWorkers(); + usbApp_->start(); + + auto result = qApplication.exec(); + std::for_each(threadPool_.begin(), threadPool_.end(), std::bind(&std::thread::join, std::placeholders::_1)); + return result; +} + +void USBMain::startUSBWorkers() +{ + auto usbWorker = [this]() { + timeval libusbEventTimeout{180, 0}; + + while(!ioService_.stopped()) + { + libusb_handle_events_timeout_completed(usbContext_, &libusbEventTimeout, nullptr); + } + }; + threadPool_.emplace_back(usbWorker); + threadPool_.emplace_back(usbWorker); + threadPool_.emplace_back(usbWorker); +} + +void USBMain::startIOServiceWorkers() +{ + auto ioServiceWorker = [this]() { + while(!ioService_.stopped()) + { + ioService_.run(); + } + }; + threadPool_.emplace_back(ioServiceWorker); + threadPool_.emplace_back(ioServiceWorker); + threadPool_.emplace_back(ioServiceWorker); +} + +} +} +} +}