[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:
its your bedtime
2021-10-26 21:34:31 +03:00
committed by GitHub
parent 400d672e81
commit fae8d8f23c
23 changed files with 948 additions and 43 deletions

View File

@@ -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);

View File

@@ -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);

View File

@@ -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;

View File

@@ -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)

View File

@@ -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) {

View File

@@ -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, "");
}

View File

@@ -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);
}

View File

@@ -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;
}