summaryrefslogtreecommitdiff
path: root/tests/vb2_ui_action_tests.c
diff options
context:
space:
mode:
Diffstat (limited to 'tests/vb2_ui_action_tests.c')
-rw-r--r--tests/vb2_ui_action_tests.c936
1 files changed, 0 insertions, 936 deletions
diff --git a/tests/vb2_ui_action_tests.c b/tests/vb2_ui_action_tests.c
deleted file mode 100644
index ba378f43..00000000
--- a/tests/vb2_ui_action_tests.c
+++ /dev/null
@@ -1,936 +0,0 @@
-/* Copyright 2020 The Chromium OS Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- *
- * Tests for UI related actions.
- */
-
-#include "2api.h"
-#include "2common.h"
-#include "2misc.h"
-#include "2nvstorage.h"
-#include "2ui.h"
-#include "2ui_private.h"
-#include "test_common.h"
-#include "vboot_api.h"
-
-/* Fixed value for ignoring some checks. */
-#define MOCK_IGNORE 0xffffu
-
-/* Mock screen index for testing screen utility functions. */
-#define MOCK_NO_SCREEN 0xef00
-#define MOCK_SCREEN_BLANK 0xef10
-#define MOCK_SCREEN_BASE 0xef11
-#define MOCK_SCREEN_MENU 0xef12
-#define MOCK_SCREEN_TARGET0 0xef20
-#define MOCK_SCREEN_TARGET1 0xef21
-#define MOCK_SCREEN_TARGET2 0xef22
-#define MOCK_SCREEN_ACTION 0xef30
-#define MOCK_SCREEN_ALL_ACTION 0xef32
-
-/* Mock data */
-/* TODO(b/156448738): Add tests for timer_disabled and error_code */
-struct display_call {
- const struct vb2_screen_info *screen;
- uint32_t locale_id;
- uint32_t selected_item;
- uint32_t disabled_item_mask;
- uint32_t hidden_item_mask;
- int timer_disabled;
- uint32_t current_page;
- enum vb2_ui_error error_code;
-} __attribute__((packed));
-
-static uint8_t workbuf[VB2_KERNEL_WORKBUF_RECOMMENDED_SIZE]
- __attribute__((aligned(VB2_WORKBUF_ALIGN)));
-static struct vb2_context *ctx;
-static struct vb2_shared_data *sd;
-static struct vb2_gbb_header gbb;
-
-static int mock_calls_until_shutdown;
-
-static struct vb2_ui_context mock_ui_context;
-
-static struct display_call mock_displayed[64];
-static int mock_displayed_count;
-static int mock_displayed_i;
-
-static uint32_t mock_key[64];
-static int mock_key_trusted[64];
-static int mock_key_count;
-static int mock_key_total;
-
-static int mock_get_screen_info_called;
-
-static vb2_error_t mock_vbtlk_retval;
-static uint32_t mock_vbtlk_expected_flag;
-
-static int mock_run_altfw_called;
-static uint32_t mock_altfw_last;
-static uint32_t mock_altfw_count;
-
-static uint32_t mock_time_ms;
-static const uint32_t mock_time_start_ms = 31ULL * VB2_MSEC_PER_SEC;
-
-/* Mock actions */
-static uint32_t mock_action_called;
-static uint32_t mock_action_countdown_limit;
-static vb2_error_t mock_action_countdown(struct vb2_ui_context *ui)
-{
- if (++mock_action_called >= mock_action_countdown_limit)
- return VB2_REQUEST_UI_EXIT;
- return VB2_SUCCESS;
-}
-
-static vb2_error_t mock_action_screen_change(struct vb2_ui_context *ui)
-{
- return vb2_ui_screen_change(ui, MOCK_SCREEN_BASE);
-}
-
-static vb2_error_t mock_action_base(struct vb2_ui_context *ui)
-{
- mock_action_called++;
- return VB2_SUCCESS;
-}
-
-static int mock_action_flags;
-static vb2_error_t mock_action_flag0(struct vb2_ui_context *ui)
-{
- if ((1 << 0) & mock_action_flags)
- return VB2_REQUEST_UI_EXIT;
- return VB2_SUCCESS;
-}
-
-static vb2_error_t mock_action_flag1(struct vb2_ui_context *ui)
-{
- if ((1 << 1) & mock_action_flags)
- return VB2_REQUEST_UI_EXIT;
- return VB2_SUCCESS;
-}
-
-static vb2_error_t mock_action_flag2(struct vb2_ui_context *ui)
-{
- if ((1 << 2) & mock_action_flags)
- return VB2_REQUEST_UI_EXIT;
- return VB2_SUCCESS;
-}
-
-static uint32_t mock_action_delay_ms;
-static vb2_error_t mock_action_msleep(struct vb2_ui_context *ui)
-{
- vb2ex_msleep(mock_action_delay_ms);
- return VB2_SUCCESS;
-}
-
-/* Mock screens */
-struct vb2_screen_info mock_screen_temp;
-const struct vb2_screen_info mock_screen_blank = {
- .id = MOCK_SCREEN_BLANK,
- .name = "mock_screen_blank",
-};
-const struct vb2_screen_info mock_screen_base = {
- .id = MOCK_SCREEN_BASE,
- .name = "mock_screen_base: menuless screen",
-};
-const struct vb2_menu_item mock_screen_menu_items[] = {
- {
- .text = "item 0",
- .target = MOCK_SCREEN_TARGET0,
- },
- {
- .text = "item 1",
- .target = MOCK_SCREEN_TARGET1,
- },
- {
- .text = "item 2",
- .target = MOCK_SCREEN_TARGET2,
- },
- {
- .text = "item 3",
- .action = mock_action_base,
- },
- {
- .text = "item 4 (no target)",
- },
-};
-const struct vb2_screen_info mock_screen_menu = {
- .id = MOCK_SCREEN_MENU,
- .name = "mock_screen_menu: screen with 5 items",
- .menu = {
- .num_items = ARRAY_SIZE(mock_screen_menu_items),
- .items = mock_screen_menu_items,
- },
-};
-const struct vb2_screen_info mock_screen_target0 = {
- .id = MOCK_SCREEN_TARGET0,
- .name = "mock_screen_target0",
-};
-const struct vb2_screen_info mock_screen_target1 = {
- .id = MOCK_SCREEN_TARGET1,
- .name = "mock_screen_target1",
-};
-const struct vb2_screen_info mock_screen_target2 = {
- .id = MOCK_SCREEN_TARGET2,
- .name = "mock_screen_target2",
-};
-const struct vb2_screen_info mock_screen_action = {
- .id = MOCK_SCREEN_ACTION,
- .name = "mock_screen_action",
- .action = mock_action_countdown,
-};
-const struct vb2_menu_item mock_screen_all_action_items[] = {
- {
- .text = "all_action_screen_item",
- .action = mock_action_flag1,
- },
-};
-const struct vb2_screen_info mock_screen_all_action = {
- .id = MOCK_SCREEN_ALL_ACTION,
- .name = "mock_screen_all_action",
- .action = mock_action_flag0,
- .menu = {
- .num_items = ARRAY_SIZE(mock_screen_all_action_items),
- .items = mock_screen_all_action_items,
- },
-};
-
-static void screen_state_eq(const struct vb2_screen_state *state,
- enum vb2_screen screen,
- uint32_t selected_item,
- uint32_t hidden_item_mask)
-{
- if (screen != MOCK_IGNORE) {
- if (state->screen == NULL)
- TEST_TRUE(0, " state.screen does not exist");
- else
- TEST_EQ(state->screen->id, screen, " state.screen");
- }
- if (selected_item != MOCK_IGNORE)
- TEST_EQ(state->selected_item,
- selected_item, " state.selected_item");
- if (hidden_item_mask != MOCK_IGNORE)
- TEST_EQ(state->hidden_item_mask,
- hidden_item_mask, " state.hidden_item_mask");
-}
-
-static void add_mock_key(uint32_t press, int trusted)
-{
- if (mock_key_total >= ARRAY_SIZE(mock_key) ||
- mock_key_total >= ARRAY_SIZE(mock_key_trusted)) {
- TEST_TRUE(0, " mock_key ran out of entries!");
- return;
- }
-
- mock_key[mock_key_total] = press;
- mock_key_trusted[mock_key_total] = trusted;
- mock_key_total++;
-}
-
-static void add_mock_keypress(uint32_t press)
-{
- add_mock_key(press, 0);
-}
-
-static void displayed_eq(const char *text,
- enum vb2_screen screen,
- uint32_t locale_id,
- uint32_t selected_item,
- uint32_t hidden_item_mask,
- int line)
-{
- char text_info[32], text_buf[128];
-
- sprintf(text_info, "(line #%d, displayed #%d)", line, mock_displayed_i);
-
- if (mock_displayed_i >= mock_displayed_count) {
- sprintf(text_buf, " %s missing screen %s",
- text_info, text);
- TEST_TRUE(0, text_buf);
- return;
- }
-
- if (screen != MOCK_IGNORE) {
- sprintf(text_buf, " %s screen of %s", text_info, text);
- TEST_EQ(mock_displayed[mock_displayed_i].screen->id, screen,
- text_buf);
- }
- if (locale_id != MOCK_IGNORE) {
- sprintf(text_buf, " %s locale_id of %s", text_info, text);
- TEST_EQ(mock_displayed[mock_displayed_i].locale_id, locale_id,
- text_buf);
- }
- if (selected_item != MOCK_IGNORE) {
- sprintf(text_buf, " %s selected_item of %s",
- text_info, text);
- TEST_EQ(mock_displayed[mock_displayed_i].selected_item,
- selected_item, text_buf);
- }
- if (hidden_item_mask != MOCK_IGNORE) {
- sprintf(text_buf, " %s hidden_item_mask of %s",
- text_info, text);
- TEST_EQ(mock_displayed[mock_displayed_i].hidden_item_mask,
- hidden_item_mask, text_buf);
- }
- mock_displayed_i++;
-}
-
-static void displayed_no_extra(int line)
-{
- char text_info[32], text_buf[128];
-
- sprintf(text_info, "(line #%d)", line);
-
- if (mock_displayed_i == 0)
- sprintf(text_buf, " %s no screen", text_info);
- else
- sprintf(text_buf, " %s no extra screens", text_info);
- TEST_EQ(mock_displayed_count, mock_displayed_i, text_buf);
-}
-
-#define DISPLAYED_EQ(...) displayed_eq(__VA_ARGS__, __LINE__)
-
-#define DISPLAYED_PASS() \
- displayed_eq("", MOCK_IGNORE, MOCK_IGNORE, MOCK_IGNORE, MOCK_IGNORE, \
- __LINE__)
-
-#define DISPLAYED_NO_EXTRA() displayed_no_extra(__LINE__)
-
-/* Reset mock data (for use before each test) */
-static void reset_common_data(void)
-{
- TEST_SUCC(vb2api_init(workbuf, sizeof(workbuf), &ctx),
- "vb2api_init failed");
-
- memset(&gbb, 0, sizeof(gbb));
-
- vb2_nv_init(ctx);
-
- sd = vb2_get_sd(ctx);
-
- ctx->flags |= VB2_CONTEXT_DEV_BOOT_ALLOWED;
-
- /* For check_shutdown_request */
- mock_calls_until_shutdown = 10;
-
- /* Reset mock_screen_temp for test by test temporary screen_info */
- mock_screen_temp = (struct vb2_screen_info){
- .id = MOCK_NO_SCREEN,
- .name = "mock_screen_temp",
- };
-
- /* Mock ui_context based on mock screens */
- memset(&mock_ui_context, 0, sizeof(mock_ui_context));
- mock_ui_context.ctx = ctx;
-
- if (!mock_ui_context.state)
- mock_ui_context.state = malloc(sizeof(*mock_ui_context.state));
- memset(mock_ui_context.state, 0, sizeof(*mock_ui_context.state));
- mock_ui_context.state->screen = &mock_screen_temp;
-
- /* For vb2ex_display_ui */
- memset(mock_displayed, 0, sizeof(mock_displayed));
- mock_displayed_count = 0;
- mock_displayed_i = 0;
-
- /* For VbExKeyboardRead */
- memset(mock_key, 0, sizeof(mock_key));
- memset(mock_key_trusted, 0, sizeof(mock_key_trusted));
- mock_key_count = 0;
- mock_key_total = 0;
-
- /* For mock actions */
- mock_action_called = 0;
- mock_action_countdown_limit = 1;
- mock_action_flags = 0;
- mock_action_delay_ms = 0;
-
- /* For chagen_screen and vb2_get_screen_info */
- mock_get_screen_info_called = 0;
-
- /* For VbTryLoadKernel */
- mock_vbtlk_retval = VB2_ERROR_MOCK;
- mock_vbtlk_expected_flag = MOCK_IGNORE;
-
- /* For vb2ex_run_altfw */
- mock_run_altfw_called = 0;
- mock_altfw_last = -100;
- mock_altfw_count = 2;
-
- /* For vb2ex_mtime and vb2ex_msleep */
- mock_time_ms = mock_time_start_ms;
-}
-
-/* Mock functions */
-struct vb2_gbb_header *vb2_get_gbb(struct vb2_context *c)
-{
- return &gbb;
-}
-
-uint32_t VbExIsShutdownRequested(void)
-{
- if (mock_calls_until_shutdown < 0) /* Never request shutdown */
- return 0;
- if (mock_calls_until_shutdown == 0)
- return 1;
- mock_calls_until_shutdown--;
-
- return 0;
-}
-
-const struct vb2_screen_info *vb2_get_screen_info(enum vb2_screen screen)
-{
- mock_get_screen_info_called++;
-
- switch ((int)screen) {
- case MOCK_SCREEN_BLANK:
- return &mock_screen_blank;
- case MOCK_SCREEN_BASE:
- return &mock_screen_base;
- case MOCK_SCREEN_MENU:
- return &mock_screen_menu;
- case MOCK_SCREEN_TARGET0:
- return &mock_screen_target0;
- case MOCK_SCREEN_TARGET1:
- return &mock_screen_target1;
- case MOCK_SCREEN_TARGET2:
- return &mock_screen_target2;
- case MOCK_SCREEN_ACTION:
- return &mock_screen_action;
- case MOCK_SCREEN_ALL_ACTION:
- return &mock_screen_all_action;
- case MOCK_NO_SCREEN:
- return NULL;
- default:
- mock_screen_temp.id = screen;
- return &mock_screen_temp;
- }
-}
-
-vb2_error_t vb2ex_display_ui(enum vb2_screen screen,
- uint32_t locale_id,
- uint32_t selected_item,
- uint32_t disabled_item_mask,
- uint32_t hidden_item_mask,
- int timer_disabled,
- uint32_t current_page,
- enum vb2_ui_error error_code)
-{
- struct display_call displayed = (struct display_call){
- .screen = vb2_get_screen_info(screen),
- .locale_id = locale_id,
- .selected_item = selected_item,
- .disabled_item_mask = disabled_item_mask,
- .hidden_item_mask = hidden_item_mask,
- .timer_disabled = timer_disabled,
- .current_page = current_page,
- .error_code = error_code,
- };
-
- /* Ignore repeated calls with same arguments */
- if (mock_displayed_count > 0 &&
- !memcmp(&mock_displayed[mock_displayed_count - 1], &displayed,
- sizeof(struct display_call)))
- return VB2_SUCCESS;
-
- VB2_DEBUG("displayed %d: screen=%#x, locale_id=%u, selected_item=%u, "
- "disabled_item_mask=%#x, hidden_item_mask=%#x, "
- "timer_disabled=%d, current_page=%u, error=%#x\n",
- mock_displayed_count, screen, locale_id, selected_item,
- disabled_item_mask, hidden_item_mask,
- timer_disabled, current_page, error_code);
-
- if (mock_displayed_count >= ARRAY_SIZE(mock_displayed)) {
- TEST_TRUE(0, " mock vb2ex_display_ui ran out of entries!");
- return VB2_ERROR_MOCK;
- }
-
- mock_displayed[mock_displayed_count++] = displayed;
-
- return VB2_SUCCESS;
-}
-
-uint32_t VbExKeyboardRead(void)
-{
- return VbExKeyboardReadWithFlags(NULL);
-}
-
-uint32_t VbExKeyboardReadWithFlags(uint32_t *key_flags)
-{
- if (mock_key_count < mock_key_total) {
- if (key_flags != NULL) {
- if (mock_key_trusted[mock_key_count])
- *key_flags = VB_KEY_FLAG_TRUSTED_KEYBOARD;
- else
- *key_flags = 0;
- }
- return mock_key[mock_key_count++];
- }
-
- return 0;
-}
-
-vb2_error_t VbTryLoadKernel(struct vb2_context *c, uint32_t disk_flags)
-{
- TEST_EQ(mock_vbtlk_expected_flag, disk_flags,
- " unexpected disk_flags");
- return mock_vbtlk_retval;
-}
-
-vb2_error_t vb2ex_run_altfw(uint32_t altfw_id)
-{
- mock_run_altfw_called++;
- mock_altfw_last = altfw_id;
-
- if (altfw_id <= mock_altfw_count)
- return VB2_SUCCESS;
- else
- return VB2_ERROR_UNKNOWN;
-}
-
-uint32_t vb2ex_get_altfw_count(void)
-{
- return mock_altfw_count;
-}
-
-uint32_t vb2ex_mtime(void)
-{
- return mock_time_ms;
-}
-
-void vb2ex_msleep(uint32_t msec)
-{
- mock_time_ms += msec;
-}
-
-/* Tests */
-static void menu_prev_tests(void)
-{
- VB2_DEBUG("Testing menu_prev...\n");
-
- /* Valid action */
- reset_common_data();
- mock_ui_context.state->screen = &mock_screen_menu;
- mock_ui_context.state->selected_item = 2;
- mock_ui_context.key = VB_KEY_UP;
- TEST_EQ(vb2_ui_menu_prev(&mock_ui_context), VB2_SUCCESS,
- "valid action");
- screen_state_eq(mock_ui_context.state, MOCK_SCREEN_MENU, 1,
- MOCK_IGNORE);
-
- /* Valid action with hidden mask */
- reset_common_data();
- mock_ui_context.state->screen = &mock_screen_menu;
- mock_ui_context.state->selected_item = 2;
- mock_ui_context.state->hidden_item_mask = 0x0a; /* 0b01010 */
- mock_ui_context.key = VB_KEY_UP;
- TEST_EQ(vb2_ui_menu_prev(&mock_ui_context), VB2_SUCCESS,
- "valid action with hidden mask");
- screen_state_eq(mock_ui_context.state, MOCK_SCREEN_MENU, 0,
- MOCK_IGNORE);
-
- /* Disabled mask does not affect menu_prev */
- reset_common_data();
- mock_ui_context.state->screen = &mock_screen_menu;
- mock_ui_context.state->selected_item = 2;
- mock_ui_context.state->disabled_item_mask = 0x0a; /* 0b01010 */
- mock_ui_context.key = VB_KEY_UP;
- TEST_EQ(vb2_ui_menu_prev(&mock_ui_context), VB2_SUCCESS,
- "valid action with disabled mask");
- screen_state_eq(mock_ui_context.state, MOCK_SCREEN_MENU, 1,
- MOCK_IGNORE);
-
- /* Invalid action (blocked) */
- reset_common_data();
- mock_ui_context.state->screen = &mock_screen_menu;
- mock_ui_context.state->selected_item = 0;
- mock_ui_context.key = VB_KEY_UP;
- TEST_EQ(vb2_ui_menu_prev(&mock_ui_context), VB2_SUCCESS,
- "invalid action (blocked)");
- screen_state_eq(mock_ui_context.state, MOCK_SCREEN_MENU, 0,
- MOCK_IGNORE);
-
- /* Invalid action (blocked by mask) */
- reset_common_data();
- mock_ui_context.state->screen = &mock_screen_menu;
- mock_ui_context.state->selected_item = 2;
- mock_ui_context.state->hidden_item_mask = 0x0b; /* 0b01011 */
- mock_ui_context.key = VB_KEY_UP;
- TEST_EQ(vb2_ui_menu_prev(&mock_ui_context), VB2_SUCCESS,
- "invalid action (blocked by mask)");
- screen_state_eq(mock_ui_context.state, MOCK_SCREEN_MENU, 2,
- MOCK_IGNORE);
-
- /* Ignore volume-up when not DETACHABLE */
- if (!DETACHABLE) {
- reset_common_data();
- mock_ui_context.state->screen = &mock_screen_menu;
- mock_ui_context.state->selected_item = 2;
- mock_ui_context.key = VB_BUTTON_VOL_UP_SHORT_PRESS;
- TEST_EQ(vb2_ui_menu_prev(&mock_ui_context), VB2_SUCCESS,
- "ignore volume-up when not DETACHABLE");
- screen_state_eq(mock_ui_context.state, MOCK_SCREEN_MENU, 2,
- MOCK_IGNORE);
- }
-
- VB2_DEBUG("...done.\n");
-}
-
-static void menu_next_tests(void)
-{
- VB2_DEBUG("Testing menu_next...\n");
-
- /* Valid action */
- reset_common_data();
- mock_ui_context.state->screen = &mock_screen_menu;
- mock_ui_context.state->selected_item = 2;
- mock_ui_context.key = VB_KEY_DOWN;
- TEST_EQ(vb2_ui_menu_next(&mock_ui_context), VB2_SUCCESS,
- "valid action");
- screen_state_eq(mock_ui_context.state, MOCK_SCREEN_MENU, 3,
- MOCK_IGNORE);
-
- /* Valid action with hidden mask */
- reset_common_data();
- mock_ui_context.state->screen = &mock_screen_menu;
- mock_ui_context.state->selected_item = 2;
- mock_ui_context.state->hidden_item_mask = 0x0a; /* 0b01010 */
- mock_ui_context.key = VB_KEY_DOWN;
- TEST_EQ(vb2_ui_menu_next(&mock_ui_context), VB2_SUCCESS,
- "valid action with hidden mask");
- screen_state_eq(mock_ui_context.state, MOCK_SCREEN_MENU, 4,
- MOCK_IGNORE);
-
- /* Disabled mask does not affect menu_next */
- reset_common_data();
- mock_ui_context.state->screen = &mock_screen_menu;
- mock_ui_context.state->selected_item = 2;
- mock_ui_context.state->disabled_item_mask = 0x0a; /* 0b01010 */
- mock_ui_context.key = VB_KEY_DOWN;
- TEST_EQ(vb2_ui_menu_next(&mock_ui_context), VB2_SUCCESS,
- "valid action with disabled mask");
- screen_state_eq(mock_ui_context.state, MOCK_SCREEN_MENU, 3,
- MOCK_IGNORE);
-
- /* Invalid action (blocked) */
- reset_common_data();
- mock_ui_context.state->screen = &mock_screen_menu;
- mock_ui_context.state->selected_item = 4;
- mock_ui_context.key = VB_KEY_DOWN;
- TEST_EQ(vb2_ui_menu_next(&mock_ui_context), VB2_SUCCESS,
- "invalid action (blocked)");
- screen_state_eq(mock_ui_context.state, MOCK_SCREEN_MENU, 4,
- MOCK_IGNORE);
-
- /* Invalid action (blocked by mask) */
- reset_common_data();
- mock_ui_context.state->screen = &mock_screen_menu;
- mock_ui_context.state->selected_item = 2;
- mock_ui_context.state->hidden_item_mask = 0x1a; /* 0b11010 */
- mock_ui_context.key = VB_KEY_DOWN;
- TEST_EQ(vb2_ui_menu_next(&mock_ui_context), VB2_SUCCESS,
- "invalid action (blocked by mask)");
- screen_state_eq(mock_ui_context.state, MOCK_SCREEN_MENU, 2,
- MOCK_IGNORE);
-
- /* Ignore volume-down when not DETACHABLE */
- if (!DETACHABLE) {
- reset_common_data();
- mock_ui_context.state->screen = &mock_screen_menu;
- mock_ui_context.state->selected_item = 2;
- mock_ui_context.key = VB_BUTTON_VOL_DOWN_SHORT_PRESS;
- TEST_EQ(vb2_ui_menu_next(&mock_ui_context), VB2_SUCCESS,
- "ignore volume-down when not DETACHABLE");
- screen_state_eq(mock_ui_context.state, MOCK_SCREEN_MENU, 2,
- MOCK_IGNORE);
- }
-
- VB2_DEBUG("...done.\n");
-}
-
-static vb2_error_t try_menu_select_helper(void)
-{
- VB2_TRY(vb2_ui_menu_select(&mock_ui_context));
- return VB2_ERROR_MOCK;
-}
-
-static void menu_select_tests(void)
-{
- VB2_DEBUG("Testing menu_select...\n");
-
- /* select action with no item screen */
- reset_common_data();
- mock_ui_context.state->screen = &mock_screen_base;
- mock_ui_context.key = VB_KEY_ENTER;
- TEST_EQ(vb2_ui_menu_select(&mock_ui_context), VB2_SUCCESS,
- "vb2_ui_menu_select with no item screen");
- screen_state_eq(mock_ui_context.state, MOCK_SCREEN_BASE, 0,
- MOCK_IGNORE);
-
- /* VB2_TRY around item selection should return right away */
- reset_common_data();
- mock_ui_context.state->screen = &mock_screen_menu;
- mock_ui_context.key = VB_KEY_ENTER;
- TEST_NEQ(try_menu_select_helper(), VB2_ERROR_MOCK,
- "continued executing after VB2_TRY(menu_select)");
-
- /* Try to select an item with a target (item 2) */
- reset_common_data();
- mock_ui_context.state->screen = &mock_screen_menu;
- mock_ui_context.state->selected_item = 2;
- mock_ui_context.key = VB_KEY_ENTER;
- TEST_EQ(vb2_ui_menu_select(&mock_ui_context), VB2_REQUEST_UI_CONTINUE,
- "select an item with a target");
- screen_state_eq(mock_ui_context.state, MOCK_SCREEN_TARGET2, 0,
- MOCK_IGNORE);
-
- /* Try to select an item with an action (item 3) */
- reset_common_data();
- mock_ui_context.state->screen = &mock_screen_menu;
- mock_ui_context.state->selected_item = 3;
- mock_ui_context.key = VB_KEY_ENTER;
- TEST_EQ(vb2_ui_menu_select(&mock_ui_context),
- VB2_SUCCESS, "select an item with an action");
- TEST_EQ(mock_action_called, 1, " action called once");
-
- /* Try to select an item with neither targets nor actions (item 4) */
- reset_common_data();
- mock_ui_context.state->screen = &mock_screen_menu;
- mock_ui_context.state->selected_item = 4;
- mock_ui_context.key = VB_KEY_ENTER;
- TEST_EQ(vb2_ui_menu_select(&mock_ui_context), VB2_SUCCESS,
- "select an item with neither targets nor actions");
- screen_state_eq(mock_ui_context.state, MOCK_SCREEN_MENU, 4,
- MOCK_IGNORE);
-
- /* Cannot select a disabled item (item 3) */
- reset_common_data();
- mock_ui_context.state->screen = &mock_screen_menu;
- mock_ui_context.state->selected_item = 3;
- mock_ui_context.state->disabled_item_mask = 0x08; /* 0b01000 */
- mock_ui_context.key = VB_KEY_ENTER;
- TEST_EQ(vb2_ui_menu_select(&mock_ui_context), VB2_SUCCESS,
- "cannot select a disabled item");
- TEST_EQ(mock_action_called, 0, " no action called");
-
- /* Ignore power button short press when not DETACHABLE */
- if (!DETACHABLE) {
- reset_common_data();
- mock_ui_context.state->screen = &mock_screen_menu;
- mock_ui_context.state->selected_item = 1;
- mock_ui_context.key = VB_BUTTON_POWER_SHORT_PRESS;
- TEST_EQ(vb2_ui_menu_select(&mock_ui_context), VB2_SUCCESS,
- "ignore power button short press when not DETACHABLE");
- screen_state_eq(mock_ui_context.state, MOCK_SCREEN_MENU, 1,
- MOCK_IGNORE);
- }
-
- VB2_DEBUG("...done.\n");
-}
-
-static void ui_loop_tests(void)
-{
- int i;
- const char *action_interfere_test_names[] = {
- "hook all actions: screen action return SUCCESS",
- "hook all actions: target action hooked return SUCCESS",
- "hook all actions: global action return SUCCESS",
- };
-
- VB2_DEBUG("Testing ui_loop...\n");
-
- /* Die if no root screen */
- reset_common_data();
- TEST_ABORT(vb2_ui_loop(ctx, MOCK_NO_SCREEN, NULL),
- "die if no root screen");
- DISPLAYED_NO_EXTRA();
-
- /* Shutdown if requested */
- reset_common_data();
- TEST_EQ(vb2_ui_loop(ctx, MOCK_SCREEN_BASE, NULL),
- VB2_REQUEST_SHUTDOWN, "shutdown if requested");
- TEST_EQ(mock_calls_until_shutdown, 0, " used up shutdown request");
- DISPLAYED_EQ("mock_screen_base", MOCK_SCREEN_BASE, MOCK_IGNORE,
- MOCK_IGNORE, MOCK_IGNORE);
- DISPLAYED_NO_EXTRA();
-
- /* Screen action */
- reset_common_data();
- mock_calls_until_shutdown = -1;
- mock_action_countdown_limit = 10;
- TEST_EQ(vb2_ui_loop(ctx, MOCK_SCREEN_ACTION, NULL),
- VB2_SUCCESS, "screen action");
- TEST_EQ(mock_action_called, 10, " action called");
-
- /* Global action */
- reset_common_data();
- mock_calls_until_shutdown = -1;
- mock_action_countdown_limit = 10;
- TEST_EQ(vb2_ui_loop(ctx, MOCK_SCREEN_BLANK, mock_action_countdown),
- VB2_SUCCESS, "global action");
- TEST_EQ(mock_action_called, 10, " action called");
-
- /* Global action can change screen */
- reset_common_data();
- TEST_EQ(vb2_ui_loop(ctx, MOCK_SCREEN_BLANK, mock_action_screen_change),
- VB2_REQUEST_SHUTDOWN, "global action can change screen");
- DISPLAYED_PASS();
- DISPLAYED_EQ("change to mock_screen_base", MOCK_SCREEN_BASE,
- MOCK_IGNORE, MOCK_IGNORE, MOCK_IGNORE);
- DISPLAYED_NO_EXTRA();
-
- /*
- * Hook all actions, and receive SUCCESS from actions one by one
- * Action #0: screen action
- * Action #1: item target action
- * Action #2: global action
- */
- for (i = 0; i <= 2; i++) {
- reset_common_data();
- add_mock_keypress(VB_KEY_ENTER);
- mock_calls_until_shutdown = -1;
- mock_action_flags |= (1 << i);
- TEST_EQ(vb2_ui_loop(ctx, MOCK_SCREEN_ALL_ACTION,
- mock_action_flag2),
- VB2_SUCCESS, action_interfere_test_names[i]);
- }
-
- /* KEY_UP, KEY_DOWN, and KEY_ENTER navigation */
- reset_common_data();
- add_mock_keypress(VB_KEY_UP); /* (blocked) */
- add_mock_keypress(VB_KEY_DOWN);
- add_mock_keypress(VB_KEY_DOWN);
- add_mock_keypress(VB_KEY_DOWN);
- add_mock_keypress(VB_KEY_DOWN);
- add_mock_keypress(VB_KEY_DOWN); /* (blocked) */
- add_mock_keypress(VB_KEY_UP);
- add_mock_keypress(VB_KEY_UP);
- add_mock_keypress(VB_KEY_ENTER);
- TEST_EQ(vb2_ui_loop(ctx, MOCK_SCREEN_MENU, NULL),
- VB2_REQUEST_SHUTDOWN, "KEY_UP, KEY_DOWN, and KEY_ENTER");
- DISPLAYED_EQ("mock_screen_menu", MOCK_SCREEN_MENU, MOCK_IGNORE, 0,
- MOCK_IGNORE);
- DISPLAYED_EQ("mock_screen_menu", MOCK_SCREEN_MENU, MOCK_IGNORE, 1,
- MOCK_IGNORE);
- DISPLAYED_EQ("mock_screen_menu", MOCK_SCREEN_MENU, MOCK_IGNORE, 2,
- MOCK_IGNORE);
- DISPLAYED_EQ("mock_screen_menu", MOCK_SCREEN_MENU, MOCK_IGNORE, 3,
- MOCK_IGNORE);
- DISPLAYED_EQ("mock_screen_menu", MOCK_SCREEN_MENU, MOCK_IGNORE, 4,
- MOCK_IGNORE);
- DISPLAYED_EQ("mock_screen_menu", MOCK_SCREEN_MENU, MOCK_IGNORE, 3,
- MOCK_IGNORE);
- DISPLAYED_EQ("mock_screen_menu", MOCK_SCREEN_MENU, MOCK_IGNORE, 2,
- MOCK_IGNORE);
- DISPLAYED_EQ("mock_screen_target_2", MOCK_SCREEN_TARGET2, MOCK_IGNORE,
- MOCK_IGNORE, MOCK_IGNORE);
- DISPLAYED_NO_EXTRA();
-
- /* For DETACHABLE */
- if (DETACHABLE) {
- reset_common_data();
- add_mock_keypress(VB_BUTTON_VOL_UP_SHORT_PRESS);
- add_mock_keypress(VB_BUTTON_VOL_DOWN_SHORT_PRESS);
- add_mock_keypress(VB_BUTTON_VOL_DOWN_SHORT_PRESS);
- add_mock_keypress(VB_BUTTON_VOL_DOWN_SHORT_PRESS);
- add_mock_keypress(VB_BUTTON_VOL_DOWN_SHORT_PRESS);
- add_mock_keypress(VB_BUTTON_VOL_DOWN_SHORT_PRESS);
- add_mock_keypress(VB_BUTTON_VOL_UP_SHORT_PRESS);
- add_mock_keypress(VB_BUTTON_VOL_UP_SHORT_PRESS);
- add_mock_keypress(VB_BUTTON_POWER_SHORT_PRESS);
- TEST_EQ(vb2_ui_loop(ctx, MOCK_SCREEN_MENU, NULL),
- VB2_REQUEST_SHUTDOWN, "DETACHABLE");
- DISPLAYED_EQ("mock_screen_menu", MOCK_SCREEN_MENU, MOCK_IGNORE,
- 0, MOCK_IGNORE);
- DISPLAYED_EQ("mock_screen_menu", MOCK_SCREEN_MENU, MOCK_IGNORE,
- 1, MOCK_IGNORE);
- DISPLAYED_EQ("mock_screen_menu", MOCK_SCREEN_MENU, MOCK_IGNORE,
- 2, MOCK_IGNORE);
- DISPLAYED_EQ("mock_screen_menu", MOCK_SCREEN_MENU, MOCK_IGNORE,
- 3, MOCK_IGNORE);
- DISPLAYED_EQ("mock_screen_menu", MOCK_SCREEN_MENU, MOCK_IGNORE,
- 4, MOCK_IGNORE);
- DISPLAYED_EQ("mock_screen_menu", MOCK_SCREEN_MENU, MOCK_IGNORE,
- 3, MOCK_IGNORE);
- DISPLAYED_EQ("mock_screen_menu", MOCK_SCREEN_MENU, MOCK_IGNORE,
- 2, MOCK_IGNORE);
- DISPLAYED_EQ("mock_screen_target_2", MOCK_SCREEN_TARGET2,
- MOCK_IGNORE, MOCK_IGNORE, MOCK_IGNORE);
- DISPLAYED_NO_EXTRA();
- }
-
- VB2_DEBUG("...done.\n");
-}
-
-static void ui_loop_delay_tests(void)
-{
- VB2_DEBUG("Testing ui_loop delay...\n");
-
- /* Sleep for 20 ms each iteration */
- reset_common_data();
- mock_calls_until_shutdown = 1;
- TEST_EQ(vb2_ui_loop(ctx, MOCK_SCREEN_BASE, mock_action_msleep),
- VB2_REQUEST_SHUTDOWN, " sleep for 20 ms in each iteration");
- TEST_EQ(mock_time_ms - mock_time_start_ms, KEY_DELAY_MS,
- " delay 20 ms in total");
-
- /* Complement to 20 ms */
- reset_common_data();
- mock_calls_until_shutdown = 1;
- mock_action_delay_ms = KEY_DELAY_MS / 2;
- TEST_EQ(vb2_ui_loop(ctx, MOCK_SCREEN_BASE, mock_action_msleep),
- VB2_REQUEST_SHUTDOWN, " complement to 20 ms");
- TEST_EQ(mock_time_ms - mock_time_start_ms, KEY_DELAY_MS,
- " delay 10 ms in total");
-
- /* No extra sleep if an iteration takes longer than KEY_DELAY_MS */
- reset_common_data();
- mock_calls_until_shutdown = 1;
- mock_action_delay_ms = 1234;
- TEST_EQ(vb2_ui_loop(ctx, MOCK_SCREEN_BASE, mock_action_msleep),
- VB2_REQUEST_SHUTDOWN, " no extra sleep time");
- TEST_EQ(mock_time_ms - mock_time_start_ms, mock_action_delay_ms,
- " no extra delay");
-
- /* Integer overflow */
- reset_common_data();
- mock_calls_until_shutdown = 1;
- mock_time_ms = UINT32_MAX;
- TEST_EQ(vb2_ui_loop(ctx, MOCK_SCREEN_BASE, mock_action_msleep),
- VB2_REQUEST_SHUTDOWN, " integer overflow #1");
- TEST_EQ(mock_time_ms - UINT32_MAX, KEY_DELAY_MS,
- " delay 20 ms in total");
-
- reset_common_data();
- mock_calls_until_shutdown = 1;
- mock_time_ms = UINT32_MAX;
- mock_action_delay_ms = KEY_DELAY_MS / 2;
- TEST_EQ(vb2_ui_loop(ctx, MOCK_SCREEN_BASE, mock_action_msleep),
- VB2_REQUEST_SHUTDOWN, " integer overflow #2");
- TEST_EQ(mock_time_ms - UINT32_MAX, KEY_DELAY_MS,
- " delay 10 ms in total");
-
- reset_common_data();
- mock_calls_until_shutdown = 1;
- mock_time_ms = UINT32_MAX;
- mock_action_delay_ms = 1234;
- TEST_EQ(vb2_ui_loop(ctx, MOCK_SCREEN_BASE, mock_action_msleep),
- VB2_REQUEST_SHUTDOWN, " integer overflow #3");
- TEST_EQ(mock_time_ms - UINT32_MAX, mock_action_delay_ms,
- " no extra delay");
-
- VB2_DEBUG("...done.\n");
-}
-
-int main(void)
-{
- /* Input actions */
- menu_prev_tests();
- menu_next_tests();
- menu_select_tests();
-
- /* Core UI loop */
- ui_loop_tests();
- ui_loop_delay_tests();
-
- return gTestSuccess ? 0 : 255;
-}