platform: msm_shared: Add lock menu support

As a part of verified boot, it requires user to confirm whether
wipe user data when trying to lock the device. So add lock menu
support.

1. Add lock menu
2. Update the unlock warning message base on the newest requirements

Change-Id: I5d8764c27cbf5992d064c1ad4e7646ec134d3d52
diff --git a/platform/msm_shared/display_menu.c b/platform/msm_shared/display_menu.c
index c9a58a8..b554860 100644
--- a/platform/msm_shared/display_menu.c
+++ b/platform/msm_shared/display_menu.c
@@ -41,19 +41,30 @@
 #include <target.h>
 #include <sys/types.h>
 #include <../../../app/aboot/devinfo.h>
+#include <../../../app/aboot/recovery.h>
 
-static const char *unlock_menu_common_msg = "If you unlock the bootloader, "\
-				"you will be able to install "\
-				"custom operating system on this phone.\n\n"\
-				"A custom OS is not subject to the same testing "\
-				"as the original OS, "\
-				"and can cause your phone and installed "\
-				"applications to stop working properly.\n\n"\
+static const char *unlock_menu_common_msg = "By unlocking the bootloader, you will be able to install "\
+				"custom operating system on this phone. "\
+				"A custom OS is not subject to the same level of testing "\
+				"as the original OS, and can cause your phone "\
+				"and installed applications to stop working properly.\n\n"\
+				"Software integrity cannot be guaranteed with a custom OS, "\
+				"so any data stored on the phone while the bootloader "\
+				"is unlocked may be at risk.\n\n"\
 				"To prevent unauthorized access to your personal data, "\
 				"unlocking the bootloader will also delete all personal "\
-				"data from your phone(a \"factory data reset\").\n\n"\
-				"Press the Volume Up/Down buttons to select Yes "\
-				"or No. Then press the Power button to continue.\n";
+				"data on your phone.\n\n"\
+				"Press the Volume keys to select whether to unlock the bootloader, "\
+				"then the Power Button to continue.\n\n";
+
+static const char *lock_menu_common_msg = "If you lock the bootloader, "\
+				"you will not be able to install "\
+				"custom operating system on this phone.\n\n"\
+				"To prevent unauthorized access to your personal data, "\
+				"locking the bootloader will also delete all personal "\
+				"data on your phone.\n\n"\
+				"Press the Volume keys to select whether to "\
+				"lock the bootloader, then the power button to continue.\n\n";
 
 #define YELLOW_WARNING_MSG	"Your device has loaded a different operating system\n\n "\
 				"Visit this link on another device:\n"
@@ -107,6 +118,18 @@
 		[3] = "Power off\n",
 		[4] = "Boot to FFBM\n"};
 
+static struct unlock_info munlock_info[] = {
+		[DISPLAY_MENU_LOCK] = {UNLOCK, FALSE},
+		[DISPLAY_MENU_UNLOCK] = {UNLOCK, TRUE},
+		[DISPLAY_MENU_LOCK_CRITICAL] = {UNLOCK_CRITICAL, FALSE},
+		[DISPLAY_MENU_UNLOCK_CRITICAL] = {UNLOCK_CRITICAL, TRUE},
+};
+
+struct unlock_option_msg munlock_option_msg[] = {
+		[TRUE] = {"DO NOT UNLOCK THE BOOTLOADER \n", "UNLOCK THE BOOTLOADER \n"},
+		[FALSE] = {"DO NOT LOCK THE BOOTLOADER \n", "LOCK THE BOOTLOADER \n"},
+};
+
 static int big_factor = 2;
 static int common_factor = 1;
 
@@ -207,40 +230,71 @@
 	return str_target;
 }
 
+/**
+  Reset device unlock status
+  @param[in] Type    The type of the unlock.
+                     [DISPLAY_MENU_UNLOCK]: unlock the device
+                     [DISPLAY_MENU_UNLOCK_CRITICAL]: critical unlock the device
+                     [DISPLAY_MENU_LOCK]: lock the device
+                     [DISPLAY_MENU_LOCK_CRITICAL]: critical lock the device
+ **/
+void reset_device_unlock_status (int type)
+{
+	struct recovery_message msg;
+
+	if (type == DISPLAY_MENU_LOCK ||
+		type == DISPLAY_MENU_UNLOCK ||
+		type == DISPLAY_MENU_LOCK_CRITICAL ||
+		type == DISPLAY_MENU_UNLOCK_CRITICAL) {
+		set_device_unlock_value (munlock_info[type].unlock_type,
+				munlock_info[type].unlock_value);
+		memset(&msg, 0, sizeof(msg));
+		snprintf(msg.recovery, sizeof(msg.recovery), "recovery\n--wipe_data");
+		write_misc(0, &msg, sizeof(msg));
+	}
+}
+
 /* msg_lock need to be holded when call this function. */
