vboot/ui: add power off options

Add power off options to screens.

BRANCH=none
BUG=b:146399181, b:145098577
TEST=make runtests
TEST=USE="menu_ui" emerge-nami depthcharge

Cq-Depend: chromium:2237367
Change-Id: I356c56361a4282b456c3a4661e518a84944e983b
Signed-off-by: Yu-Ping Wu <yupingso@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/vboot_reference/+/2237366
Reviewed-by: Joel Kitching <kitching@chromium.org>
diff --git a/firmware/2lib/2ui_screens.c b/firmware/2lib/2ui_screens.c
index 2ac3f5e..b41146d 100644
--- a/firmware/2lib/2ui_screens.c
+++ b/firmware/2lib/2ui_screens.c
@@ -40,6 +40,17 @@
 	.target = VB2_SCREEN_ADVANCED_OPTIONS, \
 }
 
+/* Action that will power off the device. */
+static vb2_error_t power_off_action(struct vb2_ui_context *ui)
+{
+	return VB2_REQUEST_SHUTDOWN;
+}
+
+#define POWER_OFF_ITEM { \
+	.text = "Power off", \
+	.action = power_off_action, \
+}
+
 /******************************************************************************/
 /* VB2_SCREEN_BLANK */
 
@@ -131,6 +142,7 @@
 static const struct vb2_menu_item recovery_broken_items[] = {
 	LANGUAGE_SELECT_ITEM,
 	ADVANCED_OPTIONS_ITEM,
+	POWER_OFF_ITEM,
 };
 
 static const struct vb2_screen_info recovery_broken_screen = {
@@ -165,6 +177,7 @@
 		.target = VB2_SCREEN_RECOVERY_TO_DEV,
 	},
 	[ADVANCED_OPTIONS_ITEM_BACK] = BACK_ITEM,
+	POWER_OFF_ITEM,
 };
 
 static const struct vb2_screen_info advanced_options_screen = {
@@ -203,6 +216,7 @@
 		.target = VB2_SCREEN_RECOVERY_DISK_STEP1,
 	},
 	ADVANCED_OPTIONS_ITEM,
