diff --git a/selfdrive/ui/SConscript b/selfdrive/ui/SConscript index 362fecb156..8b3ff91d7f 100644 --- a/selfdrive/ui/SConscript +++ b/selfdrive/ui/SConscript @@ -3,15 +3,15 @@ Import('env', 'qt_env', 'arch', 'common', 'messaging', 'gpucommon', 'visionipc', 'cereal', 'transformations') src = ['ui.cc', 'paint.cc', 'sidebar.cc', '#phonelibs/nanovg/nanovg.c'] -libs = [gpucommon, common, 'zmq', 'capnp', 'kj', 'm', 'OpenCL', cereal, - messaging, visionipc, transformations] +libs = [gpucommon, common, 'zmq', 'capnp', 'kj', 'm', 'OpenCL', 'ssl', 'crypto', + cereal, messaging, visionipc, transformations] if arch == 'aarch64': libs += ['log', 'utils', 'gui', 'ui', 'CB', 'gsl', 'adreno_utils', 'cutils', 'uuid'] if arch == 'aarch64' and "QT" not in os.environ: - libs += ['EGL', 'GLESv3', 'gnustl_shared', 'hardware', 'OpenSLES', 'cutils', 'uuid', 'ssl', 'crypto'] + libs += ['EGL', 'GLESv3', 'gnustl_shared', 'hardware', 'OpenSLES', 'cutils', 'uuid'] linkflags = ['-Wl,-rpath=/system/lib64,-rpath=/system/comma/usr/lib'] src += ["android/ui.cc", "android/sl_sound.cc"] @@ -19,14 +19,15 @@ if arch == 'aarch64' and "QT" not in os.environ: LINKFLAGS=linkflags, LIBS=libs) else: - qt_base_libs = qt_env["LIBS"] + libs + ["pthread", "ssl", "crypto"] + qt_base_libs = qt_env["LIBS"] + libs + ["pthread"] if arch == "Darwin": del qt_base_libs[qt_base_libs.index('OpenCL')] qt_env['FRAMEWORKS'] += ['OpenCL'] widgets_src = ["qt/widgets/input_field.cc", "qt/widgets/drive_stats.cc", "qt/widgets/ssh_keys.cc", "qt/widgets/toggle.cc", "qt/qt_sound.cc", - "qt/widgets/offroad_alerts.cc", "qt/widgets/setup.cc", "qt/widgets/keyboard.cc"] + "qt/widgets/offroad_alerts.cc", "qt/widgets/setup.cc", "qt/widgets/keyboard.cc", + "#phonelibs/qrcode/QrCode.cc"] if arch != 'aarch64': widgets_src += ["qt/offroad/networking.cc", "qt/offroad/wifiManager.cc"] @@ -34,13 +35,16 @@ else: widgets = qt_env.Library("qt_widgets", widgets_src, LIBS=qt_base_libs) qt_libs = qt_base_libs + [widgets] - qt_src = ["qt/ui.cc", "qt/window.cc", "qt/home.cc", "qt/api.cc", "qt/offroad/settings.cc", "qt/offroad/onboarding.cc", "#phonelibs/qrcode/QrCode.cc"] + src + qt_src = ["qt/ui.cc", "qt/window.cc", "qt/home.cc", "qt/api.cc", "qt/offroad/settings.cc", + "qt/offroad/onboarding.cc"] + src qt_env.Program("_ui", qt_src, LIBS=qt_libs) # spinner and text window qt_env.Program("qt/text", ["qt/text.cc"], LIBS=qt_base_libs) qt_env.Program("qt/spinner", ["qt/spinner.cc"], LIBS=qt_base_libs) + #qt_env.Program("tests/ssl_test", ["tests/ssl_test.cc"], LIBS=qt_base_libs) + # build setup, factory resetter, and installer if "BUILD_SETUP" in os.environ: qt_env.Program("qt/setup/reset", ["qt/setup/reset.cc"], LIBS=qt_libs) diff --git a/selfdrive/ui/qt/api.cc b/selfdrive/ui/qt/api.cc index 06f59c4072..5e92083039 100644 --- a/selfdrive/ui/qt/api.cc +++ b/selfdrive/ui/qt/api.cc @@ -9,10 +9,12 @@ #include #include #include + #include "api.hpp" #include "home.hpp" #include "common/params.h" #include "common/util.h" + #if defined(QCOM) || defined(QCOM2) const std::string private_key_path = "/persist/comma/id_rsa"; #else @@ -51,7 +53,7 @@ QString CommaApi::create_jwt(QVector> payloads, int e QJsonObject payload; payload.insert("identity", dongle_id); - + auto t = QDateTime::currentSecsSinceEpoch(); payload.insert("nbf", t); payload.insert("iat", t); @@ -60,14 +62,13 @@ QString CommaApi::create_jwt(QVector> payloads, int e payload.insert(load.first, load.second); } - QString jwt = - QJsonDocument(header).toJson(QJsonDocument::Compact).toBase64(QByteArray::Base64UrlEncoding | QByteArray::OmitTrailingEquals) + - '.' + - QJsonDocument(payload).toJson(QJsonDocument::Compact).toBase64(QByteArray::Base64UrlEncoding | QByteArray::OmitTrailingEquals); + auto b64_opts = QByteArray::Base64UrlEncoding | QByteArray::OmitTrailingEquals; + QString jwt = QJsonDocument(header).toJson(QJsonDocument::Compact).toBase64(b64_opts) + '.' + + QJsonDocument(payload).toJson(QJsonDocument::Compact).toBase64(b64_opts); auto hash = QCryptographicHash::hash(jwt.toUtf8(), QCryptographicHash::Sha256); auto sig = rsa_sign(hash); - jwt += '.' + sig.toBase64(QByteArray::Base64UrlEncoding | QByteArray::OmitTrailingEquals); + jwt += '.' + sig.toBase64(b64_opts); return jwt; } @@ -79,13 +80,15 @@ RequestRepeater::RequestRepeater(QWidget* parent, QString requestURL, int period : disableWithScreen(disableWithScreen), QObject(parent) { networkAccessManager = new QNetworkAccessManager(this); + reply = NULL; + QTimer* timer = new QTimer(this); QObject::connect(timer, &QTimer::timeout, [=](){sendRequest(requestURL, payloads);}); timer->start(period_seconds * 1000); networkTimer = new QTimer(this); networkTimer->setSingleShot(true); - networkTimer->setInterval(20000); // 20s before aborting + networkTimer->setInterval(20000); connect(networkTimer, SIGNAL(timeout()), this, SLOT(requestTimeout())); } @@ -100,11 +103,21 @@ void RequestRepeater::sendRequest(QString requestURL, QVectorget(request); @@ -119,16 +132,17 @@ void RequestRepeater::requestTimeout(){ // This function should always emit something void RequestRepeater::requestFinished(){ - if(!aborted){ + if (!aborted) { networkTimer->stop(); QString response = reply->readAll(); if (reply->error() == QNetworkReply::NoError) { emit receivedResponse(response); } else { + qDebug() << reply->errorString(); emit failedResponse(reply->errorString()); } - }else{ - emit failedResponse("Custom Openpilot network timeout"); + } else { + emit failedResponse("network timeout"); } reply->deleteLater(); reply = NULL; diff --git a/selfdrive/ui/qt/api.hpp b/selfdrive/ui/qt/api.hpp index 7f7892fe0e..3d24e6e220 100644 --- a/selfdrive/ui/qt/api.hpp +++ b/selfdrive/ui/qt/api.hpp @@ -8,16 +8,20 @@ #include #include #include + #include #include #include #include + class CommaApi : public QObject { Q_OBJECT + public: static QByteArray rsa_sign(QByteArray data); static QString create_jwt(QVector> payloads, int expiry=3600); static QString create_jwt(); + private: QNetworkAccessManager* networkAccessManager; }; @@ -27,9 +31,11 @@ private: */ class RequestRepeater : public QObject { Q_OBJECT + public: explicit RequestRepeater(QWidget* parent, QString requestURL, int period = 10, QVector> payloads = *(new QVector>()), bool disableWithScreen = true); bool active = true; + private: bool disableWithScreen; QNetworkReply* reply; @@ -37,9 +43,11 @@ private: QTimer* networkTimer; std::atomic aborted = false; // Not 100% sure we need atomic void sendRequest(QString requestURL, QVector> payloads); + private slots: void requestTimeout(); void requestFinished(); + signals: void receivedResponse(QString response); void failedResponse(QString errorString); diff --git a/selfdrive/ui/qt/ui.cc b/selfdrive/ui/qt/ui.cc index 93eb77f911..1f33c75aaf 100644 --- a/selfdrive/ui/qt/ui.cc +++ b/selfdrive/ui/qt/ui.cc @@ -14,6 +14,10 @@ int main(int argc, char *argv[]) { #endif QSurfaceFormat::setDefaultFormat(fmt); +#ifdef QCOM + QApplication::setAttribute(Qt::AA_ShareOpenGLContexts); +#endif + QApplication a(argc, argv); MainWindow w; setMainWindow(&w); diff --git a/selfdrive/ui/qt/widgets/drive_stats.cc b/selfdrive/ui/qt/widgets/drive_stats.cc index cee0119957..efb58c2b1f 100644 --- a/selfdrive/ui/qt/widgets/drive_stats.cc +++ b/selfdrive/ui/qt/widgets/drive_stats.cc @@ -1,30 +1,16 @@ -#include -#include - #include -#include #include #include #include -#include #include -#include #include #include "api.hpp" #include "common/params.h" -#include "common/util.h" #include "drive_stats.hpp" -#include "home.hpp" const double MILE_TO_KM = 1.60934; -#if defined(QCOM) || defined(QCOM2) -const std::string private_key_path = "/persist/comma/id_rsa"; -#else -const std::string private_key_path = util::getenv_default("HOME", "/.comma/persist/comma/id_rsa", "/persist/comma/id_rsa"); -#endif - void clearLayouts(QLayout* layout) { while (QLayoutItem* item = layout->takeAt(0)) { if (QWidget* widget = item->widget()) { @@ -59,7 +45,7 @@ QLayout* build_stat(QString name, int stat) { void DriveStats::parseError(QString response) { clearLayouts(vlayout); - vlayout->addWidget(new QLabel("No internet connection")); + vlayout->addWidget(new QLabel("No Internet connection"), 0, Qt::AlignCenter); } void DriveStats::parseResponse(QString response) { @@ -71,8 +57,7 @@ void DriveStats::parseResponse(QString response) { return; } - QString IsMetric = QString::fromStdString(Params().get("IsMetric")); - bool metric = (IsMetric == "1"); + bool metric = Params().read_db_bool("IsMetric"); QJsonObject json = doc.object(); auto all = json["all"].toObject(); @@ -94,7 +79,6 @@ void DriveStats::parseResponse(QString response) { QWidget* q = new QWidget; q->setLayout(gl); - vlayout->addWidget(q); } @@ -113,5 +97,4 @@ DriveStats::DriveStats(QWidget* parent) : QWidget(parent) { RequestRepeater* repeater = new RequestRepeater(this, url, 13); QObject::connect(repeater, SIGNAL(receivedResponse(QString)), this, SLOT(parseResponse(QString))); QObject::connect(repeater, SIGNAL(failedResponse(QString)), this, SLOT(parseError(QString))); - } diff --git a/selfdrive/ui/qt/widgets/drive_stats.hpp b/selfdrive/ui/qt/widgets/drive_stats.hpp index bf4cdae000..40cefbb4d9 100644 --- a/selfdrive/ui/qt/widgets/drive_stats.hpp +++ b/selfdrive/ui/qt/widgets/drive_stats.hpp @@ -1,11 +1,8 @@ #pragma once -#include #include #include -#include "api.hpp" - class DriveStats : public QWidget { Q_OBJECT diff --git a/selfdrive/ui/qt/widgets/setup.cc b/selfdrive/ui/qt/widgets/setup.cc index 193e225196..fccfe0d206 100644 --- a/selfdrive/ui/qt/widgets/setup.cc +++ b/selfdrive/ui/qt/widgets/setup.cc @@ -2,6 +2,7 @@ #include #include #include +#include #include #include #include @@ -9,18 +10,10 @@ #include "QrCode.hpp" #include "api.hpp" #include "common/params.h" -#include "common/util.h" -#include "home.hpp" #include "setup.hpp" using qrcodegen::QrCode; -#if defined(QCOM) || defined(QCOM2) -const std::string private_key_path = "/persist/comma/id_rsa"; -#else -const std::string private_key_path = util::getenv_default("HOME", "/.comma/persist/comma/id_rsa", "/persist/comma/id_rsa"); -#endif - PairingQRWidget::PairingQRWidget(QWidget* parent) : QWidget(parent) { qrCode = new QLabel; qrCode->setScaledContents(true); @@ -29,7 +22,7 @@ PairingQRWidget::PairingQRWidget(QWidget* parent) : QWidget(parent) { setLayout(v); QTimer* timer = new QTimer(this); - timer->start(30 * 1000);// HaLf a minute + timer->start(30 * 1000); connect(timer, SIGNAL(timeout()), this, SLOT(refresh())); refresh(); // Not waiting for the first refresh } @@ -41,9 +34,7 @@ void PairingQRWidget::refresh(){ if (std::min(IMEI.length(), serial.length()) <= 5) { qrCode->setText("Error getting serial: contact support"); qrCode->setWordWrap(true); - qrCode->setStyleSheet(R"( - font-size: 60px; - )"); + qrCode->setStyleSheet(R"(font-size: 60px;)"); return; } QVector> payloads; @@ -157,7 +148,6 @@ PrimeAdWidget::PrimeAdWidget(QWidget* parent) : QWidget(parent) { } - SetupWidget::SetupWidget(QWidget* parent) : QWidget(parent) { QVBoxLayout* backgroundLayout = new QVBoxLayout; @@ -184,7 +174,7 @@ SetupWidget::SetupWidget(QWidget* parent) : QWidget(parent) { QObject::connect(finishButton, SIGNAL(released()), this, SLOT(showQrCode())); finishRegistationLayout->addWidget(finishButton); - QLabel* registrationDescription = new QLabel("Pair your Comma device with the Comma Connect app"); + QLabel* registrationDescription = new QLabel("Pair your device with the comma connect app"); registrationDescription->setStyleSheet(R"( font-size: 55px; font-weight: 400; @@ -198,10 +188,8 @@ SetupWidget::SetupWidget(QWidget* parent) : QWidget(parent) { QVBoxLayout* qrLayout = new QVBoxLayout; - QLabel* qrLabel = new QLabel("Pair with Comma Connect app!"); - qrLabel->setStyleSheet(R"( - font-size: 40px; - )"); + QLabel* qrLabel = new QLabel("Pair with comma connect!"); + qrLabel->setStyleSheet(R"(font-size: 40px)"); qrLayout->addWidget(qrLabel); qrLayout->addWidget(new PairingQRWidget); @@ -232,7 +220,6 @@ SetupWidget::SetupWidget(QWidget* parent) : QWidget(parent) { QObject::connect(repeater, SIGNAL(receivedResponse(QString)), this, SLOT(replyFinished(QString))); QObject::connect(repeater, SIGNAL(failedResponse(QString)), this, SLOT(parseError(QString))); - } void SetupWidget::parseError(QString response) { @@ -243,16 +230,19 @@ void SetupWidget::parseError(QString response) { background-color: #000000; )"); } + void SetupWidget::showQrCode(){ showQr = true; mainLayout->setCurrentIndex(2); } + void SetupWidget::replyFinished(QString response) { QJsonDocument doc = QJsonDocument::fromJson(response.toUtf8()); if (doc.isNull()) { qDebug() << "JSON Parse failed on getting pairing and prime status"; return; } + if (mainLayout->currentIndex() == 0) { // If we are still on the blank widget setStyleSheet(R"( font-size: 90px; @@ -260,6 +250,7 @@ void SetupWidget::replyFinished(QString response) { background-color: #292929; )"); } + QJsonObject json = doc.object(); bool is_paired = json["is_paired"].toBool(); bool is_prime = json["prime"].toBool(); diff --git a/selfdrive/ui/qt/widgets/setup.hpp b/selfdrive/ui/qt/widgets/setup.hpp index 0224ace560..8fed2a1bbc 100644 --- a/selfdrive/ui/qt/widgets/setup.hpp +++ b/selfdrive/ui/qt/widgets/setup.hpp @@ -1,7 +1,6 @@ #pragma once #include -#include #include #include diff --git a/selfdrive/ui/qt/window.cc b/selfdrive/ui/qt/window.cc index e26a500237..d0a752a6dc 100644 --- a/selfdrive/ui/qt/window.cc +++ b/selfdrive/ui/qt/window.cc @@ -24,9 +24,11 @@ MainWindow::MainWindow(QWidget *parent) : QWidget(parent) { QObject::connect(onboardingWindow, SIGNAL(onboardingDone()), this, SLOT(closeSettings())); onboardingWindow->updateActiveScreen(); + // no outline to prevent the focus rectangle setStyleSheet(R"( * { font-family: Inter; + outline: none; } )"); } @@ -34,7 +36,7 @@ MainWindow::MainWindow(QWidget *parent) : QWidget(parent) { void MainWindow::offroadTransition(bool offroad){ if(!offroad){ closeSettings(); - } + } } void MainWindow::openSettings() { diff --git a/selfdrive/ui/tests/ssl_test.cc b/selfdrive/ui/tests/ssl_test.cc new file mode 100644 index 0000000000..acb38de7ea --- /dev/null +++ b/selfdrive/ui/tests/ssl_test.cc @@ -0,0 +1,22 @@ +#include +#include +#include +#include + +int main(int argc, char **argv) { + QCoreApplication app(argc, argv); + QSslSocket socket; + + socket.setPeerVerifyMode(QSslSocket::VerifyNone); + + qDebug() << "Supports SSL: " << QSslSocket::supportsSsl(); + qDebug() << "Version: " << QSslSocket::sslLibraryVersionString() << " " << QSslSocket::sslLibraryVersionNumber(); + qDebug() << "Build Version: " << QSslSocket::sslLibraryBuildVersionString() << " " << QSslSocket::sslLibraryBuildVersionNumber(); + + socket.connectToHost("www.google.com", 443); + + socket.write("GET / HTTP/1.1rnrn"); + + while (socket.waitForReadyRead()) + qDebug() << socket.readAll().data(); +} diff --git a/selfdrive/ui/ui b/selfdrive/ui/ui index d30f915846..e1c1748e30 100755 --- a/selfdrive/ui/ui +++ b/selfdrive/ui/ui @@ -1,11 +1,3 @@ #!/bin/sh - export LD_LIBRARY_PATH="/system/lib64:$LD_LIBRARY_PATH" - -if [ -f /EON ]; then - export QT_QPA_EGLFS_HIDECURSOR=1 - export QT_QPA_EVDEV_TOUCHSCREEN_PARAMETERS=/dev/input/event1:rotate=270 - export QT_QPA_FONTDIR=../assets/fonts -fi - exec ./_ui