-void display_unlock_menu_renew(struct select_msg_info *unlock_msg_info, int type)
+static void display_unlock_menu_renew(struct select_msg_info *unlock_msg_info,
+                                      int type, bool status)
 {
 	fbcon_clear();
 	memset(&unlock_msg_info->info, 0, sizeof(struct menu_info));
 
-	display_fbcon_menu_message("Unlock bootloader?\n",
+	display_fbcon_menu_message("<!>\n\n",
 		FBCON_UNLOCK_TITLE_MSG, big_factor);
-	fbcon_draw_line(FBCON_COMMON_MSG);
 
-	display_fbcon_menu_message((char*)unlock_menu_common_msg,
-		FBCON_COMMON_MSG, common_factor);
+	if (status) {
+		display_fbcon_menu_message((char*)unlock_menu_common_msg,
+			FBCON_COMMON_MSG, common_factor);
+	} else {
+		display_fbcon_menu_message((char*)lock_menu_common_msg,
+			FBCON_COMMON_MSG, common_factor);
+	}
+
 	fbcon_draw_line(FBCON_COMMON_MSG);
 	unlock_msg_info->info.option_start[0] = fbcon_get_current_line();
-	display_fbcon_menu_message("Yes\n",
-		FBCON_COMMON_MSG, big_factor);
+	display_fbcon_menu_message((char *)munlock_option_msg[status].ignore_msg,
+                               FBCON_COMMON_MSG, common_factor);
 	unlock_msg_info->info.option_bg[0] = fbcon_get_current_bg();
-	display_fbcon_menu_message("Unlock bootloader(may void warranty)\n",
-		FBCON_COMMON_MSG, common_factor);
 	unlock_msg_info->info.option_end[0] = fbcon_get_current_line();
 	fbcon_draw_line(FBCON_COMMON_MSG);
 	unlock_msg_info->info.option_start[1] = fbcon_get_current_line();
-	display_fbcon_menu_message("No\n",
-		FBCON_COMMON_MSG, big_factor);
+	display_fbcon_menu_message((char *)munlock_option_msg[status].comfirm_msg,
+                               FBCON_COMMON_MSG, common_factor);
 	unlock_msg_info->info.option_bg[1] = fbcon_get_current_bg();
-	display_fbcon_menu_message("Do not unlock bootloader and restart phone\n",
-		FBCON_COMMON_MSG, common_factor);
 	unlock_msg_info->info.option_end[1] = fbcon_get_current_line();
 	fbcon_draw_line(FBCON_COMMON_MSG);
 
-	if (type == UNLOCK)
+	if (type == UNLOCK) {
 		unlock_msg_info->info.msg_type = DISPLAY_MENU_UNLOCK;
-	else if (type == UNLOCK_CRITICAL)
+		if (!status)
+			unlock_msg_info->info.msg_type = DISPLAY_MENU_LOCK;
+	} else if (type == UNLOCK_CRITICAL) {
 		unlock_msg_info->info.msg_type = DISPLAY_MENU_UNLOCK_CRITICAL;
+		if (!status)
+			unlock_msg_info->info.msg_type = DISPLAY_MENU_LOCK_CRITICAL;
+	}
 
 	unlock_msg_info->info.option_num = 2;
 
@@ -472,7 +526,7 @@
 /* The fuction be called after device in fastboot mode,
  * so it's no need to initialize the msg_lock again
  */
-void display_unlock_menu(int type)
+void display_unlock_menu(int type, bool status)
 {
 	struct select_msg_info *unlock_menu_msg_info;
 	unlock_menu_msg_info = &msg_info;
@@ -489,10 +543,11 @@
 	unlock_menu_msg_info->last_msg_type =
 		unlock_menu_msg_info->info.msg_type;
 
-	display_unlock_menu_renew(unlock_menu_msg_info, type);
+	display_unlock_menu_renew(unlock_menu_msg_info, type, status);
 	mutex_release(&unlock_menu_msg_info->msg_lock);
 
-	dprintf(INFO, "creating unlock keys detect thread\n");
+	dprintf(INFO, "creating %s keys detect thread\n",
+		status ? "unlock":"lock");
 	display_menu_thread_start(unlock_menu_msg_info);
 }
 
diff --git a/platform/msm_shared/include/display_menu.h b/platform/msm_shared/include/display_menu.h
index 5320be6..f063f03 100644
--- a/platform/msm_shared/include/display_menu.h
+++ b/platform/msm_shared/include/display_menu.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2015-2016, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2015-2016, 2018, The Linux Foundation. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
@@ -44,6 +44,8 @@
 	DISPLAY_MENU_UNLOCK_CRITICAL,
 	DISPLAY_MENU_LOGGING,
 	DISPLAY_MENU_EIO,
+	DISPLAY_MENU_LOCK,
+	DISPLAY_MENU_LOCK_CRITICAL,
 };
 
 struct menu_info {
@@ -64,14 +66,24 @@
 	mutex_t			msg_lock;
 };
 
+struct unlock_option_msg {
+	const char *ignore_msg;
+	const char *comfirm_msg;
+};
+
+struct unlock_info{
+	int unlock_type;
+	boolean unlock_value;
+ };
+
 void wait_for_users_action(void);
-void display_unlock_menu_renew(struct select_msg_info *msg_info, int type);
+void reset_device_unlock_status (int type);
 void display_bootverify_menu_renew(struct select_msg_info *msg_info, int type);
 void display_bootverify_option_menu_renew(struct select_msg_info *msg_info);
 void display_fastboot_menu_renew(struct select_msg_info *fastboot_msg_info);
 void display_bootverify_menu(int type);
 void display_fastboot_menu();
-void display_unlock_menu(int type);
+void display_unlock_menu(int type, bool status);
 void msg_lock_init();
 void exit_menu_keys_detection();
 #endif				/* __PLATFORM_MSM_SHARED_DISPLAY_MENU_H */
diff --git a/platform/msm_shared/menu_keys_detect.c b/platform/msm_shared/menu_keys_detect.c
index 3a81b70..ed6a786 100644
--- a/platform/msm_shared/menu_keys_detect.c
+++ b/platform/msm_shared/menu_keys_detect.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
@@ -94,8 +94,8 @@
 };
 
 static uint32_t unlock_index_action[] = {
-		[0] = RECOVER,
-		[1] = RESTART,
+		[0] = RESTART,
+		[1] = RECOVER,
 };
 
 static int is_key_pressed(int keys_type)
