Qt setup + installer (#2511)
* getting started
* setup screens
* cleanupg
* url input
* installer
* setup
* installer
old-commit-hash: 7b72bbe9f3
commatwo_master
parent
ed4c4cd8b3
commit
be77d9c02f
5 changed files with 283 additions and 0 deletions
@ -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