apps: Add ability to do a clean reboot

Allow a clean shutdown to end in either power off or reboot. Add a
new event SYS_REBOOT to signal it and sys_reboot() to trigger the
event. SYS_REBOOT signals a reboot request and should be listened
for alongside SYS_POWEROFF events.

Change-Id: I99ba7fb5feed2bb5a0a40a274e8466ad74fe3a43
This commit is contained in:
Aidan MacDonald 2022-04-16 14:25:49 +01:00
parent 90960adf56
commit d55dceff37
15 changed files with 72 additions and 14 deletions

View file

@ -364,6 +364,7 @@ static void iap_thread(void)
/* Handle poweroff message */ /* Handle poweroff message */
case SYS_POWEROFF: case SYS_POWEROFF:
case SYS_REBOOT:
{ {
iap_shutdown = true; iap_shutdown = true;
break; break;

View file

@ -288,7 +288,8 @@ static void system_restore(void)
tree_restore(); tree_restore();
} }
static bool clean_shutdown(void (*callback)(void *), void *parameter) static bool clean_shutdown(enum shutdown_type sd_type,
void (*callback)(void *), void *parameter)
{ {
long msg_id = -1; long msg_id = -1;
@ -392,7 +393,7 @@ static bool clean_shutdown(void (*callback)(void *), void *parameter)
voice_wait(); voice_wait();
} }
shutdown_hw(); shutdown_hw(sd_type);
} }
return false; return false;
} }
@ -605,8 +606,17 @@ long default_event_handler_ex(long event, void (*callback)(void *), void *parame
return SYS_USB_CONNECTED; return SYS_USB_CONNECTED;
case SYS_POWEROFF: case SYS_POWEROFF:
if (!clean_shutdown(callback, parameter)) case SYS_REBOOT:
return SYS_POWEROFF; {
enum shutdown_type sd_type;
if (event == SYS_POWEROFF)
sd_type = SHUTDOWN_POWER_OFF;
else
sd_type = SHUTDOWN_REBOOT;
if (!clean_shutdown(sd_type, callback, parameter))
return event;
}
break; break;
#if CONFIG_CHARGING #if CONFIG_CHARGING
case SYS_CHARGER_CONNECTED: case SYS_CHARGER_CONNECTED:

View file

@ -462,6 +462,7 @@ static void thread(void)
in_usb_mode = false; in_usb_mode = false;
break; break;
case SYS_POWEROFF: case SYS_POWEROFF:
case SYS_REBOOT:
exit_reason = "power off"; exit_reason = "power off";
exit = true; exit = true;
break; break;

View file

@ -222,6 +222,7 @@ static void cb_wt_callback ( void ) {
button = rb->button_get(false); button = rb->button_get(false);
switch (button) { switch (button) {
case SYS_POWEROFF: case SYS_POWEROFF:
case SYS_REBOOT:
cb_sysevent = button; cb_sysevent = button;
#ifdef CB_RC_QUIT #ifdef CB_RC_QUIT
case CB_RC_QUIT: case CB_RC_QUIT:
@ -585,6 +586,7 @@ static struct cb_command cb_get_viewer_command (void) {
button = rb->button_get(true); button = rb->button_get(true);
switch (button) { switch (button) {
case SYS_POWEROFF: case SYS_POWEROFF:
case SYS_REBOOT:
cb_sysevent = button; cb_sysevent = button;
#ifdef CB_RC_QUIT #ifdef CB_RC_QUIT
case CB_RC_QUIT: case CB_RC_QUIT:
@ -848,6 +850,7 @@ static struct cb_command cb_getcommand (void) {
button = rb->button_get(true); button = rb->button_get(true);
switch (button) { switch (button) {
case SYS_POWEROFF: case SYS_POWEROFF:
case SYS_REBOOT:
cb_sysevent = button; cb_sysevent = button;
#ifdef CB_RC_QUIT #ifdef CB_RC_QUIT
case CB_RC_QUIT: case CB_RC_QUIT:

View file

@ -490,6 +490,7 @@ void thread(void)
rb->beep_play(1500, 100, 1000); rb->beep_play(1500, 100, 1000);
break; break;
case SYS_POWEROFF: case SYS_POWEROFF:
case SYS_REBOOT:
gCache.force_flush = true; gCache.force_flush = true;
/*fall through*/ /*fall through*/
case EV_EXIT: case EV_EXIT:

View file

@ -1090,6 +1090,7 @@ LUALIB_API int luaopen_rock(lua_State *L)
RB_CONSTANT(SYS_USB_DISCONNECTED), RB_CONSTANT(SYS_USB_DISCONNECTED),
RB_CONSTANT(SYS_TIMEOUT), RB_CONSTANT(SYS_TIMEOUT),
RB_CONSTANT(SYS_POWEROFF), RB_CONSTANT(SYS_POWEROFF),
RB_CONSTANT(SYS_REBOOT),
RB_CONSTANT(SYS_CHARGER_CONNECTED), RB_CONSTANT(SYS_CHARGER_CONNECTED),
RB_CONSTANT(SYS_CHARGER_DISCONNECTED), RB_CONSTANT(SYS_CHARGER_DISCONNECTED),

View file

@ -192,6 +192,7 @@ int mpeg_sysevent_callback(int btn,
{ {
case SYS_USB_CONNECTED: case SYS_USB_CONNECTED:
case SYS_POWEROFF: case SYS_POWEROFF:
case SYS_REBOOT:
mpeg_sysevent_id = btn; mpeg_sysevent_id = btn;
return ACTION_STD_CANCEL; return ACTION_STD_CANCEL;
} }

View file

@ -141,6 +141,7 @@ void exit_on_usb(int button)
long result = rb->default_event_handler_ex(button, cleanup_wrapper, NULL); long result = rb->default_event_handler_ex(button, cleanup_wrapper, NULL);
if (result == SYS_USB_CONNECTED) if (result == SYS_USB_CONNECTED)
_exit(PLUGIN_USB_CONNECTED); _exit(PLUGIN_USB_CONNECTED);
else if (result == SYS_POWEROFF) else if (result == SYS_POWEROFF || result == SYS_REBOOT)
/* note: nobody actually pays attention to this exit code */
_exit(PLUGIN_POWEROFF); _exit(PLUGIN_POWEROFF);
} }

View file

@ -2149,6 +2149,7 @@ static int solitaire( int skipmenu )
break; break;
case SYS_POWEROFF: case SYS_POWEROFF:
case SYS_REBOOT:
return SOLITAIRE_SAVE_AND_QUIT; return SOLITAIRE_SAVE_AND_QUIT;
default: default:

View file

@ -1534,7 +1534,8 @@ bool recording_screen(bool no_source)
break; break;
case SYS_POWEROFF: case SYS_POWEROFF:
default_event_handler(SYS_POWEROFF); case SYS_REBOOT:
default_event_handler(button);
done = true; done = true;
break; break;

View file

@ -3989,6 +3989,7 @@ static bool check_event_queue(void)
{ {
case Q_STOP_SCAN: case Q_STOP_SCAN:
case SYS_POWEROFF: case SYS_POWEROFF:
case SYS_REBOOT:
case SYS_USB_CONNECTED: case SYS_USB_CONNECTED:
return true; return true;
} }
@ -4944,6 +4945,7 @@ static void tagcache_thread(void)
break ; break ;
case SYS_POWEROFF: case SYS_POWEROFF:
case SYS_REBOOT:
break ; break ;
case SYS_USB_CONNECTED: case SYS_USB_CONNECTED:

View file

@ -668,6 +668,7 @@ void backlight_thread(void)
#endif /* HAVE_BUTTONLIGHT_BRIGHTNESS */ #endif /* HAVE_BUTTONLIGHT_BRIGHTNESS */
#endif /* HAVE_BUTTON_LIGHT */ #endif /* HAVE_BUTTON_LIGHT */
case SYS_REBOOT:
case SYS_POWEROFF: /* Lock backlight on poweroff so it doesn't */ case SYS_POWEROFF: /* Lock backlight on poweroff so it doesn't */
locked = true; /* go off before power is actually cut. */ locked = true; /* go off before power is actually cut. */
#if !defined(BOOTLOADER) #if !defined(BOOTLOADER)

View file

@ -70,6 +70,12 @@ extern unsigned int power_thread_inputs;
#endif /* CONFIG_CHARGING */ #endif /* CONFIG_CHARGING */
enum shutdown_type
{
SHUTDOWN_POWER_OFF,
SHUTDOWN_REBOOT,
};
#if CONFIG_CHARGING == CHARGING_TARGET #if CONFIG_CHARGING == CHARGING_TARGET
/* Include target-specific definitions */ /* Include target-specific definitions */
#include "powermgmt-target.h" #include "powermgmt-target.h"
@ -164,8 +170,9 @@ void handle_auto_poweroff(void);
void set_car_adapter_mode(bool setting); void set_car_adapter_mode(bool setting);
void reset_poweroff_timer(void); void reset_poweroff_timer(void);
void cancel_shutdown(void); void cancel_shutdown(void);
void shutdown_hw(void); void shutdown_hw(enum shutdown_type sd_type);
void sys_poweroff(void); void sys_poweroff(void);
void sys_reboot(void);
/* Returns true if the system should force shutdown for some reason - /* Returns true if the system should force shutdown for some reason -
* eg. low battery */ * eg. low battery */
bool query_force_shutdown(void); bool query_force_shutdown(void);

View file

@ -58,6 +58,7 @@
#define SYS_CHARGER_CONNECTED MAKE_SYS_EVENT(SYS_EVENT_CLS_POWER, 1) #define SYS_CHARGER_CONNECTED MAKE_SYS_EVENT(SYS_EVENT_CLS_POWER, 1)
#define SYS_CHARGER_DISCONNECTED MAKE_SYS_EVENT(SYS_EVENT_CLS_POWER, 2) #define SYS_CHARGER_DISCONNECTED MAKE_SYS_EVENT(SYS_EVENT_CLS_POWER, 2)
#define SYS_BATTERY_UPDATE MAKE_SYS_EVENT(SYS_EVENT_CLS_POWER, 3) #define SYS_BATTERY_UPDATE MAKE_SYS_EVENT(SYS_EVENT_CLS_POWER, 3)
#define SYS_REBOOT MAKE_SYS_EVENT(SYS_EVENT_CLS_POWER, 4)
#define SYS_FS_CHANGED MAKE_SYS_EVENT(SYS_EVENT_CLS_FILESYS, 0) #define SYS_FS_CHANGED MAKE_SYS_EVENT(SYS_EVENT_CLS_FILESYS, 0)
#define SYS_HOTSWAP_INSERTED MAKE_SYS_EVENT(SYS_EVENT_CLS_PLUG, 0) #define SYS_HOTSWAP_INSERTED MAKE_SYS_EVENT(SYS_EVENT_CLS_PLUG, 0)
#define SYS_HOTSWAP_EXTRACTED MAKE_SYS_EVENT(SYS_EVENT_CLS_PLUG, 1) #define SYS_HOTSWAP_EXTRACTED MAKE_SYS_EVENT(SYS_EVENT_CLS_PLUG, 1)

View file

@ -823,7 +823,7 @@ void powermgmt_init(void)
} }
/* Various hardware housekeeping tasks relating to shutting down the player */ /* Various hardware housekeeping tasks relating to shutting down the player */
void shutdown_hw(void) void shutdown_hw(enum shutdown_type sd_type)
{ {
charging_algorithm_close(); charging_algorithm_close();
audio_stop(); audio_stop();
@ -863,7 +863,17 @@ void shutdown_hw(void)
eeprom chips are quite slow and might be still writing the last eeprom chips are quite slow and might be still writing the last
byte. */ byte. */
sleep(HZ/4); sleep(HZ/4);
power_off();
switch (sd_type) {
case SHUTDOWN_POWER_OFF:
default:
power_off();
break;
case SHUTDOWN_REBOOT:
system_reboot();
break;
}
} }
void set_poweroff_timeout(int timeout) void set_poweroff_timeout(int timeout)
@ -878,10 +888,9 @@ void reset_poweroff_timer(void)
set_sleep_timer(sleeptimer_duration); set_sleep_timer(sleeptimer_duration);
} }
void sys_poweroff(void)
{
#ifndef BOOTLOADER #ifndef BOOTLOADER
logf("sys_poweroff()"); static void sys_shutdown_common(void)
{
/* If the main thread fails to shut down the system, we will force a /* If the main thread fails to shut down the system, we will force a
power off after an 20 second timeout - 28 seconds if recording */ power off after an 20 second timeout - 28 seconds if recording */
if (shutdown_timeout == 0) { if (shutdown_timeout == 0) {
@ -899,9 +908,26 @@ void sys_poweroff(void)
shutdown_timeout += HZ*20; shutdown_timeout += HZ*20;
#endif #endif
} }
}
queue_broadcast(SYS_POWEROFF, 0);
#endif /* BOOTLOADER */ #endif /* BOOTLOADER */
void sys_poweroff(void)
{
#ifndef BOOTLOADER
logf("sys_poweroff()");
sys_shutdown_common();
queue_broadcast(SYS_POWEROFF, 0);
#endif
}
/* not to be confused with system_reboot... :( */
void sys_reboot(void)
{
#ifndef BOOTLOADER
logf("sys_reboot()");
sys_shutdown_common();
queue_broadcast(SYS_REBOOT, 0);
#endif
} }
void cancel_shutdown(void) void cancel_shutdown(void)