mirror of
https://github.com/Next-Flip/Momentum-Firmware.git
synced 2026-05-13 09:48:35 -07:00
Snooze, timeouts, and dismissing from the locked state
This commit is contained in:
@@ -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);
|
||||||
|
|||||||
@@ -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()) {
|
||||||
|
|||||||
@@ -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++) {
|
||||||
|
|||||||
@@ -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
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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,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"
|
||||||
|
|||||||
|
Reference in New Issue
Block a user