Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[FL-3934] Alarm improvements: Snooze, timeouts, and dismissing from the locked state #4017

Draft
wants to merge 2 commits into
base: dev
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion applications/services/desktop/desktop.c
Original file line number Diff line number Diff line change
Expand Up @@ -417,7 +417,7 @@ void desktop_unlock(Desktop* desktop) {

view_port_enabled_set(desktop->lock_icon_viewport, false);
Gui* gui = furi_record_open(RECORD_GUI);
gui_set_lockdown(gui, false);
gui_remove_lockdown(gui);
furi_record_close(RECORD_GUI);
desktop_view_locked_unlock(desktop->locked_view);
scene_manager_search_and_switch_to_previous_scene(desktop->scene_manager, DesktopSceneMain);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ void desktop_scene_locked_on_enter(void* context) {
if(state == DesktopSceneLockedStateFirstEnter) {
view_port_enabled_set(desktop->lock_icon_viewport, true);
Gui* gui = furi_record_open(RECORD_GUI);
gui_set_lockdown(gui, true);
gui_set_lockdown(gui);
furi_record_close(RECORD_GUI);

if(desktop_pin_code_is_set()) {
Expand Down
28 changes: 24 additions & 4 deletions applications/services/gui/gui.c
Original file line number Diff line number Diff line change
Expand Up @@ -249,7 +249,7 @@ static void gui_redraw(Gui* gui) {

canvas_reset(gui->canvas);

if(gui->lockdown) {
if(gui_is_lockdown(gui)) {
gui_redraw_desktop(gui);
bool need_attention =
(gui_view_port_find_enabled(gui->layers[GuiLayerWindow]) != 0 ||
Expand Down Expand Up @@ -299,7 +299,7 @@ static void gui_input(Gui* gui, InputEvent* input_event) {

ViewPort* view_port = NULL;

if(gui->lockdown) {
if(gui_is_lockdown(gui)) {
view_port = gui_view_port_find_enabled(gui->layers[GuiLayerDesktop]);
} else {
view_port = gui_view_port_find_enabled(gui->layers[GuiLayerFullscreen]);
Expand Down Expand Up @@ -484,17 +484,35 @@ size_t gui_get_framebuffer_size(const Gui* gui) {
return canvas_get_buffer_size(gui->canvas);
}

void gui_set_lockdown(Gui* gui, bool lockdown) {
void gui_set_lockdown(Gui* gui) {
furi_check(gui);

gui_lock(gui);
gui->lockdown = lockdown;
FURI_LOG_D(TAG, "Releasing lockdown semaphore");
furi_semaphore_release(gui->unlock);
gui_unlock(gui);

// Request redraw
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) {
furi_check(gui);

Expand Down Expand Up @@ -529,6 +547,8 @@ Gui* gui_alloc(void) {
gui->thread_id = furi_thread_get_current_id();
// Allocate mutex
gui->mutex = furi_mutex_alloc(FuriMutexTypeNormal);
// Semaphore for the lockdown state
gui->unlock = furi_semaphore_alloc(2, 1);

// Layers
for(size_t i = 0; i < GuiLayerMAX; i++) {
Expand Down
18 changes: 15 additions & 3 deletions applications/services/gui/gui.h
Original file line number Diff line number Diff line change
Expand Up @@ -100,15 +100,27 @@ void gui_remove_framebuffer_callback(Gui* gui, GuiCanvasCommitCallback callback,
*/
size_t gui_get_framebuffer_size(const Gui* gui);

/** Set lockdown mode
/** Enable lockdown mode
*
* When lockdown mode is enabled, only GuiLayerDesktop is shown.
* This feature prevents services from showing sensitive information when flipper is locked.
*
* @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
*
Expand Down
2 changes: 1 addition & 1 deletion applications/services/gui/gui_i.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,9 @@ struct Gui {
// Thread and lock
FuriThreadId thread_id;
FuriMutex* mutex;
FuriSemaphore* unlock;

// Layers and Canvas
bool lockdown;
bool direct_draw;
ViewPortArray_t layers[GuiLayerMAX];
Canvas* canvas;
Expand Down
34 changes: 34 additions & 0 deletions applications/settings/clock_settings/clock_settings_alarm.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,12 @@

#define TAG "ClockSettingsAlarm"

#define SNOOZE_MINUTES 9
#define TIMEOUT_MINUTES 10

typedef struct {
DateTime now;
DateTime alarm_start;
IconAnimation* icon;
} ClockSettingsAlramModel;

Expand Down Expand Up @@ -47,12 +51,15 @@ static void clock_settings_alarm_draw_callback(Canvas* canvas, void* ctx) {
ClockSettingsAlramModel* model = ctx;
char buffer[64] = {};

// Clock icon
canvas_draw_icon_animation(canvas, 5, 6, model->icon);

// Time
canvas_set_font(canvas, FontBigNumbers);
snprintf(buffer, sizeof(buffer), "%02u:%02u", model->now.hour, model->now.minute);
canvas_draw_str(canvas, 58, 32, buffer);

// Date
canvas_set_font(canvas, FontPrimary);
snprintf(
buffer,
Expand All @@ -62,6 +69,11 @@ static void clock_settings_alarm_draw_callback(Canvas* canvas, void* ctx) {
model->now.month,
model->now.year);
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) {
Expand Down Expand Up @@ -95,6 +107,7 @@ int32_t clock_settings_alarm(void* p) {

// Register view port in GUI
Gui* gui = furi_record_open(RECORD_GUI);
gui_remove_lockdown(gui);
gui_add_view_port(gui, view_port, GuiLayerFullscreen);

NotificationApp* notification = furi_record_open(RECORD_NOTIFICATION);
Expand All @@ -110,12 +123,32 @@ int32_t clock_settings_alarm(void* p) {
while(running) {
if(furi_message_queue_get(event_queue, &event, 2000) == FuriStatusOk) {
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;
}
} else {
notification_message(notification, &sequence_alarm);
furi_hal_rtc_get_datetime(&model.now);
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;
}
}
}

Expand All @@ -125,6 +158,7 @@ int32_t clock_settings_alarm(void* p) {
furi_record_close(RECORD_NOTIFICATION);

view_port_enabled_set(view_port, false);
gui_set_lockdown(gui);
gui_remove_view_port(gui, view_port);
view_port_free(view_port);
furi_message_queue_free(event_queue);
Expand Down
6 changes: 4 additions & 2 deletions targets/f18/api_symbols.csv
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
entry,status,name,type,params
Version,+,78.1,,
Version,+,79.0,,
Header,+,applications/services/bt/bt_service/bt.h,,
Header,+,applications/services/bt/bt_service/bt_keys_storage.h,,
Header,+,applications/services/cli/cli.h,,
Expand Down Expand Up @@ -1724,9 +1724,11 @@ Function,+,gui_add_view_port,void,"Gui*, ViewPort*, GuiLayer"
Function,+,gui_direct_draw_acquire,Canvas*,Gui*
Function,+,gui_direct_draw_release,void,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_lockdown,void,Gui*
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_front,void,"Gui*, ViewPort*"
Function,-,hci_send_req,int,"hci_request*, uint8_t"
Expand Down
6 changes: 4 additions & 2 deletions targets/f7/api_symbols.csv
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
entry,status,name,type,params
Version,+,78.1,,
Version,+,79.0,,
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_keys_storage.h,,
Expand Down Expand Up @@ -1943,9 +1943,11 @@ Function,+,gui_add_view_port,void,"Gui*, ViewPort*, GuiLayer"
Function,+,gui_direct_draw_acquire,Canvas*,Gui*
Function,+,gui_direct_draw_release,void,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_lockdown,void,Gui*
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_front,void,"Gui*, ViewPort*"
Function,-,hci_send_req,int,"hci_request*, uint8_t"
Expand Down
Loading