Qt setup + installer (#2511)
* getting started * setup screens * cleanupg * url input * installer * setup * installeralbatross
parent
91f79acac3
commit
7b72bbe9f3
|
@ -3,3 +3,5 @@ moc_*
|
|||
|
||||
qt/text
|
||||
qt/spinner
|
||||
qt/setup/setup
|
||||
qt/setup/installer
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import os
|
||||
Import('env', 'arch', 'real_arch', 'common', 'messaging', 'gpucommon', 'visionipc', 'cereal')
|
||||
|
||||
qt_env = None
|
||||
|
@ -75,3 +76,8 @@ else:
|
|||
# spinner and text window
|
||||
qt_env.Program("qt/text", ["qt/text.cc"], LIBS=qt_libs + libs)
|
||||
qt_env.Program("qt/spinner", ["qt/spinner.cc"], LIBS=qt_libs + libs)
|
||||
|
||||
# setup and installer
|
||||
if "BUILD_SETUP" in os.environ:
|
||||
qt_env.Program("qt/setup/setup", ["qt/setup/setup.cc"], LIBS=qt_libs + libs + ['curl'])
|
||||
qt_env.Program("qt/setup/installer", ["qt/setup/installer.cc"], LIBS=qt_libs + libs)
|
||||
|
|
|
@ -0,0 +1,68 @@
|
|||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
#include <cstdlib>
|
||||
#include <iostream>
|
||||
|
||||
#ifndef BRANCH
|
||||
#define BRANCH "master"
|
||||
#endif
|
||||
|
||||
#define GIT_CLONE_COMMAND "git clone https://github.com/commaai/openpilot.git"
|
||||
|
||||
#define CONTINUE_PATH "/home/comma/continue.sh"
|
||||
|
||||
bool time_valid() {
|
||||
time_t rawtime;
|
||||
time(&rawtime);
|
||||
|
||||
struct tm * sys_time = gmtime(&rawtime);
|
||||
return (1900 + sys_time->tm_year) >= 2019;
|
||||
}
|
||||
|
||||
int fresh_clone() {
|
||||
int err;
|
||||
|
||||
// Cleanup
|
||||
err = std::system("rm -rf /tmp/openpilot");
|
||||
if(err) return 1;
|
||||
err = std::system("rm -rf /data/openpilot");
|
||||
if(err) return 1;
|
||||
|
||||
// Clone
|
||||
err = std::system(GIT_CLONE_COMMAND " -b " BRANCH " --depth=1 /tmp/openpilot");
|
||||
if(err) return 1;
|
||||
err = std::system("cd /tmp/openpilot && git submodule update --init");
|
||||
if(err) return 1;
|
||||
|
||||
err = std::system("mv /tmp/openpilot /data");
|
||||
if(err) return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int install() {
|
||||
int err;
|
||||
|
||||
// TODO: Disable SSH after install done
|
||||
|
||||
// Wait for valid time
|
||||
while (!time_valid()) {
|
||||
usleep(500 * 1000);
|
||||
std::cout << "Waiting for valid time\n";
|
||||
}
|
||||
|
||||
std::cout << "Doing fresh clone\n";
|
||||
err = fresh_clone();
|
||||
if(err) return 1;
|
||||
|
||||
// Write continue.sh
|
||||
err = std::system("cp /data/openpilot/installer/continue_openpilot.sh " CONTINUE_PATH);
|
||||
if(err == -1) return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
// TODO: make a small installation UI
|
||||
return install();
|
||||
}
|
|
@ -0,0 +1,184 @@
|
|||
#include <stdio.h>
|
||||
#include <curl/curl.h>
|
||||
|
||||
#include <QString>
|
||||
#include <QLabel>
|
||||
#include <QWidget>
|
||||
#include <QLineEdit>
|
||||
#include <QPushButton>
|
||||
#include <QVBoxLayout>
|
||||
#include <QApplication>
|
||||
|
||||
#include "setup.hpp"
|
||||
|
||||
#ifdef QCOM2
|
||||
#include <qpa/qplatformnativeinterface.h>
|
||||
#include <QPlatformSurfaceEvent>
|
||||
#include <wayland-client-protocol.h>
|
||||
#endif
|
||||
|
||||
|
||||
int download(std::string url) {
|
||||
CURL *curl;
|
||||
curl = curl_easy_init();
|
||||
if (!curl) return -1;
|
||||
|
||||
FILE *fp;
|
||||
fp = fopen("/tmp/installer", "wb");
|
||||
curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
|
||||
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, NULL);
|
||||
curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp);
|
||||
curl_easy_setopt (curl, CURLOPT_VERBOSE, 1L);
|
||||
curl_easy_perform(curl);
|
||||
curl_easy_cleanup(curl);
|
||||
fclose(fp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
QLabel * title_label(QString text) {
|
||||
QLabel *l = new QLabel(text);
|
||||
l->setStyleSheet(R"(
|
||||
QLabel {
|
||||
font-size: 100px;
|
||||
font-weight: bold;
|
||||
}
|
||||
)");
|
||||
return l;
|
||||
}
|
||||
|
||||
QWidget * Setup::getting_started() {
|
||||
QVBoxLayout *main_layout = new QVBoxLayout();
|
||||
main_layout->setContentsMargins(200, 100, 200, 100);
|
||||
|
||||
main_layout->addWidget(title_label("Getting Started"), 0, Qt::AlignCenter);
|
||||
|
||||
QLabel *body = new QLabel("Before we get on the road, let's finish\ninstallation and cover some details.");
|
||||
body->setStyleSheet(R"(font-size: 65px;)");
|
||||
main_layout->addWidget(body, 0, Qt::AlignCenter);
|
||||
|
||||
main_layout->addSpacing(100);
|
||||
|
||||
QPushButton *btn = new QPushButton("Continue");
|
||||
main_layout->addWidget(btn);
|
||||
QObject::connect(btn, SIGNAL(released()), this, SLOT(nextPage()));
|
||||
|
||||
main_layout->addSpacing(100);
|
||||
|
||||
QWidget *widget = new QWidget();
|
||||
widget->setLayout(main_layout);
|
||||
return widget;
|
||||
}
|
||||
|
||||
QWidget * Setup::network_setup() {
|
||||
QVBoxLayout *main_layout = new QVBoxLayout();
|
||||
main_layout->setMargin(100);
|
||||
|
||||
main_layout->addWidget(title_label("Connect to WiFi"), 0, Qt::AlignCenter);
|
||||
|
||||
QPushButton *btn = new QPushButton("Continue");
|
||||
main_layout->addWidget(btn);
|
||||
QObject::connect(btn, SIGNAL(released()), this, SLOT(nextPage()));
|
||||
|
||||
QWidget *widget = new QWidget();
|
||||
widget->setLayout(main_layout);
|
||||
return widget;
|
||||
}
|
||||
|
||||
QWidget * Setup::software_selection() {
|
||||
QVBoxLayout *main_layout = new QVBoxLayout();
|
||||
main_layout->setMargin(100);
|
||||
|
||||
main_layout->addWidget(title_label("Choose Software"), 0, Qt::AlignCenter);
|
||||
|
||||
QPushButton *dashcam_btn = new QPushButton("Dashcam");
|
||||
main_layout->addWidget(dashcam_btn);
|
||||
QObject::connect(dashcam_btn, SIGNAL(released()), this, SLOT(nextPage()));
|
||||
|
||||
main_layout->addSpacing(50);
|
||||
|
||||
const char* env_url = getenv("CUSTOM_URL");
|
||||
QString default_url = env_url == NULL ? "" : QString::fromStdString(env_url);
|
||||
url_input = new QLineEdit(default_url);
|
||||
url_input->setStyleSheet(R"(
|
||||
color: black;
|
||||
background-color: white;
|
||||
font-size: 55px;
|
||||
padding: 40px;
|
||||
)");
|
||||
main_layout->addWidget(url_input);
|
||||
|
||||
QPushButton *custom_btn = new QPushButton("Custom");
|
||||
main_layout->addWidget(custom_btn);
|
||||
QObject::connect(custom_btn, SIGNAL(released()), this, SLOT(nextPage()));
|
||||
|
||||
QWidget *widget = new QWidget();
|
||||
widget->setLayout(main_layout);
|
||||
return widget;
|
||||
}
|
||||
|
||||
QWidget * Setup::downloading() {
|
||||
QVBoxLayout *main_layout = new QVBoxLayout();
|
||||
|
||||
main_layout->addWidget(title_label("Downloading..."), 0, Qt::AlignCenter);
|
||||
|
||||
QWidget *widget = new QWidget();
|
||||
widget->setLayout(main_layout);
|
||||
return widget;
|
||||
}
|
||||
|
||||
void Setup::nextPage() {
|
||||
layout->setCurrentIndex(layout->currentIndex() + 1);
|
||||
|
||||
// start download
|
||||
if (layout->currentIndex() == layout->count() - 1) {
|
||||
std::string url = url_input->text().toStdString();
|
||||
download(url);
|
||||
}
|
||||
}
|
||||
|
||||
Setup::Setup(QWidget *parent) {
|
||||
layout = new QStackedLayout();
|
||||
layout->addWidget(getting_started());
|
||||
layout->addWidget(network_setup());
|
||||
layout->addWidget(software_selection());
|
||||
layout->addWidget(downloading());
|
||||
|
||||
setLayout(layout);
|
||||
setStyleSheet(R"(
|
||||
QWidget {
|
||||
color: white;
|
||||
background-color: black;
|
||||
}
|
||||
QPushButton {
|
||||
font-size: 60px;
|
||||
padding: 60px;
|
||||
width: 800px;
|
||||
color: white;
|
||||
background-color: blue;
|
||||
}
|
||||
)");
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
#ifdef QCOM2
|
||||
int w = 2160, h = 1080;
|
||||
#else
|
||||
int w = 1920, h = 1080;
|
||||
#endif
|
||||
|
||||
QApplication a(argc, argv);
|
||||
|
||||
Setup setup;
|
||||
setup.setFixedSize(w, h);
|
||||
setup.show();
|
||||
|
||||
#ifdef QCOM2
|
||||
QPlatformNativeInterface *native = QGuiApplication::platformNativeInterface();
|
||||
wl_surface *s = reinterpret_cast<wl_surface*>(native->nativeResourceForWindow("surface", setup.windowHandle()));
|
||||
wl_surface_set_buffer_transform(s, WL_OUTPUT_TRANSFORM_270);
|
||||
wl_surface_commit(s);
|
||||
setup.showFullScreen();
|
||||
#endif
|
||||
|
||||
return a.exec();
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
#include <QWidget>
|
||||
#include <QLineEdit>
|
||||
#include <QStackedLayout>
|
||||
|
||||
class Setup : public QWidget {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit Setup(QWidget *parent = 0);
|
||||
|
||||
private:
|
||||
QStackedLayout *layout;
|
||||
|
||||
QLineEdit *url_input;
|
||||
|
||||
QWidget *getting_started();
|
||||
QWidget *network_setup();
|
||||
QWidget *software_selection();
|
||||
QWidget *downloading();
|
||||
|
||||
public slots:
|
||||
void nextPage();
|
||||
};
|
Loading…
Reference in New Issue