ui: consolidate prime state management into PrimeState Class (#33473)
new class PrimeState
This commit is contained in:
@@ -16,7 +16,7 @@ if arch == "Darwin":
|
||||
qt_env['CXXFLAGS'] += ["-Wno-deprecated-declarations"]
|
||||
|
||||
qt_util = qt_env.Library("qt_util", ["#selfdrive/ui/qt/api.cc", "#selfdrive/ui/qt/util.cc"], LIBS=base_libs)
|
||||
widgets_src = ["ui.cc", "qt/widgets/input.cc", "qt/widgets/wifi.cc",
|
||||
widgets_src = ["qt/widgets/input.cc", "qt/widgets/wifi.cc", "qt/prime_state.cc",
|
||||
"qt/widgets/ssh_keys.cc", "qt/widgets/toggle.cc", "qt/widgets/controls.cc",
|
||||
"qt/widgets/offroad_alerts.cc", "qt/widgets/prime.cc", "qt/widgets/keyboard.cc",
|
||||
"qt/widgets/scrollview.cc", "qt/widgets/cameraview.cc", "#third_party/qrcode/QrCode.cc",
|
||||
@@ -26,7 +26,7 @@ widgets = qt_env.Library("qt_widgets", widgets_src, LIBS=base_libs)
|
||||
Export('widgets')
|
||||
qt_libs = [widgets, qt_util] + base_libs
|
||||
|
||||
qt_src = ["main.cc", "qt/sidebar.cc", "qt/body.cc",
|
||||
qt_src = ["main.cc", "ui.cc", "qt/sidebar.cc", "qt/body.cc",
|
||||
"qt/window.cc", "qt/home.cc", "qt/offroad/settings.cc",
|
||||
"qt/offroad/software_settings.cc", "qt/offroad/onboarding.cc",
|
||||
"qt/offroad/driverview.cc", "qt/offroad/experimental_mode.cc",
|
||||
|
||||
@@ -150,9 +150,8 @@ OffroadHome::OffroadHome(QWidget* parent) : QFrame(parent) {
|
||||
left_widget->addWidget(new PrimeAdWidget);
|
||||
left_widget->setStyleSheet("border-radius: 10px;");
|
||||
|
||||
left_widget->setCurrentIndex(uiState()->hasPrime() ? 0 : 1);
|
||||
connect(uiState(), &UIState::primeChanged, [=](bool prime) {
|
||||
left_widget->setCurrentIndex(prime ? 0 : 1);
|
||||
connect(uiState()->prime_state, &PrimeState::changed, [left_widget]() {
|
||||
left_widget->setCurrentIndex(uiState()->prime_state->isSubscribed() ? 0 : 1);
|
||||
});
|
||||
|
||||
home_layout->addWidget(left_widget, 1);
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
#include <QScrollBar>
|
||||
#include <QStyle>
|
||||
|
||||
#include "selfdrive/ui/ui.h"
|
||||
#include "selfdrive/ui/qt/qt_window.h"
|
||||
#include "selfdrive/ui/qt/util.h"
|
||||
#include "selfdrive/ui/qt/widgets/controls.h"
|
||||
@@ -73,6 +72,11 @@ Networking::Networking(QWidget* parent, bool show_advanced) : QFrame(parent) {
|
||||
main_layout->setCurrentWidget(wifiScreen);
|
||||
}
|
||||
|
||||
void Networking::setPrimeType(PrimeState::Type type) {
|
||||
an->setGsmVisible(type == PrimeState::PRIME_TYPE_NONE || type == PrimeState::PRIME_TYPE_LITE);
|
||||
wifi->ipv4_forward = (type == PrimeState::PRIME_TYPE_NONE || type == PrimeState::PRIME_TYPE_LITE);
|
||||
}
|
||||
|
||||
void Networking::refresh() {
|
||||
wifiWidget->refresh();
|
||||
an->refresh();
|
||||
@@ -204,17 +208,16 @@ AdvancedNetworking::AdvancedNetworking(QWidget* parent, WifiManager* wifi): QWid
|
||||
// Set initial config
|
||||
wifi->updateGsmSettings(roamingEnabled, QString::fromStdString(params.get("GsmApn")), metered);
|
||||
|
||||
connect(uiState(), &UIState::primeTypeChanged, this, [=](PrimeType prime_type) {
|
||||
bool gsmVisible = prime_type == PrimeType::PRIME_TYPE_NONE || prime_type == PrimeType::PRIME_TYPE_LITE;
|
||||
roamingToggle->setVisible(gsmVisible);
|
||||
editApnButton->setVisible(gsmVisible);
|
||||
meteredToggle->setVisible(gsmVisible);
|
||||
});
|
||||
|
||||
main_layout->addWidget(new ScrollView(list, this));
|
||||
main_layout->addStretch(1);
|
||||
}
|
||||
|
||||
void AdvancedNetworking::setGsmVisible(bool visible) {
|
||||
roamingToggle->setVisible(visible);
|
||||
editApnButton->setVisible(visible);
|
||||
meteredToggle->setVisible(visible);
|
||||
}
|
||||
|
||||
void AdvancedNetworking::refresh() {
|
||||
ipLabel->setText(wifi->ipv4_address);
|
||||
tetheringToggle->setEnabled(true);
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
#include <vector>
|
||||
|
||||
#include "selfdrive/ui/qt/network/wifi_manager.h"
|
||||
#include "selfdrive/ui/qt/prime_state.h"
|
||||
#include "selfdrive/ui/qt/widgets/input.h"
|
||||
#include "selfdrive/ui/qt/widgets/ssh_keys.h"
|
||||
#include "selfdrive/ui/qt/widgets/toggle.h"
|
||||
@@ -56,6 +57,7 @@ class AdvancedNetworking : public QWidget {
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit AdvancedNetworking(QWidget* parent = 0, WifiManager* wifi = 0);
|
||||
void setGsmVisible(bool visible);
|
||||
|
||||
private:
|
||||
LabelControl* ipLabel;
|
||||
@@ -81,6 +83,7 @@ class Networking : public QFrame {
|
||||
|
||||
public:
|
||||
explicit Networking(QWidget* parent = 0, bool show_advanced = true);
|
||||
void setPrimeType(PrimeState::Type type);
|
||||
WifiManager* wifi = nullptr;
|
||||
|
||||
private:
|
||||
|
||||
@@ -2,10 +2,6 @@
|
||||
|
||||
#include <utility>
|
||||
|
||||
#include "selfdrive/ui/ui.h"
|
||||
#include "selfdrive/ui/qt/widgets/prime.h"
|
||||
|
||||
#include "common/params.h"
|
||||
#include "common/swaglog.h"
|
||||
#include "selfdrive/ui/qt/util.h"
|
||||
|
||||
@@ -445,9 +441,6 @@ void WifiManager::addTetheringConnection() {
|
||||
}
|
||||
|
||||
void WifiManager::tetheringActivated(QDBusPendingCallWatcher *call) {
|
||||
int prime_type = uiState()->primeType();
|
||||
int ipv4_forward = (prime_type == PrimeType::PRIME_TYPE_NONE || prime_type == PrimeType::PRIME_TYPE_LITE);
|
||||
|
||||
if (!ipv4_forward) {
|
||||
QTimer::singleShot(5000, this, [=] {
|
||||
qWarning() << "net.ipv4.ip_forward = 0";
|
||||
|
||||
@@ -42,6 +42,7 @@ public:
|
||||
QMap<QString, Network> seenNetworks;
|
||||
QMap<QDBusObjectPath, QString> knownConnections;
|
||||
QString ipv4_address;
|
||||
bool ipv4_forward = false;
|
||||
|
||||
explicit WifiManager(QObject* parent);
|
||||
void start();
|
||||
|
||||
@@ -247,8 +247,8 @@ DevicePanel::DevicePanel(SettingsWindow *parent) : ListWidget(parent) {
|
||||
});
|
||||
addItem(translateBtn);
|
||||
|
||||
QObject::connect(uiState(), &UIState::primeTypeChanged, [this] (PrimeType type) {
|
||||
pair_device->setVisible(type == PrimeType::PRIME_TYPE_UNPAIRED);
|
||||
QObject::connect(uiState()->prime_state, &PrimeState::changed, [this] (PrimeState::Type type) {
|
||||
pair_device->setVisible(type == PrimeState::PRIME_TYPE_UNPAIRED);
|
||||
});
|
||||
QObject::connect(uiState(), &UIState::offroadTransition, [=](bool offroad) {
|
||||
for (auto btn : findChildren<ButtonControl *>()) {
|
||||
@@ -335,11 +335,6 @@ void DevicePanel::poweroff() {
|
||||
}
|
||||
}
|
||||
|
||||
void DevicePanel::showEvent(QShowEvent *event) {
|
||||
pair_device->setVisible(uiState()->primeType() == PrimeType::PRIME_TYPE_UNPAIRED);
|
||||
ListWidget::showEvent(event);
|
||||
}
|
||||
|
||||
void SettingsWindow::showEvent(QShowEvent *event) {
|
||||
setCurrentPanel(0);
|
||||
}
|
||||
@@ -386,9 +381,12 @@ SettingsWindow::SettingsWindow(QWidget *parent) : QFrame(parent) {
|
||||
TogglesPanel *toggles = new TogglesPanel(this);
|
||||
QObject::connect(this, &SettingsWindow::expandToggleDescription, toggles, &TogglesPanel::expandToggleDescription);
|
||||
|
||||
auto networking = new Networking(this);
|
||||
QObject::connect(uiState()->prime_state, &PrimeState::changed, networking, &Networking::setPrimeType);
|
||||
|
||||
QList<QPair<QString, QWidget *>> panels = {
|
||||
{tr("Device"), device},
|
||||
{tr("Network"), new Networking(this)},
|
||||
{tr("Network"), networking},
|
||||
{tr("Toggles"), toggles},
|
||||
{tr("Software"), new SoftwarePanel(this)},
|
||||
};
|
||||
|
||||
@@ -42,7 +42,6 @@ class DevicePanel : public ListWidget {
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit DevicePanel(SettingsWindow *parent);
|
||||
void showEvent(QShowEvent *event) override;
|
||||
|
||||
signals:
|
||||
void reviewTrainingGuide();
|
||||
|
||||
48
selfdrive/ui/qt/prime_state.cc
Normal file
48
selfdrive/ui/qt/prime_state.cc
Normal file
@@ -0,0 +1,48 @@
|
||||
#include "selfdrive/ui/qt/prime_state.h"
|
||||
|
||||
#include <QJsonDocument>
|
||||
|
||||
#include "selfdrive/ui/qt/api.h"
|
||||
#include "selfdrive/ui/qt/request_repeater.h"
|
||||
#include "selfdrive/ui/qt/util.h"
|
||||
|
||||
PrimeState::PrimeState(QObject* parent) : QObject(parent) {
|
||||
const char *env_prime_type = std::getenv("PRIME_TYPE");
|
||||
auto type = env_prime_type ? env_prime_type : Params().get("PrimeType");
|
||||
|
||||
if (!type.empty()) {
|
||||
prime_type = static_cast<PrimeState::Type>(std::atoi(type.c_str()));
|
||||
}
|
||||
|
||||
if (auto dongleId = getDongleId()) {
|
||||
QString url = CommaApi::BASE_URL + "/v1.1/devices/" + *dongleId + "/";
|
||||
RequestRepeater* repeater = new RequestRepeater(this, url, "ApiCache_Device", 5);
|
||||
QObject::connect(repeater, &RequestRepeater::requestDone, this, &PrimeState::handleReply);
|
||||
}
|
||||
|
||||
// Emit the initial state change
|
||||
QTimer::singleShot(1, [this]() { emit changed(prime_type); });
|
||||
}
|
||||
|
||||
void PrimeState::handleReply(const QString& response, bool success) {
|
||||
if (!success) return;
|
||||
|
||||
QJsonDocument doc = QJsonDocument::fromJson(response.toUtf8());
|
||||
if (doc.isNull()) {
|
||||
qDebug() << "JSON Parse failed on getting pairing and PrimeState status";
|
||||
return;
|
||||
}
|
||||
|
||||
QJsonObject json = doc.object();
|
||||
bool is_paired = json["is_paired"].toBool();
|
||||
auto type = static_cast<PrimeState::Type>(json["prime_type"].toInt());
|
||||
setType(is_paired ? type : PrimeState::PRIME_TYPE_UNPAIRED);
|
||||
}
|
||||
|
||||
void PrimeState::setType(PrimeState::Type type) {
|
||||
if (type != prime_type) {
|
||||
prime_type = type;
|
||||
Params().put("PrimeType", std::to_string(prime_type));
|
||||
emit changed(prime_type);
|
||||
}
|
||||
}
|
||||
33
selfdrive/ui/qt/prime_state.h
Normal file
33
selfdrive/ui/qt/prime_state.h
Normal file
@@ -0,0 +1,33 @@
|
||||
#pragma once
|
||||
|
||||
#include <QObject>
|
||||
|
||||
class PrimeState : public QObject {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
|
||||
enum Type {
|
||||
PRIME_TYPE_UNKNOWN = -2,
|
||||
PRIME_TYPE_UNPAIRED = -1,
|
||||
PRIME_TYPE_NONE = 0,
|
||||
PRIME_TYPE_MAGENTA = 1,
|
||||
PRIME_TYPE_LITE = 2,
|
||||
PRIME_TYPE_BLUE = 3,
|
||||
PRIME_TYPE_MAGENTA_NEW = 4,
|
||||
PRIME_TYPE_PURPLE = 5,
|
||||
};
|
||||
|
||||
PrimeState(QObject *parent);
|
||||
void setType(PrimeState::Type type);
|
||||
inline PrimeState::Type currentType() const { return prime_type; }
|
||||
inline bool isSubscribed() const { return prime_type > PrimeState::PRIME_TYPE_NONE; }
|
||||
|
||||
signals:
|
||||
void changed(PrimeState::Type prime_type);
|
||||
|
||||
private:
|
||||
void handleReply(const QString &response, bool success);
|
||||
|
||||
PrimeState::Type prime_type = PrimeState::PRIME_TYPE_UNKNOWN;
|
||||
};
|
||||
@@ -246,33 +246,12 @@ SetupWidget::SetupWidget(QWidget* parent) : QFrame(parent) {
|
||||
sp_retain.setRetainSizeWhenHidden(true);
|
||||
setSizePolicy(sp_retain);
|
||||
|
||||
// set up API requests
|
||||
if (auto dongleId = getDongleId()) {
|
||||
QString url = CommaApi::BASE_URL + "/v1.1/devices/" + *dongleId + "/";
|
||||
RequestRepeater* repeater = new RequestRepeater(this, url, "ApiCache_Device", 5);
|
||||
|
||||
QObject::connect(repeater, &RequestRepeater::requestDone, this, &SetupWidget::replyFinished);
|
||||
}
|
||||
}
|
||||
|
||||
void SetupWidget::replyFinished(const QString &response, bool success) {
|
||||
if (!success) return;
|
||||
|
||||
QJsonDocument doc = QJsonDocument::fromJson(response.toUtf8());
|
||||
if (doc.isNull()) {
|
||||
qDebug() << "JSON Parse failed on getting pairing and prime status";
|
||||
return;
|
||||
}
|
||||
|
||||
QJsonObject json = doc.object();
|
||||
bool is_paired = json["is_paired"].toBool();
|
||||
PrimeType prime_type = static_cast<PrimeType>(json["prime_type"].toInt());
|
||||
uiState()->setPrimeType(is_paired ? prime_type : PrimeType::PRIME_TYPE_UNPAIRED);
|
||||
|
||||
if (!is_paired) {
|
||||
mainLayout->setCurrentIndex(0);
|
||||
} else {
|
||||
popup->reject();
|
||||
mainLayout->setCurrentIndex(1);
|
||||
}
|
||||
QObject::connect(uiState()->prime_state, &PrimeState::changed, [this](PrimeState::Type type) {
|
||||
if (type == PrimeState::PRIME_TYPE_UNPAIRED) {
|
||||
mainLayout->setCurrentIndex(0); // Display "Pair your device" widget
|
||||
} else {
|
||||
popup->reject();
|
||||
mainLayout->setCurrentIndex(1); // Display Wi-Fi prompt widget
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -66,7 +66,4 @@ signals:
|
||||
private:
|
||||
PairingPopup *popup;
|
||||
QStackedWidget *mainLayout;
|
||||
|
||||
private slots:
|
||||
void replyFinished(const QString &response, bool success);
|
||||
};
|
||||
|
||||
@@ -210,13 +210,8 @@ UIState::UIState(QObject *parent) : QObject(parent) {
|
||||
"pandaStates", "carParams", "driverMonitoringState", "carState", "driverStateV2",
|
||||
"wideRoadCameraState", "managerState", "selfdriveState",
|
||||
});
|
||||
|
||||
Params params;
|
||||
language = QString::fromStdString(params.get("LanguageSetting"));
|
||||
auto prime_value = params.get("PrimeType");
|
||||
if (!prime_value.empty()) {
|
||||
prime_type = static_cast<PrimeType>(std::atoi(prime_value.c_str()));
|
||||
}
|
||||
prime_state = new PrimeState(this);
|
||||
language = QString::fromStdString(Params().get("LanguageSetting"));
|
||||
|
||||
// update timer
|
||||
timer = new QTimer(this);
|
||||
@@ -229,31 +224,12 @@ void UIState::update() {
|
||||
update_state(this);
|
||||
updateStatus();
|
||||
|
||||
if (std::getenv("PRIME_TYPE")) {
|
||||
setPrimeType((PrimeType)atoi(std::getenv("PRIME_TYPE")));
|
||||
}
|
||||
|
||||
if (sm->frame % UI_FREQ == 0) {
|
||||
watchdog_kick(nanos_since_boot());
|
||||
}
|
||||
emit uiUpdate(*this);
|
||||
}
|
||||
|
||||
void UIState::setPrimeType(PrimeType type) {
|
||||
if (type != prime_type) {
|
||||
bool prev_prime = hasPrime();
|
||||
|
||||
prime_type = type;
|
||||
Params().put("PrimeType", std::to_string(prime_type));
|
||||
emit primeTypeChanged(prime_type);
|
||||
|
||||
bool prime = hasPrime();
|
||||
if (prev_prime != prime) {
|
||||
emit primeChanged(prime);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Device::Device(QObject *parent) : brightness_filter(BACKLIGHT_OFFROAD, BACKLIGHT_TS, BACKLIGHT_DT), QObject(parent) {
|
||||
setAwake(true);
|
||||
resetInteractiveTimeout();
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
#include "common/params.h"
|
||||
#include "common/timing.h"
|
||||
#include "system/hardware/hw.h"
|
||||
#include "selfdrive/ui/qt/prime_state.h"
|
||||
|
||||
const int UI_BORDER_SIZE = 30;
|
||||
const int UI_HEADER_HEIGHT = 420;
|
||||
@@ -40,17 +41,6 @@ typedef enum UIStatus {
|
||||
STATUS_ENGAGED,
|
||||
} UIStatus;
|
||||
|
||||
enum PrimeType {
|
||||
PRIME_TYPE_UNKNOWN = -2,
|
||||
PRIME_TYPE_UNPAIRED = -1,
|
||||
PRIME_TYPE_NONE = 0,
|
||||
PRIME_TYPE_MAGENTA = 1,
|
||||
PRIME_TYPE_LITE = 2,
|
||||
PRIME_TYPE_BLUE = 3,
|
||||
PRIME_TYPE_MAGENTA_NEW = 4,
|
||||
PRIME_TYPE_PURPLE = 5,
|
||||
};
|
||||
|
||||
const QColor bg_colors [] = {
|
||||
[STATUS_DISENGAGED] = QColor(0x17, 0x33, 0x49, 0xc8),
|
||||
[STATUS_OVERRIDE] = QColor(0x91, 0x9b, 0x95, 0xf1),
|
||||
@@ -94,10 +84,6 @@ public:
|
||||
return scene.started && (*sm)["selfdriveState"].getSelfdriveState().getEnabled();
|
||||
}
|
||||
|
||||
void setPrimeType(PrimeType type);
|
||||
inline PrimeType primeType() const { return prime_type; }
|
||||
inline bool hasPrime() const { return prime_type > PrimeType::PRIME_TYPE_NONE; }
|
||||
|
||||
int fb_w = 0, fb_h = 0;
|
||||
|
||||
std::unique_ptr<SubMaster> sm;
|
||||
@@ -108,12 +94,11 @@ public:
|
||||
QString language;
|
||||
|
||||
QTransform car_space_transform;
|
||||
PrimeState *prime_state;
|
||||
|
||||
signals:
|
||||
void uiUpdate(const UIState &s);
|
||||
void offroadTransition(bool offroad);
|
||||
void primeChanged(bool prime);
|
||||
void primeTypeChanged(PrimeType prime_type);
|
||||
|
||||
private slots:
|
||||
void update();
|
||||
@@ -121,7 +106,6 @@ private slots:
|
||||
private:
|
||||
QTimer *timer;
|
||||
bool started_prev = false;
|
||||
PrimeType prime_type = PrimeType::PRIME_TYPE_UNKNOWN;
|
||||
};
|
||||
|
||||
UIState *uiState();
|
||||
|
||||
Reference in New Issue
Block a user