mirror of
https://github.com/Next-Flip/Momentum-Firmware.git
synced 2026-05-12 15:08:36 -07:00
Merge branch 'dev' of https://github.com/DarkFlippers/unleashed-firmware into xfw-dev
This commit is contained in:
@@ -4,6 +4,15 @@
|
||||
#include <gui/gui.h>
|
||||
#include <font_info.h>
|
||||
|
||||
/**
|
||||
* @brief Draw string using given font
|
||||
* @param canvas canvas to draw string at
|
||||
* @param x horizontal position
|
||||
* @param y vertical position
|
||||
* @param text string to draw
|
||||
* @param text_length string length
|
||||
* @param font font to be used to draw string
|
||||
*/
|
||||
void canvas_draw_str_ex(
|
||||
Canvas* canvas,
|
||||
uint8_t x,
|
||||
|
||||
11
applications/external/totp/ui/common_dialogs.h
vendored
11
applications/external/totp/ui/common_dialogs.h
vendored
@@ -3,5 +3,16 @@
|
||||
#include <dialogs/dialogs.h>
|
||||
#include "../types/plugin_state.h"
|
||||
|
||||
/**
|
||||
* @brief Shows standard dialog about the fact that error occurred when loading config file
|
||||
* @param plugin_state application state
|
||||
* @return dialog button which user pressed to close the dialog
|
||||
*/
|
||||
DialogMessageButton totp_dialogs_config_loading_error(PluginState* plugin_state);
|
||||
|
||||
/**
|
||||
* @brief Shows standard dialog about the fact that error occurred when updating config file
|
||||
* @param plugin_state application state
|
||||
* @return dialog button which user pressed to close the dialog
|
||||
*/
|
||||
DialogMessageButton totp_dialogs_config_updating_error(PluginState* plugin_state);
|
||||
@@ -116,3 +116,8 @@ bool totp_scene_director_handle_event(PluginEvent* const event, PluginState* con
|
||||
|
||||
return processing;
|
||||
}
|
||||
|
||||
void totp_scene_director_force_redraw(PluginState* const plugin_state) {
|
||||
PluginEvent event = {.type = EventForceRedraw};
|
||||
furi_message_queue_put(plugin_state->event_queue, &event, FuriWaitForever);
|
||||
}
|
||||
@@ -33,3 +33,9 @@ void totp_scene_director_render(Canvas* const canvas, PluginState* const plugin_
|
||||
* @return \c true if event handled and applilcation should continue; \c false if application should be closed
|
||||
*/
|
||||
bool totp_scene_director_handle_event(PluginEvent* const event, PluginState* const plugin_state);
|
||||
|
||||
/**
|
||||
* @brief Forces screen to be redraw\updated
|
||||
* @param plugin_state application state
|
||||
*/
|
||||
void totp_scene_director_force_redraw(PluginState* const plugin_state);
|
||||
@@ -42,7 +42,7 @@ typedef struct {
|
||||
|
||||
struct TotpAddContext {
|
||||
SceneState* scene_state;
|
||||
uint8_t* iv;
|
||||
const CryptoSettings* crypto_settings;
|
||||
};
|
||||
|
||||
enum TotpIteratorUpdateTokenResultsEx { TotpIteratorUpdateTokenResultInvalidSecret = 1 };
|
||||
@@ -58,7 +58,7 @@ static TotpIteratorUpdateTokenResult add_token_handler(TokenInfo* tokenInfo, con
|
||||
context_t->scene_state->token_secret,
|
||||
context_t->scene_state->token_secret_length,
|
||||
PlainTokenSecretEncodingBase32,
|
||||
context_t->iv)) {
|
||||
context_t->crypto_settings)) {
|
||||
return TotpIteratorUpdateTokenResultInvalidSecret;
|
||||
}
|
||||
|
||||
@@ -271,7 +271,7 @@ bool totp_scene_add_new_token_handle_event(
|
||||
break;
|
||||
case ConfirmButton: {
|
||||
struct TotpAddContext add_context = {
|
||||
.iv = plugin_state->iv, .scene_state = scene_state};
|
||||
.scene_state = scene_state, .crypto_settings = &plugin_state->crypto_settings};
|
||||
TokenInfoIteratorContext* iterator_context =
|
||||
totp_config_get_token_iterator_context(plugin_state);
|
||||
TotpIteratorUpdateTokenResult add_result = totp_token_info_iterator_add_new_token(
|
||||
|
||||
@@ -13,14 +13,30 @@
|
||||
#include "../../../services/convert/convert.h"
|
||||
#include <roll_value.h>
|
||||
#include "../../../features_config.h"
|
||||
#ifdef TOTP_BADBT_TYPE_ENABLED
|
||||
#ifdef TOTP_BADBT_AUTOMATION_ENABLED
|
||||
#include "../../../workers/bt_type_code/bt_type_code.h"
|
||||
#endif
|
||||
|
||||
#ifdef TOTP_BADBT_AUTOMATION_ENABLED
|
||||
#define AUTOMATION_LIST_MAX_INDEX (3)
|
||||
#else
|
||||
#define AUTOMATION_LIST_MAX_INDEX (1)
|
||||
#endif
|
||||
#define BAD_KB_LAYOUT_LIST_MAX_INDEX (1)
|
||||
#define FONT_TEST_STR_LENGTH (7)
|
||||
|
||||
static const char* YES_NO_LIST[] = {"NO", "YES"};
|
||||
static const char* ON_OFF_LIST[] = {"OFF", "ON"};
|
||||
static const char* AUTOMATION_LIST[] = {
|
||||
"None",
|
||||
"USB"
|
||||
#ifdef TOTP_BADBT_AUTOMATION_ENABLED
|
||||
,
|
||||
"Bluetooth",
|
||||
"BT and USB"
|
||||
#endif
|
||||
};
|
||||
static const char* BAD_KB_LAYOUT_LIST[] = {"QWERTY", "AZERTY"};
|
||||
static const char* FONT_TEST_STR = "0123BCD";
|
||||
static const uint8_t FONT_TEST_STR_LENGTH = 7;
|
||||
|
||||
typedef enum {
|
||||
HoursInput,
|
||||
@@ -28,10 +44,8 @@ typedef enum {
|
||||
FontSelect,
|
||||
SoundSwitch,
|
||||
VibroSwitch,
|
||||
BadUsbSwitch,
|
||||
#ifdef TOTP_BADBT_TYPE_ENABLED
|
||||
BadBtSwitch,
|
||||
#endif
|
||||
AutomationSwitch,
|
||||
BadKeyboardLayoutSelect,
|
||||
ConfirmButton
|
||||
} Control;
|
||||
|
||||
@@ -40,11 +54,9 @@ typedef struct {
|
||||
uint8_t tz_offset_minutes;
|
||||
bool notification_sound;
|
||||
bool notification_vibro;
|
||||
bool badusb_enabled;
|
||||
#ifdef TOTP_BADBT_TYPE_ENABLED
|
||||
bool badbt_enabled;
|
||||
#endif
|
||||
uint8_t y_offset;
|
||||
AutomationMethod automation_method;
|
||||
uint16_t y_offset;
|
||||
AutomationKeyboardLayout automation_kb_layout;
|
||||
Control selected_control;
|
||||
uint8_t active_font;
|
||||
} SceneState;
|
||||
@@ -60,10 +72,11 @@ void totp_scene_app_settings_activate(PluginState* plugin_state) {
|
||||
scene_state->tz_offset_minutes = 60.0f * off_dec;
|
||||
scene_state->notification_sound = plugin_state->notification_method & NotificationMethodSound;
|
||||
scene_state->notification_vibro = plugin_state->notification_method & NotificationMethodVibro;
|
||||
scene_state->badusb_enabled = plugin_state->automation_method & AutomationMethodBadUsb;
|
||||
#ifdef TOTP_BADBT_TYPE_ENABLED
|
||||
scene_state->badbt_enabled = plugin_state->automation_method & AutomationMethodBadBt;
|
||||
#endif
|
||||
scene_state->automation_method =
|
||||
MIN(plugin_state->automation_method, AUTOMATION_LIST_MAX_INDEX);
|
||||
scene_state->automation_kb_layout =
|
||||
MIN(plugin_state->automation_kb_layout, BAD_KB_LAYOUT_LIST_MAX_INDEX);
|
||||
|
||||
scene_state->active_font = plugin_state->active_font_index;
|
||||
}
|
||||
|
||||
@@ -83,127 +96,121 @@ static void two_digit_to_str(int8_t num, char* str) {
|
||||
|
||||
void totp_scene_app_settings_render(Canvas* const canvas, const PluginState* plugin_state) {
|
||||
const SceneState* scene_state = plugin_state->current_scene_state;
|
||||
if(scene_state->selected_control < FontSelect) {
|
||||
canvas_set_font(canvas, FontPrimary);
|
||||
canvas_draw_str_aligned(
|
||||
canvas, 0, 0 - scene_state->y_offset, AlignLeft, AlignTop, "Timezone offset");
|
||||
canvas_set_font(canvas, FontSecondary);
|
||||
|
||||
canvas_set_font(canvas, FontPrimary);
|
||||
canvas_draw_str_aligned(
|
||||
canvas, 0, 0 - scene_state->y_offset, AlignLeft, AlignTop, "Timezone offset");
|
||||
canvas_set_font(canvas, FontSecondary);
|
||||
char tmp_str[4];
|
||||
two_digit_to_str(scene_state->tz_offset_hours, &tmp_str[0]);
|
||||
canvas_draw_str_aligned(
|
||||
canvas, 0, 17 - scene_state->y_offset, AlignLeft, AlignTop, "Hours:");
|
||||
ui_control_select_render(
|
||||
canvas,
|
||||
36,
|
||||
10 - scene_state->y_offset,
|
||||
SCREEN_WIDTH - 36 - UI_CONTROL_VSCROLL_WIDTH,
|
||||
&tmp_str[0],
|
||||
scene_state->selected_control == HoursInput);
|
||||
|
||||
char tmp_str[4];
|
||||
two_digit_to_str(scene_state->tz_offset_hours, &tmp_str[0]);
|
||||
canvas_draw_str_aligned(canvas, 0, 17 - scene_state->y_offset, AlignLeft, AlignTop, "Hours:");
|
||||
ui_control_select_render(
|
||||
canvas,
|
||||
36,
|
||||
10 - scene_state->y_offset,
|
||||
SCREEN_WIDTH - 36,
|
||||
&tmp_str[0],
|
||||
scene_state->selected_control == HoursInput);
|
||||
two_digit_to_str(scene_state->tz_offset_minutes, &tmp_str[0]);
|
||||
canvas_draw_str_aligned(
|
||||
canvas, 0, 35 - scene_state->y_offset, AlignLeft, AlignTop, "Minutes:");
|
||||
ui_control_select_render(
|
||||
canvas,
|
||||
36,
|
||||
28 - scene_state->y_offset,
|
||||
SCREEN_WIDTH - 36 - UI_CONTROL_VSCROLL_WIDTH,
|
||||
&tmp_str[0],
|
||||
scene_state->selected_control == MinutesInput);
|
||||
|
||||
two_digit_to_str(scene_state->tz_offset_minutes, &tmp_str[0]);
|
||||
canvas_draw_str_aligned(
|
||||
canvas, 0, 35 - scene_state->y_offset, AlignLeft, AlignTop, "Minutes:");
|
||||
ui_control_select_render(
|
||||
canvas,
|
||||
36,
|
||||
28 - scene_state->y_offset,
|
||||
SCREEN_WIDTH - 36,
|
||||
&tmp_str[0],
|
||||
scene_state->selected_control == MinutesInput);
|
||||
} else if(scene_state->selected_control < SoundSwitch) {
|
||||
canvas_set_font(canvas, FontPrimary);
|
||||
canvas_draw_str_aligned(
|
||||
canvas, 0, 64 - scene_state->y_offset, AlignLeft, AlignTop, "Font");
|
||||
canvas_set_font(canvas, FontSecondary);
|
||||
|
||||
canvas_draw_icon(
|
||||
canvas,
|
||||
SCREEN_WIDTH_CENTER - 5,
|
||||
SCREEN_HEIGHT - 5 - scene_state->y_offset,
|
||||
&I_totp_arrow_bottom_10x5);
|
||||
const FONT_INFO* const font = available_fonts[scene_state->active_font];
|
||||
ui_control_select_render(
|
||||
canvas,
|
||||
0,
|
||||
74 - scene_state->y_offset,
|
||||
SCREEN_WIDTH - UI_CONTROL_VSCROLL_WIDTH,
|
||||
font->name,
|
||||
scene_state->selected_control == FontSelect);
|
||||
|
||||
canvas_set_font(canvas, FontPrimary);
|
||||
canvas_draw_str_aligned(canvas, 0, 64 - scene_state->y_offset, AlignLeft, AlignTop, "Font");
|
||||
canvas_set_font(canvas, FontSecondary);
|
||||
uint8_t font_x_offset =
|
||||
SCREEN_WIDTH_CENTER -
|
||||
(((font->charInfo[0].width + font->spacePixels) * FONT_TEST_STR_LENGTH) >> 1);
|
||||
uint8_t font_y_offset = 108 - scene_state->y_offset - (font->height >> 1);
|
||||
canvas_draw_str_ex(
|
||||
canvas, font_x_offset, font_y_offset, FONT_TEST_STR, FONT_TEST_STR_LENGTH, font);
|
||||
|
||||
const FONT_INFO* const font = available_fonts[scene_state->active_font];
|
||||
ui_control_select_render(
|
||||
canvas,
|
||||
0,
|
||||
74 - scene_state->y_offset,
|
||||
SCREEN_WIDTH,
|
||||
font->name,
|
||||
scene_state->selected_control == FontSelect);
|
||||
} else if(scene_state->selected_control < AutomationSwitch) {
|
||||
canvas_set_font(canvas, FontPrimary);
|
||||
canvas_draw_str_aligned(
|
||||
canvas, 0, 128 - scene_state->y_offset, AlignLeft, AlignTop, "Notifications");
|
||||
canvas_set_font(canvas, FontSecondary);
|
||||
|
||||
uint8_t font_x_offset =
|
||||
SCREEN_WIDTH_CENTER -
|
||||
(((font->charInfo[0].width + font->spacePixels) * FONT_TEST_STR_LENGTH) >> 1);
|
||||
uint8_t font_y_offset = 108 - scene_state->y_offset - (font->height >> 1);
|
||||
canvas_draw_str_ex(
|
||||
canvas, font_x_offset, font_y_offset, FONT_TEST_STR, FONT_TEST_STR_LENGTH, font);
|
||||
canvas_draw_str_aligned(
|
||||
canvas, 0, 145 - scene_state->y_offset, AlignLeft, AlignTop, "Sound:");
|
||||
ui_control_select_render(
|
||||
canvas,
|
||||
36,
|
||||
138 - scene_state->y_offset,
|
||||
SCREEN_WIDTH - 36 - UI_CONTROL_VSCROLL_WIDTH,
|
||||
YES_NO_LIST[scene_state->notification_sound],
|
||||
scene_state->selected_control == SoundSwitch);
|
||||
|
||||
canvas_draw_icon(
|
||||
canvas, SCREEN_WIDTH_CENTER - 5, 123 - scene_state->y_offset, &I_totp_arrow_bottom_10x5);
|
||||
canvas_draw_str_aligned(
|
||||
canvas, 0, 163 - scene_state->y_offset, AlignLeft, AlignTop, "Vibro:");
|
||||
ui_control_select_render(
|
||||
canvas,
|
||||
36,
|
||||
156 - scene_state->y_offset,
|
||||
SCREEN_WIDTH - 36 - UI_CONTROL_VSCROLL_WIDTH,
|
||||
YES_NO_LIST[scene_state->notification_vibro],
|
||||
scene_state->selected_control == VibroSwitch);
|
||||
} else {
|
||||
canvas_set_font(canvas, FontPrimary);
|
||||
canvas_draw_str_aligned(
|
||||
canvas, 0, 192 - scene_state->y_offset, AlignLeft, AlignTop, "Automation");
|
||||
canvas_set_font(canvas, FontSecondary);
|
||||
|
||||
canvas_set_font(canvas, FontPrimary);
|
||||
canvas_draw_str_aligned(
|
||||
canvas, 0, 128 - scene_state->y_offset, AlignLeft, AlignTop, "Notifications");
|
||||
canvas_set_font(canvas, FontSecondary);
|
||||
canvas_draw_str_aligned(
|
||||
canvas, 0, 209 - scene_state->y_offset, AlignLeft, AlignTop, "Method:");
|
||||
ui_control_select_render(
|
||||
canvas,
|
||||
36,
|
||||
202 - scene_state->y_offset,
|
||||
SCREEN_WIDTH - 36 - UI_CONTROL_VSCROLL_WIDTH,
|
||||
AUTOMATION_LIST[scene_state->automation_method],
|
||||
scene_state->selected_control == AutomationSwitch);
|
||||
|
||||
canvas_draw_str_aligned(canvas, 0, 145 - scene_state->y_offset, AlignLeft, AlignTop, "Sound:");
|
||||
ui_control_select_render(
|
||||
canvas,
|
||||
36,
|
||||
138 - scene_state->y_offset,
|
||||
SCREEN_WIDTH - 36,
|
||||
YES_NO_LIST[scene_state->notification_sound],
|
||||
scene_state->selected_control == SoundSwitch);
|
||||
canvas_draw_str_aligned(
|
||||
canvas, 0, 227 - scene_state->y_offset, AlignLeft, AlignTop, "Layout:");
|
||||
|
||||
canvas_draw_str_aligned(canvas, 0, 163 - scene_state->y_offset, AlignLeft, AlignTop, "Vibro:");
|
||||
ui_control_select_render(
|
||||
canvas,
|
||||
36,
|
||||
156 - scene_state->y_offset,
|
||||
SCREEN_WIDTH - 36,
|
||||
YES_NO_LIST[scene_state->notification_vibro],
|
||||
scene_state->selected_control == VibroSwitch);
|
||||
ui_control_select_render(
|
||||
canvas,
|
||||
36,
|
||||
220 - scene_state->y_offset,
|
||||
SCREEN_WIDTH - 36 - UI_CONTROL_VSCROLL_WIDTH,
|
||||
BAD_KB_LAYOUT_LIST[scene_state->automation_kb_layout],
|
||||
scene_state->selected_control == BadKeyboardLayoutSelect);
|
||||
|
||||
canvas_draw_icon(
|
||||
canvas, SCREEN_WIDTH_CENTER - 5, 187 - scene_state->y_offset, &I_totp_arrow_bottom_10x5);
|
||||
ui_control_button_render(
|
||||
canvas,
|
||||
SCREEN_WIDTH_CENTER - 24,
|
||||
242 - scene_state->y_offset,
|
||||
48,
|
||||
13,
|
||||
"Confirm",
|
||||
scene_state->selected_control == ConfirmButton);
|
||||
}
|
||||
|
||||
canvas_set_font(canvas, FontPrimary);
|
||||
canvas_draw_str_aligned(
|
||||
canvas, 0, 192 - scene_state->y_offset, AlignLeft, AlignTop, "Automation");
|
||||
canvas_set_font(canvas, FontSecondary);
|
||||
|
||||
canvas_draw_str_aligned(
|
||||
canvas, 0, 209 - scene_state->y_offset, AlignLeft, AlignTop, "BadUSB:");
|
||||
ui_control_select_render(
|
||||
canvas,
|
||||
36,
|
||||
202 - scene_state->y_offset,
|
||||
SCREEN_WIDTH - 36,
|
||||
ON_OFF_LIST[scene_state->badusb_enabled],
|
||||
scene_state->selected_control == BadUsbSwitch);
|
||||
|
||||
#ifdef TOTP_BADBT_TYPE_ENABLED
|
||||
canvas_draw_str_aligned(canvas, 0, 227 - scene_state->y_offset, AlignLeft, AlignTop, "BadBT:");
|
||||
ui_control_select_render(
|
||||
canvas,
|
||||
36,
|
||||
220 - scene_state->y_offset,
|
||||
SCREEN_WIDTH - 36,
|
||||
ON_OFF_LIST[scene_state->badbt_enabled],
|
||||
scene_state->selected_control == BadBtSwitch);
|
||||
#endif
|
||||
|
||||
ui_control_button_render(
|
||||
canvas,
|
||||
SCREEN_WIDTH_CENTER - 24,
|
||||
#ifdef TOTP_BADBT_TYPE_ENABLED
|
||||
242 - scene_state->y_offset,
|
||||
#else
|
||||
229 - scene_state->y_offset,
|
||||
#endif
|
||||
48,
|
||||
13,
|
||||
"Confirm",
|
||||
scene_state->selected_control == ConfirmButton);
|
||||
ui_control_vscroll_render(
|
||||
canvas, SCREEN_WIDTH - 3, 0, SCREEN_HEIGHT, scene_state->selected_control, ConfirmButton);
|
||||
}
|
||||
|
||||
bool totp_scene_app_settings_handle_event(
|
||||
@@ -268,14 +275,21 @@ bool totp_scene_app_settings_handle_event(
|
||||
scene_state->notification_sound = !scene_state->notification_sound;
|
||||
} else if(scene_state->selected_control == VibroSwitch) {
|
||||
scene_state->notification_vibro = !scene_state->notification_vibro;
|
||||
} else if(scene_state->selected_control == BadUsbSwitch) {
|
||||
scene_state->badusb_enabled = !scene_state->badusb_enabled;
|
||||
} else if(scene_state->selected_control == AutomationSwitch) {
|
||||
totp_roll_value_uint8_t(
|
||||
&scene_state->automation_method,
|
||||
1,
|
||||
0,
|
||||
AUTOMATION_LIST_MAX_INDEX,
|
||||
RollOverflowBehaviorRoll);
|
||||
} else if(scene_state->selected_control == BadKeyboardLayoutSelect) {
|
||||
totp_roll_value_uint8_t(
|
||||
&scene_state->automation_kb_layout,
|
||||
1,
|
||||
0,
|
||||
BAD_KB_LAYOUT_LIST_MAX_INDEX,
|
||||
RollOverflowBehaviorRoll);
|
||||
}
|
||||
#ifdef TOTP_BADBT_TYPE_ENABLED
|
||||
else if(scene_state->selected_control == BadBtSwitch) {
|
||||
scene_state->badbt_enabled = !scene_state->badbt_enabled;
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
case InputKeyLeft:
|
||||
if(scene_state->selected_control == HoursInput) {
|
||||
@@ -295,14 +309,21 @@ bool totp_scene_app_settings_handle_event(
|
||||
scene_state->notification_sound = !scene_state->notification_sound;
|
||||
} else if(scene_state->selected_control == VibroSwitch) {
|
||||
scene_state->notification_vibro = !scene_state->notification_vibro;
|
||||
} else if(scene_state->selected_control == BadUsbSwitch) {
|
||||
scene_state->badusb_enabled = !scene_state->badusb_enabled;
|
||||
} else if(scene_state->selected_control == AutomationSwitch) {
|
||||
totp_roll_value_uint8_t(
|
||||
&scene_state->automation_method,
|
||||
-1,
|
||||
0,
|
||||
AUTOMATION_LIST_MAX_INDEX,
|
||||
RollOverflowBehaviorRoll);
|
||||
} else if(scene_state->selected_control == BadKeyboardLayoutSelect) {
|
||||
totp_roll_value_uint8_t(
|
||||
&scene_state->automation_kb_layout,
|
||||
-1,
|
||||
0,
|
||||
BAD_KB_LAYOUT_LIST_MAX_INDEX,
|
||||
RollOverflowBehaviorRoll);
|
||||
}
|
||||
#ifdef TOTP_BADBT_TYPE_ENABLED
|
||||
else if(scene_state->selected_control == BadBtSwitch) {
|
||||
scene_state->badbt_enabled = !scene_state->badbt_enabled;
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
case InputKeyOk:
|
||||
break;
|
||||
@@ -323,22 +344,18 @@ bool totp_scene_app_settings_handle_event(
|
||||
(scene_state->notification_sound ? NotificationMethodSound : NotificationMethodNone) |
|
||||
(scene_state->notification_vibro ? NotificationMethodVibro : NotificationMethodNone);
|
||||
|
||||
plugin_state->automation_method = scene_state->badusb_enabled ? AutomationMethodBadUsb :
|
||||
AutomationMethodNone;
|
||||
#ifdef TOTP_BADBT_TYPE_ENABLED
|
||||
plugin_state->automation_method |= scene_state->badbt_enabled ? AutomationMethodBadBt :
|
||||
AutomationMethodNone;
|
||||
#endif
|
||||
|
||||
plugin_state->automation_method = scene_state->automation_method;
|
||||
plugin_state->active_font_index = scene_state->active_font;
|
||||
plugin_state->automation_kb_layout = scene_state->automation_kb_layout;
|
||||
|
||||
if(!totp_config_file_update_user_settings(plugin_state)) {
|
||||
totp_dialogs_config_updating_error(plugin_state);
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifdef TOTP_BADBT_TYPE_ENABLED
|
||||
if(!scene_state->badbt_enabled && plugin_state->bt_type_code_worker_context != NULL) {
|
||||
#ifdef TOTP_BADBT_AUTOMATION_ENABLED
|
||||
if((scene_state->automation_method & AutomationMethodBadBt) == 0 &&
|
||||
plugin_state->bt_type_code_worker_context != NULL) {
|
||||
totp_bt_type_code_worker_free(plugin_state->bt_type_code_worker_context);
|
||||
plugin_state->bt_type_code_worker_context = NULL;
|
||||
}
|
||||
|
||||
@@ -7,10 +7,10 @@
|
||||
#include "../../../services/config/config.h"
|
||||
#include "../../scene_director.h"
|
||||
#include "../../totp_scenes_enum.h"
|
||||
#include "../../../services/crypto/crypto.h"
|
||||
#include "../../../services/crypto/crypto_facade.h"
|
||||
#include "../../../types/user_pin_codes.h"
|
||||
|
||||
#define MAX_CODE_LENGTH TOTP_IV_SIZE
|
||||
#define MAX_CODE_LENGTH CRYPTO_IV_LENGTH
|
||||
static const uint8_t PIN_ASTERISK_RADIUS = 3;
|
||||
static const uint8_t PIN_ASTERISK_STEP = (PIN_ASTERISK_RADIUS << 1) + 2;
|
||||
|
||||
@@ -25,7 +25,7 @@ void totp_scene_authenticate_activate(PluginState* plugin_state) {
|
||||
scene_state->code_length = 0;
|
||||
memset(&scene_state->code_input[0], 0, MAX_CODE_LENGTH);
|
||||
plugin_state->current_scene_state = scene_state;
|
||||
memset(&plugin_state->iv[0], 0, TOTP_IV_SIZE);
|
||||
memset(&plugin_state->crypto_settings.iv[0], 0, CRYPTO_IV_LENGTH);
|
||||
}
|
||||
|
||||
void totp_scene_authenticate_render(Canvas* const canvas, PluginState* plugin_state) {
|
||||
@@ -36,7 +36,7 @@ void totp_scene_authenticate_render(Canvas* const canvas, PluginState* plugin_st
|
||||
v_shift = -10;
|
||||
}
|
||||
|
||||
if(plugin_state->crypto_verify_data == NULL) {
|
||||
if(plugin_state->crypto_settings.crypto_verify_data == NULL) {
|
||||
canvas_draw_str_aligned(
|
||||
canvas,
|
||||
SCREEN_WIDTH_CENTER,
|
||||
@@ -124,20 +124,22 @@ bool totp_scene_authenticate_handle_event(
|
||||
}
|
||||
} else if(event->input.type == InputTypeRelease && event->input.key == InputKeyOk) {
|
||||
CryptoSeedIVResult seed_result = totp_crypto_seed_iv(
|
||||
plugin_state, &scene_state->code_input[0], scene_state->code_length);
|
||||
&plugin_state->crypto_settings, &scene_state->code_input[0], scene_state->code_length);
|
||||
|
||||
if(seed_result & CryptoSeedIVResultFlagSuccess &&
|
||||
seed_result & CryptoSeedIVResultFlagNewCryptoVerifyData) {
|
||||
totp_config_file_update_crypto_signatures(plugin_state);
|
||||
}
|
||||
|
||||
if(totp_crypto_verify_key(plugin_state)) {
|
||||
if(totp_crypto_verify_key(&plugin_state->crypto_settings)) {
|
||||
FURI_LOG_D(LOGGING_TAG, "PIN is valid");
|
||||
totp_config_file_ensure_latest_encryption(
|
||||
plugin_state, &scene_state->code_input[0], scene_state->code_length);
|
||||
totp_scene_director_activate_scene(plugin_state, TotpSceneGenerateToken);
|
||||
} else {
|
||||
FURI_LOG_D(LOGGING_TAG, "PIN is NOT valid");
|
||||
memset(&scene_state->code_input[0], 0, MAX_CODE_LENGTH);
|
||||
memset(&plugin_state->iv[0], 0, TOTP_IV_SIZE);
|
||||
memset(&plugin_state->crypto_settings.iv[0], 0, CRYPTO_IV_LENGTH);
|
||||
scene_state->code_length = 0;
|
||||
|
||||
DialogMessage* message = dialog_message_alloc();
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
#include "../../../features_config.h"
|
||||
#include "../../../workers/generate_totp_code/generate_totp_code.h"
|
||||
#include "../../../workers/usb_type_code/usb_type_code.h"
|
||||
#ifdef TOTP_BADBT_TYPE_ENABLED
|
||||
#ifdef TOTP_BADBT_AUTOMATION_ENABLED
|
||||
#include "../../../workers/bt_type_code/bt_type_code.h"
|
||||
#endif
|
||||
|
||||
@@ -34,50 +34,40 @@ typedef struct {
|
||||
typedef struct {
|
||||
char last_code[TokenDigitsCountMax + 1];
|
||||
TotpUsbTypeCodeWorkerContext* usb_type_code_worker_context;
|
||||
NotificationMessage const** notification_sequence_new_token;
|
||||
NotificationMessage const** notification_sequence_automation;
|
||||
NotificationMessage const* notification_sequence_new_token[8];
|
||||
NotificationMessage const* notification_sequence_automation[11];
|
||||
FuriMutex* last_code_update_sync;
|
||||
TotpGenerateCodeWorkerContext* generate_code_worker_context;
|
||||
UiPrecalculatedDimensions ui_precalculated_dimensions;
|
||||
const FONT_INFO* active_font;
|
||||
NotificationApp* notification_app;
|
||||
} SceneState;
|
||||
|
||||
static const NotificationSequence*
|
||||
get_notification_sequence_new_token(const PluginState* plugin_state, SceneState* scene_state) {
|
||||
if(scene_state->notification_sequence_new_token == NULL) {
|
||||
uint8_t i = 0;
|
||||
uint8_t length = 4;
|
||||
if(scene_state->notification_sequence_new_token[0] == NULL) {
|
||||
NotificationMessage const** sequence = &scene_state->notification_sequence_new_token[0];
|
||||
*(sequence++) = &message_display_backlight_on;
|
||||
*(sequence++) = &message_green_255;
|
||||
if(plugin_state->notification_method & NotificationMethodVibro) {
|
||||
length += 2;
|
||||
*(sequence++) = &message_vibro_on;
|
||||
}
|
||||
|
||||
if(plugin_state->notification_method & NotificationMethodSound) {
|
||||
length += 2;
|
||||
*(sequence++) = &message_note_c5;
|
||||
}
|
||||
|
||||
scene_state->notification_sequence_new_token = malloc(sizeof(void*) * length);
|
||||
furi_check(scene_state->notification_sequence_new_token != NULL);
|
||||
scene_state->notification_sequence_new_token[i++] = &message_display_backlight_on;
|
||||
scene_state->notification_sequence_new_token[i++] = &message_green_255;
|
||||
*(sequence++) = &message_delay_50;
|
||||
|
||||
if(plugin_state->notification_method & NotificationMethodVibro) {
|
||||
scene_state->notification_sequence_new_token[i++] = &message_vibro_on;
|
||||
*(sequence++) = &message_vibro_off;
|
||||
}
|
||||
|
||||
if(plugin_state->notification_method & NotificationMethodSound) {
|
||||
scene_state->notification_sequence_new_token[i++] = &message_note_c5;
|
||||
*(sequence++) = &message_sound_off;
|
||||
}
|
||||
|
||||
scene_state->notification_sequence_new_token[i++] = &message_delay_50;
|
||||
|
||||
if(plugin_state->notification_method & NotificationMethodVibro) {
|
||||
scene_state->notification_sequence_new_token[i++] = &message_vibro_off;
|
||||
}
|
||||
|
||||
if(plugin_state->notification_method & NotificationMethodSound) {
|
||||
scene_state->notification_sequence_new_token[i++] = &message_sound_off;
|
||||
}
|
||||
|
||||
scene_state->notification_sequence_new_token[i++] = NULL;
|
||||
*(sequence++) = NULL;
|
||||
}
|
||||
|
||||
return (NotificationSequence*)scene_state->notification_sequence_new_token;
|
||||
@@ -85,44 +75,33 @@ static const NotificationSequence*
|
||||
|
||||
static const NotificationSequence*
|
||||
get_notification_sequence_automation(const PluginState* plugin_state, SceneState* scene_state) {
|
||||
if(scene_state->notification_sequence_automation == NULL) {
|
||||
uint8_t i = 0;
|
||||
uint8_t length = 3;
|
||||
if(scene_state->notification_sequence_automation[0] == NULL) {
|
||||
NotificationMessage const** sequence = &scene_state->notification_sequence_automation[0];
|
||||
|
||||
*(sequence++) = &message_blue_255;
|
||||
if(plugin_state->notification_method & NotificationMethodVibro) {
|
||||
length += 2;
|
||||
*(sequence++) = &message_vibro_on;
|
||||
}
|
||||
|
||||
if(plugin_state->notification_method & NotificationMethodSound) {
|
||||
length += 6;
|
||||
*(sequence++) = &message_note_d5; //-V525
|
||||
*(sequence++) = &message_delay_50;
|
||||
*(sequence++) = &message_note_e4;
|
||||
*(sequence++) = &message_delay_50;
|
||||
*(sequence++) = &message_note_f3;
|
||||
}
|
||||
|
||||
scene_state->notification_sequence_automation = malloc(sizeof(void*) * length);
|
||||
furi_check(scene_state->notification_sequence_automation != NULL);
|
||||
*(sequence++) = &message_delay_50;
|
||||
|
||||
scene_state->notification_sequence_automation[i++] = &message_blue_255;
|
||||
if(plugin_state->notification_method & NotificationMethodVibro) {
|
||||
scene_state->notification_sequence_automation[i++] = &message_vibro_on;
|
||||
*(sequence++) = &message_vibro_off;
|
||||
}
|
||||
|
||||
if(plugin_state->notification_method & NotificationMethodSound) {
|
||||
scene_state->notification_sequence_automation[i++] = &message_note_d5; //-V525
|
||||
scene_state->notification_sequence_automation[i++] = &message_delay_50;
|
||||
scene_state->notification_sequence_automation[i++] = &message_note_e4;
|
||||
scene_state->notification_sequence_automation[i++] = &message_delay_50;
|
||||
scene_state->notification_sequence_automation[i++] = &message_note_f3;
|
||||
*(sequence++) = &message_sound_off;
|
||||
}
|
||||
|
||||
scene_state->notification_sequence_automation[i++] = &message_delay_50;
|
||||
|
||||
if(plugin_state->notification_method & NotificationMethodVibro) {
|
||||
scene_state->notification_sequence_automation[i++] = &message_vibro_off;
|
||||
}
|
||||
|
||||
if(plugin_state->notification_method & NotificationMethodSound) {
|
||||
scene_state->notification_sequence_automation[i++] = &message_sound_off;
|
||||
}
|
||||
|
||||
scene_state->notification_sequence_automation[i++] = NULL;
|
||||
*(sequence++) = NULL;
|
||||
}
|
||||
|
||||
return (NotificationSequence*)scene_state->notification_sequence_automation;
|
||||
@@ -154,7 +133,7 @@ static void draw_totp_code(Canvas* const canvas, const PluginState* const plugin
|
||||
}
|
||||
|
||||
static void on_new_token_code_generated(bool time_left, void* context) {
|
||||
const PluginState* plugin_state = context;
|
||||
PluginState* const plugin_state = context;
|
||||
const TokenInfoIteratorContext* iterator_context =
|
||||
totp_config_get_token_iterator_context(plugin_state);
|
||||
if(totp_token_info_iterator_get_total_count(iterator_context) == 0) {
|
||||
@@ -175,13 +154,16 @@ static void on_new_token_code_generated(bool time_left, void* context) {
|
||||
|
||||
if(time_left) {
|
||||
notification_message(
|
||||
plugin_state->notification_app,
|
||||
get_notification_sequence_new_token(plugin_state, plugin_state->current_scene_state));
|
||||
scene_state->notification_app,
|
||||
get_notification_sequence_new_token(plugin_state, scene_state));
|
||||
}
|
||||
|
||||
totp_scene_director_force_redraw(plugin_state);
|
||||
}
|
||||
|
||||
static void on_code_lifetime_updated_generated(float code_lifetime_percent, void* context) {
|
||||
SceneState* scene_state = context;
|
||||
PluginState* const plugin_state = context;
|
||||
SceneState* scene_state = plugin_state->current_scene_state;
|
||||
scene_state->ui_precalculated_dimensions.progress_bar_width =
|
||||
(uint8_t)((float)(SCREEN_WIDTH - (PROGRESS_BAR_MARGIN << 1)) * code_lifetime_percent);
|
||||
scene_state->ui_precalculated_dimensions.progress_bar_x =
|
||||
@@ -189,6 +171,7 @@ static void on_code_lifetime_updated_generated(float code_lifetime_percent, void
|
||||
scene_state->ui_precalculated_dimensions.progress_bar_width) >>
|
||||
1) +
|
||||
PROGRESS_BAR_MARGIN;
|
||||
totp_scene_director_force_redraw(plugin_state);
|
||||
}
|
||||
|
||||
void totp_scene_generate_token_activate(PluginState* plugin_state) {
|
||||
@@ -201,12 +184,18 @@ void totp_scene_generate_token_activate(PluginState* plugin_state) {
|
||||
scene_state->last_code_update_sync = furi_mutex_alloc(FuriMutexTypeNormal);
|
||||
if(plugin_state->automation_method & AutomationMethodBadUsb) {
|
||||
scene_state->usb_type_code_worker_context = totp_usb_type_code_worker_start(
|
||||
scene_state->last_code, TokenDigitsCountMax + 1, scene_state->last_code_update_sync);
|
||||
scene_state->last_code,
|
||||
TokenDigitsCountMax + 1,
|
||||
scene_state->last_code_update_sync,
|
||||
plugin_state->automation_kb_layout);
|
||||
}
|
||||
|
||||
scene_state->active_font = available_fonts[plugin_state->active_font_index];
|
||||
scene_state->notification_app = furi_record_open(RECORD_NOTIFICATION);
|
||||
scene_state->notification_sequence_automation[0] = NULL;
|
||||
scene_state->notification_sequence_new_token[0] = NULL;
|
||||
|
||||
#ifdef TOTP_BADBT_TYPE_ENABLED
|
||||
#ifdef TOTP_BADBT_AUTOMATION_ENABLED
|
||||
|
||||
if(plugin_state->automation_method & AutomationMethodBadBt) {
|
||||
if(plugin_state->bt_type_code_worker_context == NULL) {
|
||||
@@ -216,7 +205,8 @@ void totp_scene_generate_token_activate(PluginState* plugin_state) {
|
||||
plugin_state->bt_type_code_worker_context,
|
||||
scene_state->last_code,
|
||||
TokenDigitsCountMax + 1,
|
||||
scene_state->last_code_update_sync);
|
||||
scene_state->last_code_update_sync,
|
||||
plugin_state->automation_kb_layout);
|
||||
}
|
||||
#endif
|
||||
const TokenInfoIteratorContext* iterator_context =
|
||||
@@ -226,7 +216,7 @@ void totp_scene_generate_token_activate(PluginState* plugin_state) {
|
||||
totp_token_info_iterator_get_current_token(iterator_context),
|
||||
scene_state->last_code_update_sync,
|
||||
plugin_state->timezone_offset,
|
||||
plugin_state->iv);
|
||||
&plugin_state->crypto_settings);
|
||||
|
||||
totp_generate_code_worker_set_code_generated_handler(
|
||||
scene_state->generate_code_worker_context, &on_new_token_code_generated, plugin_state);
|
||||
@@ -234,7 +224,7 @@ void totp_scene_generate_token_activate(PluginState* plugin_state) {
|
||||
totp_generate_code_worker_set_lifetime_changed_handler(
|
||||
scene_state->generate_code_worker_context,
|
||||
&on_code_lifetime_updated_generated,
|
||||
scene_state);
|
||||
plugin_state);
|
||||
|
||||
update_totp_params(
|
||||
plugin_state, totp_token_info_iterator_get_current_token_index(iterator_context));
|
||||
@@ -298,11 +288,10 @@ void totp_scene_generate_token_render(Canvas* const canvas, PluginState* plugin_
|
||||
canvas, SCREEN_WIDTH - 8, SCREEN_HEIGHT_CENTER - 24, &I_totp_arrow_right_8x9);
|
||||
}
|
||||
|
||||
#ifdef TOTP_AUTOMATION_ICONS_ENABLED
|
||||
if(plugin_state->automation_method & AutomationMethodBadUsb) {
|
||||
canvas_draw_icon(
|
||||
canvas,
|
||||
#ifdef TOTP_BADBT_TYPE_ENABLED
|
||||
#ifdef TOTP_BADBT_AUTOMATION_ENABLED
|
||||
SCREEN_WIDTH_CENTER -
|
||||
(plugin_state->automation_method & AutomationMethodBadBt ? 33 : 15),
|
||||
#else
|
||||
@@ -313,7 +302,7 @@ void totp_scene_generate_token_render(Canvas* const canvas, PluginState* plugin_
|
||||
&I_hid_usb_31x9);
|
||||
}
|
||||
|
||||
#ifdef TOTP_BADBT_TYPE_ENABLED
|
||||
#ifdef TOTP_BADBT_AUTOMATION_ENABLED
|
||||
if(plugin_state->automation_method & AutomationMethodBadBt &&
|
||||
plugin_state->bt_type_code_worker_context != NULL &&
|
||||
totp_bt_type_code_worker_is_advertising(plugin_state->bt_type_code_worker_context)) {
|
||||
@@ -325,7 +314,6 @@ void totp_scene_generate_token_render(Canvas* const canvas, PluginState* plugin_
|
||||
&I_hid_ble_31x9);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
bool totp_scene_generate_token_handle_event(
|
||||
@@ -351,11 +339,11 @@ bool totp_scene_generate_token_handle_event(
|
||||
TotpUsbTypeCodeWorkerEventType,
|
||||
totp_token_info_iterator_get_current_token(iterator_context)->automation_features);
|
||||
notification_message(
|
||||
plugin_state->notification_app,
|
||||
scene_state->notification_app,
|
||||
get_notification_sequence_automation(plugin_state, scene_state));
|
||||
return true;
|
||||
}
|
||||
#ifdef TOTP_BADBT_TYPE_ENABLED
|
||||
#ifdef TOTP_BADBT_AUTOMATION_ENABLED
|
||||
else if(
|
||||
event->input.key == InputKeyUp &&
|
||||
plugin_state->automation_method & AutomationMethodBadBt) {
|
||||
@@ -367,7 +355,7 @@ bool totp_scene_generate_token_handle_event(
|
||||
TotpBtTypeCodeWorkerEventType,
|
||||
totp_token_info_iterator_get_current_token(iterator_context)->automation_features);
|
||||
notification_message(
|
||||
plugin_state->notification_app,
|
||||
scene_state->notification_app,
|
||||
get_notification_sequence_automation(plugin_state, scene_state));
|
||||
return true;
|
||||
}
|
||||
@@ -428,23 +416,17 @@ void totp_scene_generate_token_deactivate(PluginState* plugin_state) {
|
||||
|
||||
totp_generate_code_worker_stop(scene_state->generate_code_worker_context);
|
||||
|
||||
furi_record_close(RECORD_NOTIFICATION);
|
||||
|
||||
if(plugin_state->automation_method & AutomationMethodBadUsb) {
|
||||
totp_usb_type_code_worker_stop(scene_state->usb_type_code_worker_context);
|
||||
}
|
||||
#ifdef TOTP_BADBT_TYPE_ENABLED
|
||||
#ifdef TOTP_BADBT_AUTOMATION_ENABLED
|
||||
if(plugin_state->automation_method & AutomationMethodBadBt) {
|
||||
totp_bt_type_code_worker_stop(plugin_state->bt_type_code_worker_context);
|
||||
}
|
||||
#endif
|
||||
|
||||
if(scene_state->notification_sequence_new_token != NULL) {
|
||||
free(scene_state->notification_sequence_new_token);
|
||||
}
|
||||
|
||||
if(scene_state->notification_sequence_automation != NULL) {
|
||||
free(scene_state->notification_sequence_automation);
|
||||
}
|
||||
|
||||
furi_mutex_free(scene_state->last_code_update_sync);
|
||||
|
||||
free(scene_state);
|
||||
|
||||
24
applications/external/totp/ui/ui_controls.c
vendored
24
applications/external/totp/ui/ui_controls.c
vendored
@@ -113,3 +113,27 @@ void ui_control_button_render(
|
||||
canvas_set_color(canvas, ColorBlack);
|
||||
}
|
||||
}
|
||||
|
||||
void ui_control_vscroll_render(
|
||||
Canvas* const canvas,
|
||||
uint8_t x,
|
||||
uint8_t y,
|
||||
uint8_t height,
|
||||
uint8_t position,
|
||||
uint8_t max_position) {
|
||||
canvas_draw_line(canvas, x, y, x, y + height);
|
||||
uint8_t block_height = height / MIN(10, max_position);
|
||||
uint8_t block_position_y =
|
||||
height * ((float)position / (float)max_position) - (block_height >> 1);
|
||||
uint8_t block_position_y_abs = y + block_position_y;
|
||||
if(block_position_y_abs + block_height > height) {
|
||||
block_position_y_abs = height - block_height;
|
||||
}
|
||||
|
||||
canvas_draw_box(
|
||||
canvas,
|
||||
x - (UI_CONTROL_VSCROLL_WIDTH >> 1),
|
||||
block_position_y_abs,
|
||||
UI_CONTROL_VSCROLL_WIDTH,
|
||||
block_height);
|
||||
}
|
||||
|
||||
19
applications/external/totp/ui/ui_controls.h
vendored
19
applications/external/totp/ui/ui_controls.h
vendored
@@ -3,6 +3,8 @@
|
||||
#include <inttypes.h>
|
||||
#include <gui/gui.h>
|
||||
|
||||
#define UI_CONTROL_VSCROLL_WIDTH (3)
|
||||
|
||||
/**
|
||||
* @brief Renders TextBox control
|
||||
* @param canvas canvas to render control at
|
||||
@@ -51,3 +53,20 @@ void ui_control_select_render(
|
||||
uint8_t width,
|
||||
const char* text,
|
||||
bool is_selected);
|
||||
|
||||
/**
|
||||
* @brief Renders vertical scroll bar
|
||||
* @param canvas canvas to render control at
|
||||
* @param x horizontal position of a control to be rendered at
|
||||
* @param y vertical position of a control to be rendered at
|
||||
* @param height control height
|
||||
* @param position current position
|
||||
* @param max_position maximal position
|
||||
*/
|
||||
void ui_control_vscroll_render(
|
||||
Canvas* const canvas,
|
||||
uint8_t x,
|
||||
uint8_t y,
|
||||
uint8_t height,
|
||||
uint8_t position,
|
||||
uint8_t max_position);
|
||||
|
||||
Reference in New Issue
Block a user