forked from openDsh/openauto
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathautoapp.cpp
More file actions
226 lines (186 loc) · 8.51 KB
/
Copy pathautoapp.cpp
File metadata and controls
226 lines (186 loc) · 8.51 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
#include <thread>
#include <QApplication>
#include <QWindow>
#include <QMainWindow>
#include <QStackedWidget>
#include <QFile>
#include <QThread>
#include <QStyleFactory>
#include <QMetaType>
#include <QScreen>
#include <QString>
#include <QProcess>
#include "aasdk/USB/USBHub.hpp"
#include "aasdk/USB/ConnectedAccessoriesEnumerator.hpp"
#include "aasdk/USB/AccessoryModeQueryChain.hpp"
#include "aasdk/USB/AccessoryModeQueryChainFactory.hpp"
#include "aasdk/USB/AccessoryModeQueryFactory.hpp"
#include "aasdk/TCP/TCPWrapper.hpp"
#include "openauto/App.hpp"
#include "openauto/Service/AndroidAutoEntityFactory.hpp"
#include "openauto/Service/ServiceFactory.hpp"
#include "openauto/Service/BluetoothAdvertiseService.hpp"
#include "openauto/Configuration/Configuration.hpp"
#include "./Pages/HomePage.hpp"
#include "./Pages/ProjectionPage.hpp"
#include "./Service/OpenautoEventFilter.hpp"
#include "./Service/Alsa.hpp"
#include "./Service/SteeringWheelControl.hpp"
#include "OpenautoLog.hpp"
using namespace openauto;
using ThreadPool = std::vector<std::thread>;
void startUSBWorkers(boost::asio::io_service& ioService, libusb_context* usbContext, ThreadPool& threadPool)
{
auto usbWorker = [&ioService, usbContext]() {
timeval libusbEventTimeout{180, 0};
while(!ioService.stopped())
{
libusb_handle_events_timeout_completed(usbContext, &libusbEventTimeout, nullptr);
}
};
threadPool.emplace_back(usbWorker);
threadPool.emplace_back(usbWorker);
threadPool.emplace_back(usbWorker);
threadPool.emplace_back(usbWorker);
}
void startIOServiceWorkers(boost::asio::io_service& ioService, ThreadPool& threadPool)
{
auto ioServiceWorker = [&ioService]() {
ioService.run();
};
threadPool.emplace_back(ioServiceWorker);
threadPool.emplace_back(ioServiceWorker);
threadPool.emplace_back(ioServiceWorker);
threadPool.emplace_back(ioServiceWorker);
}
void reconnectToLastBluetoothDevice(QString address)
{
auto connectCommand = QString("bluetoothctl disconnect %1 && bluetoothctl connect %1").arg(address);
QProcess::startDetached("/bin/sh", QStringList() << "-c" << connectCommand);
}
int main(int argc, char* argv[])
{
QApplication::setStyle(QStyleFactory::create("Fusion"));
QApplication app(argc, argv);
app.setOverrideCursor(Qt::BlankCursor);
app.processEvents();
// ===================================== SERVICE STUFF
libusb_context* usbContext;
if(libusb_init(&usbContext) != 0)
{
OPENAUTO_LOG(error) << "[OpenAuto] libusb init failed.";
return 1;
}
boost::asio::io_service ioService;
boost::asio::io_service::work work(ioService);
std::vector<std::thread> threadPool;
startUSBWorkers(ioService, usbContext, threadPool);
startIOServiceWorkers(ioService, threadPool);
autoapp::service::Alsa alsaWorker;
// ===================================== UI STUFF
QMainWindow window;
QStackedWidget stackedWidget;
stackedWidget.setStyleSheet("background-color: #111111;color: #eeeeec;");
autoapp::pages::HomePage homePage;
QObject::connect(&homePage, &autoapp::pages::HomePage::exit, []() { std::exit(0); });
stackedWidget.addWidget(&homePage);
autoapp::pages::ProjectionPage projectionPage(&alsaWorker);
projectionPage.hide();
stackedWidget.addWidget(&projectionPage);
stackedWidget.setCurrentIndex(0);
window.setCentralWidget(&stackedWidget);
// ===================================== SERVICE STUFF
auto configuration = std::make_shared<openauto::configuration::Configuration>();
aasdk::tcp::TCPWrapper tcpWrapper;
aasdk::usb::USBWrapper usbWrapper(usbContext);
aasdk::usb::AccessoryModeQueryFactory queryFactory(usbWrapper, ioService);
aasdk::usb::AccessoryModeQueryChainFactory queryChainFactory(usbWrapper, ioService, queryFactory);
openauto::service::ServiceFactory serviceFactory(ioService, configuration, projectionPage.aaFrame);
openauto::service::AndroidAutoEntityFactory androidAutoEntityFactory(ioService, configuration, serviceFactory);
openauto::service::BluetoothAdvertiseService bluetoothAdvertiseService(configuration);
auto usbHub(std::make_shared<aasdk::usb::USBHub>(usbWrapper, ioService, queryChainFactory));
auto connectedAccessoriesEnumerator(std::make_shared<aasdk::usb::ConnectedAccessoriesEnumerator>(usbWrapper, ioService, queryChainFactory));
auto openautoApp = std::make_shared<openauto::App>(ioService, usbWrapper, tcpWrapper, androidAutoEntityFactory, std::move(usbHub), std::move(connectedAccessoriesEnumerator));
autoapp::service::OpenautoEventFilter filter;
app.installEventFilter(&filter);
QObject::connect(&filter, &autoapp::service::OpenautoEventFilter::onAppEvent, [&projectionPage, &homePage, &stackedWidget, &openautoApp](openauto::service::AppEventType value) {
switch (value) {
case openauto::service::AppEventType::ProjectionShow:
stackedWidget.setCurrentIndex(1);
projectionPage.show();
break;
case openauto::service::AppEventType::ProjectionEnd:
projectionPage.hide();
stackedWidget.setCurrentIndex(0);
openautoApp->onAndroidAutoQuit();
break;
case openauto::service::AppEventType::AndroidAutoStopped:
projectionPage.hide();
homePage.setStatusLabel("Waiting for device");
stackedWidget.setCurrentIndex(0);
break;
case openauto::service::AppEventType::BluetoothConnected:
homePage.setStatusLabel("Wireless device found");
break;
case openauto::service::AppEventType::WirelessConnecting:
homePage.setStatusLabel("Wireless device connecting");
break;
case openauto::service::AppEventType::UsbConnecting:
homePage.setStatusLabel("USB device connecting");
break;
}
});
homePage.setStatusLabel("Waiting for device");
auto screenSize = QGuiApplication::primaryScreen()->size();
window.resize(screenSize);
projectionPage.aaFrame->resize(screenSize);
window.show();
window.activateWindow();
alsaWorker.start();
openautoApp->waitForDevice(true);
bluetoothAdvertiseService.startAdvertising();
// ===================================== BLUETOOTH CONNECT
auto lastPairedAddress = QString::fromStdString(configuration->getLastBluetoothPair());
if (!lastPairedAddress.isEmpty()) {
QObject::connect(&homePage, &autoapp::pages::HomePage::bluetoothConnect, [&lastPairedAddress]() {
OPENAUTO_LOG(info) << "Connect bluetooth";
reconnectToLastBluetoothDevice(lastPairedAddress);
});
OPENAUTO_LOG(info) << "Autoconnecting bluetooth";
reconnectToLastBluetoothDevice(lastPairedAddress);
}
// ===================================== KEYPRESS FORWARDER
qRegisterMetaType<Qt::Key>();
autoapp::service::SteeringWheelControl swcWorker;
swcWorker.start();
QObject::connect(&swcWorker, &autoapp::service::SteeringWheelControl::onKeyPress, [&app, &alsaWorker, &projectionPage](Qt::Key key) {
if (key == Qt::Key_VolumeDown || key == Qt::Key_VolumeUp) {
alsaWorker.adjustVolumeRelative(key == Qt::Key_VolumeDown ? -5 : 5);
} else {
app.postEvent(projectionPage.aaFrame, new QKeyEvent(QEvent::KeyPress, key, Qt::NoModifier));
app.postEvent(projectionPage.aaFrame, new QKeyEvent(QEvent::KeyRelease, key, Qt::NoModifier));
}
});
// ===================================== DEVELOPMENT TEST CONNECT
QObject::connect(&homePage, &autoapp::pages::HomePage::testConnect, [&openautoApp, &tcpWrapper, &ioService]() {
OPENAUTO_LOG(info) << "Test connection";
aasdk::tcp::ITCPEndpoint::SocketPointer socket = std::make_shared<boost::asio::ip::tcp::socket>(ioService);
try {
if (!tcpWrapper.connect(*socket, "192.168.1.8", 5277)) {
openautoApp->start(std::move(socket), false);
} else {
OPENAUTO_LOG(info) << "TCP connection failed";
}
} catch (const boost::system::system_error& se) {
OPENAUTO_LOG(error) << "Failed to open socket";
}
});
auto result = app.exec();
std::for_each(threadPool.begin(), threadPool.end(), std::bind(&std::thread::join, std::placeholders::_1));
libusb_exit(usbContext);
swcWorker.quit();
swcWorker.wait();
alsaWorker.quit();
alsaWorker.wait();
return result;
}