[FL-2152] New PIN lock (#989)

* [Fl-2152] New PIN Lock, part 1
* Fix errors & leaks, renaming
* Add support to f6
* Fix error, remove duplicate code
* Fix drawing corners of Lock Popup
* FuriHal: insomnia if usb connected
* Applications: cleanup timers use

Co-authored-by: Aleksandr Kutuzov <alleteam@gmail.com>
This commit is contained in:
Albert Kharisov
2022-02-10 22:17:41 +04:00
committed by GitHub
parent 2a52d2d620
commit 21ac37a6f6
81 changed files with 2461 additions and 1176 deletions
@@ -1,5 +1,6 @@
#pragma once
#include <furi_hal.h>
#include <stdint.h>
#include <stdbool.h>
#include <toolbox/saved_struct.h>
@@ -9,6 +10,8 @@
#define DESKTOP_SETTINGS_MAGIC (0x17)
#define PIN_MAX_LENGTH 12
#define DESKTOP_SETTINGS_RUN_PIN_SETUP_ARG "run_pin_setup"
#define SAVE_DESKTOP_SETTINGS(x) \
saved_struct_save( \
DESKTOP_SETTINGS_PATH, \
@@ -25,12 +28,27 @@
DESKTOP_SETTINGS_MAGIC, \
DESKTOP_SETTINGS_VER)
#define MAX_PIN_SIZE 10
#define MIN_PIN_SIZE 4
typedef struct {
InputKey data[MAX_PIN_SIZE];
uint8_t length;
uint8_t data[PIN_MAX_LENGTH];
} PinCode;
typedef struct {
uint16_t favorite;
PinCode pincode;
PinCode pin_code;
} DesktopSettings;
static inline bool pins_are_equal(const PinCode* pin_code1, const PinCode* pin_code2) {
furi_assert(pin_code1);
furi_assert(pin_code2);
bool result = false;
if(pin_code1->length == pin_code2->length) {
result = !memcmp(pin_code1->data, pin_code2->data, pin_code1->length);
}
return result;
}
@@ -1,6 +1,10 @@
#include "desktop_settings_app.h"
#include <furi.h>
#include <gui/modules/popup.h>
#include <gui/scene_manager.h>
#include "desktop_settings_app.h"
#include "scenes/desktop_settings_scene.h"
#include "../views/desktop_view_pin_input.h"
static bool desktop_settings_custom_event_callback(void* context, uint32_t event) {
furi_assert(context);
@@ -30,17 +34,28 @@ DesktopSettingsApp* desktop_settings_app_alloc() {
view_dispatcher_attach_to_gui(app->view_dispatcher, app->gui, ViewDispatcherTypeFullscreen);
app->popup = popup_alloc();
app->submenu = submenu_alloc();
app->pin_input_view = desktop_view_pin_input_alloc();
app->pin_setup_howto_view = desktop_settings_view_pin_setup_howto_alloc();
app->pin_setup_howto2_view = desktop_settings_view_pin_setup_howto2_alloc();
view_dispatcher_add_view(
app->view_dispatcher, DesktopSettingsAppViewMenu, submenu_get_view(app->submenu));
app->code_input = code_input_alloc();
view_dispatcher_add_view(
app->view_dispatcher, DesktopSettingsAppViewIdPopup, popup_get_view(app->popup));
view_dispatcher_add_view(
app->view_dispatcher,
DesktopSettingsAppViewPincodeInput,
code_input_get_view(app->code_input));
scene_manager_next_scene(app->scene_manager, DesktopSettingsAppSceneStart);
DesktopSettingsAppViewIdPinInput,
desktop_view_pin_input_get_view(app->pin_input_view));
view_dispatcher_add_view(
app->view_dispatcher,
DesktopSettingsAppViewIdPinSetupHowto,
desktop_settings_view_pin_setup_howto_get_view(app->pin_setup_howto_view));
view_dispatcher_add_view(
app->view_dispatcher,
DesktopSettingsAppViewIdPinSetupHowto2,
desktop_settings_view_pin_setup_howto2_get_view(app->pin_setup_howto2_view));
return app;
}
@@ -48,9 +63,15 @@ void desktop_settings_app_free(DesktopSettingsApp* app) {
furi_assert(app);
// Variable item list
view_dispatcher_remove_view(app->view_dispatcher, DesktopSettingsAppViewMenu);
view_dispatcher_remove_view(app->view_dispatcher, DesktopSettingsAppViewIdPopup);
view_dispatcher_remove_view(app->view_dispatcher, DesktopSettingsAppViewIdPinInput);
view_dispatcher_remove_view(app->view_dispatcher, DesktopSettingsAppViewIdPinSetupHowto);
view_dispatcher_remove_view(app->view_dispatcher, DesktopSettingsAppViewIdPinSetupHowto2);
submenu_free(app->submenu);
view_dispatcher_remove_view(app->view_dispatcher, DesktopSettingsAppViewPincodeInput);
code_input_free(app->code_input);
popup_free(app->popup);
desktop_view_pin_input_free(app->pin_input_view);
desktop_settings_view_pin_setup_howto_free(app->pin_setup_howto_view);
desktop_settings_view_pin_setup_howto2_free(app->pin_setup_howto2_view);
// View dispatcher
view_dispatcher_free(app->view_dispatcher);
scene_manager_free(app->scene_manager);
@@ -62,6 +83,12 @@ void desktop_settings_app_free(DesktopSettingsApp* app) {
extern int32_t desktop_settings_app(void* p) {
DesktopSettingsApp* app = desktop_settings_app_alloc();
LOAD_DESKTOP_SETTINGS(&app->settings);
if(!strcmp(p, DESKTOP_SETTINGS_RUN_PIN_SETUP_ARG)) {
scene_manager_next_scene(app->scene_manager, DesktopSettingsAppScenePinSetupHowto);
} else {
scene_manager_next_scene(app->scene_manager, DesktopSettingsAppSceneStart);
}
view_dispatcher_run(app->view_dispatcher);
desktop_settings_app_free(app);
return 0;
@@ -1,22 +1,22 @@
#pragma once
#include <gui/gui.h>
#include <gui/modules/popup.h>
#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"
typedef enum {
CodeEventsSetPin,
CodeEventsChangePin,
CodeEventsDisablePin,
} CodeEventsEnum;
#include "desktop/views/desktop_view_pin_input.h"
#include "views/desktop_settings_view_pin_setup_howto.h"
#include "views/desktop_settings_view_pin_setup_howto2.h"
typedef enum {
DesktopSettingsAppViewMenu,
DesktopSettingsAppViewPincodeInput,
DesktopSettingsAppViewIdPopup,
DesktopSettingsAppViewIdPinInput,
DesktopSettingsAppViewIdPinSetupHowto,
DesktopSettingsAppViewIdPinSetupHowto2,
} DesktopSettingsAppView;
typedef struct {
@@ -26,7 +26,13 @@ typedef struct {
SceneManager* scene_manager;
ViewDispatcher* view_dispatcher;
Submenu* submenu;
CodeInput* code_input;
Popup* popup;
DesktopViewPinInput* pin_input_view;
DesktopSettingsViewPinSetupHowto* pin_setup_howto_view;
DesktopSettingsViewPinSetupHowto2* pin_setup_howto2_view;
PinCode pincode_buffer;
bool pincode_buffer_filled;
uint8_t menu_idx;
@@ -1,4 +1,11 @@
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)
ADD_SCENE(desktop_settings, pin_menu, PinMenu)
ADD_SCENE(desktop_settings, pin_auth, PinAuth)
ADD_SCENE(desktop_settings, pin_error, PinError)
ADD_SCENE(desktop_settings, pin_disable, PinDisable)
ADD_SCENE(desktop_settings, pin_setup, PinSetup)
ADD_SCENE(desktop_settings, pin_setup_howto, PinSetupHowto)
ADD_SCENE(desktop_settings, pin_setup_howto2, PinSetupHowto2)
ADD_SCENE(desktop_settings, pin_setup_done, PinSetupDone)
@@ -0,0 +1,7 @@
#pragma once
#define SCENE_STATE_PIN_AUTH_DISABLE (0)
#define SCENE_STATE_PIN_AUTH_CHANGE_PIN (1)
#define SCENE_STATE_PIN_ERROR_MISMATCH (0)
#define SCENE_STATE_PIN_ERROR_WRONG (1)
@@ -0,0 +1,95 @@
#include <stdint.h>
#include <furi/check.h>
#include <gui/scene_manager.h>
#include "../desktop_settings_app.h"
#include "desktop/desktop_settings/desktop_settings.h"
#include "desktop/views/desktop_view_pin_input.h"
#include "desktop_settings_scene.h"
#include "desktop_settings_scene_i.h"
#define SCENE_EVENT_EXIT (0U)
#define SCENE_EVENT_PINS_EQUAL (1U)
#define SCENE_EVENT_PINS_DIFFERENT (2U)
static void pin_auth_done_callback(const PinCode* pin_code, void* context) {
furi_assert(pin_code);
furi_assert(context);
DesktopSettingsApp* app = context;
app->pincode_buffer = *pin_code;
if(pins_are_equal(&app->settings.pin_code, pin_code)) {
view_dispatcher_send_custom_event(app->view_dispatcher, SCENE_EVENT_PINS_EQUAL);
} else {
view_dispatcher_send_custom_event(app->view_dispatcher, SCENE_EVENT_PINS_DIFFERENT);
}
}
static void pin_auth_back_callback(void* context) {
DesktopSettingsApp* app = context;
view_dispatcher_send_custom_event(app->view_dispatcher, SCENE_EVENT_EXIT);
}
void desktop_settings_scene_pin_auth_on_enter(void* context) {
DesktopSettingsApp* app = context;
LOAD_DESKTOP_SETTINGS(&app->settings);
furi_assert(app->settings.pin_code.length > 0);
desktop_view_pin_input_set_context(app->pin_input_view, app);
desktop_view_pin_input_set_back_callback(app->pin_input_view, pin_auth_back_callback);
desktop_view_pin_input_set_done_callback(app->pin_input_view, pin_auth_done_callback);
desktop_view_pin_input_set_label_button(app->pin_input_view, "OK");
desktop_view_pin_input_set_label_primary(app->pin_input_view, 0, 0, NULL);
desktop_view_pin_input_set_label_secondary(
app->pin_input_view, 0, 8, "Enter your current PIN:");
desktop_view_pin_input_reset_pin(app->pin_input_view);
desktop_view_pin_input_unlock_input(app->pin_input_view);
view_dispatcher_switch_to_view(app->view_dispatcher, DesktopSettingsAppViewIdPinInput);
}
bool desktop_settings_scene_pin_auth_on_event(void* context, SceneManagerEvent event) {
DesktopSettingsApp* app = context;
bool consumed = false;
if(event.type == SceneManagerEventTypeCustom) {
switch(event.event) {
case SCENE_EVENT_PINS_DIFFERENT:
scene_manager_set_scene_state(
app->scene_manager, DesktopSettingsAppScenePinError, SCENE_STATE_PIN_ERROR_WRONG);
scene_manager_next_scene(app->scene_manager, DesktopSettingsAppScenePinError);
consumed = true;
break;
case SCENE_EVENT_PINS_EQUAL: {
uint32_t state =
scene_manager_get_scene_state(app->scene_manager, DesktopSettingsAppScenePinAuth);
if(state == SCENE_STATE_PIN_AUTH_CHANGE_PIN) {
scene_manager_next_scene(app->scene_manager, DesktopSettingsAppScenePinSetupHowto);
} else if(state == SCENE_STATE_PIN_AUTH_DISABLE) {
scene_manager_next_scene(app->scene_manager, DesktopSettingsAppScenePinDisable);
} else {
furi_assert(0);
}
consumed = true;
break;
}
case SCENE_EVENT_EXIT:
scene_manager_search_and_switch_to_previous_scene(
app->scene_manager, DesktopSettingsAppScenePinMenu);
consumed = true;
break;
default:
consumed = true;
break;
}
}
return consumed;
}
void desktop_settings_scene_pin_auth_on_exit(void* context) {
furi_assert(context);
DesktopSettingsApp* app = context;
desktop_view_pin_input_set_back_callback(app->pin_input_view, NULL);
desktop_view_pin_input_set_done_callback(app->pin_input_view, NULL);
}
@@ -0,0 +1,56 @@
#include <stdint.h>
#include <furi/check.h>
#include <gui/scene_manager.h>
#include <gui/modules/popup.h>
#include "../desktop_settings_app.h"
#include "../desktop_settings.h"
#include "desktop/desktop_settings/desktop_settings.h"
#include "desktop_settings_scene.h"
#define SCENE_EVENT_EXIT (0U)
static void pin_disable_back_callback(void* context) {
furi_assert(context);
DesktopSettingsApp* app = context;
view_dispatcher_send_custom_event(app->view_dispatcher, SCENE_EVENT_EXIT);
}
void desktop_settings_scene_pin_disable_on_enter(void* context) {
furi_assert(context);
DesktopSettingsApp* app = context;
app->settings.pin_code.length = 0;
memset(app->settings.pin_code.data, '0', sizeof(app->settings.pin_code.data));
SAVE_DESKTOP_SETTINGS(&app->settings);
popup_set_context(app->popup, app);
popup_set_callback(app->popup, pin_disable_back_callback);
popup_set_icon(app->popup, 0, 2, &I_DolphinMafia_115x62);
popup_set_header(app->popup, "PIN\ndeleted!", 95, 9, AlignCenter, AlignCenter);
popup_set_timeout(app->popup, 1500);
popup_enable_timeout(app->popup);
view_dispatcher_switch_to_view(app->view_dispatcher, DesktopSettingsAppViewIdPopup);
}
bool desktop_settings_scene_pin_disable_on_event(void* context, SceneManagerEvent event) {
DesktopSettingsApp* app = context;
bool consumed = false;
if(event.type == SceneManagerEventTypeCustom) {
switch(event.event) {
case SCENE_EVENT_EXIT:
scene_manager_search_and_switch_to_previous_scene(
app->scene_manager, DesktopSettingsAppScenePinMenu);
consumed = true;
break;
default:
consumed = true;
break;
}
}
return consumed;
}
void desktop_settings_scene_pin_disable_on_exit(void* context) {
}
@@ -0,0 +1,76 @@
#include <stdint.h>
#include <furi/check.h>
#include <gui/scene_manager.h>
#include "desktop/desktop_settings/desktop_settings.h"
#include "desktop/views/desktop_view_pin_input.h"
#include "desktop_settings_scene.h"
#include "desktop_settings_scene_i.h"
#include "../../desktop_helpers.h"
#include "../desktop_settings_app.h"
#define SCENE_EVENT_EXIT (0U)
static void pin_error_back_callback(void* context) {
furi_assert(context);
DesktopSettingsApp* app = context;
view_dispatcher_send_custom_event(app->view_dispatcher, SCENE_EVENT_EXIT);
}
static void pin_error_done_callback(const PinCode* pin_code, void* context) {
furi_assert(context);
DesktopSettingsApp* app = context;
view_dispatcher_send_custom_event(app->view_dispatcher, SCENE_EVENT_EXIT);
}
void desktop_settings_scene_pin_error_on_enter(void* context) {
DesktopSettingsApp* app = context;
desktop_helpers_emit_error_notification();
desktop_view_pin_input_set_context(app->pin_input_view, app);
desktop_view_pin_input_set_back_callback(app->pin_input_view, pin_error_back_callback);
desktop_view_pin_input_set_done_callback(app->pin_input_view, pin_error_done_callback);
uint32_t state =
scene_manager_get_scene_state(app->scene_manager, DesktopSettingsAppScenePinError);
if(state == SCENE_STATE_PIN_ERROR_MISMATCH) {
desktop_view_pin_input_set_label_primary(app->pin_input_view, 29, 8, "PIN mismatch!");
} else if(state == SCENE_STATE_PIN_ERROR_WRONG) {
desktop_view_pin_input_set_label_primary(app->pin_input_view, 35, 8, "Wrong PIN!");
} else {
furi_assert(0);
}
desktop_view_pin_input_set_label_secondary(app->pin_input_view, 0, 8, NULL);
desktop_view_pin_input_set_label_button(app->pin_input_view, "Retry");
desktop_view_pin_input_lock_input(app->pin_input_view);
desktop_view_pin_input_set_pin(app->pin_input_view, &app->pincode_buffer);
view_dispatcher_switch_to_view(app->view_dispatcher, DesktopSettingsAppViewIdPinInput);
}
bool desktop_settings_scene_pin_error_on_event(void* context, SceneManagerEvent event) {
DesktopSettingsApp* app = context;
bool consumed = false;
if(event.type == SceneManagerEventTypeCustom) {
switch(event.event) {
case SCENE_EVENT_EXIT:
scene_manager_previous_scene(app->scene_manager);
consumed = true;
break;
default:
consumed = true;
break;
}
}
return consumed;
}
void desktop_settings_scene_pin_error_on_exit(void* context) {
furi_assert(context);
DesktopSettingsApp* app = context;
desktop_view_pin_input_unlock_input(app->pin_input_view);
desktop_view_pin_input_set_back_callback(app->pin_input_view, NULL);
desktop_view_pin_input_set_done_callback(app->pin_input_view, NULL);
}
@@ -1,38 +1,45 @@
#include "../desktop_settings_app.h"
#include "applications.h"
#include "desktop_settings_scene.h"
#include <gui/scene_manager.h>
#include <applications.h>
static void desktop_settings_scene_pincode_menu_submenu_callback(void* context, uint32_t index) {
#include "../desktop_settings_app.h"
#include "desktop_settings_scene.h"
#include "desktop_settings_scene_i.h"
#define SCENE_EVENT_SET_PIN 0
#define SCENE_EVENT_CHANGE_PIN 1
#define SCENE_EVENT_DISABLE_PIN 2
static void desktop_settings_scene_pin_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) {
void desktop_settings_scene_pin_menu_on_enter(void* context) {
DesktopSettingsApp* app = context;
Submenu* submenu = app->submenu;
submenu_reset(submenu);
if(!app->settings.pincode.length) {
if(!app->settings.pin_code.length) {
submenu_add_item(
submenu,
"Set Pin",
CodeEventsSetPin,
desktop_settings_scene_pincode_menu_submenu_callback,
SCENE_EVENT_SET_PIN,
desktop_settings_scene_pin_menu_submenu_callback,
app);
} else {
submenu_add_item(
submenu,
"Change Pin",
CodeEventsChangePin,
desktop_settings_scene_pincode_menu_submenu_callback,
SCENE_EVENT_CHANGE_PIN,
desktop_settings_scene_pin_menu_submenu_callback,
app);
submenu_add_item(
submenu,
"Disable",
CodeEventsDisablePin,
desktop_settings_scene_pincode_menu_submenu_callback,
SCENE_EVENT_DISABLE_PIN,
desktop_settings_scene_pin_menu_submenu_callback,
app);
}
@@ -41,28 +48,28 @@ void desktop_settings_scene_pincode_menu_on_enter(void* context) {
view_dispatcher_switch_to_view(app->view_dispatcher, DesktopSettingsAppViewMenu);
}
bool desktop_settings_scene_pincode_menu_on_event(void* context, SceneManagerEvent event) {
bool desktop_settings_scene_pin_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);
case SCENE_EVENT_SET_PIN:
scene_manager_next_scene(app->scene_manager, DesktopSettingsAppScenePinSetupHowto);
consumed = true;
break;
case CodeEventsChangePin:
case SCENE_EVENT_CHANGE_PIN:
scene_manager_set_scene_state(
app->scene_manager, DesktopSettingsAppScenePinCodeInput, event.event);
scene_manager_next_scene(app->scene_manager, DesktopSettingsAppScenePinCodeInput);
app->scene_manager,
DesktopSettingsAppScenePinAuth,
SCENE_STATE_PIN_AUTH_CHANGE_PIN);
scene_manager_next_scene(app->scene_manager, DesktopSettingsAppScenePinAuth);
consumed = true;
break;
case CodeEventsDisablePin:
case SCENE_EVENT_DISABLE_PIN:
scene_manager_set_scene_state(
app->scene_manager, DesktopSettingsAppScenePinCodeInput, event.event);
scene_manager_next_scene(app->scene_manager, DesktopSettingsAppScenePinCodeInput);
app->scene_manager, DesktopSettingsAppScenePinAuth, SCENE_STATE_PIN_AUTH_DISABLE);
scene_manager_next_scene(app->scene_manager, DesktopSettingsAppScenePinAuth);
consumed = true;
break;
default:
@@ -73,7 +80,7 @@ bool desktop_settings_scene_pincode_menu_on_event(void* context, SceneManagerEve
return consumed;
}
void desktop_settings_scene_pincode_menu_on_exit(void* context) {
void desktop_settings_scene_pin_menu_on_exit(void* context) {
DesktopSettingsApp* app = context;
submenu_reset(app->submenu);
}
@@ -0,0 +1,107 @@
#include <stdint.h>
#include <furi/check.h>
#include <gui/scene_manager.h>
#include "../desktop_settings_app.h"
#include "desktop/desktop_settings/desktop_settings.h"
#include "desktop/views/desktop_view_pin_input.h"
#include "desktop_settings_scene.h"
#include "desktop_settings_scene_i.h"
#define SCENE_EVENT_EXIT (0U)
#define SCENE_EVENT_1ST_PIN_ENTERED (1U)
#define SCENE_EVENT_PINS_EQUAL (2U)
#define SCENE_EVENT_PINS_DIFFERENT (3U)
static void pin_setup_done_callback(const PinCode* pin_code, void* context) {
furi_assert(pin_code);
furi_assert(context);
DesktopSettingsApp* app = context;
if(!app->pincode_buffer_filled) {
app->pincode_buffer = *pin_code;
app->pincode_buffer_filled = true;
view_dispatcher_send_custom_event(app->view_dispatcher, SCENE_EVENT_1ST_PIN_ENTERED);
} else {
app->pincode_buffer_filled = false;
if(pins_are_equal(&app->pincode_buffer, pin_code)) {
view_dispatcher_send_custom_event(app->view_dispatcher, SCENE_EVENT_PINS_EQUAL);
} else {
view_dispatcher_send_custom_event(app->view_dispatcher, SCENE_EVENT_PINS_DIFFERENT);
}
}
}
static void pin_setup_back_callback(void* context) {
DesktopSettingsApp* app = context;
view_dispatcher_send_custom_event(app->view_dispatcher, SCENE_EVENT_EXIT);
}
void desktop_settings_scene_pin_setup_on_enter(void* context) {
DesktopSettingsApp* app = context;
app->pincode_buffer_filled = false;
desktop_view_pin_input_set_context(app->pin_input_view, app);
desktop_view_pin_input_set_back_callback(app->pin_input_view, pin_setup_back_callback);
desktop_view_pin_input_set_done_callback(app->pin_input_view, pin_setup_done_callback);
desktop_view_pin_input_set_label_button(app->pin_input_view, "OK");
desktop_view_pin_input_set_label_primary(app->pin_input_view, 0, 0, NULL);
desktop_view_pin_input_set_label_secondary(
app->pin_input_view, 0, 8, "Enter from 4 to 10 arrows:");
desktop_view_pin_input_reset_pin(app->pin_input_view);
desktop_view_pin_input_unlock_input(app->pin_input_view);
view_dispatcher_switch_to_view(app->view_dispatcher, DesktopSettingsAppViewIdPinInput);
}
bool desktop_settings_scene_pin_setup_on_event(void* context, SceneManagerEvent event) {
DesktopSettingsApp* app = context;
bool consumed = false;
if(event.type == SceneManagerEventTypeCustom) {
switch(event.event) {
case SCENE_EVENT_1ST_PIN_ENTERED:
desktop_view_pin_input_set_label_button(app->pin_input_view, "OK");
desktop_view_pin_input_set_label_primary(app->pin_input_view, 0, 0, NULL);
desktop_view_pin_input_set_label_secondary(
app->pin_input_view, 0, 8, "Confirm your PIN:");
desktop_view_pin_input_reset_pin(app->pin_input_view);
desktop_view_pin_input_unlock_input(app->pin_input_view);
consumed = true;
break;
case SCENE_EVENT_PINS_DIFFERENT:
scene_manager_set_scene_state(
app->scene_manager,
DesktopSettingsAppScenePinError,
SCENE_STATE_PIN_ERROR_MISMATCH);
scene_manager_next_scene(app->scene_manager, DesktopSettingsAppScenePinError);
consumed = true;
break;
case SCENE_EVENT_PINS_EQUAL:
scene_manager_next_scene(app->scene_manager, DesktopSettingsAppScenePinSetupHowto2);
consumed = true;
break;
case SCENE_EVENT_EXIT: {
uint32_t scene_found;
scene_found = scene_manager_search_and_switch_to_previous_scene(
app->scene_manager, DesktopSettingsAppScenePinMenu);
if(!scene_found) {
view_dispatcher_stop(app->view_dispatcher);
}
consumed = true;
break;
}
default:
consumed = true;
break;
}
}
return consumed;
}
void desktop_settings_scene_pin_setup_on_exit(void* context) {
furi_assert(context);
DesktopSettingsApp* app = context;
desktop_view_pin_input_set_back_callback(app->pin_input_view, NULL);
desktop_view_pin_input_set_done_callback(app->pin_input_view, NULL);
}
@@ -0,0 +1,77 @@
#include <furi.h>
#include <notification/notification.h>
#include <notification/notification_messages.h>
#include <stdint.h>
#include <gui/scene_manager.h>
#include <gui/view_dispatcher.h>
#include "../desktop_settings_app.h"
#include "desktop/desktop_settings/desktop_settings.h"
#include "desktop/views/desktop_view_pin_input.h"
#include "desktop_settings_scene.h"
#define SCENE_EVENT_DONE (0U)
static void pin_setup_done_callback(const PinCode* pin_code, void* context) {
furi_assert(pin_code);
furi_assert(context);
DesktopSettingsApp* app = context;
view_dispatcher_send_custom_event(app->view_dispatcher, SCENE_EVENT_DONE);
}
void desktop_settings_scene_pin_setup_done_on_enter(void* context) {
DesktopSettingsApp* app = context;
app->settings.pin_code = app->pincode_buffer;
SAVE_DESKTOP_SETTINGS(&app->settings);
NotificationApp* notification = furi_record_open("notification");
notification_message(notification, &sequence_single_vibro);
furi_record_close("notification");
desktop_view_pin_input_set_context(app->pin_input_view, app);
desktop_view_pin_input_set_back_callback(app->pin_input_view, NULL);
desktop_view_pin_input_set_done_callback(app->pin_input_view, pin_setup_done_callback);
desktop_view_pin_input_set_pin(app->pin_input_view, &app->settings.pin_code);
desktop_view_pin_input_set_label_button(app->pin_input_view, "Done");
desktop_view_pin_input_set_label_primary(app->pin_input_view, 29, 8, "PIN activated!");
desktop_view_pin_input_set_label_secondary(
app->pin_input_view, 7, 45, "Remember or write it down");
desktop_view_pin_input_lock_input(app->pin_input_view);
desktop_view_pin_input_set_pin_position(app->pin_input_view, 64, 24);
view_dispatcher_switch_to_view(app->view_dispatcher, DesktopSettingsAppViewIdPinInput);
}
bool desktop_settings_scene_pin_setup_done_on_event(void* context, SceneManagerEvent event) {
DesktopSettingsApp* app = context;
bool consumed = false;
if(event.type == SceneManagerEventTypeCustom) {
switch(event.event) {
case SCENE_EVENT_DONE: {
bool scene_found = false;
scene_found = scene_manager_search_and_switch_to_previous_scene(
app->scene_manager, DesktopSettingsAppScenePinMenu);
if(!scene_found) {
view_dispatcher_stop(app->view_dispatcher);
}
consumed = true;
break;
}
default:
consumed = true;
break;
}
} else if(event.type == SceneManagerEventTypeBack) {
consumed = true;
}
return consumed;
}
void desktop_settings_scene_pin_setup_done_on_exit(void* context) {
furi_assert(context);
DesktopSettingsApp* app = context;
desktop_view_pin_input_set_pin_position(app->pin_input_view, 64, 32);
desktop_view_pin_input_set_back_callback(app->pin_input_view, NULL);
desktop_view_pin_input_set_done_callback(app->pin_input_view, NULL);
}
@@ -0,0 +1,44 @@
#include <furi.h>
#include <gui/scene_manager.h>
#include <gui/view_dispatcher.h>
#include "desktop_settings_scene.h"
#include "../desktop_settings_app.h"
#include "../views/desktop_settings_view_pin_setup_howto.h"
#define SCENE_EXIT_EVENT (0U)
static void desktop_settings_scene_pin_lock_done_callback(void* context) {
DesktopSettingsApp* app = context;
view_dispatcher_send_custom_event(app->view_dispatcher, SCENE_EXIT_EVENT);
}
void desktop_settings_scene_pin_setup_howto_on_enter(void* context) {
DesktopSettingsApp* app = context;
desktop_settings_view_pin_setup_howto_set_callback(
app->pin_setup_howto_view, desktop_settings_scene_pin_lock_done_callback, app);
view_dispatcher_switch_to_view(app->view_dispatcher, DesktopSettingsAppViewIdPinSetupHowto);
}
bool desktop_settings_scene_pin_setup_howto_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_next_scene(app->scene_manager, DesktopSettingsAppScenePinSetup);
consumed = true;
break;
default:
furi_assert(0);
consumed = true;
break;
}
}
return consumed;
}
void desktop_settings_scene_pin_setup_howto_on_exit(void* context) {
}
@@ -0,0 +1,67 @@
#include <furi.h>
#include <gui/scene_manager.h>
#include <stdint.h>
#include "desktop_settings_scene.h"
#include "../desktop_settings_app.h"
#include "../views/desktop_settings_view_pin_setup_howto2.h"
#define SCENE_EXIT_EVENT (0U)
#define SCENE_DONE_EVENT (1U)
static void desktop_settings_scene_pin_setup_howto2_done_callback(void* context) {
DesktopSettingsApp* app = context;
view_dispatcher_send_custom_event(app->view_dispatcher, SCENE_DONE_EVENT);
}
static void desktop_settings_scene_pin_setup_howto2_exit_callback(void* context) {
DesktopSettingsApp* app = context;
view_dispatcher_send_custom_event(app->view_dispatcher, SCENE_EXIT_EVENT);
}
void desktop_settings_scene_pin_setup_howto2_on_enter(void* context) {
DesktopSettingsApp* app = context;
desktop_settings_view_pin_setup_howto2_set_context(app->pin_setup_howto2_view, app);
desktop_settings_view_pin_setup_howto2_set_ok_callback(
app->pin_setup_howto2_view, desktop_settings_scene_pin_setup_howto2_done_callback);
desktop_settings_view_pin_setup_howto2_set_cancel_callback(
app->pin_setup_howto2_view, desktop_settings_scene_pin_setup_howto2_exit_callback);
view_dispatcher_switch_to_view(app->view_dispatcher, DesktopSettingsAppViewIdPinSetupHowto2);
}
bool desktop_settings_scene_pin_setup_howto2_on_event(void* context, SceneManagerEvent event) {
DesktopSettingsApp* app = context;
bool consumed = false;
if(event.type == SceneManagerEventTypeCustom) {
switch(event.event) {
case SCENE_DONE_EVENT: {
scene_manager_next_scene(app->scene_manager, DesktopSettingsAppScenePinSetupDone);
consumed = true;
break;
}
case SCENE_EXIT_EVENT: {
bool scene_found = false;
scene_found = scene_manager_search_and_switch_to_previous_scene(
app->scene_manager, DesktopSettingsAppScenePinMenu);
if(!scene_found) {
view_dispatcher_stop(app->view_dispatcher);
}
consumed = true;
break;
}
default:
furi_assert(0);
consumed = true;
break;
}
}
return consumed;
}
void desktop_settings_scene_pin_setup_howto2_on_exit(void* context) {
DesktopSettingsApp* app = context;
desktop_settings_view_pin_setup_howto2_set_ok_callback(app->pin_setup_howto2_view, NULL);
desktop_settings_view_pin_setup_howto2_set_cancel_callback(app->pin_setup_howto2_view, NULL);
}
@@ -1,64 +0,0 @@
#include "../desktop_settings_app.h"
#include "desktop_settings_scene.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;
SAVE_DESKTOP_SETTINGS(&app->settings);
code_input_set_result_callback(app->code_input, NULL, NULL, NULL, NULL, NULL, 0);
code_input_set_header_text(app->code_input, "");
}
@@ -1,11 +1,10 @@
#include <applications.h>
#include "../desktop_settings_app.h"
#include "applications.h"
#include "desktop_settings_scene.h"
enum DesktopSettingsStartSubmenuIndex {
DesktopSettingsStartSubmenuIndexFavorite,
DesktopSettingsStartSubmenuIndexPinSetup,
};
#define SCENE_EVENT_SELECT_FAVORITE 0
#define SCENE_EVENT_SELECT_PIN_SETUP 1
static void desktop_settings_scene_start_submenu_callback(void* context, uint32_t index) {
DesktopSettingsApp* app = context;
@@ -19,14 +18,14 @@ void desktop_settings_scene_start_on_enter(void* context) {
submenu_add_item(
submenu,
"Favorite App",
DesktopSettingsStartSubmenuIndexFavorite,
SCENE_EVENT_SELECT_FAVORITE,
desktop_settings_scene_start_submenu_callback,
app);
submenu_add_item(
submenu,
"PIN Setup",
DesktopSettingsStartSubmenuIndexPinSetup,
SCENE_EVENT_SELECT_PIN_SETUP,
desktop_settings_scene_start_submenu_callback,
app);
@@ -39,12 +38,12 @@ bool desktop_settings_scene_start_on_event(void* context, SceneManagerEvent even
if(event.type == SceneManagerEventTypeCustom) {
switch(event.event) {
case DesktopSettingsStartSubmenuIndexFavorite:
case SCENE_EVENT_SELECT_FAVORITE:
scene_manager_next_scene(app->scene_manager, DesktopSettingsAppSceneFavorite);
consumed = true;
break;
case DesktopSettingsStartSubmenuIndexPinSetup:
scene_manager_next_scene(app->scene_manager, DesktopSettingsAppScenePinCodeMenu);
case SCENE_EVENT_SELECT_PIN_SETUP:
scene_manager_next_scene(app->scene_manager, DesktopSettingsAppScenePinMenu);
consumed = true;
break;
}
@@ -0,0 +1,78 @@
#include <furi.h>
#include <furi_hal.h>
#include <gui/elements.h>
#include <gui/canvas.h>
#include <toolbox/version.h>
#include <assets_icons.h>
#include <dolphin/helpers/dolphin_state.h>
#include <dolphin/dolphin.h>
#include "desktop_settings_view_pin_setup_howto.h"
struct DesktopSettingsViewPinSetupHowto {
View* view;
DesktopSettingsViewPinSetupHowtoDoneCallback callback;
void* context;
};
static void desktop_settings_view_pin_setup_howto_draw(Canvas* canvas, void* model) {
furi_assert(canvas);
furi_assert(model);
canvas_draw_icon(canvas, 16, 18, &I_Pin_attention_dpad_29x29);
elements_button_right(canvas, "Next");
canvas_set_font(canvas, FontPrimary);
elements_multiline_text_aligned(canvas, 64, 0, AlignCenter, AlignTop, "Setting up PIN");
canvas_set_font(canvas, FontSecondary);
elements_multiline_text(canvas, 58, 24, "Prepare to use\narrows as\nPIN symbols");
}
static bool desktop_settings_view_pin_setup_howto_input(InputEvent* event, void* context) {
furi_assert(event);
furi_assert(context);
DesktopSettingsViewPinSetupHowto* instance = context;
bool consumed = false;
if((event->key == InputKeyRight) && (event->type == InputTypeShort)) {
instance->callback(instance->context);
consumed = true;
}
return consumed;
}
void desktop_settings_view_pin_setup_howto_set_callback(
DesktopSettingsViewPinSetupHowto* instance,
DesktopSettingsViewPinSetupHowtoDoneCallback callback,
void* context) {
furi_assert(instance);
furi_assert(callback);
instance->callback = callback;
instance->context = context;
}
DesktopSettingsViewPinSetupHowto* desktop_settings_view_pin_setup_howto_alloc() {
DesktopSettingsViewPinSetupHowto* view = furi_alloc(sizeof(DesktopSettingsViewPinSetupHowto));
view->view = view_alloc();
view_allocate_model(view->view, ViewModelTypeLockFree, 1);
view_set_context(view->view, view);
view_set_draw_callback(view->view, desktop_settings_view_pin_setup_howto_draw);
view_set_input_callback(view->view, desktop_settings_view_pin_setup_howto_input);
return view;
}
void desktop_settings_view_pin_setup_howto_free(DesktopSettingsViewPinSetupHowto* instance) {
furi_assert(instance);
view_free(instance->view);
free(instance);
}
View* desktop_settings_view_pin_setup_howto_get_view(DesktopSettingsViewPinSetupHowto* instance) {
furi_assert(instance);
return instance->view;
}
@@ -0,0 +1,15 @@
#pragma once
#include <gui/view.h>
typedef struct DesktopSettingsViewPinSetupHowto DesktopSettingsViewPinSetupHowto;
typedef void (*DesktopSettingsViewPinSetupHowtoDoneCallback)(void*);
void desktop_settings_view_pin_setup_howto_set_callback(
DesktopSettingsViewPinSetupHowto* instance,
DesktopSettingsViewPinSetupHowtoDoneCallback callback,
void* context);
DesktopSettingsViewPinSetupHowto* desktop_settings_view_pin_setup_howto_alloc();
void desktop_settings_view_pin_setup_howto_free(DesktopSettingsViewPinSetupHowto* instance);
View* desktop_settings_view_pin_setup_howto_get_view(DesktopSettingsViewPinSetupHowto* instance);
@@ -0,0 +1,101 @@
#include <furi.h>
#include <furi_hal.h>
#include <gui/elements.h>
#include <gui/canvas.h>
#include <toolbox/version.h>
#include <assets_icons.h>
#include <dolphin/helpers/dolphin_state.h>
#include <dolphin/dolphin.h>
#include "desktop_settings_view_pin_setup_howto2.h"
struct DesktopSettingsViewPinSetupHowto2 {
View* view;
DesktopSettingsViewPinSetupHowto2Callback cancel_callback;
DesktopSettingsViewPinSetupHowto2Callback ok_callback;
void* context;
};
static void desktop_settings_view_pin_setup_howto2_draw(Canvas* canvas, void* model) {
furi_assert(canvas);
furi_assert(model);
canvas_set_font(canvas, FontSecondary);
elements_multiline_text_aligned(
canvas,
64,
24,
AlignCenter,
AlignCenter,
"Forgotten PIN can only be\n"
"reset with entire device.\n"
"Read docs How to reset PIN.");
elements_button_right(canvas, "OK");
elements_button_left(canvas, "Cancel");
}
static bool desktop_settings_view_pin_setup_howto2_input(InputEvent* event, void* context) {
furi_assert(event);
furi_assert(context);
DesktopSettingsViewPinSetupHowto2* instance = context;
bool consumed = false;
if(event->type == InputTypeShort) {
if(event->key == InputKeyRight) {
instance->ok_callback(instance->context);
consumed = true;
} else if(event->key == InputKeyLeft) {
instance->cancel_callback(instance->context);
consumed = true;
}
}
return consumed;
}
void desktop_settings_view_pin_setup_howto2_set_context(
DesktopSettingsViewPinSetupHowto2* instance,
void* context) {
furi_assert(instance);
instance->context = context;
}
void desktop_settings_view_pin_setup_howto2_set_cancel_callback(
DesktopSettingsViewPinSetupHowto2* instance,
DesktopSettingsViewPinSetupHowto2Callback callback) {
furi_assert(instance);
instance->cancel_callback = callback;
}
void desktop_settings_view_pin_setup_howto2_set_ok_callback(
DesktopSettingsViewPinSetupHowto2* instance,
DesktopSettingsViewPinSetupHowto2Callback callback) {
furi_assert(instance);
instance->ok_callback = callback;
}
DesktopSettingsViewPinSetupHowto2* desktop_settings_view_pin_setup_howto2_alloc() {
DesktopSettingsViewPinSetupHowto2* view =
furi_alloc(sizeof(DesktopSettingsViewPinSetupHowto2));
view->view = view_alloc();
view_allocate_model(view->view, ViewModelTypeLockFree, 1);
view_set_context(view->view, view);
view_set_draw_callback(view->view, desktop_settings_view_pin_setup_howto2_draw);
view_set_input_callback(view->view, desktop_settings_view_pin_setup_howto2_input);
return view;
}
void desktop_settings_view_pin_setup_howto2_free(DesktopSettingsViewPinSetupHowto2* instance) {
furi_assert(instance);
view_free(instance->view);
free(instance);
}
View* desktop_settings_view_pin_setup_howto2_get_view(DesktopSettingsViewPinSetupHowto2* instance) {
furi_assert(instance);
return instance->view;
}
@@ -0,0 +1,20 @@
#pragma once
#include <gui/view.h>
typedef struct DesktopSettingsViewPinSetupHowto2 DesktopSettingsViewPinSetupHowto2;
typedef void (*DesktopSettingsViewPinSetupHowto2Callback)(void*);
DesktopSettingsViewPinSetupHowto2* desktop_settings_view_pin_setup_howto2_alloc();
void desktop_settings_view_pin_setup_howto2_free(DesktopSettingsViewPinSetupHowto2* instance);
View* desktop_settings_view_pin_setup_howto2_get_view(DesktopSettingsViewPinSetupHowto2* instance);
void desktop_settings_view_pin_setup_howto2_set_context(
DesktopSettingsViewPinSetupHowto2* instance,
void* context);
void desktop_settings_view_pin_setup_howto2_set_cancel_callback(
DesktopSettingsViewPinSetupHowto2* instance,
DesktopSettingsViewPinSetupHowto2Callback callback);
void desktop_settings_view_pin_setup_howto2_set_ok_callback(
DesktopSettingsViewPinSetupHowto2* instance,
DesktopSettingsViewPinSetupHowto2Callback callback);