diff --git a/apps/evm_family/evm_sign_msg.c b/apps/evm_family/evm_sign_msg.c index c1786d7a4..208926f62 100644 --- a/apps/evm_family/evm_sign_msg.c +++ b/apps/evm_family/evm_sign_msg.c @@ -343,52 +343,82 @@ static bool get_msg_data(evm_query_t *query) { return true; } -static bool get_user_verification() { +bool get_eth_sign_user_verification(const uint8_t *msg_data, + size_t total_msg_size) { + bool result = false; + const size_t array_size = total_msg_size * 2 + 3; + char *buffer = malloc(array_size); + memzero(buffer, array_size); + snprintf(buffer, array_size, "0x"); + byte_array_to_hex_string( + msg_data, total_msg_size, buffer + 2, array_size - 2); + // TODO: Add a limit on size of data per confirmation based on LVGL buffer + // and split message into multiple confirmations accordingly + result = core_scroll_page( + UI_TEXT_VERIFY_MESSAGE, (const char *)buffer, evm_send_error); + memzero(buffer, array_size); + free(buffer); + return result; +} + +bool get_typed_data_user_verification( + evm_sign_typed_data_struct_t *typed_data) { + bool result = true; + ui_display_node *display_node = NULL; + evm_init_typed_data_display_node(&display_node, typed_data); + while (NULL != display_node) { + result = core_scroll_page( + display_node->title, display_node->value, evm_send_error); + display_node = display_node->next; + + if (!result) { + break; + } + } + return result; +} +bool display_message_and_get_user_verification( + evm_sign_msg_context_t *sign_msg_ctx) { bool result = false; - switch (sign_msg_ctx.init.message_type) { + switch (sign_msg_ctx->init.message_type) { case EVM_SIGN_MSG_TYPE_ETH_SIGN: { - const size_t array_size = sign_msg_ctx.init.total_msg_size * 2 + 3; - char *buffer = malloc(array_size); - memzero(buffer, array_size); - snprintf(buffer, array_size, "0x"); - byte_array_to_hex_string(sign_msg_ctx.msg_data, - sign_msg_ctx.init.total_msg_size, - buffer + 2, - array_size - 2); - // TODO: Add a limit on size of data per confirmation based on LVGL buffer - // and split message into multiple confirmations accordingly - result = core_scroll_page( - UI_TEXT_VERIFY_MESSAGE, (const char *)buffer, evm_send_error); - memzero(buffer, array_size); - free(buffer); + result = get_eth_sign_user_verification( + sign_msg_ctx->msg_data, sign_msg_ctx->init.total_msg_size); } break; case EVM_SIGN_MSG_TYPE_PERSONAL_SIGN: { // TODO: Add a limit on size of data per confirmation based on LVGL buffer // and split message into multiple confirmations accordingly result = core_scroll_page(UI_TEXT_VERIFY_MESSAGE, - (const char *)sign_msg_ctx.msg_data, + (const char *)sign_msg_ctx->msg_data, evm_send_error); } break; case EVM_SIGN_MSG_TYPE_SIGN_TYPED_DATA: { - ui_display_node *display_node = NULL; - evm_init_typed_data_display_node(&display_node, - &(sign_msg_ctx.typed_data)); - while (NULL != display_node) { - result = core_scroll_page( - display_node->title, display_node->value, evm_send_error); - display_node = display_node->next; - - if (!result) { - break; - } - } + result = get_typed_data_user_verification(&(sign_msg_ctx->typed_data)); } break; default: break; } + return result; +} + +static bool get_user_verification() { + bool result = false; + skip_choice_confirmation_scr_init("Proceed to view message or skip"); + + evt_status_t status = get_events(EVENT_CONFIG_UI, MAX_INACTIVITY_TIMEOUT); + if (status.p0_event.flag) + return result; + if (status.ui_event.event_occured && + (UI_EVENT_REJECT == status.ui_event.event_type)) { + delay_scr_init("Message verification skipped", DELAY_TIME); + delay_scr_init("Proceed on your own risk", DELAY_TIME); + result = true; + } else { + result = display_message_and_get_user_verification(&sign_msg_ctx); + } if (result) { set_app_flow_status(EVM_SIGN_MSG_STATUS_VERIFY); diff --git a/common/interfaces/user_interface/ui_common.c b/common/interfaces/user_interface/ui_common.c index 321247bf6..5fed4e8fb 100644 --- a/common/interfaces/user_interface/ui_common.c +++ b/common/interfaces/user_interface/ui_common.c @@ -287,6 +287,23 @@ void ui_skip_btn(lv_obj_t *skip_btn, lv_btn_set_style(skip_btn, LV_BTN_STYLE_REL, &ui->btn_rel); } +void ui_show_btn(lv_obj_t *show_btn, + const lv_event_cb_t event_cb, + const bool hidden) { + ASSERT(show_btn != NULL); + + lv_obj_set_size(show_btn, 46, LV_DPI / 5 - 5); + lv_obj_align(show_btn, NULL, LV_ALIGN_IN_BOTTOM_LEFT, 3, 0); + lv_obj_set_event_cb(show_btn, event_cb); + + lv_obj_t *label = lv_label_create(show_btn, NULL); + lv_label_set_text(label, "Show " LV_SYMBOL_DOWN); + lv_obj_set_hidden(show_btn, hidden); + lv_group_add_obj(ui->g, show_btn); + + lv_btn_set_style(show_btn, LV_BTN_STYLE_REL, &ui->btn_rel); +} + void ui_backspace(lv_obj_t *backspace, const lv_event_cb_t event_cb) { ASSERT(backspace != NULL); diff --git a/common/interfaces/user_interface/ui_common.h b/common/interfaces/user_interface/ui_common.h index e33b54714..59f7ea710 100644 --- a/common/interfaces/user_interface/ui_common.h +++ b/common/interfaces/user_interface/ui_common.h @@ -217,6 +217,24 @@ void ui_next_btn(lv_obj_t *next_btn, lv_event_cb_t event_cb, bool hidden); */ void ui_skip_btn(lv_obj_t *skip_btn, lv_event_cb_t event_cb, bool hidden); +/** + * @brief Create UI for skip button + * @details + * + * @param show_btn Lvgl object for skip button + * @param event_cb Event callback fot skip button + * @param hidden Is the skip button hidden + * + * @return + * @retval + * + * @see + * @since v1.0.0 + * + * @note + */ +void ui_show_btn(lv_obj_t *show_btn, lv_event_cb_t event_cb, bool hidden); + /** * @brief UI for backspace button * @details diff --git a/common/interfaces/user_interface/ui_skip_instruction.c b/common/interfaces/user_interface/ui_skip_instruction.c index 52e7c6df4..f163c4270 100644 --- a/common/interfaces/user_interface/ui_skip_instruction.c +++ b/common/interfaces/user_interface/ui_skip_instruction.c @@ -61,27 +61,43 @@ #include "nfc.h" #include "ui_events_priv.h" -static struct Card_Detect_Data *data = NULL; -static struct Card_Detect_Object *obj = NULL; +static struct Skip_instruction_data *data = NULL; +static struct Skip_instruction_object *obj = NULL; static void skip_instruction_scr_create(); -void skip_instruction_scr_init(const char *text) { +void skip_only_instruction_scr_init(const char *text) { ASSERT(text != NULL); lv_obj_clean(lv_scr_act()); - data = malloc(sizeof(struct Card_Detect_Data)); - obj = malloc(sizeof(struct Card_Detect_Object)); + data = malloc(sizeof(struct Skip_instruction_data)); + obj = malloc(sizeof(struct Skip_instruction_object)); if (data != NULL) { data->text = (char *)text; + data->display_show_option = false; + } + skip_instruction_scr_create(); +} + +void skip_choice_confirmation_scr_init(const char *text) { + ASSERT(text != NULL); + + lv_obj_clean(lv_scr_act()); + + data = malloc(sizeof(struct Skip_instruction_data)); + obj = malloc(sizeof(struct Skip_instruction_object)); + + if (data != NULL) { + data->text = (char *)text; + data->display_show_option = true; } skip_instruction_scr_create(); } void skip_instruction_scr_destructor() { if (data != NULL) { - memzero(data, sizeof(struct Card_Detect_Data)); + memzero(data, sizeof(struct Skip_instruction_data)); free(data); data = NULL; } @@ -92,27 +108,46 @@ void skip_instruction_scr_destructor() { } } -void skip_instruction_scr_focus_skip() { - lv_group_focus_obj(obj->skip_btn); +static void show_btn_event_handler(lv_obj_t *show_btn, const lv_event_t event) { + switch (event) { + case LV_EVENT_KEY: + switch (lv_indev_get_key(ui_get_indev())) { + case LV_KEY_RIGHT: + lv_group_focus_obj(obj->skip_btn); + break; + default: + break; + } + break; + case LV_EVENT_CLICKED: + ui_set_confirm_event(); + break; + case LV_EVENT_DEFOCUSED: + lv_btn_set_state(show_btn, LV_BTN_STATE_REL); + break; + case LV_EVENT_DELETE: + /* Destruct object and data variables in case the object is being deleted + * directly using lv_obj_clean() */ + skip_instruction_scr_destructor(); + break; + default: + break; + } } -/** - * @brief Skip button event handler. - * @details - * - * @param skip_btn Skip button lvgl object. - * @param event Type of event. - * - * @return - * @retval - * - * @see - * @since v1.0.0 - * - * @note - */ static void skip_btn_event_handler(lv_obj_t *skip_btn, const lv_event_t event) { switch (event) { + case LV_EVENT_KEY: + switch (lv_indev_get_key(ui_get_indev())) { + case LV_KEY_LEFT: + if (data->display_show_option) { + lv_group_focus_obj(obj->show_btn); + } + break; + default: + break; + } + break; case LV_EVENT_CLICKED: ui_set_cancel_event(); break; @@ -129,20 +164,6 @@ static void skip_btn_event_handler(lv_obj_t *skip_btn, const lv_event_t event) { } } -/** - * @brief Create card detect screen - * @details - * - * @param - * - * @return - * @retval - * - * @see - * @since v1.0.0 - * - * @note - */ void skip_instruction_scr_create() { ASSERT(obj != NULL); ASSERT(data != NULL); @@ -152,5 +173,10 @@ void skip_instruction_scr_create() { ui_paragraph(obj->text, data->text, LV_LABEL_ALIGN_CENTER); ui_skip_btn(obj->skip_btn, skip_btn_event_handler, false); - skip_instruction_scr_focus_skip(); + + if (data->display_show_option) { + obj->show_btn = lv_btn_create(lv_scr_act(), NULL); + ui_show_btn(obj->show_btn, show_btn_event_handler, false); + } + lv_group_focus_obj(obj->show_btn); } \ No newline at end of file diff --git a/common/interfaces/user_interface/ui_skip_instruction.h b/common/interfaces/user_interface/ui_skip_instruction.h index 96d7fa9e6..60ce45146 100644 --- a/common/interfaces/user_interface/ui_skip_instruction.h +++ b/common/interfaces/user_interface/ui_skip_instruction.h @@ -22,8 +22,9 @@ * * @note */ -struct Card_Detect_Data { +struct Skip_instruction_data { char *text; + bool display_show_option; }; /** @@ -35,9 +36,10 @@ struct Card_Detect_Data { * * @note */ -struct Card_Detect_Object { +struct Skip_instruction_object { lv_obj_t *text; lv_obj_t *skip_btn; + lv_obj_t *show_btn; }; /** @@ -54,7 +56,23 @@ struct Card_Detect_Object { * * @note */ -void skip_instruction_scr_init(const char *text); +void skip_only_instruction_scr_init(const char *text); + +/** + * @brief Initialize and create card detect screen + * @details + * + * @param text card detect text + * + * @return + * @retval + * + * @see + * @since v1.0.0 + * + * @note + */ +void skip_choice_confirmation_scr_init(const char *text); /** * @brief Clear card detect screen diff --git a/src/card_flows/card_flow_pairing.c b/src/card_flows/card_flow_pairing.c index c59fde9c1..de0c9d953 100644 --- a/src/card_flows/card_flow_pairing.c +++ b/src/card_flows/card_flow_pairing.c @@ -109,7 +109,7 @@ bool card_flow_pairing(uint8_t *cards_paired) { } snprintf(display, sizeof(display), UI_TEXT_PAIRING_TAP_CARD, card_number); - skip_instruction_scr_init(display); + skip_only_instruction_scr_init(display); // Enable task to select NFC card nfc_en_select_card_task();