+	POWER_OFF_ITEM,
 };
 
 static const struct vb2_screen_info recovery_select_screen = {
@@ -217,6 +231,7 @@
 
 static const struct vb2_menu_item recovery_invalid_items[] = {
 	LANGUAGE_SELECT_ITEM,
+	POWER_OFF_ITEM,
 };
 
 static const struct vb2_screen_info recovery_invalid_screen = {
@@ -321,6 +336,7 @@
 		.text = "Cancel",
 		.action = vb2_ui_change_root,
 	},
+	POWER_OFF_ITEM,
 };
 
 static const struct vb2_screen_info recovery_to_dev_screen = {
@@ -338,6 +354,7 @@
 	LANGUAGE_SELECT_ITEM,
 	NEXT_ITEM(VB2_SCREEN_RECOVERY_PHONE_STEP2),
 	BACK_ITEM,
+	POWER_OFF_ITEM,
 };
 
 static const struct vb2_screen_info recovery_phone_step1_screen = {
@@ -352,6 +369,7 @@
 static const struct vb2_menu_item recovery_phone_step2_items[] = {
 	LANGUAGE_SELECT_ITEM,
 	BACK_ITEM,
+	POWER_OFF_ITEM,
 };
 
 static const struct vb2_screen_info recovery_phone_step2_screen = {
@@ -367,6 +385,7 @@
 	LANGUAGE_SELECT_ITEM,
 	NEXT_ITEM(VB2_SCREEN_RECOVERY_DISK_STEP2),
 	BACK_ITEM,
+	POWER_OFF_ITEM,
 };
 
 static const struct vb2_screen_info recovery_disk_step1_screen = {
@@ -382,6 +401,7 @@
 	LANGUAGE_SELECT_ITEM,
 	NEXT_ITEM(VB2_SCREEN_RECOVERY_DISK_STEP3),
 	BACK_ITEM,
+	POWER_OFF_ITEM,
 };
 
 static const struct vb2_screen_info recovery_disk_step2_screen = {
@@ -396,6 +416,7 @@
 static const struct vb2_menu_item recovery_disk_step3_items[] = {
 	LANGUAGE_SELECT_ITEM,
 	BACK_ITEM,
+	POWER_OFF_ITEM,
 };
 
 static const struct vb2_screen_info recovery_disk_step3_screen = {
@@ -539,6 +560,7 @@
 		.action = vb2_ui_developer_mode_boot_external_action,
 	},
 	ADVANCED_OPTIONS_ITEM,
+	POWER_OFF_ITEM,
 };
 
 static const struct vb2_screen_info developer_mode_screen = {
@@ -574,6 +596,7 @@
 		.text = "Cancel",
 		.action = vb2_ui_change_root,
 	},
+	POWER_OFF_ITEM,
 };
 
 static const struct vb2_screen_info developer_to_norm_screen = {
@@ -588,6 +611,7 @@
 static const struct vb2_menu_item developer_boot_external_items[] = {
 	LANGUAGE_SELECT_ITEM,
 	BACK_ITEM,
+	POWER_OFF_ITEM,
 };
 
 static const struct vb2_screen_info developer_boot_external_screen = {
@@ -603,6 +627,7 @@
 static const struct vb2_menu_item developer_invalid_disk_items[] = {
 	LANGUAGE_SELECT_ITEM,
 	BACK_ITEM,
+	POWER_OFF_ITEM,
 };
 
 static const struct vb2_screen_info developer_invalid_disk_screen = {
diff --git a/tests/vb2_ui_tests.c b/tests/vb2_ui_tests.c
index 676f16f..407a081 100644
--- a/tests/vb2_ui_tests.c
+++ b/tests/vb2_ui_tests.c
@@ -694,6 +694,17 @@
 	TEST_EQ(vb2_nv_get(ctx, VB2_NV_DISABLE_DEV_REQUEST), 0,
 		"  disable dev request");
 
+	/* Power off */
+	reset_common_data(FOR_DEVELOPER);
+	add_mock_vbtlk(VB2_SUCCESS, VB_DISK_FLAG_FIXED);
+	/* Navigate to the bottom most menu item */
+	add_mock_keypress(VB_KEY_DOWN);
+	add_mock_keypress(VB_KEY_DOWN);
+	add_mock_keypress(VB_KEY_DOWN);
+	add_mock_keypress(VB_KEY_ENTER);
+	TEST_EQ(vb2_developer_menu(ctx), VB2_REQUEST_SHUTDOWN,
+		"select power off");
+
 	VB2_DEBUG("...done.\n");
 }
 
@@ -1077,7 +1088,6 @@
 	add_mock_keypress(VB_KEY_ESC);
 	add_mock_keypress(VB_KEY_DOWN);
 	add_mock_keypress(VB_KEY_DOWN);
-	add_mock_keypress(VB_KEY_DOWN);  /* Blocked */
 	TEST_EQ(vb2_developer_menu(ctx), VB2_REQUEST_SHUTDOWN,
 		"dev mode screen");
 	/* #4: Advanced options */
@@ -1113,7 +1123,6 @@
 	add_mock_keypress(VB_KEY_DOWN);
 	add_mock_keypress(VB_KEY_DOWN);
 	add_mock_keypress(VB_KEY_ENTER);
-	add_mock_keypress(VB_KEY_DOWN);
 	extend_calls_until_shutdown();
 	TEST_EQ(vb2_developer_menu(ctx), VB2_REQUEST_SHUTDOWN,
 		"advanced options screen");
@@ -1157,7 +1166,6 @@
 	add_mock_keypress(VB_KEY_ENTER);
 	/* End of menu */
 	add_mock_keypress(VB_KEY_ESC);
-	add_mock_keypress(VB_KEY_DOWN);  /* Blocked */
 	extend_calls_until_shutdown();
 	TEST_EQ(vb2_broken_recovery_menu(ctx), VB2_REQUEST_SHUTDOWN,
 		"broken screen");
@@ -1190,7 +1198,6 @@
 	add_mock_keypress(VB_KEY_ENTER);
 	/* End of menu */
 	add_mock_keypress(VB_KEY_ENTER);
-	add_mock_keypress(VB_KEY_DOWN);  /* Blocked */
 	extend_calls_until_shutdown();
 	TEST_EQ(vb2_broken_recovery_menu(ctx), VB2_REQUEST_SHUTDOWN,
 		"advanced options screen");
@@ -1239,7 +1246,6 @@
 	add_mock_keypress(VB_KEY_ESC);
 	add_mock_keypress(VB_KEY_DOWN);
 	add_mock_keypress(VB_KEY_DOWN);
-	add_mock_keypress(VB_KEY_DOWN);  /* Blocked */
 	extend_calls_until_shutdown();
 	TEST_EQ(vb2_manual_recovery_menu(ctx), VB2_REQUEST_SHUTDOWN,
 		"recovery select screen");
@@ -1300,7 +1306,6 @@
 	add_mock_keypress(VB_KEY_DOWN);
 	add_mock_keypress(VB_KEY_ENTER);
 	add_mock_keypress(VB_KEY_DOWN);
-	add_mock_keypress(VB_KEY_DOWN);  /* Blocked */
 	extend_calls_until_shutdown();
 	TEST_EQ(vb2_manual_recovery_menu(ctx), VB2_REQUEST_SHUTDOWN,
 		"advanced options screen");