Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Release API LEVEL 18 v18.3.0 #629

Merged
merged 9 commits into from
Apr 23, 2024
2 changes: 1 addition & 1 deletion Makefile.rules
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
ifeq ($(USE_NBGL),0)
SDK_SOURCE_PATH += lib_bagl lib_ux
else
SDK_SOURCE_PATH += lib_nbgl lib_ux_nbgl
SDK_SOURCE_PATH += lib_nbgl lib_ux_nbgl lib_ux_sync
endif

define uniq =
Expand Down
8 changes: 8 additions & 0 deletions lib_nbgl/include/nbgl_use_case.h
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,14 @@ void nbgl_useCaseReview(nbgl_operationType_t operationType,
const char *finishTitle,
nbgl_choiceCallback_t choiceCallback);

void nbgl_useCaseReviewLight(nbgl_operationType_t operationType,
const nbgl_layoutTagValueList_t *tagValueList,
const nbgl_icon_details_t *icon,
const char *reviewTitle,
const char *reviewSubTitle,
const char *finishTitle,
nbgl_choiceCallback_t choiceCallback);

void nbgl_useCaseAddressReview(const char *address,
const nbgl_layoutTagValueList_t *additionalTagValueList,
const nbgl_icon_details_t *icon,
Expand Down
8 changes: 2 additions & 6 deletions lib_nbgl/src/nbgl_layout.c
Original file line number Diff line number Diff line change
Expand Up @@ -203,9 +203,8 @@ static void touchCallback(nbgl_obj_t *obj, nbgl_touchType_t eventType)
|| (eventType == SWIPED_RIGHT))
&& (obj->type == CONTAINER)) {
#if (!defined(TARGET_STAX) && defined(NBGL_KEYBOARD))
if ((layout->swipeUsage == SWIPE_USAGE_SUGGESTIONS)
&& keyboardSwipeCallback(obj, eventType)) {
// if this swipe event is consumed, return here
if (layout->swipeUsage == SWIPE_USAGE_SUGGESTIONS) {
keyboardSwipeCallback(obj, eventType);
return;
}
#endif // TARGET_STAX
Expand Down Expand Up @@ -728,9 +727,6 @@ nbgl_layout_t *nbgl_layoutGet(const nbgl_layoutDescription_t *description)
memset(layout, 0, sizeof(nbgl_layoutInternal_t));

nbTouchableControls = 0;
#ifdef NBGL_KEYBOARD
keyboardInit();
#endif // NBGL_KEYBOARD

layout->callback = (nbgl_layoutTouchCallback_t) PIC(description->onActionCallback);
layout->modal = description->modal;
Expand Down
1 change: 0 additions & 1 deletion lib_nbgl/src/nbgl_layout_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,6 @@ typedef struct nbgl_layoutInternal_s {
/**********************
* GLOBAL PROTOTYPES
**********************/
void keyboardInit(void);
bool keyboardSwipeCallback(nbgl_obj_t *obj, nbgl_touchType_t eventType);
void layoutAddObject(nbgl_layoutInternal_t *layout, nbgl_obj_t *obj);
layoutObj_t *layoutAddCallbackObj(nbgl_layoutInternal_t *layout,
Expand Down
19 changes: 9 additions & 10 deletions lib_nbgl/src/nbgl_layout_keyboard.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,9 @@ enum {
PAGE_INDICATOR_INDEX = 0,
LEFT_HALF_INDEX, // half disc displayed on the bottom left
RIGHT_HALF_INDEX, // half disc displayed on the bottom right
FIRST_BUTTON_INDEX
FIRST_BUTTON_INDEX,
SECOND_BUTTON_INDEX,
NB_SUGGESTION_CHILDREN
};
#endif // TARGET_STAX

Expand Down Expand Up @@ -140,11 +142,6 @@ static bool updateSuggestionButtons(nbgl_container_t *container,
* GLOBAL INTERNAL FUNCTIONS
**********************/

void keyboardInit(void)
{
nbActiveButtons = 0;
}

#ifdef TARGET_FLEX
bool keyboardSwipeCallback(nbgl_obj_t *obj, nbgl_touchType_t eventType)
{
Expand All @@ -170,6 +167,7 @@ bool keyboardSwipeCallback(nbgl_obj_t *obj, nbgl_touchType_t eventType)

if (i < (uint32_t) nbActiveButtons) {
if (updateSuggestionButtons(suggestionsContainer, eventType, i)) {
io_seproxyhal_play_tune(TUNE_TAP_CASUAL);
nbgl_redrawObject((nbgl_obj_t *) suggestionsContainer, NULL, false);
nbgl_refreshSpecial(FULL_COLOR_PARTIAL_REFRESH);
}
Expand Down Expand Up @@ -322,16 +320,17 @@ static nbgl_container_t *addSuggestionButtons(nbgl_layoutInternal_t *layoutInt,
suggestionsContainer->obj.area.height = SMALL_BUTTON_HEIGHT + 28;
// on Flex, the first child is used by the progress indicator, if more that 2 buttons
suggestionsContainer->nbChildren = nbActiveButtons + FIRST_BUTTON_INDEX;
suggestionsContainer->children = (nbgl_obj_t **) nbgl_containerPoolGet(
NB_MAX_VISIBLE_SUGGESTION_BUTTONS + 1, layoutInt->layer);
suggestionsContainer->children
= (nbgl_obj_t **) nbgl_containerPoolGet(NB_SUGGESTION_CHILDREN, layoutInt->layer);

#endif // TARGET_STAX
// put suggestionsContainer at 24px of the bottom of main container
suggestionsContainer->obj.alignmentMarginY = compactMode ? 12 : 24;
suggestionsContainer->obj.alignment = BOTTOM_MIDDLE;

// create all possible suggestion buttons, even if not displayed at first
nbgl_objPoolGetArray(BUTTON, NB_MAX_SUGGESTION_BUTTONS, 0, (nbgl_obj_t **) &choiceButtons);
nbgl_objPoolGetArray(
BUTTON, NB_MAX_SUGGESTION_BUTTONS, layoutInt->layer, (nbgl_obj_t **) &choiceButtons);
for (int i = 0; i < NB_MAX_SUGGESTION_BUTTONS; i++) {
obj = layoutAddCallbackObj(
layoutInt, (nbgl_obj_t *) choiceButtons[i], firstButtonToken + i, tuneId);
Expand Down Expand Up @@ -388,7 +387,7 @@ static nbgl_container_t *addSuggestionButtons(nbgl_layoutInternal_t *layoutInt,
suggestionsContainer->children[PAGE_INDICATOR_INDEX] = (nbgl_obj_t *) indicator;
// also allocate the semi disc that may be displayed on the left or right of the full
// buttons
nbgl_objPoolGetArray(IMAGE, 2, 0, (nbgl_obj_t **) &partialButtonImages);
nbgl_objPoolGetArray(IMAGE, 2, layoutInt->layer, (nbgl_obj_t **) &partialButtonImages);
partialButtonImages[0]->buffer = &C_left_half_64px;
partialButtonImages[0]->obj.alignment = TOP_LEFT;
partialButtonImages[0]->foregroundColor = BLACK;
Expand Down
4 changes: 2 additions & 2 deletions lib_nbgl/src/nbgl_layout_keypad.c
Original file line number Diff line number Diff line change
Expand Up @@ -515,12 +515,12 @@ int nbgl_layoutUpdateKeypadContent(nbgl_layout_t *layout,
if (nbActiveDigits == container->nbChildren) {
return 0;
}
// deactivate the next digit
// deactivate the next digit by turning it to white
image = (nbgl_image_t *) container->children[nbActiveDigits];
image->foregroundColor = WHITE;
}
else {
image->buffer = &DIGIT_ICON;
// activate it the last digit by turning it to black
image->foregroundColor = BLACK;
}
}
Expand Down
35 changes: 12 additions & 23 deletions lib_nbgl/src/nbgl_page.c
Original file line number Diff line number Diff line change
Expand Up @@ -105,29 +105,18 @@ static void addContent(nbgl_pageContent_t *content,
= {.type = HEADER_EMPTY, .separationLine = false, .emptySpace.height = 40};
nbgl_layoutAddHeader(layout, &headerDesc);
}
uint16_t nbLines = nbgl_getTextNbLinesInWidth(
content->tagValueDetails.tagValueList.smallCaseForValue ? SMALL_BOLD_FONT
: LARGE_MEDIUM_FONT,
content->tagValueDetails.tagValueList.pairs[0].value,
SCREEN_WIDTH - 2 * BORDER_MARGIN,
content->tagValueDetails.tagValueList.wrapping);
// automatically display a button if content is longer that nbMaxLinesForValue
if (nbLines > (content->tagValueDetails.tagValueList.nbMaxLinesForValue)) {
nbgl_layoutButton_t buttonInfo;
content->tagValueDetails.tagValueList.nbMaxLinesForValue -= 3;
nbgl_layoutAddTagValueList(layout, &content->tagValueDetails.tagValueList);
buttonInfo.fittingContent = true;
buttonInfo.icon = content->tagValueDetails.detailsButtonIcon;
buttonInfo.style = WHITE_BACKGROUND;
buttonInfo.text = content->tagValueDetails.detailsButtonText;
buttonInfo.token = content->tagValueDetails.detailsButtonToken;
buttonInfo.tuneId = content->tagValueDetails.tuneId;
buttonInfo.onBottom = false;
nbgl_layoutAddButton(layout, &buttonInfo);
}
else {
nbgl_layoutAddTagValueList(layout, &content->tagValueDetails.tagValueList);
}
// display a button under tag/value
nbgl_layoutButton_t buttonInfo;
content->tagValueDetails.tagValueList.nbMaxLinesForValue -= 3;
nbgl_layoutAddTagValueList(layout, &content->tagValueDetails.tagValueList);
buttonInfo.fittingContent = true;
buttonInfo.icon = content->tagValueDetails.detailsButtonIcon;
buttonInfo.style = WHITE_BACKGROUND;
buttonInfo.text = content->tagValueDetails.detailsButtonText;
buttonInfo.token = content->tagValueDetails.detailsButtonToken;
buttonInfo.tuneId = content->tagValueDetails.tuneId;
buttonInfo.onBottom = false;
nbgl_layoutAddButton(layout, &buttonInfo);
break;
}
case TAG_VALUE_CONFIRM: {
Expand Down
67 changes: 67 additions & 0 deletions lib_nbgl/src/nbgl_use_case.c
Original file line number Diff line number Diff line change
Expand Up @@ -368,6 +368,16 @@ static void prepareReviewLastPage(nbgl_contentInfoLongPress_t *infoLongPress,
infoLongPress->longPressToken = CONFIRM_TOKEN;
}

static void prepareReviewLightLastPage(nbgl_contentInfoButton_t *infoButton,
const nbgl_icon_details_t *icon,
const char *finishTitle)
{
infoButton->text = finishTitle;
infoButton->icon = icon;
infoButton->buttonText = "Approve";
infoButton->buttonToken = CONFIRM_TOKEN;
}

static const char *getRejectReviewText(nbgl_operationType_t operationType)
{
#ifdef TARGET_STAX
Expand Down Expand Up @@ -2397,6 +2407,63 @@ void nbgl_useCaseReview(nbgl_operationType_t operationType,
displayGenericContextPage(0, true);
}

/**
* @brief Draws a flow of pages of a light review. A back key is available on top-left of the
* screen, except in first page It is possible to go to next page thanks to "tap to continue".
* @note All tag/value pairs are provided in the API and the number of pages is automatically
* computed, the last page being a short press one
*
* @param operationType type of operation (Operation, Transaction, Message)
* @param tagValueList list of tag/value pairs
* @param icon icon used on first and last review page
* @param reviewTitle string used in the first review page
* @param reviewSubTitle string to set under reviewTitle (can be NULL)
* @param finishTitle string used in the last review page
* @param choiceCallback callback called when operation is accepted (param is true) or rejected
* (param is false)
*/
void nbgl_useCaseReviewLight(nbgl_operationType_t operationType,
const nbgl_layoutTagValueList_t *tagValueList,
const nbgl_icon_details_t *icon,
const char *reviewTitle,
const char *reviewSubTitle,
const char *finishTitle,
nbgl_choiceCallback_t choiceCallback)
{
reset_callbacks();
memset(&genericContext, 0, sizeof(genericContext));

// memorize context
onChoice = choiceCallback;
navType = GENERIC_NAV;
pageTitle = NULL;

genericContext.genericContents.contentsList = localContentsList;
genericContext.genericContents.nbContents = 3;
memset(localContentsList, 0, 3 * sizeof(nbgl_content_t));

// First a centered info
localContentsList[0].type = CENTERED_INFO;
prepareReviewFirstPage(
&localContentsList[0].content.centeredInfo, icon, reviewTitle, reviewSubTitle);

// Then the tag/value pairs
localContentsList[1].type = TAG_VALUE_LIST;
memcpy(&localContentsList[1].content.tagValueList,
tagValueList,
sizeof(nbgl_layoutTagValueList_t));

// Eventually the long press page
localContentsList[2].type = INFO_BUTTON;
prepareReviewLightLastPage(&localContentsList[2].content.infoButton, icon, finishTitle);

// compute number of pages & fill navigation structure
uint8_t nbPages = nbgl_useCaseGetNbPagesForGenericContents(&genericContext.genericContents, 0);
prepareNavInfo(true, nbPages, getRejectReviewText(operationType));

displayGenericContextPage(0, true);
}

/**
* @brief Draws a flow of pages of a review with automatic pagination depending on content
* to be displayed that is passed through contents.
Expand Down
17 changes: 17 additions & 0 deletions lib_standard_app/io.c
Original file line number Diff line number Diff line change
Expand Up @@ -218,3 +218,20 @@ WEAK int io_send_response_buffers(const buffer_t *rdatalist, size_t count, uint1

return ret;
}

#ifdef STANDARD_APP_SYNC_RAPDU
WEAK bool io_recv_and_process_event(void)
{
int apdu_state = G_io_app.apdu_state;

os_io_seph_recv_and_process(0);

// If an APDU was received in previous os_io_seph_recv_and_process call and
// is waiting to be processed, return true
if (apdu_state == APDU_IDLE && G_io_app.apdu_state != APDU_IDLE) {
return true;
}

return false;
}
#endif
71 changes: 71 additions & 0 deletions lib_ux_sync/include/ux_sync.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
#ifdef HAVE_NBGL

#include "nbgl_use_case.h"

typedef enum {
UX_SYNC_RET_APPROVED,
UX_SYNC_RET_REJECTED,
UX_SYNC_RET_QUITTED,
UX_SYNC_RET_APDU_RECEIVED,
UX_SYNC_RET_ERROR
} ux_sync_ret_t;

ux_sync_ret_t ux_sync_homeAndSettings(const char *appName,
const nbgl_icon_details_t *appIcon,
const char *tagline,
const uint8_t initSettingPage,
const nbgl_genericContents_t *settingContents,
const nbgl_contentInfoList_t *infosList,
const nbgl_homeAction_t *action);

ux_sync_ret_t ux_sync_review(nbgl_operationType_t operationType,
const nbgl_layoutTagValueList_t *tagValueList,
const nbgl_icon_details_t *icon,
const char *reviewTitle,
const char *reviewSubTitle,
const char *finishTitle);

ux_sync_ret_t ux_sync_reviewLight(nbgl_operationType_t operationType,
const nbgl_layoutTagValueList_t *tagValueList,
const nbgl_icon_details_t *icon,
const char *reviewTitle,
const char *reviewSubTitle,
const char *finishTitle);

ux_sync_ret_t ux_sync_addressReview(const char *address,
const nbgl_layoutTagValueList_t *additionalTagValueList,
const nbgl_icon_details_t *icon,
const char *reviewTitle,
const char *reviewSubTitle);

ux_sync_ret_t ux_sync_reviewStatus(nbgl_reviewStatusType_t reviewStatusType);

ux_sync_ret_t ux_sync_status(const char *message, bool isSuccess);

ux_sync_ret_t ux_sync_reviewStreamingStart(nbgl_operationType_t operationType,
const nbgl_icon_details_t *icon,
const char *reviewTitle,
const char *reviewSubTitle);

ux_sync_ret_t ux_sync_reviewStreamingContinue(const nbgl_layoutTagValueList_t *tagValueList);

ux_sync_ret_t ux_sync_reviewStreamingFinish(const char *finishTitle);

ux_sync_ret_t ux_sync_genericReview(const nbgl_genericContents_t *contents, const char *rejectText);

ux_sync_ret_t ux_sync_genericConfiguration(const char *title,
uint8_t initPage,
const nbgl_genericContents_t *contents);

/*
* This function must be implemented by the caller.
* It must wait for the next seph event and process it except for APDU events.
* It must return:
* - true when an APDU has been received in the processed event
* - false otherwise
*
* Note on C apps using SDK lib_standard_app, this is already provided in io.c by the lib.
*/
extern bool io_recv_and_process_event(void);

#endif
Loading
Loading