From 453c9ffe4516a2ecf611e9afdd55019ee76cbbfd Mon Sep 17 00:00:00 2001 From: Nicolas Roggeman Date: Mon, 24 Jun 2024 10:45:41 +0200 Subject: [PATCH 1/3] Force reject text when using old Use Case API (cherry picked from commit d8b570a0e9f195390ebdd41a6390d76afce9e13c) --- lib_nbgl/src/nbgl_use_case.c | 192 +++++++++++++++++++---------------- 1 file changed, 102 insertions(+), 90 deletions(-) diff --git a/lib_nbgl/src/nbgl_use_case.c b/lib_nbgl/src/nbgl_use_case.c index a22a9da50..5b793c51c 100644 --- a/lib_nbgl/src/nbgl_use_case.c +++ b/lib_nbgl/src/nbgl_use_case.c @@ -1590,6 +1590,64 @@ static void bundleNavReviewStreamingChoice(bool confirm) } } +static void useCaseReview(nbgl_operationType_t operationType, + const nbgl_contentTagValueList_t *tagValueList, + const nbgl_icon_details_t *icon, + const char *reviewTitle, + const char *reviewSubTitle, + const char *finishTitle, + nbgl_choiceCallback_t choiceCallback, + bool isLight) +{ + reset_callbacks(); + memset(&genericContext, 0, sizeof(genericContext)); + + bundleNavContext.review.operationType = operationType; + bundleNavContext.review.choiceCallback = choiceCallback; + + // memorize context + onChoice = bundleNavReviewChoice; + 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 + STARTING_CONTENT.type = CENTERED_INFO; + prepareReviewFirstPage( + &STARTING_CONTENT.content.centeredInfo, icon, reviewTitle, reviewSubTitle); + + // Then the tag/value pairs + localContentsList[1].type = TAG_VALUE_LIST; + memcpy(&localContentsList[1].content.tagValueList, + tagValueList, + sizeof(nbgl_contentTagValueList_t)); + localContentsList[1].contentActionCallback = tagValueList->actionCallback; + + // The last page + if (isLight) { + localContentsList[2].type = INFO_BUTTON; + prepareReviewLightLastPage(&localContentsList[2].content.infoButton, icon, finishTitle); + } + else { + localContentsList[2].type = INFO_LONG_PRESS; + prepareReviewLastPage(&localContentsList[2].content.infoLongPress, icon, finishTitle); + } + + // compute number of pages & fill navigation structure + uint8_t nbPages = nbgl_useCaseGetNbPagesForGenericContents(&genericContext.genericContents, 0); + prepareNavInfo(true, nbPages, getRejectReviewText(operationType)); + +#ifdef HAVE_PIEZO_SOUND + // Play notification sound + io_seproxyhal_play_tune(TUNE_LOOK_AT_ME); +#endif // HAVE_PIEZO_SOUND + + displayGenericContextPage(0, true); +} + /********************** * GLOBAL FUNCTIONS **********************/ @@ -1894,11 +1952,10 @@ void nbgl_useCasePlugInHome(const char *plugInName, * For each page, the given navCallback will be called to get the content. Only 'type' and * union has to be set in this content * - * @param title string to set in touchable (or not) title + * @param title string to set in touchable title * @param initPage page on which to start [0->(nbPages-1)] * @param nbPages number of pages - * @param touchable if true, the title is used to quit and quitCallback is called (unused, it is - * always on) + * @param touchable unused, it is always on * @param quitCallback callback called when quit button (or title) is pressed * @param navCallback callback called when navigation arrows are pressed * @param controlsCallback callback called when any controls in the settings (radios, switches) is @@ -2290,7 +2347,8 @@ void nbgl_useCaseRegularReview(uint8_t initPage, navType = REVIEW_NAV; // fill navigation structure - prepareNavInfo(true, nbPages, rejectText); + UNUSED(rejectText); + prepareNavInfo(true, nbPages, getRejectReviewText(TYPE_OPERATION)); displayReviewPage(initPage, true); } @@ -2326,7 +2384,8 @@ void nbgl_useCaseForwardOnlyReview(const char *rejectText, navType = REVIEW_NAV; // fill navigation structure - prepareNavInfo(true, NBGL_NO_PROGRESS_INDICATOR, rejectText); + UNUSED(rejectText); + prepareNavInfo(true, NBGL_NO_PROGRESS_INDICATOR, getRejectReviewText(TYPE_OPERATION)); navInfo.progressIndicator = false; navInfo.skipText = "Skip"; @@ -2366,7 +2425,8 @@ void nbgl_useCaseForwardOnlyReviewNoSkip(const char *rejectText, navType = REVIEW_NAV; // fill navigation structure - prepareNavInfo(true, NBGL_NO_PROGRESS_INDICATOR, rejectText); + UNUSED(rejectText); + prepareNavInfo(true, NBGL_NO_PROGRESS_INDICATOR, getRejectReviewText(TYPE_OPERATION)); navInfo.progressIndicator = false; displayReviewPage(0, false); } @@ -2420,7 +2480,8 @@ void nbgl_useCaseStaticReview(const nbgl_contentTagValueList_t *tagValueList, // compute number of pages & fill navigation structure uint8_t nbPages = nbgl_useCaseGetNbPagesForGenericContents(&genericContext.genericContents, 0); - prepareNavInfo(true, nbPages, rejectText); + UNUSED(rejectText); + prepareNavInfo(true, nbPages, getRejectReviewText(TYPE_OPERATION)); displayGenericContextPage(0, true); } @@ -2476,14 +2537,16 @@ void nbgl_useCaseStaticReviewLight(const nbgl_contentTagValueList_t *tagValueLis // compute number of pages & fill navigation structure uint8_t nbPages = nbgl_useCaseGetNbPagesForGenericContents(&genericContext.genericContents, 0); - prepareNavInfo(true, nbPages, rejectText); + UNUSED(rejectText); + prepareNavInfo(true, nbPages, getRejectReviewText(TYPE_OPERATION)); displayGenericContextPage(0, true); } /** - * @brief Draws a flow of pages of a 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". + * @brief Draws a flow of pages of a review. Navigation operates with either swipe or navigation + * keys at bottom right. The last page contains a long-press button with the given finishTitle and + * the given icon. * @note All tag/value pairs are provided in the API and the number of pages is automatically * computed, the last page being a long press one * @@ -2504,52 +2567,20 @@ void nbgl_useCaseReview(nbgl_operationType_t operationType, const char *finishTitle, nbgl_choiceCallback_t choiceCallback) { - reset_callbacks(); - memset(&genericContext, 0, sizeof(genericContext)); - - bundleNavContext.review.operationType = operationType; - bundleNavContext.review.choiceCallback = choiceCallback; - - // memorize context - onChoice = bundleNavReviewChoice; - 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 - STARTING_CONTENT.type = CENTERED_INFO; - prepareReviewFirstPage( - &STARTING_CONTENT.content.centeredInfo, icon, reviewTitle, reviewSubTitle); - - // Then the tag/value pairs - localContentsList[1].type = TAG_VALUE_LIST; - memcpy(&localContentsList[1].content.tagValueList, - tagValueList, - sizeof(nbgl_contentTagValueList_t)); - localContentsList[1].contentActionCallback = tagValueList->actionCallback; - - // Eventually the long press page - localContentsList[2].type = INFO_LONG_PRESS; - prepareReviewLastPage(&localContentsList[2].content.infoLongPress, icon, finishTitle); - - // compute number of pages & fill navigation structure - uint8_t nbPages = nbgl_useCaseGetNbPagesForGenericContents(&genericContext.genericContents, 0); - prepareNavInfo(true, nbPages, getRejectReviewText(operationType)); - -#ifdef HAVE_PIEZO_SOUND - // Play notification sound - io_seproxyhal_play_tune(TUNE_LOOK_AT_ME); -#endif // HAVE_PIEZO_SOUND - - displayGenericContextPage(0, true); + useCaseReview(operationType, + tagValueList, + icon, + reviewTitle, + reviewSubTitle, + finishTitle, + choiceCallback, + false); } /** - * @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". + * @brief Draws a flow of pages of a light review. Navigation operates with either swipe or + * navigation keys at bottom right. The last page contains a button/footer with the given + * finishTitle and the given icon. * @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 * @@ -2570,43 +2601,14 @@ void nbgl_useCaseReviewLight(nbgl_operationType_t operationType, 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 - STARTING_CONTENT.type = CENTERED_INFO; - prepareReviewFirstPage( - &STARTING_CONTENT.content.centeredInfo, icon, reviewTitle, reviewSubTitle); - - // Then the tag/value pairs - localContentsList[1].type = TAG_VALUE_LIST; - memcpy(&localContentsList[1].content.tagValueList, - tagValueList, - sizeof(nbgl_contentTagValueList_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)); - -#ifdef HAVE_PIEZO_SOUND - // Play notification sound - io_seproxyhal_play_tune(TUNE_LOOK_AT_ME); -#endif // HAVE_PIEZO_SOUND - - displayGenericContextPage(0, true); + useCaseReview(operationType, + tagValueList, + icon, + reviewTitle, + reviewSubTitle, + finishTitle, + choiceCallback, + true); } /** @@ -2637,6 +2639,11 @@ void nbgl_useCaseGenericReview(const nbgl_genericContents_t *contents, prepareNavInfo(true, nbPages, rejectText); navInfo.quitToken = QUIT_TOKEN; +#ifdef HAVE_PIEZO_SOUND + // Play notification sound + io_seproxyhal_play_tune(TUNE_LOOK_AT_ME); +#endif // HAVE_PIEZO_SOUND + displayGenericContextPage(0, true); } @@ -2891,6 +2898,11 @@ void nbgl_useCaseAddressConfirmationExt(const char *addres prepareNavInfo(true, nbPages, "Cancel"); +#ifdef HAVE_PIEZO_SOUND + // Play notification sound + io_seproxyhal_play_tune(TUNE_LOOK_AT_ME); +#endif // HAVE_PIEZO_SOUND + displayGenericContextPage(0, true); } From 9582082900e7093775df40b4063ed8dc65b42864 Mon Sep 17 00:00:00 2001 From: Alexis Grojean Date: Fri, 14 Jun 2024 15:53:51 +0200 Subject: [PATCH 2/3] Add setter functions in ux_sync lib for synchronous call return code and "end of flow" variables. (cherry picked from commit 05c2e5f87897404b63992dc11064d19fbebace7d) --- lib_ux_sync/include/ux_sync.h | 4 ++++ lib_ux_sync/src/ux_sync.c | 22 ++++++++++++++++++++++ 2 files changed, 26 insertions(+) diff --git a/lib_ux_sync/include/ux_sync.h b/lib_ux_sync/include/ux_sync.h index 938ffe10e..97710b76b 100644 --- a/lib_ux_sync/include/ux_sync.h +++ b/lib_ux_sync/include/ux_sync.h @@ -10,6 +10,10 @@ typedef enum { UX_SYNC_RET_ERROR } ux_sync_ret_t; +void ux_sync_setReturnCode(ux_sync_ret_t ret); + +void ux_sync_setEnded(bool ended); + ux_sync_ret_t ux_sync_homeAndSettings(const char *appName, const nbgl_icon_details_t *appIcon, const char *tagline, diff --git a/lib_ux_sync/src/ux_sync.c b/lib_ux_sync/src/ux_sync.c index ffc977e8f..ecc8edc4e 100644 --- a/lib_ux_sync/src/ux_sync.c +++ b/lib_ux_sync/src/ux_sync.c @@ -49,6 +49,28 @@ static ux_sync_ret_t ux_sync_wait(bool exitOnApdu) return g_ret; } +/** + * @brief Sets the return code of synchronous UX calls. Can be used by content action callbacks + * defined by application code. + * + * @param ret return code to set. + */ +void ux_sync_setReturnCode(ux_sync_ret_t ret) +{ + g_ret = ret; +} + +/** + * @brief Sets the ended flag of synchronous UX calls. Can be used by content action callbacks + * defined by application code to end the UX flow. + * + * @param ended flag to set. + */ +void ux_sync_setEnded(bool ended) +{ + g_ended = ended; +} + /** * @brief Draws the extended version of home page of an app (page on which we land when launching it * from dashboard) with automatic support of setting display. From 603cf09dcfd139410443bf6ef6f265ca2cf67443 Mon Sep 17 00:00:00 2001 From: abonnaudet-ledger <71646516+abonnaudet-ledger@users.noreply.github.com> Date: Mon, 24 Jun 2024 10:31:59 +0200 Subject: [PATCH 3/3] Update README.md (cherry picked from commit ae3e6ad465c7ce407cf52fd973f92b39d0e7a4a7) --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 4ca3a6498..90e798270 100644 --- a/README.md +++ b/README.md @@ -82,6 +82,7 @@ OS release candidates are only kept in the list when a corresponding OS release | 18 | europa_0.1.0-re3
flex_0.2.0-rc1
flex_0.2.0-rc2
nanox_2.3.0-rc5
nanos+_1.2.0-rc5 | :heavy_check_mark: | 19 | flex_1.0.0-rc1
flex_1.0.0-rc2
flex_1.0.0
flex_1.0.1
| :x: | 20 | stax_1.5.0-rc1
flex_1.1.0-rc1 | :heavy_check_mark: +| 21 | stax_1.5.0-rc2 | :heavy_check_mark: ### Cherry-picking process: