* no outline

* disable on qcom for now

* fix qt 5.12.8

* cleanup drive stats

* widgets cleanup

* ssl test

* revert that

* disable by default

Co-authored-by: Comma Device <device@comma.ai>
pull/20203/head
Adeeb Shihadeh 4 years ago committed by GitHub
parent 7921759bbe
commit ec8b21c261
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 16
      selfdrive/ui/SConscript
  2. 36
      selfdrive/ui/qt/api.cc
  3. 8
      selfdrive/ui/qt/api.hpp
  4. 4
      selfdrive/ui/qt/ui.cc
  5. 21
      selfdrive/ui/qt/widgets/drive_stats.cc
  6. 3
      selfdrive/ui/qt/widgets/drive_stats.hpp
  7. 29
      selfdrive/ui/qt/widgets/setup.cc
  8. 1
      selfdrive/ui/qt/widgets/setup.hpp
  9. 4
      selfdrive/ui/qt/window.cc
  10. 22
      selfdrive/ui/tests/ssl_test.cc
  11. 8
      selfdrive/ui/ui

@ -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)

@ -9,10 +9,12 @@
#include <QWidget>
#include <QTimer>
#include <QRandomGenerator>
#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<QPair<QString, QJsonValue>> 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<QPair<QString, QJsonValue>> 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, QVector<QPair<QString, QJs
if(reply != NULL){
return;
}
aborted = false;
QString token = CommaApi::create_jwt(payloads);
QNetworkRequest request;
request.setUrl(QUrl(requestURL));
request.setRawHeader("Authorization", ("JWT " + token).toUtf8());
request.setRawHeader(QByteArray("Authorization"), ("JWT " + token).toUtf8());
// TODO: fix this
/*
#ifdef QCOM
QSslConfiguration ssl = QSslConfiguration::defaultConfiguration();
ssl.setPeerVerifyMode(QSslSocket::VerifyNone);
request.setSslConfiguration(ssl);
#endif
*/
reply = networkAccessManager->get(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;

@ -8,16 +8,20 @@
#include <QString>
#include <QVector>
#include <QWidget>
#include <atomic>
#include <openssl/bio.h>
#include <openssl/pem.h>
#include <openssl/rsa.h>
class CommaApi : public QObject {
Q_OBJECT
public:
static QByteArray rsa_sign(QByteArray data);
static QString create_jwt(QVector<QPair<QString, QJsonValue>> 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<QPair<QString, QJsonValue>> payloads = *(new QVector<QPair<QString, QJsonValue>>()), bool disableWithScreen = true);
bool active = true;
private:
bool disableWithScreen;
QNetworkReply* reply;
@ -37,9 +43,11 @@ private:
QTimer* networkTimer;
std::atomic<bool> aborted = false; // Not 100% sure we need atomic
void sendRequest(QString requestURL, QVector<QPair<QString, QJsonValue>> payloads);
private slots:
void requestTimeout();
void requestFinished();
signals:
void receivedResponse(QString response);
void failedResponse(QString errorString);

@ -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);

@ -1,30 +1,16 @@
#include <cassert>
#include <iostream>
#include <QDebug>
#include <QFile>
#include <QJsonDocument>
#include <QJsonObject>
#include <QLabel>
#include <QNetworkRequest>
#include <QStackedLayout>
#include <QTimer>
#include <QVBoxLayout>
#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)));
}

@ -1,11 +1,8 @@
#pragma once
#include <QNetworkReply>
#include <QVBoxLayout>
#include <QWidget>
#include "api.hpp"
class DriveStats : public QWidget {
Q_OBJECT

@ -2,6 +2,7 @@
#include <QJsonDocument>
#include <QJsonObject>
#include <QLabel>
#include <QPushButton>
#include <QStackedLayout>
#include <QTimer>
#include <QVBoxLayout>
@ -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<QPair<QString, QJsonValue>> 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();

@ -1,7 +1,6 @@
#pragma once
#include <QLabel>
#include <QNetworkReply>
#include <QStackedLayout>
#include <QWidget>

@ -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() {

@ -0,0 +1,22 @@
#include <QDebug>
#include <QApplication>
#include <QSslSocket>
#include <QNetworkProxy>
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();
}

@ -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

Loading…
Cancel
Save