Qt setup + installer (#2511)
	
		
	
				
					
				
			* getting started
* setup screens
* cleanupg
* url input
* installer
* setup
* installer
old-commit-hash: 7b72bbe9f3
			
			
				vw-mqb-aeb
			
			
		
							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