diff options
author | Hsuan Ting Chen <roccochen@chromium.org> | 2020-09-23 14:55:24 +0800 |
---|---|---|
committer | Commit Bot <commit-bot@chromium.org> | 2020-11-12 12:40:03 +0000 |
commit | 58894ec1de7fa63948a04f72434931081f0458e4 (patch) | |
tree | 279443064ae7c06da339f14c656721e1be97a98e | |
parent | 7991ecdb219a5290e2e5a9663b19fce8e5b15145 (diff) | |
download | vboot-58894ec1de7fa63948a04f72434931081f0458e4.tar.gz |
vboot/ui: Remove extra delay for long iteration time
If an iteration takes longer than KEY_DELAY_MS, no extra delay.
Otherwise, delay until the iteration time reaches KEY_DELAY_MS.
BUG=b:168776970
BRANCH=none
TEST=Build locally
Signed-off-by: Hsuan Ting Chen <roccochen@chromium.org>
Change-Id: Ia78dbe1cc87d08c02f99f4fc9269929c12c18b77
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/vboot_reference/+/2424373
-rw-r--r-- | firmware/2lib/2ui.c | 7 | ||||
-rw-r--r-- | tests/vb2_ui_action_tests.c | 85 |
2 files changed, 91 insertions, 1 deletions
diff --git a/firmware/2lib/2ui.c b/firmware/2lib/2ui.c index 24f74736..10de1760 100644 --- a/firmware/2lib/2ui.c +++ b/firmware/2lib/2ui.c @@ -300,6 +300,7 @@ vb2_error_t ui_loop(struct vb2_context *ctx, enum vb2_screen root_screen_id, const struct vb2_menu *menu; const struct vb2_screen_info *root_info; uint32_t key_flags; + uint32_t start_time_ms, elapsed_ms; vb2_error_t rv; memset(&ui, 0, sizeof(ui)); @@ -316,6 +317,8 @@ vb2_error_t ui_loop(struct vb2_context *ctx, enum vb2_screen root_screen_id, prev_error_code = VB2_UI_ERROR_NONE; while (1) { + start_time_ms = vb2ex_mtime(); + /* Draw if there are state changes. */ if (memcmp(&prev_state, ui.state, sizeof(*ui.state)) || /* Redraw when timer is disabled. */ @@ -392,7 +395,9 @@ vb2_error_t ui_loop(struct vb2_context *ctx, enum vb2_screen root_screen_id, } /* Delay. */ - vb2ex_msleep(KEY_DELAY_MS); + elapsed_ms = vb2ex_mtime() - start_time_ms; + if (elapsed_ms < KEY_DELAY_MS) + vb2ex_msleep(KEY_DELAY_MS - elapsed_ms); } return VB2_SUCCESS; diff --git a/tests/vb2_ui_action_tests.c b/tests/vb2_ui_action_tests.c index 84bb9e04..f6f18dcc 100644 --- a/tests/vb2_ui_action_tests.c +++ b/tests/vb2_ui_action_tests.c @@ -71,6 +71,9 @@ static int mock_vbexlegacy_called; static enum VbAltFwIndex_t mock_altfw_num_last; static uint32_t mock_bootloader_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; @@ -114,6 +117,13 @@ static vb2_error_t mock_action_flag2(struct vb2_ui_context *ui) return VB2_REQUEST_UI_CONTINUE; } +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_REQUEST_UI_CONTINUE; +} + /* Mock screens */ struct vb2_screen_info mock_screen_temp; const struct vb2_screen_info mock_screen_blank = { @@ -339,6 +349,7 @@ static void reset_common_data(void) 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; @@ -355,6 +366,9 @@ static void reset_common_data(void) mock_vbexlegacy_called = 0; mock_altfw_num_last = -100; mock_bootloader_count = 2; + + /* For vb2ex_mtime and vb2ex_msleep */ + mock_time_ms = mock_time_start_ms; } /* Mock functions */ @@ -499,6 +513,16 @@ uint32_t vb2ex_get_bootloader_count(void) return mock_bootloader_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) { @@ -962,6 +986,66 @@ static void ui_loop_tests(void) 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(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(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(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(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(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(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 */ @@ -977,6 +1061,7 @@ int main(void) /* Core UI loop */ ui_loop_tests(); + ui_loop_delay_tests(); return gTestSuccess ? 0 : 255; } |