#include #include #include #include #include #include #include "selfdrive/ui/qt/qt_window.h" #include "selfdrive/ui/qt/setup/reset.h" #define NVME "/dev/nvme0n1" #define USERDATA "/dev/disk/by-partlabel/userdata" void Reset::doErase() { // best effort to wipe nvme std::system("sudo umount " NVME); std::system("yes | sudo mkfs.ext4 " NVME); int rm = std::system("sudo rm -rf /data/*"); std::system("sudo umount " USERDATA); int fmt = std::system("yes | sudo mkfs.ext4 " USERDATA); if (rm == 0 || fmt == 0) { std::system("sudo reboot"); } body->setText(tr("Reset failed. Reboot to try again.")); rebootBtn->show(); } void Reset::startReset() { body->setText(tr("Resetting device...\nThis may take up to a minute.")); rejectBtn->hide(); rebootBtn->hide(); confirmBtn->hide(); #ifdef __aarch64__ QTimer::singleShot(100, this, &Reset::doErase); #endif } void Reset::confirm() { const QString confirm_txt = tr("Are you sure you want to reset your device?"); if (body->text() != confirm_txt) { body->setText(confirm_txt); } else { startReset(); } } Reset::Reset(ResetMode mode, QWidget *parent) : QWidget(parent) { QVBoxLayout *main_layout = new QVBoxLayout(this); main_layout->setContentsMargins(45, 220, 45, 45); main_layout->setSpacing(0); QLabel *title = new QLabel(tr("System Reset")); title->setStyleSheet("font-size: 90px; font-weight: 600;"); main_layout->addWidget(title, 0, Qt::AlignTop | Qt::AlignLeft); main_layout->addSpacing(60); body = new QLabel(tr("Press confirm to erase all content and settings. Press cancel to resume boot.")); body->setWordWrap(true); body->setStyleSheet("font-size: 80px; font-weight: light;"); main_layout->addWidget(body, 1, Qt::AlignTop | Qt::AlignLeft); QHBoxLayout *blayout = new QHBoxLayout(); main_layout->addLayout(blayout); blayout->setSpacing(50); rejectBtn = new QPushButton(tr("Cancel")); blayout->addWidget(rejectBtn); QObject::connect(rejectBtn, &QPushButton::clicked, QCoreApplication::instance(), &QCoreApplication::quit); rebootBtn = new QPushButton(tr("Reboot")); blayout->addWidget(rebootBtn); #ifdef __aarch64__ QObject::connect(rebootBtn, &QPushButton::clicked, [=]{ std::system("sudo reboot"); }); #endif confirmBtn = new QPushButton(tr("Confirm")); confirmBtn->setStyleSheet(R"( QPushButton { background-color: #465BEA; } QPushButton:pressed { background-color: #3049F4; } )"); blayout->addWidget(confirmBtn); QObject::connect(confirmBtn, &QPushButton::clicked, this, &Reset::confirm); bool recover = mode == ResetMode::RECOVER; rejectBtn->setVisible(!recover); rebootBtn->setVisible(recover); if (recover) { body->setText(tr("Unable to mount data partition. Partition may be corrupted. Press confirm to erase and reset your device.")); } // automatically start if we're just finishing up an ABL reset if (mode == ResetMode::FORMAT) { startReset(); } setStyleSheet(R"( * { font-family: Inter; color: white; background-color: black; } QLabel { margin-left: 140; } QPushButton { height: 160; font-size: 55px; font-weight: 400; border-radius: 10px; background-color: #333333; } QPushButton:pressed { background-color: #444444; } )"); } int main(int argc, char *argv[]) { ResetMode mode = ResetMode::USER_RESET; if (argc > 1) { if (strcmp(argv[1], "--recover") == 0) { mode = ResetMode::RECOVER; } else if (strcmp(argv[1], "--format") == 0) { mode = ResetMode::FORMAT; } } QApplication a(argc, argv); Reset reset(mode); setMainWindow(&reset); return a.exec(); }