[FL-1968] Pin code locking (#788)
* Gui: code input module * Gui: fix size to fit frame * Desktop: PIN config and lock option * Gui: code input: cleanup, offset input fields if no header present * Desktop: move code unlock to desktop_locked scene * Desktop: fix unlock with back key * Desktop: bump settings version * Desktop: correct scene usage. Co-authored-by: あく <alleteam@gmail.com>
This commit is contained in:
@@ -3,11 +3,20 @@
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#define DESKTOP_SETTINGS_VER (0)
|
||||
#define DESKTOP_SETTINGS_VER (1)
|
||||
#define PIN_MAX_LENGTH 12
|
||||
|
||||
typedef struct {
|
||||
uint8_t length;
|
||||
uint8_t data[PIN_MAX_LENGTH];
|
||||
} PinCode;
|
||||
|
||||
typedef struct {
|
||||
uint8_t version;
|
||||
uint16_t favorite;
|
||||
|
||||
PinCode pincode;
|
||||
bool locked;
|
||||
} DesktopSettings;
|
||||
|
||||
bool desktop_settings_load(DesktopSettings* desktop_settings);
|
||||
|
@@ -33,10 +33,13 @@ DesktopSettingsApp* desktop_settings_app_alloc() {
|
||||
|
||||
app->submenu = submenu_alloc();
|
||||
view_dispatcher_add_view(
|
||||
app->view_dispatcher, DesktopSettingsAppViewMain, submenu_get_view(app->submenu));
|
||||
app->view_dispatcher, DesktopSettingsAppViewMenu, submenu_get_view(app->submenu));
|
||||
|
||||
app->code_input = code_input_alloc();
|
||||
view_dispatcher_add_view(
|
||||
app->view_dispatcher, DesktopSettingsAppViewFavorite, submenu_get_view(app->submenu));
|
||||
app->view_dispatcher,
|
||||
DesktopSettingsAppViewPincodeInput,
|
||||
code_input_get_view(app->code_input));
|
||||
|
||||
scene_manager_next_scene(app->scene_manager, DesktopSettingsAppSceneStart);
|
||||
return app;
|
||||
@@ -45,9 +48,10 @@ DesktopSettingsApp* desktop_settings_app_alloc() {
|
||||
void desktop_settings_app_free(DesktopSettingsApp* app) {
|
||||
furi_assert(app);
|
||||
// Variable item list
|
||||
view_dispatcher_remove_view(app->view_dispatcher, DesktopSettingsAppViewMain);
|
||||
view_dispatcher_remove_view(app->view_dispatcher, DesktopSettingsAppViewFavorite);
|
||||
view_dispatcher_remove_view(app->view_dispatcher, DesktopSettingsAppViewMenu);
|
||||
submenu_free(app->submenu);
|
||||
view_dispatcher_remove_view(app->view_dispatcher, DesktopSettingsAppViewPincodeInput);
|
||||
code_input_free(app->code_input);
|
||||
// View dispatcher
|
||||
view_dispatcher_free(app->view_dispatcher);
|
||||
scene_manager_free(app->scene_manager);
|
||||
|
@@ -6,20 +6,32 @@
|
||||
#include <gui/view_dispatcher.h>
|
||||
#include <gui/scene_manager.h>
|
||||
#include <gui/modules/submenu.h>
|
||||
#include <gui/modules/code_input.h>
|
||||
|
||||
#include "desktop_settings.h"
|
||||
|
||||
#include "scenes/desktop_settings_scene.h"
|
||||
|
||||
typedef enum {
|
||||
DesktopSettingsAppViewMain,
|
||||
DesktopSettingsAppViewFavorite,
|
||||
CodeEventsSetPin,
|
||||
CodeEventsChangePin,
|
||||
CodeEventsDisablePin,
|
||||
} CodeEventsEnum;
|
||||
|
||||
typedef enum {
|
||||
DesktopSettingsAppViewMenu,
|
||||
DesktopSettingsAppViewPincodeInput,
|
||||
} DesktopSettingsAppView;
|
||||
|
||||
typedef struct {
|
||||
DesktopSettings settings;
|
||||
|
||||
Gui* gui;
|
||||
SceneManager* scene_manager;
|
||||
ViewDispatcher* view_dispatcher;
|
||||
Submenu* submenu;
|
||||
CodeInput* code_input;
|
||||
|
||||
uint8_t menu_idx;
|
||||
|
||||
} DesktopSettingsApp;
|
||||
|
@@ -1,2 +1,4 @@
|
||||
ADD_SCENE(desktop_settings, start, Start)
|
||||
ADD_SCENE(desktop_settings, favorite, Favorite)
|
||||
ADD_SCENE(desktop_settings, pincode_menu, PinCodeMenu)
|
||||
ADD_SCENE(desktop_settings, pincode_input, PinCodeInput)
|
||||
|
@@ -22,7 +22,7 @@ void desktop_settings_scene_favorite_on_enter(void* context) {
|
||||
|
||||
submenu_set_header(app->submenu, "Quick access app:");
|
||||
submenu_set_selected_item(app->submenu, app->settings.favorite);
|
||||
view_dispatcher_switch_to_view(app->view_dispatcher, DesktopSettingsAppViewFavorite);
|
||||
view_dispatcher_switch_to_view(app->view_dispatcher, DesktopSettingsAppViewMenu);
|
||||
}
|
||||
|
||||
bool desktop_settings_scene_favorite_on_event(void* context, SceneManagerEvent event) {
|
||||
|
@@ -0,0 +1,62 @@
|
||||
#include "../desktop_settings_app.h"
|
||||
|
||||
#define SCENE_EXIT_EVENT (0U)
|
||||
|
||||
void desktop_settings_scene_ok_callback(void* context) {
|
||||
DesktopSettingsApp* app = context;
|
||||
uint32_t state =
|
||||
scene_manager_get_scene_state(app->scene_manager, DesktopSettingsAppScenePinCodeInput);
|
||||
|
||||
if(state == CodeEventsDisablePin) {
|
||||
memset(app->settings.pincode.data, 0, app->settings.pincode.length * sizeof(uint8_t));
|
||||
app->settings.pincode.length = 0;
|
||||
}
|
||||
|
||||
view_dispatcher_send_custom_event(app->view_dispatcher, SCENE_EXIT_EVENT);
|
||||
}
|
||||
|
||||
void desktop_settings_scene_pincode_input_on_enter(void* context) {
|
||||
DesktopSettingsApp* app = context;
|
||||
CodeInput* code_input = app->code_input;
|
||||
|
||||
uint32_t state =
|
||||
scene_manager_get_scene_state(app->scene_manager, DesktopSettingsAppScenePinCodeInput);
|
||||
bool update = state != CodeEventsDisablePin;
|
||||
|
||||
code_input_set_header_text(code_input, "PIN Code Setup");
|
||||
code_input_set_result_callback(
|
||||
code_input,
|
||||
desktop_settings_scene_ok_callback,
|
||||
NULL,
|
||||
app,
|
||||
app->settings.pincode.data,
|
||||
&app->settings.pincode.length,
|
||||
update);
|
||||
|
||||
view_dispatcher_switch_to_view(app->view_dispatcher, DesktopSettingsAppViewPincodeInput);
|
||||
}
|
||||
|
||||
bool desktop_settings_scene_pincode_input_on_event(void* context, SceneManagerEvent event) {
|
||||
DesktopSettingsApp* app = context;
|
||||
bool consumed = false;
|
||||
|
||||
if(event.type == SceneManagerEventTypeCustom) {
|
||||
switch(event.event) {
|
||||
case SCENE_EXIT_EVENT:
|
||||
scene_manager_previous_scene(app->scene_manager);
|
||||
consumed = true;
|
||||
break;
|
||||
|
||||
default:
|
||||
consumed = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return consumed;
|
||||
}
|
||||
|
||||
void desktop_settings_scene_pincode_input_on_exit(void* context) {
|
||||
DesktopSettingsApp* app = context;
|
||||
code_input_set_result_callback(app->code_input, NULL, NULL, NULL, NULL, NULL, 0);
|
||||
code_input_set_header_text(app->code_input, "");
|
||||
}
|
@@ -0,0 +1,78 @@
|
||||
#include "../desktop_settings_app.h"
|
||||
#include "applications.h"
|
||||
|
||||
static void desktop_settings_scene_pincode_menu_submenu_callback(void* context, uint32_t index) {
|
||||
DesktopSettingsApp* app = context;
|
||||
view_dispatcher_send_custom_event(app->view_dispatcher, index);
|
||||
}
|
||||
|
||||
void desktop_settings_scene_pincode_menu_on_enter(void* context) {
|
||||
DesktopSettingsApp* app = context;
|
||||
Submenu* submenu = app->submenu;
|
||||
submenu_clean(submenu);
|
||||
|
||||
if(!app->settings.pincode.length) {
|
||||
submenu_add_item(
|
||||
submenu,
|
||||
"Set Pin",
|
||||
CodeEventsSetPin,
|
||||
desktop_settings_scene_pincode_menu_submenu_callback,
|
||||
app);
|
||||
|
||||
} else {
|
||||
submenu_add_item(
|
||||
submenu,
|
||||
"Change Pin",
|
||||
CodeEventsChangePin,
|
||||
desktop_settings_scene_pincode_menu_submenu_callback,
|
||||
app);
|
||||
|
||||
submenu_add_item(
|
||||
submenu,
|
||||
"Disable",
|
||||
CodeEventsDisablePin,
|
||||
desktop_settings_scene_pincode_menu_submenu_callback,
|
||||
app);
|
||||
}
|
||||
|
||||
submenu_set_header(app->submenu, "Pin code settings:");
|
||||
submenu_set_selected_item(app->submenu, app->menu_idx);
|
||||
view_dispatcher_switch_to_view(app->view_dispatcher, DesktopSettingsAppViewMenu);
|
||||
}
|
||||
|
||||
bool desktop_settings_scene_pincode_menu_on_event(void* context, SceneManagerEvent event) {
|
||||
DesktopSettingsApp* app = context;
|
||||
bool consumed = false;
|
||||
|
||||
if(event.type == SceneManagerEventTypeCustom) {
|
||||
switch(event.event) {
|
||||
case CodeEventsSetPin:
|
||||
scene_manager_set_scene_state(
|
||||
app->scene_manager, DesktopSettingsAppScenePinCodeInput, event.event);
|
||||
scene_manager_next_scene(app->scene_manager, DesktopSettingsAppScenePinCodeInput);
|
||||
consumed = true;
|
||||
break;
|
||||
case CodeEventsChangePin:
|
||||
scene_manager_set_scene_state(
|
||||
app->scene_manager, DesktopSettingsAppScenePinCodeInput, event.event);
|
||||
scene_manager_next_scene(app->scene_manager, DesktopSettingsAppScenePinCodeInput);
|
||||
consumed = true;
|
||||
break;
|
||||
case CodeEventsDisablePin:
|
||||
scene_manager_set_scene_state(
|
||||
app->scene_manager, DesktopSettingsAppScenePinCodeInput, event.event);
|
||||
scene_manager_next_scene(app->scene_manager, DesktopSettingsAppScenePinCodeInput);
|
||||
consumed = true;
|
||||
break;
|
||||
default:
|
||||
consumed = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return consumed;
|
||||
}
|
||||
|
||||
void desktop_settings_scene_pincode_menu_on_exit(void* context) {
|
||||
DesktopSettingsApp* app = context;
|
||||
submenu_clean(app->submenu);
|
||||
}
|
@@ -29,7 +29,7 @@ void desktop_settings_scene_start_on_enter(void* context) {
|
||||
desktop_settings_scene_start_submenu_callback,
|
||||
app);
|
||||
|
||||
view_dispatcher_switch_to_view(app->view_dispatcher, DesktopSettingsAppViewMain);
|
||||
view_dispatcher_switch_to_view(app->view_dispatcher, DesktopSettingsAppViewMenu);
|
||||
}
|
||||
|
||||
bool desktop_settings_scene_start_on_event(void* context, SceneManagerEvent event) {
|
||||
@@ -39,7 +39,11 @@ bool desktop_settings_scene_start_on_event(void* context, SceneManagerEvent even
|
||||
if(event.type == SceneManagerEventTypeCustom) {
|
||||
switch(event.event) {
|
||||
case DesktopSettingsStartSubmenuIndexFavorite:
|
||||
scene_manager_next_scene(app->scene_manager, DesktopSettingsAppViewFavorite);
|
||||
scene_manager_next_scene(app->scene_manager, DesktopSettingsAppSceneFavorite);
|
||||
consumed = true;
|
||||
break;
|
||||
case DesktopSettingsStartSubmenuIndexPinSetup:
|
||||
scene_manager_next_scene(app->scene_manager, DesktopSettingsAppScenePinCodeMenu);
|
||||
consumed = true;
|
||||
break;
|
||||
}
|
||||
|
Reference in New Issue
Block a user