Skip to content

Commit

Permalink
Merge pull request #857 from LedgerHQ/enable-screenshots-generation
Browse files Browse the repository at this point in the history
Add screenshots generation feature in SDK
  • Loading branch information
nroggeman-ledger authored Feb 4, 2025
2 parents 4d003bb + 5315527 commit 55afb41
Show file tree
Hide file tree
Showing 95 changed files with 9,104 additions and 7 deletions.
8 changes: 4 additions & 4 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,13 @@ TARGET ?= stax
NBGL_DEFINES_stax := \
HAVE_SE_TOUCH \
NBGL_PAGE \
NBGL_QRCODE \
SCREEN_SIZE_WALLET
NBGL_QRCODE \
SCREEN_SIZE_WALLET

NBGL_DEFINES_nano := \
NBGL_STEP \
NBGL_FLOW \
SCREEN_SIZE_NANO
NBGL_FLOW \
SCREEN_SIZE_NANO

NBGL_DEFINES := $(NBGL_DEFINES_$(TARGET))

Expand Down
3 changes: 0 additions & 3 deletions lib_nbgl/src/nbgl_obj.c
Original file line number Diff line number Diff line change
Expand Up @@ -125,9 +125,6 @@ static const draw_function_t draw_functions[NB_OBJ_TYPES] = {
uint8_t ramBuffer[GZLIB_UNCOMPRESSED_CHUNK];

#ifdef BUILD_SCREENSHOTS
// Contains the last string index used
extern UX_LOC_STRINGS_INDEX last_string_id;

// Variables used to store important values (nb lines, bold state etc)
extern uint16_t last_nb_lines, last_nb_pages;
extern bool last_bold_state, verbose;
Expand Down
299 changes: 299 additions & 0 deletions tests/screenshots/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,299 @@
# Makefile to build and launch screenshots
# The generated screenshots can be used to validate NBGL Application Use Cases
GCC ?= gcc
PRODUCT_NAME ?=$(word 1, $(subst _, ,$(MAKECMDGOALS)))

# possible products
PRODUCT_NAMES = stax nanox flex nanosp

ifeq (, $(filter $(PRODUCT_NAMES), $(PRODUCT_NAME)))
$(error "Product $(PRODUCT_NAME) not found")
endif

SRC_DIR := src
PRODUCT_DIR := build/$(PRODUCT_NAME)
BUILD_DIR := $(PRODUCT_DIR)
GEN_DIR := $(BUILD_DIR)/generated
OBJ_DIR := $(BUILD_DIR)/obj
BIN_DIR := $(BUILD_DIR)/bin
PUBLIC_SDK_DIR := ../..

SCREENSHOTS_SRC_DIR := .


WARNINGS := -Wall -Wextra \
-Wshadow -Wundef -Wmaybe-uninitialized -Wmissing-prototypes -Wno-discarded-qualifiers \
-Wunused-function -Wno-error=strict-prototypes -Wpointer-arith -fno-strict-aliasing -Wno-error=cpp -Wuninitialized \
-Wunused-parameter -Wno-missing-field-initializers -Wno-format-nonliteral -Wno-cast-qual -Wunreachable-code -Wno-switch-default \
-Wreturn-type -Wmultichar -Wformat-security -Wno-ignored-qualifiers -Wno-error=pedantic -Wsign-compare -Wdouble-promotion -Wclobbered -Wdeprecated \
-Wempty-body -Wshift-negative-value -Wstack-usage=2048 \
-Wtype-limits -Wsizeof-pointer-memaccess -Wpointer-arith \
-Werror

CFLAGS := -O0 -g $(WARNINGS)

# Add simulator define to allow modification of source
DEFINES+= \
LINUX_SIMU=1 \
VERSION=\"$(VERSION)\" \
WITH_STDIO \
HAVE_NBGL \
HAVE_SEED_COOKIE \
HAVE_ECC \
HAVE_SHA256 \
HAVE_SHA512 \
HAVE_PBKDF2 \
HAVE_RNG \
HAVE_HASH \
HAVE_INDEXED_STRINGS \
NBGL_KEYBOARD \
NBGL_KEYPAD \
HAVE_RECOVER \
OS_IO_SEPROXYHAL \
USB_SEGMENT_SIZE=64 \
IO_HID_EP_LENGTH=64 \
IO_SEPROXYHAL_BUFFER_SIZE_B=300 \
BUILD_SCREENSHOTS

ifeq ($(PRODUCT_NAME),stax)
TARGET_DEFINES += \
TARGET_STAX \
HAVE_SIDE_SCREEN \
HAVE_BAGL_FONT_INTER_REGULAR_24PX \
HAVE_BAGL_FONT_INTER_SEMIBOLD_24PX \
HAVE_BAGL_FONT_INTER_MEDIUM_32PX \
SCREEN_SIZE_WALLET

TARGET_ID := 0x33200004
endif

ifeq ($(PRODUCT_NAME),flex)
TARGET_DEFINES += \
TARGET_FLEX \
HAVE_BAGL_FONT_INTER_REGULAR_28PX \
HAVE_BAGL_FONT_INTER_SEMIBOLD_28PX \
HAVE_BAGL_FONT_INTER_MEDIUM_36PX \
SCREEN_SIZE_WALLET

TARGET_ID := 0x33300004
endif

ifeq ($(PRODUCT_NAME),nanox)
TARGET_DEFINES += \
TARGET_NANOX \
HAVE_BATTERY \
HAVE_HARDWARE_VERSIONS \
SCREEN_SIZE_NANO

TARGET_ID := 0x33000004
endif

ifeq ($(PRODUCT_NAME),nanosp)
TARGET_DEFINES += \
TARGET_NANOSP \
SCREEN_SIZE_NANO

TARGET_ID := 0x33100004
endif

#if Nano
ifeq (, $(filter $(TARGET_DEFINES), SCREEN_SIZE_WALLET))
TARGET_DEFINES += \
MONITOR_ZOOM=4 \
HAVE_BRIGHTNESS_SETTING \
NBGL_USE_CASE \
NBGL_STEP \
HAVE_BAGL_FONT_OPEN_SANS_REGULAR_11PX \
HAVE_BAGL_FONT_OPEN_SANS_EXTRABOLD_11PX \
HAVE_BAGL_FONT_OPEN_SANS_LIGHT_16PX \
HAVE_SE_SCREEN \
HAVE_SEPROXYHAL_MCU

APP_PATH := $(SRC_DIR)/app/nano
FLOWS_PATH := $(SCREENSHOTS_SRC_DIR)/flows/nano

GLYPH_OPT := --reverse

else #if wallet
TARGET_DEFINES += \
HAVE_BLE \
HAVE_BATTERY \
HAVE_SE_TOUCH \
HAVE_NFC \
HAVE_PIEZO_SOUND \
HAVE_BACKGROUND_IMG \
NBGL_QRCODE \
NBGL_PAGE \
NBGL_USE_CASE \
HAVE_SE_EINK_DISPLAY

APP_PATH := $(SRC_DIR)/app/wallet
FLOWS_PATH := $(SCREENSHOTS_SRC_DIR)/flows/wallet
endif

DEFINES += $(TARGET_DEFINES)

PROPERTIES_FILENAME = $(PRODUCT_NAME).properties

GLYPH_DESTC := $(GEN_DIR)/glyphs.c
GLYPH_DESTH := $(GEN_DIR)/glyphs.h

APP_ICON_DESTC := $(GEN_DIR)/app_icons.c
APP_ICON_DESTH := $(GEN_DIR)/app_icons.h

NBGL_PATH := $(PUBLIC_SDK_DIR)/lib_nbgl

INC:= \
/usr/include/SDL2 \
$(APP_PATH) \
$(SRC_DIR)/main \
$(SRC_DIR)/uzlib \
$(PUBLIC_SDK_DIR)/target/$(PRODUCT_NAME)/include \
$(PUBLIC_SDK_DIR)/include \
$(PUBLIC_SDK_DIR)/lib_ux_nbgl \
$(PUBLIC_SDK_DIR)/lib_cxng/include \
$(NBGL_PATH)/include/fonts \
$(NBGL_PATH)/include \
$(PUBLIC_SDK_DIR)/qrcode/include \
$(GEN_DIR)

LDLIBS := -lSDL2 -lm -lbsd
LDFLAGS := -Xlinker -Map=$(BUILD_DIR)/memory.map
BIN := $(BIN_DIR)/simulator

COMPILE = $(GCC) $(CFLAGS) $(addprefix -I,$(INC)) $(addprefix -D,$(DEFINES))

# Automatically include all source files
SRCS := $(shell find $(APP_PATH) -type f -name '*.c')
SRCS += $(shell find $(SRC_DIR)/uzlib -type f -name '*.c')
SRCS += $(shell find $(SRC_DIR)/main -type f -name '*.c')
LIB_SRCS := $(shell find $(NBGL_PATH)/src -type f -name '*.c')
LIB_SRCS += $(shell find $(NBGL_PATH)/fonts -type f -name '*.c')
LIB_SRCS += $(shell find $(PUBLIC_SDK_DIR)/qrcode/src -type f -name '*.c')

APP_ICON_FILES = $(addprefix $(APP_PATH)/glyphs/,$(sort $(notdir $(shell find $(APP_PATH)/glyphs/))))
APP_ICON_FILENAMES = $(sort $(notdir $(shell find $(APP_PATH)/glyphs/)))
GLYPH_FILES = $(addprefix $(APP_PATH)/glyphs/,$(sort $(notdir $(shell find $(APP_PATH)/glyphs/))))

ifneq (, $(filter $(PRODUCT_NAME), stax flex))
GLYPH_FILES += $(addprefix $(NBGL_PATH)/glyphs/wallet/,$(sort $(notdir $(shell find $(NBGL_PATH)/glyphs/wallet/))))
GLYPH_FILES += $(addprefix $(NBGL_PATH)/glyphs/64px/,$(sort $(notdir $(shell find $(NBGL_PATH)/glyphs/64px/))))
else
GLYPH_FILES += $(addprefix $(NBGL_PATH)/glyphs/nano/,$(sort $(notdir $(shell find $(NBGL_PATH)/glyphs/nano/))))
endif

ifeq ($(PRODUCT_NAME),stax)
GLYPH_FILES += $(addprefix $(NBGL_PATH)/glyphs/32px/,$(sort $(notdir $(shell find $(NBGL_PATH)/glyphs/32px/))))
endif
ifeq ($(PRODUCT_NAME),flex)
GLYPH_FILES += $(addprefix $(NBGL_PATH)/glyphs/40px/,$(sort $(notdir $(shell find $(NBGL_PATH)/glyphs/40px/))))
endif

ICON_SCRIPT := $(NBGL_PATH)/tools/icon2glyph.py

OBJECTS := $(patsubst $(SRC_DIR)/%,$(OBJ_DIR)/%,$(SRCS:.c=.o))
OBJECTS += $(patsubst $(PUBLIC_SDK_DIR)/%,$(OBJ_DIR)/%,$(LIB_SRCS:.c=.o))
OBJECTS += $(OBJ_DIR)/glyphs.o
OBJECTS += $(OBJ_DIR)/app_icons.o

# Creation of glyphs.c, containing all icons, from all
$(GLYPH_DESTH): $(GLYPH_FILES) $(ICON_SCRIPT) | $(GEN_DIR)
@echo [GLYPH] Compiling... $@
@python3 $(ICON_SCRIPT) $(GLYPH_OPT) --glyphcheader $(GLYPH_DESTH) --glyphcfile $(GLYPH_DESTC) $(GLYPH_FILES)

$(GLYPH_DESTC): $(GLYPH_DESTH)

# Creation of special app_icon.h, containing all app icons,
$(APP_ICON_DESTH): $(APP_ICON_FILES) hexbitmap2c.py | $(GEN_DIR)
@echo [ICON] Creating... $@
@rm -f $(ICON_HEX_FILE)
@echo "/* Generated */" > $(APP_ICON_DESTC)
@echo "/* Generated */" > $(APP_ICON_DESTH)
@for file in $(APP_ICON_FILENAMES) ; do \
python3 $(ICON_SCRIPT) $(GLYPH_OPT) --hexbitmap tmp_$$file.hex $(APP_PATH)/glyphs/$$file ; \
python3 hexbitmap2c.py --hexbitmap tmp_$$file.hex --inc $(APP_ICON_DESTH) --src $(APP_ICON_DESTC) --variable $$file; \
rm -f tmp_$$file.hex; \
done

$(APP_ICON_DESTC): $(APP_ICON_DESTH)

# Compile all C source files, except generated ones into .o (and .d for dependencies)
$(OBJ_DIR)/%.o: $(SRC_DIR)/%.c $(GLYPH_DESTH) $(APP_ICON_DESTH) | $(OBJ_DIR)
@echo 'Compiling source file: $<'
@mkdir -p $(dir $@)
@$(COMPILE) -c -MMD -MP -MF"$(OBJ_DIR)/$*.d" -o "$@" "$<"

# Compile lib C source files, except generated ones into .o (and .d for dependencies)
$(OBJ_DIR)/%.o: $(PUBLIC_SDK_DIR)/%.c $(GLYPH_DESTH) $(APP_ICON_DESTH) | $(OBJ_DIR)
@echo 'Compiling source file: $<'
@mkdir -p $(dir $@)
@$(COMPILE) -c -MMD -MP -MF"$(OBJ_DIR)/$*.d" -o "$@" "$<"

# Compile generated C source files into .o (and .d for dependencies)
$(OBJ_DIR)/%.o: $(GEN_DIR)/%.c | $(OBJ_DIR)
@echo 'Compiling generated file: $<'
@$(COMPILE) -c -MMD -MP -MF"$(OBJ_DIR)/$*.d" -o "$@" "$<"

# Rule to link all objects into the final binary
$(BIN): $(OBJECTS) | $(BIN_DIR)
@echo 'Linking $@'
@$(GCC) -o $@ $+ $(LDFLAGS) -ljson-c -lpng ${LDLIBS}

# Rule to create directories
$(BIN_DIR) $(OBJ_DIR) $(GEN_DIR) $(BUILD_DIR) $(BUILD_DIR)/screenshots:
@mkdir -p $@

.PHONY: screenshots

# how to generate all screenshots for all scenarios (flows)
# at the end, it creates a top level index
%_screenshots: $(BIN) | $(BUILD_DIR)/screenshots
@echo "Building... "$@
@python3 $(SCREENSHOTS_SRC_DIR)/launch_screenshots.py -b $(BIN) -w $(BUILD_DIR)/screenshots -f $(FLOWS_PATH) -p $(PROPERTIES_FILENAME) -n $(PRODUCT_NAME)

%_clean:
rm -rf $(PRODUCT_DIR)


##
## Nanox
##

nanox: $(BIN)

nanox_clean:

nanox_screenshots: $(BIN)

#
##
## NanoSP
##

nanosp: $(BIN)

nanosp_clean:

nanosp_screenshots: $(BIN)

#
## Stax
##

stax: $(BIN)

stax_clean:

stax_screenshots: $(BIN)

##
## Flex
##

flex: $(BIN)

flex_clean:

flex_screenshots: $(BIN)

-include $(OBJECTS:%.o=%.d)
42 changes: 42 additions & 0 deletions tests/screenshots/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# Screenshots generation

## Prerequisite

TBC

## Overview

The goal of this mechanism is to generate screenshots of usual Applications scenarios.

It can be used for any product (Stax, Flex, NanoX, NanoS+)

## Launch screenshots generation

The screenshots generator can be built and launched in the same command, for a given product

```
make <product>_screenshots
```

where `<product>` can be:

- `flex`
- `stax`
- `nanox`
- `nanosp`

so for example to generate screenshots for Flex:

```
make flex_screenshots
```

The result can be found in `build/<product>/screenshots`

## Clean

The environment can be cleaned-up with:

```
make <product>_clean
```
16 changes: 16 additions & 0 deletions tests/screenshots/flex.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"devicename": "Lily's Crypto",
"bootloader_version": "2.2",
"seph_version": "1.95",
"seph_serial": "2100200782107028",
"os_version": "2.0.1",
"os_flags": 0,

"language": 0,

"autoboot": true,

"piezosound": 3,

"features": 4,
}
Loading

0 comments on commit 55afb41

Please sign in to comment.