Snooze, timeouts, and dismissing from the locked state

This commit is contained in:
Astra
2024-11-26 19:26:58 +09:00
parent 51aafd1b5e
commit a47443ed1c
8 changed files with 84 additions and 14 deletions

View File

@@ -417,7 +417,7 @@ void desktop_unlock(Desktop* desktop) {
view_port_enabled_set(desktop->lock_icon_viewport, false); view_port_enabled_set(desktop->lock_icon_viewport, false);
Gui* gui = furi_record_open(RECORD_GUI); Gui* gui = furi_record_open(RECORD_GUI);
gui_set_lockdown(gui, false); gui_remove_lockdown(gui);
furi_record_close(RECORD_GUI); furi_record_close(RECORD_GUI);
desktop_view_locked_unlock(desktop->locked_view); desktop_view_locked_unlock(desktop->locked_view);
scene_manager_search_and_switch_to_previous_scene(desktop->scene_manager, DesktopSceneMain); scene_manager_search_and_switch_to_previous_scene(desktop->scene_manager, DesktopSceneMain);

View File

@@ -45,7 +45,7 @@ void desktop_scene_locked_on_enter(void* context) {
if(state == DesktopSceneLockedStateFirstEnter) { if(state == DesktopSceneLockedStateFirstEnter) {
view_port_enabled_set(desktop->lock_icon_viewport, true); view_port_enabled_set(desktop->lock_icon_viewport, true);
Gui* gui = furi_record_open(RECORD_GUI); Gui* gui = furi_record_open(RECORD_GUI);
gui_set_lockdown(gui, true); gui_set_lockdown(gui);
furi_record_close(RECORD_GUI); furi_record_close(RECORD_GUI);
if(desktop_pin_code_is_set()) { if(desktop_pin_code_is_set()) {

View File

@@ -249,7 +249,7 @@ static void gui_redraw(Gui* gui) {
canvas_reset(gui->canvas); canvas_reset(gui->canvas);
if(gui->lockdown) { if(gui_is_lockdown(gui)) {
gui_redraw_desktop(gui); gui_redraw_desktop(gui);
bool need_attention = bool need_attention =
(gui_view_port_find_enabled(gui->layers[GuiLayerWindow]) != 0 || (gui_view_port_find_enabled(gui->layers[GuiLayerWindow]) != 0 ||
@@ -299,7 +299,7 @@ static void gui_input(Gui* gui, InputEvent* input_event) {
ViewPort* view_port = NULL; ViewPort* view_port = NULL;
if(gui->lockdown) { if(gui_is_lockdown(gui)) {
view_port = gui_view_port_find_enabled(gui->layers[GuiLayerDesktop]); view_port = gui_view_port_find_enabled(gui->layers[GuiLayerDesktop]);
} else { } else {
view_port = gui_view_port_find_enabled(gui->layers[GuiLayerFullscreen]); view_port = gui_view_port_find_enabled(gui->layers[GuiLayerFullscreen]);
@@ -484,17 +484,35 @@ size_t gui_get_framebuffer_size(const Gui* gui) {
return canvas_get_buffer_size(gui->canvas); return canvas_get_buffer_size(gui->canvas);
} }
void gui_set_lockdown(Gui* gui, bool lockdown) { void gui_set_lockdown(Gui* gui) {
furi_check(gui); furi_check(gui);
gui_lock(gui); gui_lock(gui);
gui->lockdown = lockdown; FURI_LOG_D(TAG, "Releasing lockdown semaphore");
furi_semaphore_release(gui->unlock);
gui_unlock(gui); gui_unlock(gui);
// Request redraw // Request redraw
gui_update(gui); gui_update(gui);
} }
void gui_remove_lockdown(Gui* gui) {
furi_check(gui);
FURI_LOG_D(TAG, "Acquiring lockdown semaphore");
gui_lock(gui);
if(furi_semaphore_acquire(gui->unlock, 1000) != FuriStatusOk) {
furi_crash("Could not acquire lockdown semaphore");
}
gui_unlock(gui);
}
bool gui_is_lockdown(const Gui* gui) {
furi_check(gui);
return furi_semaphore_get_count(gui->unlock) == 0;
}
Canvas* gui_direct_draw_acquire(Gui* gui) { Canvas* gui_direct_draw_acquire(Gui* gui) {
furi_check(gui); furi_check(gui);
@@ -529,6 +547,8 @@ Gui* gui_alloc(void) {
gui->thread_id = furi_thread_get_current_id(); gui->thread_id = furi_thread_get_current_id();
// Allocate mutex // Allocate mutex
gui->mutex = furi_mutex_alloc(FuriMutexTypeNormal); gui->mutex = furi_mutex_alloc(FuriMutexTypeNormal);
// Semaphore for the lockdown state
gui->unlock = furi_semaphore_alloc(2, 1);
// Layers // Layers
for(size_t i = 0; i < GuiLayerMAX; i++) { for(size_t i = 0; i < GuiLayerMAX; i++) {

View File

@@ -100,15 +100,27 @@ void gui_remove_framebuffer_callback(Gui* gui, GuiCanvasCommitCallback callback,
*/ */
size_t gui_get_framebuffer_size(const Gui* gui); size_t gui_get_framebuffer_size(const Gui* gui);
/** Set lockdown mode /** Enable lockdown mode
* *
* When lockdown mode is enabled, only GuiLayerDesktop is shown. * When lockdown mode is enabled, only GuiLayerDesktop is shown.
* This feature prevents services from showing sensitive information when flipper is locked. * This feature prevents services from showing sensitive information when flipper is locked.
* *
* @param gui Gui instance * @param gui Gui instance
* @param lockdown bool, true if enabled
*/ */
void gui_set_lockdown(Gui* gui, bool lockdown); void gui_set_lockdown(Gui* gui);
/** Disable lockdown mode
*
* @param gui Gui instance
*/
void gui_remove_lockdown(Gui* gui);
/** Check if Gui is in lockdown mode
*
* @param gui Gui instance
* @return bool true if Gui is in lockdown mode
*/
bool gui_is_lockdown(const Gui* gui);
/** Acquire Direct Draw lock and get Canvas instance /** Acquire Direct Draw lock and get Canvas instance
* *

View File

@@ -48,9 +48,9 @@ struct Gui {
// Thread and lock // Thread and lock
FuriThreadId thread_id; FuriThreadId thread_id;
FuriMutex* mutex; FuriMutex* mutex;
FuriSemaphore* unlock;
// Layers and Canvas // Layers and Canvas
bool lockdown;
bool direct_draw; bool direct_draw;
ViewPortArray_t layers[GuiLayerMAX]; ViewPortArray_t layers[GuiLayerMAX];
Canvas* canvas; Canvas* canvas;

View File

@@ -11,8 +11,12 @@
#define TAG "ClockSettingsAlarm" #define TAG "ClockSettingsAlarm"
#define SNOOZE_MINUTES 9
#define TIMEOUT_MINUTES 10
typedef struct { typedef struct {
DateTime now; DateTime now;
DateTime alarm_start;
IconAnimation* icon; IconAnimation* icon;
} ClockSettingsAlramModel; } ClockSettingsAlramModel;
@@ -47,12 +51,15 @@ static void clock_settings_alarm_draw_callback(Canvas* canvas, void* ctx) {
ClockSettingsAlramModel* model = ctx; ClockSettingsAlramModel* model = ctx;
char buffer[64] = {}; char buffer[64] = {};
// Clock icon
canvas_draw_icon_animation(canvas, 5, 6, model->icon); canvas_draw_icon_animation(canvas, 5, 6, model->icon);
// Time
canvas_set_font(canvas, FontBigNumbers); canvas_set_font(canvas, FontBigNumbers);
snprintf(buffer, sizeof(buffer), "%02u:%02u", model->now.hour, model->now.minute); snprintf(buffer, sizeof(buffer), "%02u:%02u", model->now.hour, model->now.minute);
canvas_draw_str(canvas, 58, 32, buffer); canvas_draw_str(canvas, 58, 32, buffer);
// Date
canvas_set_font(canvas, FontPrimary); canvas_set_font(canvas, FontPrimary);
snprintf( snprintf(
buffer, buffer,
@@ -62,6 +69,11 @@ static void clock_settings_alarm_draw_callback(Canvas* canvas, void* ctx) {
model->now.month, model->now.month,
model->now.year); model->now.year);
canvas_draw_str(canvas, 60, 44, buffer); canvas_draw_str(canvas, 60, 44, buffer);
// Press Back to snooze
canvas_set_font(canvas, FontPrimary);
canvas_draw_icon_ex(canvas, 5, 50, &I_back_btn_10x8, 0);
canvas_draw_str_aligned(canvas, 20, 50, AlignLeft, AlignTop, "Snooze");
} }
static void clock_settings_alarm_input_callback(InputEvent* input_event, void* ctx) { static void clock_settings_alarm_input_callback(InputEvent* input_event, void* ctx) {
@@ -95,6 +107,7 @@ int32_t clock_settings_alarm(void* p) {
// Register view port in GUI // Register view port in GUI
Gui* gui = furi_record_open(RECORD_GUI); Gui* gui = furi_record_open(RECORD_GUI);
gui_remove_lockdown(gui);
gui_add_view_port(gui, view_port, GuiLayerFullscreen); gui_add_view_port(gui, view_port, GuiLayerFullscreen);
NotificationApp* notification = furi_record_open(RECORD_NOTIFICATION); NotificationApp* notification = furi_record_open(RECORD_NOTIFICATION);
@@ -110,12 +123,32 @@ int32_t clock_settings_alarm(void* p) {
while(running) { while(running) {
if(furi_message_queue_get(event_queue, &event, 2000) == FuriStatusOk) { if(furi_message_queue_get(event_queue, &event, 2000) == FuriStatusOk) {
if(event.type == InputTypePress) { if(event.type == InputTypePress) {
// Snooze
if(event.key == InputKeyBack) {
furi_hal_rtc_get_datetime(&model.now);
model.now.minute += SNOOZE_MINUTES;
model.now.hour += model.now.minute / 60;
model.now.minute %= 60;
model.now.hour %= 24;
furi_hal_rtc_set_alarm(NULL, false);
furi_hal_rtc_set_alarm(&model.now, true);
}
running = false; running = false;
} }
} else { } else {
notification_message(notification, &sequence_alarm); notification_message(notification, &sequence_alarm);
furi_hal_rtc_get_datetime(&model.now); furi_hal_rtc_get_datetime(&model.now);
view_port_update(view_port); view_port_update(view_port);
// Stop the alarm if it has been ringing for more than TIMEOUT_MINUTES
furi_hal_rtc_get_alarm(&model.alarm_start);
if((model.now.hour == model.alarm_start.hour &&
model.now.minute >= model.alarm_start.minute + TIMEOUT_MINUTES) ||
(model.now.hour == (model.alarm_start.hour + 1) % 24 &&
model.now.minute < (model.alarm_start.minute + TIMEOUT_MINUTES) % 60)) {
running = false;
}
} }
} }
@@ -125,6 +158,7 @@ int32_t clock_settings_alarm(void* p) {
furi_record_close(RECORD_NOTIFICATION); furi_record_close(RECORD_NOTIFICATION);
view_port_enabled_set(view_port, false); view_port_enabled_set(view_port, false);
gui_set_lockdown(gui);
gui_remove_view_port(gui, view_port); gui_remove_view_port(gui, view_port);
view_port_free(view_port); view_port_free(view_port);
furi_message_queue_free(event_queue); furi_message_queue_free(event_queue);

View File

@@ -1,5 +1,5 @@
entry,status,name,type,params entry,status,name,type,params
Version,+,78.1,, Version,v,79.0,,
Header,+,applications/services/bt/bt_service/bt.h,, Header,+,applications/services/bt/bt_service/bt.h,,
Header,+,applications/services/bt/bt_service/bt_keys_storage.h,, Header,+,applications/services/bt/bt_service/bt_keys_storage.h,,
Header,+,applications/services/cli/cli.h,, Header,+,applications/services/cli/cli.h,,
@@ -1724,9 +1724,11 @@ Function,+,gui_add_view_port,void,"Gui*, ViewPort*, GuiLayer"
Function,+,gui_direct_draw_acquire,Canvas*,Gui* Function,+,gui_direct_draw_acquire,Canvas*,Gui*
Function,+,gui_direct_draw_release,void,Gui* Function,+,gui_direct_draw_release,void,Gui*
Function,+,gui_get_framebuffer_size,size_t,const Gui* Function,+,gui_get_framebuffer_size,size_t,const Gui*
Function,+,gui_is_lockdown,_Bool,const Gui*
Function,+,gui_remove_framebuffer_callback,void,"Gui*, GuiCanvasCommitCallback, void*" Function,+,gui_remove_framebuffer_callback,void,"Gui*, GuiCanvasCommitCallback, void*"
Function,+,gui_remove_lockdown,void,Gui*
Function,+,gui_remove_view_port,void,"Gui*, ViewPort*" Function,+,gui_remove_view_port,void,"Gui*, ViewPort*"
Function,+,gui_set_lockdown,void,"Gui*, _Bool" Function,+,gui_set_lockdown,void,Gui*
Function,-,gui_view_port_send_to_back,void,"Gui*, ViewPort*" Function,-,gui_view_port_send_to_back,void,"Gui*, ViewPort*"
Function,+,gui_view_port_send_to_front,void,"Gui*, ViewPort*" Function,+,gui_view_port_send_to_front,void,"Gui*, ViewPort*"
Function,-,hci_send_req,int,"hci_request*, uint8_t" Function,-,hci_send_req,int,"hci_request*, uint8_t"
1 entry status name type params
2 Version + v 78.1 79.0
3 Header + applications/services/bt/bt_service/bt.h
4 Header + applications/services/bt/bt_service/bt_keys_storage.h
5 Header + applications/services/cli/cli.h
1724 Function + gui_direct_draw_acquire Canvas* Gui*
1725 Function + gui_direct_draw_release void Gui*
1726 Function + gui_get_framebuffer_size size_t const Gui*
1727 Function + gui_is_lockdown _Bool const Gui*
1728 Function + gui_remove_framebuffer_callback void Gui*, GuiCanvasCommitCallback, void*
1729 Function + gui_remove_lockdown void Gui*
1730 Function + gui_remove_view_port void Gui*, ViewPort*
1731 Function + gui_set_lockdown void Gui*, _Bool Gui*
1732 Function - gui_view_port_send_to_back void Gui*, ViewPort*
1733 Function + gui_view_port_send_to_front void Gui*, ViewPort*
1734 Function - hci_send_req int hci_request*, uint8_t

View File

@@ -1,5 +1,5 @@
entry,status,name,type,params entry,status,name,type,params
Version,+,78.1,, Version,+,79.0,,
Header,+,applications/drivers/subghz/cc1101_ext/cc1101_ext_interconnect.h,, Header,+,applications/drivers/subghz/cc1101_ext/cc1101_ext_interconnect.h,,
Header,+,applications/services/bt/bt_service/bt.h,, Header,+,applications/services/bt/bt_service/bt.h,,
Header,+,applications/services/bt/bt_service/bt_keys_storage.h,, Header,+,applications/services/bt/bt_service/bt_keys_storage.h,,
@@ -1943,9 +1943,11 @@ Function,+,gui_add_view_port,void,"Gui*, ViewPort*, GuiLayer"
Function,+,gui_direct_draw_acquire,Canvas*,Gui* Function,+,gui_direct_draw_acquire,Canvas*,Gui*
Function,+,gui_direct_draw_release,void,Gui* Function,+,gui_direct_draw_release,void,Gui*
Function,+,gui_get_framebuffer_size,size_t,const Gui* Function,+,gui_get_framebuffer_size,size_t,const Gui*
Function,+,gui_is_lockdown,_Bool,const Gui*
Function,+,gui_remove_framebuffer_callback,void,"Gui*, GuiCanvasCommitCallback, void*" Function,+,gui_remove_framebuffer_callback,void,"Gui*, GuiCanvasCommitCallback, void*"
Function,+,gui_remove_lockdown,void,Gui*
Function,+,gui_remove_view_port,void,"Gui*, ViewPort*" Function,+,gui_remove_view_port,void,"Gui*, ViewPort*"
Function,+,gui_set_lockdown,void,"Gui*, _Bool" Function,+,gui_set_lockdown,void,Gui*
Function,-,gui_view_port_send_to_back,void,"Gui*, ViewPort*" Function,-,gui_view_port_send_to_back,void,"Gui*, ViewPort*"
Function,+,gui_view_port_send_to_front,void,"Gui*, ViewPort*" Function,+,gui_view_port_send_to_front,void,"Gui*, ViewPort*"
Function,-,hci_send_req,int,"hci_request*, uint8_t" Function,-,hci_send_req,int,"hci_request*, uint8_t"
1 entry status name type params
2 Version + 78.1 79.0
3 Header + applications/drivers/subghz/cc1101_ext/cc1101_ext_interconnect.h
4 Header + applications/services/bt/bt_service/bt.h
5 Header + applications/services/bt/bt_service/bt_keys_storage.h
1943 Function + gui_direct_draw_acquire Canvas* Gui*
1944 Function + gui_direct_draw_release void Gui*
1945 Function + gui_get_framebuffer_size size_t const Gui*
1946 Function + gui_is_lockdown _Bool const Gui*
1947 Function + gui_remove_framebuffer_callback void Gui*, GuiCanvasCommitCallback, void*
1948 Function + gui_remove_lockdown void Gui*
1949 Function + gui_remove_view_port void Gui*, ViewPort*
1950 Function + gui_set_lockdown void Gui*, _Bool Gui*
1951 Function - gui_view_port_send_to_back void Gui*, ViewPort*
1952 Function + gui_view_port_send_to_front void Gui*, ViewPort*
1953 Function - hci_send_req int hci_request*, uint8_t