You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
204 lines
6.0 KiB
204 lines
6.0 KiB
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <math.h>
|
|
#include <sys/resource.h>
|
|
|
|
#include <algorithm>
|
|
|
|
#include "common/util.h"
|
|
#include "common/utilpp.h"
|
|
#include "common/params.h"
|
|
#include "common/touch.h"
|
|
#include "common/swaglog.h"
|
|
|
|
#include "ui.hpp"
|
|
#include "paint.hpp"
|
|
#include "android/sl_sound.hpp"
|
|
|
|
volatile sig_atomic_t do_exit = 0;
|
|
static void set_do_exit(int sig) {
|
|
do_exit = 1;
|
|
}
|
|
|
|
static void ui_set_brightness(UIState *s, int brightness) {
|
|
static int last_brightness = -1;
|
|
if (last_brightness != brightness && (s->awake || brightness == 0)) {
|
|
if (set_brightness(brightness)) {
|
|
last_brightness = brightness;
|
|
}
|
|
}
|
|
}
|
|
|
|
int event_processing_enabled = -1;
|
|
static void enable_event_processing(bool yes) {
|
|
if (event_processing_enabled != 1 && yes) {
|
|
system("service call window 18 i32 1"); // enable event processing
|
|
event_processing_enabled = 1;
|
|
} else if (event_processing_enabled != 0 && !yes) {
|
|
system("service call window 18 i32 0"); // disable event processing
|
|
event_processing_enabled = 0;
|
|
}
|
|
}
|
|
|
|
// TODO: implement double tap to wake and actually turn display off
|
|
static void handle_display_state(UIState *s, bool user_input) {
|
|
|
|
static int display_mode = HWC_POWER_MODE_OFF;
|
|
static int display_timeout = 0;
|
|
|
|
// determine desired state
|
|
int desired_mode = display_mode;
|
|
if (user_input || s->ignition || s->started) {
|
|
desired_mode = HWC_POWER_MODE_NORMAL;
|
|
display_timeout = 30*UI_FREQ;
|
|
} else {
|
|
display_timeout = std::max(display_timeout-1, 0);
|
|
if (display_timeout == 0) {
|
|
desired_mode = HWC_POWER_MODE_OFF;
|
|
}
|
|
}
|
|
|
|
// handle state transition
|
|
if (display_mode != desired_mode) {
|
|
LOGW("setting display mode %d", desired_mode);
|
|
|
|
display_mode = desired_mode;
|
|
s->awake = display_mode == HWC_POWER_MODE_NORMAL;
|
|
framebuffer_set_power(s->fb, display_mode);
|
|
enable_event_processing(s->awake);
|
|
|
|
if (!s->awake) {
|
|
ui_set_brightness(s, 0);
|
|
}
|
|
}
|
|
}
|
|
|
|
static void handle_vision_touch(UIState *s, int touch_x, int touch_y) {
|
|
if (s->started && (touch_x >= s->scene.viz_rect.x - bdr_s)
|
|
&& (s->active_app != cereal::UiLayoutState::App::SETTINGS)) {
|
|
if (!s->scene.frontview) {
|
|
s->scene.uilayout_sidebarcollapsed = !s->scene.uilayout_sidebarcollapsed;
|
|
} else {
|
|
write_db_value("IsDriverViewEnabled", "0", 1);
|
|
}
|
|
}
|
|
}
|
|
|
|
static void handle_sidebar_touch(UIState *s, int touch_x, int touch_y) {
|
|
if (!s->scene.uilayout_sidebarcollapsed && touch_x <= sbr_w) {
|
|
if (settings_btn.ptInRect(touch_x, touch_y)) {
|
|
s->active_app = cereal::UiLayoutState::App::SETTINGS;
|
|
} else if (home_btn.ptInRect(touch_x, touch_y)) {
|
|
if (s->started) {
|
|
s->active_app = cereal::UiLayoutState::App::NONE;
|
|
s->scene.uilayout_sidebarcollapsed = true;
|
|
} else {
|
|
s->active_app = cereal::UiLayoutState::App::HOME;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
static void update_offroad_layout_state(UIState *s, PubMaster *pm) {
|
|
static int timeout = 0;
|
|
static bool prev_collapsed = false;
|
|
static cereal::UiLayoutState::App prev_app = cereal::UiLayoutState::App::NONE;
|
|
if (timeout > 0) {
|
|
timeout--;
|
|
}
|
|
if (prev_collapsed != s->scene.uilayout_sidebarcollapsed || prev_app != s->active_app || timeout == 0) {
|
|
MessageBuilder msg;
|
|
auto layout = msg.initEvent().initUiLayoutState();
|
|
layout.setActiveApp(s->active_app);
|
|
layout.setSidebarCollapsed(s->scene.uilayout_sidebarcollapsed);
|
|
pm->send("offroadLayout", msg);
|
|
LOGD("setting active app to %d with sidebar %d", (int)s->active_app, s->scene.uilayout_sidebarcollapsed);
|
|
prev_collapsed = s->scene.uilayout_sidebarcollapsed;
|
|
prev_app = s->active_app;
|
|
timeout = 2 * UI_FREQ;
|
|
}
|
|
}
|
|
|
|
int main(int argc, char* argv[]) {
|
|
setpriority(PRIO_PROCESS, 0, -14);
|
|
signal(SIGINT, (sighandler_t)set_do_exit);
|
|
SLSound sound;
|
|
|
|
UIState uistate = {};
|
|
UIState *s = &uistate;
|
|
ui_init(s);
|
|
s->sound = &sound;
|
|
|
|
handle_display_state(s, true);
|
|
enable_event_processing(true);
|
|
|
|
PubMaster *pm = new PubMaster({"offroadLayout"});
|
|
|
|
TouchState touch = {0};
|
|
touch_init(&touch);
|
|
|
|
// light sensor scaling and volume params
|
|
const bool LEON = util::read_file("/proc/cmdline").find("letv") != std::string::npos;
|
|
|
|
float brightness_b = 0, brightness_m = 0;
|
|
int result = read_param(&brightness_b, "BRIGHTNESS_B", true);
|
|
result += read_param(&brightness_m, "BRIGHTNESS_M", true);
|
|
if(result != 0) {
|
|
brightness_b = LEON ? 10.0 : 5.0;
|
|
brightness_m = LEON ? 2.6 : 1.3;
|
|
write_param_float(brightness_b, "BRIGHTNESS_B", true);
|
|
write_param_float(brightness_m, "BRIGHTNESS_M", true);
|
|
}
|
|
float smooth_brightness = brightness_b;
|
|
|
|
const int MIN_VOLUME = LEON ? 12 : 9;
|
|
const int MAX_VOLUME = LEON ? 15 : 12;
|
|
s->sound->setVolume(MIN_VOLUME);
|
|
|
|
while (!do_exit) {
|
|
if (!s->started || !s->vision_connected) {
|
|
// Delay a while to avoid 9% cpu usage while car is not started and user is keeping touching on the screen.
|
|
usleep(30 * 1000);
|
|
}
|
|
double u1 = millis_since_boot();
|
|
|
|
ui_update(s);
|
|
|
|
// poll for touch events
|
|
int touch_x = -1, touch_y = -1;
|
|
int touched = touch_poll(&touch, &touch_x, &touch_y, 0);
|
|
if (touched == 1) {
|
|
handle_sidebar_touch(s, touch_x, touch_y);
|
|
handle_vision_touch(s, touch_x, touch_y);
|
|
}
|
|
|
|
// Don't waste resources on drawing in case screen is off
|
|
handle_display_state(s, touched == 1);
|
|
if (!s->awake) {
|
|
continue;
|
|
}
|
|
|
|
// up one notch every 5 m/s
|
|
s->sound->setVolume(fmin(MAX_VOLUME, MIN_VOLUME + s->scene.controls_state.getVEgo() / 5));
|
|
|
|
// set brightness
|
|
float clipped_brightness = fmin(512, (s->light_sensor*brightness_m) + brightness_b);
|
|
smooth_brightness = fmin(255, clipped_brightness * 0.01 + smooth_brightness * 0.99);
|
|
ui_set_brightness(s, (int)smooth_brightness);
|
|
|
|
update_offroad_layout_state(s, pm);
|
|
|
|
ui_draw(s);
|
|
double u2 = millis_since_boot();
|
|
if (!s->scene.frontview && (u2-u1 > 66)) {
|
|
// warn on sub 15fps
|
|
LOGW("slow frame(%llu) time: %.2f", (s->sm)->frame, u2-u1);
|
|
}
|
|
framebuffer_swap(s->fb);
|
|
}
|
|
|
|
handle_display_state(s, true);
|
|
delete s->sm;
|
|
delete pm;
|
|
return 0;
|
|
}
|
|
|