@@ -118,21 +118,7 @@
 	fbcon_clear();
 	switch (reason) {
 		case RECOVER:
-			if (msg_info->info.msg_type == DISPLAY_MENU_UNLOCK) {
-				set_device_unlock_value(UNLOCK, TRUE);
-			} else if (msg_info->info.msg_type == DISPLAY_MENU_UNLOCK_CRITICAL) {
-				set_device_unlock_value(UNLOCK_CRITICAL, TRUE);
-			}
-
-			if (msg_info->info.msg_type == DISPLAY_MENU_UNLOCK ||
-				msg_info->info.msg_type == DISPLAY_MENU_UNLOCK_CRITICAL) {
-				/* wipe data */
-				struct recovery_message msg;
-
-				memset(&msg, 0, sizeof(msg));
-				snprintf(msg.recovery, sizeof(msg.recovery), "recovery\n--wipe_data");
-				write_misc(0, &msg, sizeof(msg));
-			}
+			reset_device_unlock_status(msg_info->info.msg_type);
 			reboot_device(RECOVERY_MODE);
 			break;
 		case RESTART:
@@ -267,6 +253,8 @@
 			break;
 		case DISPLAY_MENU_UNLOCK:
 		case DISPLAY_MENU_UNLOCK_CRITICAL:
+		case DISPLAY_MENU_LOCK:
+		case DISPLAY_MENU_LOCK_CRITICAL:
 			if(msg_info->info.option_index < ARRAY_SIZE(unlock_index_action))
 				reason = unlock_index_action[msg_info->info.option_index];
 			break;
@@ -308,6 +296,16 @@
 		menu_volume_down_func,
 		power_key_func,
 	},
+	[DISPLAY_MENU_LOCK] = {
+		menu_volume_up_func,
+		menu_volume_down_func,
+		power_key_func,
+	},
+	[DISPLAY_MENU_LOCK_CRITICAL] = {
+		menu_volume_up_func,
+		menu_volume_down_func,
+		power_key_func,
+	},
 	[DISPLAY_MENU_YELLOW] = {
 		boot_warning_volume_keys_func,
 		boot_warning_volume_keys_func,