blob: e663bdd40d51335bb69844d2bb32b781acf56409 [file] [log] [blame]
/* 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
* met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* * Neither the name of The Linux Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <debug.h>
#include <reg.h>
#include <stdlib.h>
#include <openssl/evp.h>
#include <dev/fbcon.h>
#include <kernel/thread.h>
#include <display_menu.h>
#include <menu_keys_detect.h>
#include <boot_verifier.h>
#include <string.h>
#include <platform.h>
#include <smem.h>
#include <target.h>
#include <sys/types.h>
#include <../../../app/aboot/devinfo.h>
#include <../../../app/aboot/recovery.h>
/*[TracyChui]Show memory information on fastboot screen 20200612 start */
#include <mmu.h>
/*[TracyChui]Show memory information on fastboot screen 20200612 end */
#define TITLE_MSG "<!>\n\n"
//[Arima][8901][JialongJhan] Command mode update screen 20190516 Start
extern int msm_display_flush();
//[Arima][8901][JialongJhan] Command mode update screen 20190516 End
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 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"
#define ORANGE_WARNING_MSG "The boot loader is unlocked and software integrity cannot "\
"be guaranteed. Any data stored on the device may be available to attackers. "\
"Do not store any sensitive data on the device.\n\n"\
"Visit this link on another device:\n"
#define RED_WARNING_MSG "Your device is corrupt. It can't be\ntrusted and will not boot\n\n" \
"Visit this link on another device:\n"
#define LOGGING_WARNING_MSG "The dm-verity is not started in enforcing mode and may "\
"not work properly\n\nTo learn more, visit:\n"
#define EIO_WARNING_MSG "Your device is corrupt. It can't be\n trusted and may not work properly.\n\n"\
"Visit this link on another device:\n"
#define PAUSE_BOOT_MSG "PRESS POWER KEY TO PAUSE BOOT\n\n"
#define CONTINUE_BOOT_MSG "PRESS POWER KEY TO CONTINUE\n\n"
#define URL_MSG "g.co/ABH\n\n"
#define DELAY_5SEC 5000
#define DELAY_10SEC 10000
#define DELAY_30SEC 30000
static bool is_thread_start = false;
static struct select_msg_info msg_info;
#if VERIFIED_BOOT || VERIFIED_BOOT_2
struct boot_verify_info {
int msg_type;
const char *title_msg;
const char *warning_msg;
const char *url_msg;
const char *notice_msg;
};
struct boot_verify_info boot_verify_info[] = {
[DISPLAY_MENU_RED] = {FBCON_RED_MSG, TITLE_MSG, RED_WARNING_MSG, URL_MSG, NULL},
[DISPLAY_MENU_YELLOW] = {FBCON_YELLOW_MSG, TITLE_MSG, YELLOW_WARNING_MSG, URL_MSG, PAUSE_BOOT_MSG},
[DISPLAY_MENU_ORANGE] = {FBCON_ORANGE_MSG, TITLE_MSG, ORANGE_WARNING_MSG, URL_MSG, PAUSE_BOOT_MSG},
[DISPLAY_MENU_LOGGING] = {FBCON_RED_MSG, TITLE_MSG, LOGGING_WARNING_MSG, NULL, NULL},
[DISPLAY_MENU_EIO] = {FBCON_RED_MSG, TITLE_MSG, EIO_WARNING_MSG, URL_MSG, CONTINUE_BOOT_MSG}};
#endif
static char *verify_option_menu[] = {
[POWEROFF] = "Power off\n",
[RESTART] = "Restart\n",
[RECOVER] = "Recovery\n",
[FASTBOOT] = "Fastboot\n",
[BACK] = "Back to previous page\n"};
/*[20200120][TracyChui]Remove FFBM item in fastboot mode start */
static char *fastboot_option_menu[] = {
[0] = "START\n",
[1] = "Restart bootloader\n",
[2] = "Recovery mode\n",
[3] = "Power off\n"};
/*[20200120][TracyChui]Remove FFBM item in fastboot mode end */
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;
static void wait_for_exit()
{
struct select_msg_info *select_msg;
select_msg = &msg_info;
mutex_acquire(&select_msg->msg_lock);
while(!select_msg->info.rel_exit == true) {
mutex_release(&select_msg->msg_lock);
thread_sleep(10);
mutex_acquire(&select_msg->msg_lock);
}
mutex_release(&select_msg->msg_lock);
is_thread_start = false;
fbcon_clear();
display_image_on_screen();
//[Arima][8901][JialongJhan] Command mode update screen 20190618 Start
msm_display_flush();
//[Arima][8901][JialongJhan] Command mode update screen 20190618 End
}
void wait_for_users_action()
{
if (is_display_disabled())
return;
/* Waiting for exit menu keys detection if there is no any usr action
* otherwise it will do the action base on the keys detection thread
*/
wait_for_exit();
}
void exit_menu_keys_detection()
{
struct select_msg_info *select_msg;
select_msg = &msg_info;
if (is_display_disabled())
return;
mutex_acquire(&select_msg->msg_lock);
select_msg->info.is_exit = true;
mutex_release(&select_msg->msg_lock);
wait_for_exit();
}
static void set_message_factor()
{
uint32_t tmp_factor = 0;
uint32_t max_x_count = 0;
uint32_t max_x = 0;
if (fbcon_get_width() < fbcon_get_height())
max_x_count = CHAR_NUM_PERROW_POR;
else
max_x_count = CHAR_NUM_PERROW_HOR;
max_x = fbcon_get_max_x();
tmp_factor = max_x/max_x_count;
if(tmp_factor <= 1) {
big_factor = 2;
common_factor = 1;
} else {
big_factor = tmp_factor*2;
common_factor = tmp_factor;
}
}
/* If y_start == 0, it will draw message from the current Y axis location,
otherwise it will start from the the value of y_start. */
static void display_fbcon_menu_message(char *str, unsigned type,
unsigned scale_factor, int y_start)
{
while(*str != 0) {
fbcon_putc_factor(*str++, type, scale_factor, y_start);
y_start = 0;
}
}
static char *str_align_right(char *str, int factor)
{
uint32_t max_x = 0;
int diff = 0;
int i = 0;
char *str_target = NULL;
max_x = fbcon_get_max_x();
if (!str_target && max_x) {
str_target = malloc(max_x);
}
if (str_target) {
memset(str_target, 0, max_x);
if ( max_x/factor > strlen(str)) {
if (factor == 1)
diff = max_x/factor - strlen(str) - 1;
else
diff = max_x/factor - strlen(str);
for (i = 0; i < diff; i++) {
strlcat(str_target, " ", max_x);
}
}
strlcat(str_target, str, max_x);
}
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. */
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("<!>\n\n",
FBCON_UNLOCK_TITLE_MSG, big_factor, 0);
if (status) {
display_fbcon_menu_message((char*)unlock_menu_common_msg,
FBCON_COMMON_MSG, common_factor, 0);
} else {
display_fbcon_menu_message((char*)lock_menu_common_msg,
FBCON_COMMON_MSG, common_factor, 0);
}
fbcon_draw_line(FBCON_COMMON_MSG);
unlock_msg_info->info.option_start[0] = fbcon_get_current_line();
display_fbcon_menu_message((char *)munlock_option_msg[status].ignore_msg,
FBCON_COMMON_MSG, common_factor, 0);
unlock_msg_info->info.option_bg[0] = fbcon_get_current_bg();
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((char *)munlock_option_msg[status].comfirm_msg,
FBCON_COMMON_MSG, common_factor, 0);
unlock_msg_info->info.option_bg[1] = fbcon_get_current_bg();
unlock_msg_info->info.option_end[1] = fbcon_get_current_line();
fbcon_draw_line(FBCON_COMMON_MSG);
if (type == UNLOCK) {
unlock_msg_info->info.msg_type = DISPLAY_MENU_UNLOCK;
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;
/* Initialize the option index */
unlock_msg_info->info.option_index= 2;
}
#if VERIFIED_BOOT || VERIFIED_BOOT_2
/* msg_lock need to be holded when call this function. */
void display_bootverify_menu_renew(struct select_msg_info *msg_info, int type)
{
unsigned char* fp_buf = NULL;
char fp_str_temp[EVP_MAX_MD_SIZE] = {'\0'};
char fp_str[EVP_MAX_MD_SIZE*2] = {'\0'};
char str_temp[8];
uint32 fp_size = 0;
unsigned int i = 0;
uint32_t timeout = DELAY_10SEC;
fbcon_clear();
memset(&msg_info->info, 0, sizeof(struct menu_info));
if(boot_verify_info[type].title_msg != NULL)
display_fbcon_menu_message((char*)boot_verify_info[type].title_msg,
boot_verify_info[type].msg_type, big_factor, 0);
if(boot_verify_info[type].warning_msg != NULL)
display_fbcon_menu_message((char*)boot_verify_info[type].warning_msg,
FBCON_COMMON_MSG, common_factor, 0);
if(boot_verify_info[type].url_msg != NULL) {
dprintf(INFO, "display_fbcon_menu_message: Location=%d\n", fbcon_get_current_line());
display_fbcon_menu_message((char*)boot_verify_info[type].url_msg,
boot_verify_info[type].msg_type, common_factor, 0);
dprintf(INFO, "display_fbcon_menu_message: Location=%d\n", fbcon_get_current_line());
}
if(boot_verify_info[type].notice_msg != NULL) {
msg_info->info.option_start[0] = fbcon_get_current_line();
dprintf(INFO, "display_fbcon_menu_message: Location=%d\n", msg_info->info.option_start[0]);
display_fbcon_menu_message((char*)boot_verify_info[type].notice_msg,
FBCON_COMMON_MSG, common_factor, 0);
msg_info->info.option_end[0] = fbcon_get_current_line();
}
if (type == DISPLAY_MENU_YELLOW) {
fp_buf = get_boot_fingerprint(&fp_size);
if (fp_buf != NULL) {
strlcpy(fp_str_temp, (char const *)fp_buf, fp_size);
for (i = 0; i < fp_size; i++) {
if(i == fp_size - 1)
snprintf(str_temp, sizeof(str_temp), "%02x", fp_str_temp[i]);
else
snprintf(str_temp, sizeof(str_temp), "%02x-", fp_str_temp[i]);
strlcat(fp_str, str_temp, sizeof(fp_str));
}
}
display_fbcon_menu_message("ID:", FBCON_COMMON_MSG, common_factor, 0);
display_fbcon_menu_message(fp_str, FBCON_COMMON_MSG, common_factor, 0);
}
switch (type) {
case DISPLAY_MENU_RED:
timeout = DELAY_30SEC;
break;
case DISPLAY_MENU_EIO:
#if ENABLE_VB_ATTEST
timeout = DELAY_30SEC;
#endif
break;
default:
timeout = DELAY_10SEC;
break;
}
msg_info->info.msg_type = type;
/* Initialize the time out time */
msg_info->info.timeout_time = timeout;
}
void display_bootverify_menu_update (struct select_msg_info *msg_info)
{
int location = msg_info->info.option_start[0];
/* clean the old msg */
fbcon_clear_msg (location, msg_info->info.option_end[0]);
display_fbcon_menu_message(CONTINUE_BOOT_MSG, FBCON_COMMON_MSG, common_factor, location);
msg_info->info.timeout_time = DELAY_30SEC;
}
#endif
/* msg_lock need to be holded when call this function. */
void display_bootverify_option_menu_renew(struct select_msg_info *msg_info)
{
int i = 0;
int len = 0;
fbcon_clear();
memset(&msg_info->info, 0, sizeof(struct menu_info));
len = ARRAY_SIZE(verify_option_menu);
display_fbcon_menu_message("Options menu:\n\n",
FBCON_COMMON_MSG, big_factor, 0);
display_fbcon_menu_message("Press volume key to select, and "\
"press power key to select\n\n", FBCON_COMMON_MSG, common_factor, 0);
for (i = 0; i < len; i++) {
fbcon_draw_line(FBCON_COMMON_MSG);
msg_info->info.option_start[i] = fbcon_get_current_line();
display_fbcon_menu_message(verify_option_menu[i],
FBCON_COMMON_MSG, common_factor, 0);
msg_info->info.option_bg[i]= fbcon_get_current_bg();
msg_info->info.option_end[i]= fbcon_get_current_line();
}
fbcon_draw_line(FBCON_COMMON_MSG);
msg_info->info.msg_type = DISPLAY_MENU_MORE_OPTION;
msg_info->info.option_num = len;
/* Initialize the option index */
msg_info->info.option_index= len;
}
/* msg_lock need to be holded when call this function. */
void display_fastboot_menu_renew(struct select_msg_info *fastboot_msg_info)
{
int len;
int msg_type = FBCON_COMMON_MSG;
char msg_buf[64];
char msg[128];
/* The fastboot menu is switched base on the option index
* So it's need to store the index for the menu switching
*/
uint32_t option_index = fastboot_msg_info->info.option_index;
fbcon_clear();
memset(&fastboot_msg_info->info, 0, sizeof(struct menu_info));
len = ARRAY_SIZE(fastboot_option_menu);
switch(option_index) {
case 0:
msg_type = FBCON_GREEN_MSG;
break;
case 1:
case 2:
msg_type = FBCON_RED_MSG;
break;
case 3:
case 4:
msg_type = FBCON_COMMON_MSG;
break;
}
fbcon_draw_line(msg_type);
display_fbcon_menu_message(fastboot_option_menu[option_index],
msg_type, big_factor, 0);
fbcon_draw_line(msg_type);
display_fbcon_menu_message("\n\nPress volume key to select, and "\
"press power key to select\n\n", FBCON_COMMON_MSG, common_factor, 0);
display_fbcon_menu_message("FASTBOOT MODE\n", FBCON_RED_MSG, common_factor, 0);
get_product_name((unsigned char *) msg_buf);
snprintf(msg, sizeof(msg), "PRODUCT_NAME - %s\n", msg_buf);
display_fbcon_menu_message(msg, FBCON_COMMON_MSG, common_factor, 0);
memset(msg_buf, 0, sizeof(msg_buf));
smem_get_hw_platform_name((unsigned char *) msg_buf, sizeof(msg_buf));
snprintf(msg, sizeof(msg), "VARIANT - %s %s\n",
msg_buf, target_is_emmc_boot()? "eMMC":"UFS");
display_fbcon_menu_message(msg, FBCON_COMMON_MSG, common_factor, 0);
memset(msg_buf, 0, sizeof(msg_buf));
get_bootloader_version((unsigned char *) msg_buf);
snprintf(msg, sizeof(msg), "BOOTLOADER VERSION - %s\n",
msg_buf);
display_fbcon_menu_message(msg, FBCON_COMMON_MSG, common_factor, 0);
memset(msg_buf, 0, sizeof(msg_buf));
get_baseband_version((unsigned char *) msg_buf);
snprintf(msg, sizeof(msg), "BASEBAND VERSION - %s\n",
msg_buf);
display_fbcon_menu_message(msg, FBCON_COMMON_MSG, common_factor, 0);
memset(msg_buf, 0, sizeof(msg_buf));
target_serialno((unsigned char *) msg_buf);
snprintf(msg, sizeof(msg), "SERIAL NUMBER - %s\n", msg_buf);
display_fbcon_menu_message(msg, FBCON_COMMON_MSG, common_factor, 0);
/*[TracyChui]Show memory information on fastboot screen 20200612 start */
dprintf(CRITICAL,"smem_get_ddr_size=%llu\n", smem_get_ddr_size());
if (smem_get_ddr_size() == MEM_3GB) {
snprintf(msg, sizeof(msg), "INTERNAL STORAGE SIZE - 32G\n");
} else if (smem_get_ddr_size() > MEM_3GB) {
if (smem_get_ddr_size() < MEM_4GB)
{
snprintf(msg, sizeof(msg), "INTERNAL STORAGE SIZE - 64G\n");
}
else
{
snprintf(msg, sizeof(msg), "INTERNAL STORAGE SIZE - \n");
}
} else {
snprintf(msg, sizeof(msg), "INTERNAL STORAGE SIZE - UNKNOWN\n");
}
display_fbcon_menu_message(msg, FBCON_COMMON_MSG, common_factor, 0);
memset(msg_buf, 0, sizeof(msg_buf));
smem_get_ddr_manufacturer_id((unsigned char *) msg_buf);
dprintf(CRITICAL,"smem_get_ddr_size=%llu\n", smem_get_ddr_size());
if (smem_get_ddr_size() == MEM_3GB) {
snprintf(msg, sizeof(msg), "MAIN MEMORY SIZE AND VENDOR - 3G\n");
} else if (smem_get_ddr_size() > MEM_3GB) {
if (smem_get_ddr_size() < MEM_4GB)
{
snprintf(msg, sizeof(msg), "MAIN MEMORY SIZE AND VENDOR - 4G %s\n", msg_buf);
}
else
{
snprintf(msg, sizeof(msg), "MAIN MEMORY SIZE AND VENDOR - %s\n", msg_buf);
}
} else {
snprintf(msg, sizeof(msg), "MAIN MEMORY SIZE AND VENDOR - %s\n", msg_buf);
}
display_fbcon_menu_message(msg, FBCON_COMMON_MSG, common_factor, 0);
/*[TracyChui]Show memory information on fastboot screen 20200612 end */
snprintf(msg, sizeof(msg), "SECURE BOOT - %s\n",
is_secure_boot_enable()? "enabled":"disabled");
display_fbcon_menu_message(msg, FBCON_COMMON_MSG, common_factor, 0);
snprintf(msg, sizeof(msg), "DEVICE STATE - %s\n",
is_device_locked()? "locked":"unlocked");
display_fbcon_menu_message(msg, FBCON_RED_MSG, common_factor, 0);
fastboot_msg_info->info.msg_type = DISPLAY_MENU_FASTBOOT;
fastboot_msg_info->info.option_num = len;
fastboot_msg_info->info.option_index = option_index;
}
void msg_lock_init()
{
static bool is_msg_lock_init = false;
struct select_msg_info *msg_lock_info;
msg_lock_info = &msg_info;
if (!is_msg_lock_init) {
mutex_init(&msg_lock_info->msg_lock);
is_msg_lock_init = true;
}
}
static void display_menu_thread_start(struct select_msg_info *msg_info)
{
thread_t *thr;
if (!is_thread_start) {
thr = thread_create("selectkeydetect", &select_msg_keys_detect,
(void*)msg_info, DEFAULT_PRIORITY, DEFAULT_STACK_SIZE);
if (!thr) {
dprintf(CRITICAL, "ERROR: creat device status detect thread failed!!\n");
return;
}
thread_resume(thr);
is_thread_start = true;
}
}
/* 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, bool status)
{
struct select_msg_info *unlock_menu_msg_info;
unlock_menu_msg_info = &msg_info;
if (is_display_disabled())
return;
set_message_factor();
msg_lock_init();
mutex_acquire(&unlock_menu_msg_info->msg_lock);
/* Initialize the last_msg_type */
unlock_menu_msg_info->last_msg_type =
unlock_menu_msg_info->info.msg_type;
display_unlock_menu_renew(unlock_menu_msg_info, type, status);
//[Arima][8901][JialongJhan] Command mode update screen 20190618 Start
msm_display_flush();
//[Arima][8901][JialongJhan] Command mode update screen 20190618 End
mutex_release(&unlock_menu_msg_info->msg_lock);
dprintf(INFO, "creating %s keys detect thread\n",
status ? "unlock":"lock");
display_menu_thread_start(unlock_menu_msg_info);
}
void display_fastboot_menu()
{
struct select_msg_info *fastboot_menu_msg_info;
fastboot_menu_msg_info = &msg_info;
if (is_display_disabled())
return;
set_message_factor();
msg_lock_init();
mutex_acquire(&fastboot_menu_msg_info->msg_lock);
/* There are 4 pages for fastboot menu:
* Page: Start/Fastboot/Recovery/Poweroff
* The menu is switched base on the option index
* Initialize the option index and last_msg_type
*/
fastboot_menu_msg_info->info.option_index = 0;
fastboot_menu_msg_info->last_msg_type =
fastboot_menu_msg_info->info.msg_type;
display_fastboot_menu_renew(fastboot_menu_msg_info);
//[Arima][8901][JialongJhan] Command mode update screen 20190618 Start
msm_display_flush();
//[Arima][8901][JialongJhan] Command mode update screen 20190618 End
mutex_release(&fastboot_menu_msg_info->msg_lock);
dprintf(INFO, "creating fastboot menu keys detect thread\n");
display_menu_thread_start(fastboot_menu_msg_info);
}
#if VERIFIED_BOOT || VERIFIED_BOOT_2
void display_bootverify_menu(int type)
{
struct select_msg_info *bootverify_menu_msg_info;
bootverify_menu_msg_info = &msg_info;
if (is_display_disabled())
return;
set_message_factor();
msg_lock_init();
mutex_acquire(&bootverify_menu_msg_info->msg_lock);
/* Initialize the last_msg_type */
bootverify_menu_msg_info->last_msg_type =
bootverify_menu_msg_info->info.msg_type;
display_bootverify_menu_renew(bootverify_menu_msg_info, type);
//[Arima][8901][JialongJhan] Command mode update screen 201906118 Start
msm_display_flush();
//[Arima][8901][JialongJhan] Command mode update screen 20190618 End
mutex_release(&bootverify_menu_msg_info->msg_lock);
dprintf(INFO, "creating boot verify keys detect thread\n");
display_menu_thread_start(bootverify_menu_msg_info);
}
#endif