good updater experience (#25724)
* good updater experience
* set params on startup
* no fetch on first loop
* little type hinting
* little more
* update translations
* always set params with valid overlay
* wrap check
* use the param
* more wrapping
* vanish
* cleanup
* remove that
old-commit-hash: c4e63d14ab
taco
parent
7cd138328e
commit
46cfb5c45b
18 changed files with 550 additions and 512 deletions
@ -0,0 +1,156 @@ |
|||||||
|
#include "selfdrive/ui/qt/offroad/settings.h" |
||||||
|
|
||||||
|
#include <cassert> |
||||||
|
#include <cmath> |
||||||
|
#include <string> |
||||||
|
|
||||||
|
#include <QDebug> |
||||||
|
#include <QLabel> |
||||||
|
|
||||||
|
#include "common/params.h" |
||||||
|
#include "common/util.h" |
||||||
|
#include "selfdrive/ui/ui.h" |
||||||
|
#include "selfdrive/ui/qt/util.h" |
||||||
|
#include "selfdrive/ui/qt/widgets/controls.h" |
||||||
|
#include "selfdrive/ui/qt/widgets/input.h" |
||||||
|
#include "system/hardware/hw.h" |
||||||
|
|
||||||
|
|
||||||
|
void SoftwarePanel::checkForUpdates() { |
||||||
|
std::system("pkill -SIGUSR1 -f selfdrive.updated"); |
||||||
|
} |
||||||
|
|
||||||
|
SoftwarePanel::SoftwarePanel(QWidget* parent) : ListWidget(parent) { |
||||||
|
onroadLbl = new QLabel(tr("Updates are only downloaded while the car is off.")); |
||||||
|
onroadLbl->setStyleSheet("font-size: 50px; font-weight: 400; text-align: left; padding-top: 30px; padding-bottom: 30px;"); |
||||||
|
addItem(onroadLbl); |
||||||
|
|
||||||
|
// current version
|
||||||
|
versionLbl = new LabelControl(tr("Current Version"), ""); |
||||||
|
addItem(versionLbl); |
||||||
|
|
||||||
|
// download update btn
|
||||||
|
downloadBtn = new ButtonControl(tr("Download"), tr("CHECK")); |
||||||
|
connect(downloadBtn, &ButtonControl::clicked, [=]() { |
||||||
|
downloadBtn->setEnabled(false); |
||||||
|
if (downloadBtn->text() == tr("CHECK")) { |
||||||
|
checkForUpdates(); |
||||||
|
} else { |
||||||
|
std::system("pkill -SIGHUP -f selfdrive.updated"); |
||||||
|
} |
||||||
|
}); |
||||||
|
addItem(downloadBtn); |
||||||
|
|
||||||
|
// install update btn
|
||||||
|
installBtn = new ButtonControl(tr("Install Update"), tr("INSTALL")); |
||||||
|
connect(installBtn, &ButtonControl::clicked, [=]() { |
||||||
|
installBtn->setEnabled(false); |
||||||
|
params.putBool("DoShutdown", true); |
||||||
|
}); |
||||||
|
addItem(installBtn); |
||||||
|
|
||||||
|
// branch selecting
|
||||||
|
targetBranchBtn = new ButtonControl(tr("Target Branch"), tr("SELECT")); |
||||||
|
connect(targetBranchBtn, &ButtonControl::clicked, [=]() { |
||||||
|
auto current = params.get("GitBranch"); |
||||||
|
QStringList branches = QString::fromStdString(params.get("UpdaterAvailableBranches")).split(","); |
||||||
|
for (QString b : {current.c_str(), "devel-staging", "devel", "master-ci", "master"}) { |
||||||
|
auto i = branches.indexOf(b); |
||||||
|
if (i >= 0) { |
||||||
|
branches.removeAt(i); |
||||||
|
branches.insert(0, b); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
QString cur = QString::fromStdString(params.get("UpdaterTargetBranch")); |
||||||
|
QString selection = MultiOptionDialog::getSelection(tr("Select a branch"), branches, cur, this); |
||||||
|
if (!selection.isEmpty()) { |
||||||
|
params.put("UpdaterTargetBranch", selection.toStdString()); |
||||||
|
targetBranchBtn->setValue(QString::fromStdString(params.get("UpdaterTargetBranch"))); |
||||||
|
checkForUpdates(); |
||||||
|
} |
||||||
|
}); |
||||||
|
if (!params.getBool("IsTestedBranch")) { |
||||||
|
addItem(targetBranchBtn); |
||||||
|
} |
||||||
|
|
||||||
|
// uninstall button
|
||||||
|
auto uninstallBtn = new ButtonControl(tr("Uninstall %1").arg(getBrand()), tr("UNINSTALL")); |
||||||
|
connect(uninstallBtn, &ButtonControl::clicked, [&]() { |
||||||
|
if (ConfirmationDialog::confirm(tr("Are you sure you want to uninstall?"), this)) { |
||||||
|
params.putBool("DoUninstall", true); |
||||||
|
} |
||||||
|
}); |
||||||
|
addItem(uninstallBtn); |
||||||
|
|
||||||
|
fs_watch = new QFileSystemWatcher(this); |
||||||
|
QObject::connect(fs_watch, &QFileSystemWatcher::fileChanged, [=](const QString path) { |
||||||
|
updateLabels(); |
||||||
|
}); |
||||||
|
|
||||||
|
connect(uiState(), &UIState::offroadTransition, [=](bool offroad) { |
||||||
|
is_onroad = !offroad; |
||||||
|
updateLabels(); |
||||||
|
}); |
||||||
|
|
||||||
|
updateLabels(); |
||||||
|
} |
||||||
|
|
||||||
|
void SoftwarePanel::showEvent(QShowEvent *event) { |
||||||
|
// nice for testing on PC
|
||||||
|
installBtn->setEnabled(true); |
||||||
|
|
||||||
|
updateLabels(); |
||||||
|
} |
||||||
|
|
||||||
|
void SoftwarePanel::updateLabels() { |
||||||
|
// add these back in case the files got removed
|
||||||
|
fs_watch->addPath(QString::fromStdString(params.getParamPath("LastUpdateTime"))); |
||||||
|
fs_watch->addPath(QString::fromStdString(params.getParamPath("UpdateFailedCount"))); |
||||||
|
fs_watch->addPath(QString::fromStdString(params.getParamPath("UpdaterState"))); |
||||||
|
fs_watch->addPath(QString::fromStdString(params.getParamPath("UpdateAvailable"))); |
||||||
|
|
||||||
|
if (!isVisible()) { |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
// updater only runs offroad
|
||||||
|
onroadLbl->setVisible(is_onroad); |
||||||
|
downloadBtn->setVisible(!is_onroad); |
||||||
|
|
||||||
|
// download update
|
||||||
|
QString updater_state = QString::fromStdString(params.get("UpdaterState")); |
||||||
|
bool failed = std::atoi(params.get("UpdateFailedCount").c_str()) > 0; |
||||||
|
if (updater_state != "idle") { |
||||||
|
downloadBtn->setEnabled(false); |
||||||
|
downloadBtn->setValue(updater_state); |
||||||
|
} else { |
||||||
|
if (failed) { |
||||||
|
downloadBtn->setText("CHECK"); |
||||||
|
downloadBtn->setValue("failed to check for update"); |
||||||
|
} else if (params.getBool("UpdaterFetchAvailable")) { |
||||||
|
downloadBtn->setText("DOWNLOAD"); |
||||||
|
downloadBtn->setValue("update available"); |
||||||
|
} else { |
||||||
|
QString lastUpdate = "never"; |
||||||
|
auto tm = params.get("LastUpdateTime"); |
||||||
|
if (!tm.empty()) { |
||||||
|
lastUpdate = timeAgo(QDateTime::fromString(QString::fromStdString(tm + "Z"), Qt::ISODate)); |
||||||
|
} |
||||||
|
downloadBtn->setText("CHECK"); |
||||||
|
downloadBtn->setValue("up to date, last checked " + lastUpdate); |
||||||
|
} |
||||||
|
downloadBtn->setEnabled(true); |
||||||
|
} |
||||||
|
targetBranchBtn->setValue(QString::fromStdString(params.get("UpdaterTargetBranch"))); |
||||||
|
|
||||||
|
// current + new versions
|
||||||
|
versionLbl->setText(QString::fromStdString(params.get("UpdaterCurrentDescription")).left(40)); |
||||||
|
versionLbl->setDescription(QString::fromStdString(params.get("UpdaterCurrentReleaseNotes"))); |
||||||
|
|
||||||
|
installBtn->setVisible(!is_onroad && params.getBool("UpdateAvailable")); |
||||||
|
installBtn->setValue(QString::fromStdString(params.get("UpdaterNewDescription")).left(35)); |
||||||
|
installBtn->setDescription(QString::fromStdString(params.get("UpdaterNewReleaseNotes"))); |
||||||
|
|
||||||
|
update(); |
||||||
|
} |
Loading…
Reference in new issue