blob: 11303f32ba81b75e313ca56acf7f406ab400c789 [file] [log] [blame]
lijuang84dedfe2019-11-05 19:00:37 +08001/* Copyright (c) 2015-2017, 2019 The Linux Foundation. All rights reserved.
Amit Blay6281ebc2015-01-11 14:44:08 +02002 *
3 * Redistribution and use in source and binary forms, with or without
4 * modification, are permitted provided that the following conditions are
5 * met:
6 * * Redistributions of source code must retain the above copyright
7 * notice, this list of conditions and the following disclaimer.
8 * * Redistributions in binary form must reproduce the above
9 * copyright notice, this list of conditions and the following
10 * disclaimer in the documentation and/or other materials provided
11 * with the distribution.
12 * * Neither the name of The Linux Foundation nor the names of its
13 * contributors may be used to endorse or promote products derived
14 * from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
23 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
25 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
26 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29#include <debug.h>
30#include <dev/fbcon.h>
31#include <target.h>
32#include <mmc.h>
33#include <partition_parser.h>
34#include <stdlib.h>
Reut Zysman18411272015-02-09 13:47:27 +020035#include <string.h>
Reut Zysman3f3eccd2016-04-20 22:05:36 +030036#include <display_menu.h>
37#include <qtimer.h>
Amir Kotzer7e5e45c2016-10-24 00:18:33 +030038#include <pm8x41.h>
39#include <platform.h>
Amit Blay6281ebc2015-01-11 14:44:08 +020040#include "mdtp.h"
Reut Zysman561d81a2015-08-26 17:37:28 +030041#include "mdtp_defs.h"
Reut Zysmanff6bab92016-02-09 14:06:31 +020042#include "mdtp_fs.h"
Reut Zysman18411272015-02-09 13:47:27 +020043
44// Image releative locations
45#define ERROR_MESSAGE_RELATIVE_Y_LOCATION (0.18)
46#define MAIN_TEXT_RELATIVE_Y_LOCATION (0.33)
47#define PIN_RELATIVE_Y_LOCATION (0.47)
48#define PIN_TEXT_RELATIVE_Y_LOCATION (0.57)
49#define OK_BUTTON_RELATIVE_Y_LOCATION (0.75)
50#define OK_TEXT_RELATIVE_Y_LOCATION (0.82)
51
Reut Zysman18411272015-02-09 13:47:27 +020052#define MDTP_PRESSING_DELAY_MSEC (400)
53#define MDTP_MAX_IMAGE_SIZE (1183000) //size in bytes, includes some extra bytes since we round up to block size in read
54#define RGB888_BLACK (0x000000)
55#define BITS_PER_BYTE (8)
Amir Kotzer7e5e45c2016-10-24 00:18:33 +030056#define POWER_KEY_LONG_PRESS (4000) // 4 seconds in milliseconds
Reut Zysman18411272015-02-09 13:47:27 +020057
58
Amit Blay8e2731c2015-04-28 21:54:55 +030059#define CENTER_IMAGE_ON_X_AXIS(image_width,screen_width) (((screen_width)-(image_width))/2)
Reut Zysman18411272015-02-09 13:47:27 +020060
Reut Zysman18411272015-02-09 13:47:27 +020061extern uint32_t target_volume_up();
62extern uint32_t target_volume_down();
Amit Blayf43af752015-11-10 19:13:37 +020063extern int msm_display_on();
Amit Blay6281ebc2015-01-11 14:44:08 +020064
Reut Zysman18411272015-02-09 13:47:27 +020065struct mdtp_fbimage {
Reut Zysman3f3eccd2016-04-20 22:05:36 +030066 uint32_t width;
67 uint32_t height;
68 uint8_t image[MDTP_MAX_IMAGE_SIZE];
Reut Zysman18411272015-02-09 13:47:27 +020069};
Amit Blay6281ebc2015-01-11 14:44:08 +020070
Reut Zysman18411272015-02-09 13:47:27 +020071/*----------------------------------------------------------------------------
72 * Global Variables
73 * -------------------------------------------------------------------------*/
Amit Blay6281ebc2015-01-11 14:44:08 +020074
Amir Kotzer20716f12016-02-24 10:31:18 +020075static uint32_t g_pin_frames_x_location[MDTP_PIN_LEN] = {0};
Reut Zysman18411272015-02-09 13:47:27 +020076static uint32_t g_pin_frames_y_location = 0;
Reut Zysman3f3eccd2016-04-20 22:05:36 +030077static bool g_diplay_pin = false;
Reut Zysman18411272015-02-09 13:47:27 +020078
79static bool g_initial_screen_displayed = false;
80
Rami Butsteinfaecf7f2015-06-04 16:39:30 +030081static struct mdtp_fbimage *g_mdtp_header = NULL;
Reut Zysman18411272015-02-09 13:47:27 +020082static struct fbcon_config *fb_config = NULL;
83
Reut Zysman561d81a2015-08-26 17:37:28 +030084
Reut Zysman18411272015-02-09 13:47:27 +020085/*----------------------------------------------------------------------------
86 * Local Functions
87 * -------------------------------------------------------------------------*/
88
89/**
Rami Butsteinfaecf7f2015-06-04 16:39:30 +030090 * Allocate mdtp image
91 */
92static void alloc_mdtp_image() {
93 if (!g_mdtp_header) {
94 g_mdtp_header = (struct mdtp_fbimage *)malloc(sizeof(struct mdtp_fbimage));
95 ASSERT(g_mdtp_header);
96 }
97}
98
99/**
100 * Free mdtp image
101 */
102void free_mdtp_image() {
103 if (g_mdtp_header) {
104 free(g_mdtp_header);
105 g_mdtp_header = NULL;
106 }
107}
108
109/**
Reut Zysman18411272015-02-09 13:47:27 +0200110 * Load images from EMMC
111 */
112static struct mdtp_fbimage* mdtp_read_mmc_image(uint32_t offset, uint32_t width, uint32_t height)
Amit Blay6281ebc2015-01-11 14:44:08 +0200113{
114 int index = INVALID_PTN;
115 unsigned long long ptn = 0;
Rami Butsteinfaecf7f2015-06-04 16:39:30 +0300116 struct mdtp_fbimage *logo = g_mdtp_header;
Amit Blaydf42d2f2015-02-03 16:37:09 +0200117 uint32_t block_size = mmc_get_device_blocksize();
Amit Blay6281ebc2015-01-11 14:44:08 +0200118
119 index = partition_get_index("mdtp");
120 if (index == 0) {
121 dprintf(CRITICAL, "ERROR: mdtp Partition table not found\n");
122 return NULL;
123 }
124
125 ptn = partition_get_offset(index);
126 if (ptn == 0) {
127 dprintf(CRITICAL, "ERROR: mdtp Partition invalid\n");
128 return NULL;
129 }
130
Reut Zysman18411272015-02-09 13:47:27 +0200131 if (fb_config)
Amit Blay6281ebc2015-01-11 14:44:08 +0200132 {
Reut Zysman18411272015-02-09 13:47:27 +0200133 uint8_t *base = logo->image;
Amit Blay8e2731c2015-04-28 21:54:55 +0300134 unsigned bytes_per_bpp = ((fb_config->bpp) / BITS_PER_BYTE);
Brahmaji K167995f2017-06-15 14:44:51 +0530135 unsigned int data_len = ROUNDUP(width*height*bytes_per_bpp, block_size);
136 if (data_len > MDTP_MAX_IMAGE_SIZE) {
137 dprintf(CRITICAL, "ERROR: incorrect mdtp image size\n");
138 return NULL;
139 }
Amit Blay6281ebc2015-01-11 14:44:08 +0200140
Brahmaji K167995f2017-06-15 14:44:51 +0530141 if (mmc_read(ptn+offset, (void*)base, data_len)) {
Reut Zysman3f3eccd2016-04-20 22:05:36 +0300142 fbcon_clear();
143 dprintf(CRITICAL, "ERROR: mdtp image read failed\n");
144 return NULL;
Amit Blay6281ebc2015-01-11 14:44:08 +0200145 }
Amit Blay4418fb42015-05-05 08:45:13 +0300146
Reut Zysman18411272015-02-09 13:47:27 +0200147 logo->width = width;
148 logo->height = height;
Amit Blay6281ebc2015-01-11 14:44:08 +0200149 }
150
151 return logo;
152}
153
Reut Zysman18411272015-02-09 13:47:27 +0200154/**
155 * flush fbcon display
156 *
157 * The function is duplicated from fbcon.c
158 */
159static void fbcon_flush(void)
Amit Blay6281ebc2015-01-11 14:44:08 +0200160{
Reut Zysman18411272015-02-09 13:47:27 +0200161 if (fb_config->update_start)
162 fb_config->update_start();
163 if (fb_config->update_done)
164 while (!fb_config->update_done());
165}
Amit Blay6281ebc2015-01-11 14:44:08 +0200166
Reut Zysman18411272015-02-09 13:47:27 +0200167/**
168 * Clear complete section on the screen.
169 * The section is of section_height, and is located from the y
170 * coordinate and down.
171 */
172static void fbcon_clear_section(uint32_t y, uint32_t section_height)
173{
174 unsigned image_base;
175 unsigned bytes_per_bpp;
Amit Blay6281ebc2015-01-11 14:44:08 +0200176
Reut Zysman18411272015-02-09 13:47:27 +0200177 if (fb_config)
Amit Blay6281ebc2015-01-11 14:44:08 +0200178 {
Reut Zysman3f3eccd2016-04-20 22:05:36 +0300179 image_base = (y *(fb_config->width));
Reut Zysman18411272015-02-09 13:47:27 +0200180 bytes_per_bpp = ((fb_config->bpp) / BITS_PER_BYTE);
Amit Blay6281ebc2015-01-11 14:44:08 +0200181
Reut Zysman18411272015-02-09 13:47:27 +0200182 unsigned count = fb_config->width*section_height;
183 memset(fb_config->base + image_base*bytes_per_bpp, RGB888_BLACK, count*bytes_per_bpp);
184
185 fbcon_flush();
Amit Blay6281ebc2015-01-11 14:44:08 +0200186 }
Reut Zysman18411272015-02-09 13:47:27 +0200187 else
Amit Blay6281ebc2015-01-11 14:44:08 +0200188 {
Reut Zysman3f3eccd2016-04-20 22:05:36 +0300189 dprintf(CRITICAL,"ERROR: fbcon_config struct is NULL\n");
190 display_error_msg(); /* This will never return */
Amit Blay6281ebc2015-01-11 14:44:08 +0200191 }
Amit Blay6281ebc2015-01-11 14:44:08 +0200192}
193
Reut Zysman18411272015-02-09 13:47:27 +0200194/**
195 * Put image at a specific (x,y) location on the screen.
196 * Duplicated from fbcon.c, with modifications to allow (x,y) location (instead of a centered image),
197 * and display bmp images properly (order of copying the lines to the screen was reversed)
198 */
199static void fbcon_putImage_in_location(struct mdtp_fbimage *fbimg, uint32_t x, uint32_t y)
Amit Blay6281ebc2015-01-11 14:44:08 +0200200{
Reut Zysman3f3eccd2016-04-20 22:05:36 +0300201 unsigned i = 0;
202 unsigned bytes_per_bpp;
203 unsigned image_base;
204 unsigned width, pitch, height;
205 unsigned char *logo_base = NULL;
Amit Blay6281ebc2015-01-11 14:44:08 +0200206
Reut Zysman3f3eccd2016-04-20 22:05:36 +0300207 if (!fb_config) {
Reut Zysman18411272015-02-09 13:47:27 +0200208 dprintf(CRITICAL,"ERROR: NULL configuration, image cannot be displayed\n");
209 return;
Amit Blay6281ebc2015-01-11 14:44:08 +0200210 }
211
Reut Zysman18411272015-02-09 13:47:27 +0200212 if(fbimg) {
213 width = pitch = fbimg->width;
214 height = fbimg->height;
215 logo_base = (unsigned char *)fbimg->image;
216 }
217 else {
Reut Zysman3f3eccd2016-04-20 22:05:36 +0300218 dprintf(CRITICAL,"ERROR: invalid image struct\n");
219 return;
Amit Blay6281ebc2015-01-11 14:44:08 +0200220 }
221
Reut Zysman18411272015-02-09 13:47:27 +0200222 bytes_per_bpp = ((fb_config->bpp) / BITS_PER_BYTE);
223
224#if DISPLAY_TYPE_MIPI
225 if (bytes_per_bpp == 3)
Amit Blay6281ebc2015-01-11 14:44:08 +0200226 {
Reut Zysman18411272015-02-09 13:47:27 +0200227 if (fbimg->width == fb_config->width && fbimg->height == fb_config->height)
Reut Zysman18411272015-02-09 13:47:27 +0200228 {
Amit Blay8e2731c2015-04-28 21:54:55 +0300229 dprintf(CRITICAL,"ERROR: full screen image, cannot be displayed\n");
230 return;
231 }
232
233 if (fbimg->width > fb_config->width || fbimg->height > fb_config->height ||
Reut Zysman3f3eccd2016-04-20 22:05:36 +0300234 (x > (fb_config->width - fbimg->width)) || (y > (fb_config->height - fbimg->height)))
Amit Blay8e2731c2015-04-28 21:54:55 +0300235 {
Reut Zysman3f3eccd2016-04-20 22:05:36 +0300236 dprintf(CRITICAL,"ERROR: invalid image size, larger than the screen or exceeds its margins\n");
237 return;
Amit Blay6281ebc2015-01-11 14:44:08 +0200238 }
Reut Zysman18411272015-02-09 13:47:27 +0200239
240 image_base = ( (y *(fb_config->width)) + x);
241 for (i = 0; i < height; i++) {
242 memcpy (fb_config->base + ((image_base + (i * (fb_config->width))) * bytes_per_bpp),
Reut Zysman3f3eccd2016-04-20 22:05:36 +0300243 logo_base + ((height - 1 - i) * pitch * bytes_per_bpp), width * bytes_per_bpp);
Reut Zysman18411272015-02-09 13:47:27 +0200244 }
Amit Blay6281ebc2015-01-11 14:44:08 +0200245 }
Amit Blay8e2731c2015-04-28 21:54:55 +0300246 else
247 {
248 dprintf(CRITICAL,"ERROR: invalid bpp value\n");
249 display_error_msg(); /* This will never return */
250 }
Amit Blay6281ebc2015-01-11 14:44:08 +0200251
Amit Blay4418fb42015-05-05 08:45:13 +0300252 /* Flush the contents to memory before giving the data to dma */
253 arch_clean_invalidate_cache_range((addr_t) fb_config->base, (fb_config->height * fb_config->width * bytes_per_bpp));
254
Reut Zysman18411272015-02-09 13:47:27 +0200255 fbcon_flush();
Amit Blayf43af752015-11-10 19:13:37 +0200256 msm_display_on();
Reut Zysman18411272015-02-09 13:47:27 +0200257
Reut Zysman18411272015-02-09 13:47:27 +0200258#endif
Amit Blay6281ebc2015-01-11 14:44:08 +0200259}
260
Reut Zysman18411272015-02-09 13:47:27 +0200261/**
262 * Display main error message
263 */
264static int display_error_message()
Amit Blay6281ebc2015-01-11 14:44:08 +0200265{
Reut Zysman3f3eccd2016-04-20 22:05:36 +0300266 struct mdtp_fbimage *fbimg;
Amit Blay6281ebc2015-01-11 14:44:08 +0200267
Reut Zysman3f3eccd2016-04-20 22:05:36 +0300268 if (fb_config)
Reut Zysman18411272015-02-09 13:47:27 +0200269 {
Reut Zysman3f3eccd2016-04-20 22:05:36 +0300270 uint32_t x = CENTER_IMAGE_ON_X_AXIS(get_image_width(ALERT_MESSAGE),fb_config->width);
Reut Zysman18411272015-02-09 13:47:27 +0200271 uint32_t y = ((fb_config->height)*ERROR_MESSAGE_RELATIVE_Y_LOCATION);
Reut Zysman3f3eccd2016-04-20 22:05:36 +0300272 fbimg = mdtp_read_mmc_image(get_image_offset(ALERT_MESSAGE),get_image_width(ALERT_MESSAGE), get_image_height(ALERT_MESSAGE));
273 if (NULL == fbimg)
274 {
275 dprintf(CRITICAL,"ERROR: failed to read error image from mmc\n");
276 return -1;
277 }
Reut Zysman18411272015-02-09 13:47:27 +0200278
Reut Zysman3f3eccd2016-04-20 22:05:36 +0300279 fbcon_putImage_in_location(fbimg, x, y);
Reut Zysman18411272015-02-09 13:47:27 +0200280
281 return 0;
282 }
283 else
284 {
Reut Zysman3f3eccd2016-04-20 22:05:36 +0300285 dprintf(CRITICAL,"ERROR: fbcon_config struct is NULL\n");
Reut Zysman18411272015-02-09 13:47:27 +0200286 return -1;
287 }
Amit Blay6281ebc2015-01-11 14:44:08 +0200288}
289
Reut Zysman18411272015-02-09 13:47:27 +0200290/**
291 * Read from mmc the image in the given offset, of the given width and height.
292 * Then, display the image on the screen in the given (x,y) location.
293 */
294static void display_image(uint32_t offset, uint32_t width, uint32_t height, uint32_t x, uint32_t y)
Amit Blay6281ebc2015-01-11 14:44:08 +0200295{
Reut Zysman3f3eccd2016-04-20 22:05:36 +0300296 struct mdtp_fbimage *fbimg;
Amit Blay6281ebc2015-01-11 14:44:08 +0200297
Reut Zysman3f3eccd2016-04-20 22:05:36 +0300298 if (fb_config)
299 {
300 fbimg = mdtp_read_mmc_image(offset, width, height);
301 if (NULL == fbimg)
302 {
303 dprintf(CRITICAL,"ERROR: failed to read image from mmc\n");
304 display_error_msg(); /* This will never return */
305 }
Amit Blay6281ebc2015-01-11 14:44:08 +0200306
Reut Zysman3f3eccd2016-04-20 22:05:36 +0300307 fbcon_putImage_in_location(fbimg, x, y);
308 }
309 else
310 {
311 dprintf(CRITICAL,"ERROR: fbcon_config struct is NULL\n");
312 display_error_msg(); /* This will never return */
313 }
Amit Blay6281ebc2015-01-11 14:44:08 +0200314}
315
Reut Zysman18411272015-02-09 13:47:27 +0200316/**
317 * Display initial delay message
318 */
319static void display_initial_delay()
Amit Blay6281ebc2015-01-11 14:44:08 +0200320{
Reut Zysmanff6bab92016-02-09 14:06:31 +0200321 uint32_t x = CENTER_IMAGE_ON_X_AXIS(get_image_width(MAINTEXT_5SECONDS),fb_config->width);
Reut Zysman18411272015-02-09 13:47:27 +0200322 uint32_t y = (fb_config->height)*MAIN_TEXT_RELATIVE_Y_LOCATION;
Reut Zysmanff6bab92016-02-09 14:06:31 +0200323 display_image(get_image_offset(MAINTEXT_5SECONDS), get_image_width(MAINTEXT_5SECONDS), get_image_height(MAINTEXT_5SECONDS), x, y);
Amit Blay6281ebc2015-01-11 14:44:08 +0200324}
325
Reut Zysman18411272015-02-09 13:47:27 +0200326/**
327 * Display "enter PIN" message
328 */
329static void display_enter_pin()
Amit Blay6281ebc2015-01-11 14:44:08 +0200330{
Reut Zysmanff6bab92016-02-09 14:06:31 +0200331 uint32_t x = CENTER_IMAGE_ON_X_AXIS(get_image_width(MAINTEXT_ENTERPIN),fb_config->width);
Reut Zysman18411272015-02-09 13:47:27 +0200332 uint32_t y = (fb_config->height)*MAIN_TEXT_RELATIVE_Y_LOCATION;
Reut Zysmanff6bab92016-02-09 14:06:31 +0200333 display_image(get_image_offset(MAINTEXT_ENTERPIN), get_image_width(MAINTEXT_ENTERPIN), get_image_height(MAINTEXT_ENTERPIN), x, y);
Amit Blay6281ebc2015-01-11 14:44:08 +0200334}
335
Reut Zysman18411272015-02-09 13:47:27 +0200336/**
337 * Display invalid PIN message
338 */
339static void display_invalid_pin()
Amit Blay6281ebc2015-01-11 14:44:08 +0200340{
Reut Zysman3f3eccd2016-04-20 22:05:36 +0300341 uint32_t x = CENTER_IMAGE_ON_X_AXIS(get_image_width(MAINTEXT_INCORRECTPIN),fb_config->width);
Reut Zysman18411272015-02-09 13:47:27 +0200342 uint32_t y = (fb_config->height)*MAIN_TEXT_RELATIVE_Y_LOCATION;
Amit Blay6281ebc2015-01-11 14:44:08 +0200343
Reut Zysmanff6bab92016-02-09 14:06:31 +0200344 display_image(get_image_offset(MAINTEXT_INCORRECTPIN), get_image_width(MAINTEXT_INCORRECTPIN), get_image_height(MAINTEXT_INCORRECTPIN), x, y);
Amit Blay6281ebc2015-01-11 14:44:08 +0200345}
346
Reut Zysman18411272015-02-09 13:47:27 +0200347/**
348 * Clear digits instructions
349 */
350static void display_digits_instructions()
Amit Blay6281ebc2015-01-11 14:44:08 +0200351{
Reut Zysman3f3eccd2016-04-20 22:05:36 +0300352 uint32_t x = CENTER_IMAGE_ON_X_AXIS(get_image_width(PINTEXT),fb_config->width);
Reut Zysman18411272015-02-09 13:47:27 +0200353 uint32_t y = (fb_config->height)*PIN_TEXT_RELATIVE_Y_LOCATION;
354
Reut Zysmanff6bab92016-02-09 14:06:31 +0200355 display_image(get_image_offset(PINTEXT), get_image_width(PINTEXT), get_image_height(PINTEXT), x, y);
Reut Zysman18411272015-02-09 13:47:27 +0200356}
357
358/**
359 * Clear digits instructions
360 */
361static void clear_digits_instructions()
362{
Reut Zysman3f3eccd2016-04-20 22:05:36 +0300363 uint32_t y = (fb_config->height)*PIN_TEXT_RELATIVE_Y_LOCATION;
364 fbcon_clear_section(y, get_image_height(PINTEXT));
Reut Zysman18411272015-02-09 13:47:27 +0200365}
366
367/**
368 * Display a digit as un-selected.
369 */
370static void display_digit(uint32_t x, uint32_t y, uint32_t digit)
371{
Reut Zysman3f3eccd2016-04-20 22:05:36 +0300372 if (g_diplay_pin == false)
373 return;
374
375 display_image(get_image_offset(PIN_UNSELECTED_0 + digit),
376 get_image_width(PIN_UNSELECTED_0 + digit), get_image_height(PIN_UNSELECTED_0 + digit), x, y);
Reut Zysman18411272015-02-09 13:47:27 +0200377}
378
379/**
380 * Display a digit as selected.
381 */
382static void display_selected_digit(uint32_t x, uint32_t y, uint32_t digit)
383{
Reut Zysman3f3eccd2016-04-20 22:05:36 +0300384 if (g_diplay_pin == false)
385 return;
386
Reut Zysmanff6bab92016-02-09 14:06:31 +0200387 display_image(get_image_offset(PIN_SELECTED_0 + digit),
388 get_image_width(PIN_SELECTED_0 + digit),
389 get_image_height(PIN_SELECTED_0 + digit), x, y);
Reut Zysman18411272015-02-09 13:47:27 +0200390}
391
392/**
393 * Display OK button as un-selected.
394 */
395static void display_ok_button()
396{
Reut Zysman3f3eccd2016-04-20 22:05:36 +0300397 uint32_t ok_x = CENTER_IMAGE_ON_X_AXIS(get_image_width(BTN_OK_OFF),fb_config->width);
Reut Zysman18411272015-02-09 13:47:27 +0200398 uint32_t ok_y = (fb_config->height)*OK_BUTTON_RELATIVE_Y_LOCATION;
399
Reut Zysmanff6bab92016-02-09 14:06:31 +0200400 display_image(get_image_offset(BTN_OK_OFF), get_image_width(BTN_OK_OFF),get_image_height(BTN_OK_OFF), ok_x, ok_y);
Reut Zysman18411272015-02-09 13:47:27 +0200401}
402
403/**
404 * Display OK button as selected.
405 */
406static void display_selected_ok_button()
407{
Reut Zysman3f3eccd2016-04-20 22:05:36 +0300408 uint32_t ok_x = CENTER_IMAGE_ON_X_AXIS(get_image_width(BTN_OK_ON),fb_config->width);
Reut Zysman18411272015-02-09 13:47:27 +0200409 uint32_t ok_y = (fb_config->height)*OK_BUTTON_RELATIVE_Y_LOCATION;
410
Reut Zysmanff6bab92016-02-09 14:06:31 +0200411 display_image(get_image_offset(BTN_OK_ON), get_image_width(BTN_OK_ON), get_image_height(BTN_OK_ON), ok_x, ok_y);
Reut Zysman18411272015-02-09 13:47:27 +0200412}
413
Reut Zysmanff6bab92016-02-09 14:06:31 +0200414
Reut Zysman18411272015-02-09 13:47:27 +0200415/**
416 * Display the instructions for the OK button.
417 */
418static void display_pin_instructions()
419{
Reut Zysman3f3eccd2016-04-20 22:05:36 +0300420 uint32_t x = CENTER_IMAGE_ON_X_AXIS(get_image_width(ACCEPTEDIT_TEXT),fb_config->width);
Reut Zysman18411272015-02-09 13:47:27 +0200421 uint32_t y = (fb_config->height)*OK_TEXT_RELATIVE_Y_LOCATION;
422
Reut Zysmanff6bab92016-02-09 14:06:31 +0200423 display_image(get_image_offset(ACCEPTEDIT_TEXT), get_image_width(ACCEPTEDIT_TEXT), get_image_height(ACCEPTEDIT_TEXT), x, y);
Reut Zysman18411272015-02-09 13:47:27 +0200424}
425
426/**
427 * Clear the instructions for the OK button.
428 */
429static void clear_pin_message()
430{
Reut Zysman3f3eccd2016-04-20 22:05:36 +0300431 uint32_t y = (fb_config->height)*OK_TEXT_RELATIVE_Y_LOCATION;
Reut Zysman18411272015-02-09 13:47:27 +0200432
Reut Zysmanff6bab92016-02-09 14:06:31 +0200433 fbcon_clear_section(y,get_image_height(ACCEPTEDIT_TEXT));
Reut Zysman33512bc2015-08-09 19:17:09 +0300434}
435
436/**
437 * Initialize data structures required for MDTP UI.
438 */
439static void init_mdtp_ui_data()
440{
441 fb_config = fbcon_display();
442 alloc_mdtp_image();
Reut Zysman18411272015-02-09 13:47:27 +0200443}
444
445/**
446 * Display the basic layout of the screen (done only once).
447 */
448static void display_initial_screen(uint32_t pin_length)
449{
Rami Butsteinfaecf7f2015-06-04 16:39:30 +0300450 if (g_initial_screen_displayed == true)
Reut Zysman18411272015-02-09 13:47:27 +0200451 return;
452
Reut Zysman33512bc2015-08-09 19:17:09 +0300453 init_mdtp_ui_data();
Reut Zysman18411272015-02-09 13:47:27 +0200454
Rami Butsteinfaecf7f2015-06-04 16:39:30 +0300455 if (fb_config)
Reut Zysman18411272015-02-09 13:47:27 +0200456 {
457 fbcon_clear();
458
459 if (display_error_message())
Reut Zysman3f3eccd2016-04-20 22:05:36 +0300460 display_error_msg(); /* This will never return */
Reut Zysman18411272015-02-09 13:47:27 +0200461 display_initial_delay();
462
463 mdelay(INITIAL_DELAY_MSECONDS);
464
465 g_pin_frames_y_location = ((fb_config->height)*PIN_RELATIVE_Y_LOCATION);
466
Reut Zysmanff6bab92016-02-09 14:06:31 +0200467 uint32_t total_pin_length = pin_length*get_image_width(PIN_UNSELECTED_0) + mdtp_fs_get_param(DIGIT_SPACE)*(pin_length - 1);
Reut Zysman18411272015-02-09 13:47:27 +0200468
Reut Zysman3f3eccd2016-04-20 22:05:36 +0300469 if (fb_config->width > total_pin_length)
Reut Zysman18411272015-02-09 13:47:27 +0200470 {
Reut Zysman3f3eccd2016-04-20 22:05:36 +0300471 g_diplay_pin = true;
472
473 uint32_t complete_pin_centered = (fb_config->width - total_pin_length)/2;
474
475 for (uint32_t i=0; i<pin_length; i++)
476 {
477 g_pin_frames_x_location[i] = complete_pin_centered + i*(mdtp_fs_get_param(DIGIT_SPACE) + get_image_width(PIN_UNSELECTED_0));
478 }
479
480 for (uint32_t i=0; i<pin_length; i++)
481 {
482 display_digit(g_pin_frames_x_location[i], g_pin_frames_y_location, 0);
483 }
Reut Zysman18411272015-02-09 13:47:27 +0200484 }
Reut Zysman3f3eccd2016-04-20 22:05:36 +0300485 else
Reut Zysman18411272015-02-09 13:47:27 +0200486 {
Reut Zysman3f3eccd2016-04-20 22:05:36 +0300487 dprintf(CRITICAL,"ERROR: screen is not wide enough, PIN digits can't be displayed\n");
Reut Zysman18411272015-02-09 13:47:27 +0200488 }
489
490 display_ok_button();
491
492 g_initial_screen_displayed = true;
493 }
494 else
495 {
Reut Zysman3f3eccd2016-04-20 22:05:36 +0300496 dprintf(CRITICAL,"ERROR: fbcon_config struct is NULL\n");
497 display_error_msg(); /* This will never return */
Reut Zysman18411272015-02-09 13:47:27 +0200498 }
499}
500
501/**
502 * Display the recovery PIN screen and set received buffer
503 * with the PIN the user has entered.
504 * The entered PIN will be validated by the calling function.
505 */
506static void display_get_pin_interface(char *entered_pin, uint32_t pin_length)
507{
508 uint32_t previous_position = 0, current_position = 0;
Amir Kotzer7e5e45c2016-10-24 00:18:33 +0300509 time_t pwrkey_press_timer = 0;
Reut Zysman18411272015-02-09 13:47:27 +0200510
511 display_initial_screen(pin_length);
512 display_enter_pin();
513
514 // Convert ascii to digits
515 for (uint32_t i=0; i<pin_length; i++)
516 {
517 entered_pin[i] -= '0';
518 }
519 display_selected_digit(g_pin_frames_x_location[0], g_pin_frames_y_location, entered_pin[0]);
520 display_digits_instructions();
Amit Blay6281ebc2015-01-11 14:44:08 +0200521
522 while (1)
523 {
Amir Kotzer7e5e45c2016-10-24 00:18:33 +0300524 // Check if the power key is being pressed
525 if(pm8x41_get_pwrkey_is_pressed())
526 {
527 // Check if it is the first power key press event
528 if (pwrkey_press_timer == 0)
529 {
530 // Init reference time to first power key press event detected
531 pwrkey_press_timer = current_time();
532 }
533 // If the power key is being pressed long enough, shutdown the device
534 if ((current_time() - pwrkey_press_timer) >= POWER_KEY_LONG_PRESS){
535 dprintf(INFO, "Power key pressed - shutting down\n");
536 shutdown_device();
537 }
538 }
539 else
540 {
541 // Power key isn't being pressed, reset power key press reference time
542 pwrkey_press_timer = 0;
543 }
544
Reut Zysman18411272015-02-09 13:47:27 +0200545 if (target_volume_up())
Amit Blay6281ebc2015-01-11 14:44:08 +0200546 {
Reut Zysman18411272015-02-09 13:47:27 +0200547 // current position is the OK button
548 if (current_position == pin_length)
549 {
550 // Convert digits to ascii and
551 // validate entered PIN in the calling function
552 for (uint32_t i=0; i<pin_length; i++)
553 {
554 entered_pin[i] += '0';
555 }
556 return;
557 }
558
559 // current position is a PIN slot
560 entered_pin[current_position] = (entered_pin[current_position]+1) % 10;
561 display_selected_digit(g_pin_frames_x_location[current_position], g_pin_frames_y_location, entered_pin[current_position]);
562 mdelay(MDTP_PRESSING_DELAY_MSEC);
563 }
564 if (target_volume_down())
565 {
566 previous_position = current_position;
567 current_position = (current_position+1) % (pin_length+1);
568
569 // previous position was the OK button
570 if (previous_position == pin_length)
571 {
572 clear_pin_message();
573 display_ok_button();
574
575 display_digits_instructions();
576 display_selected_digit(g_pin_frames_x_location[current_position], g_pin_frames_y_location, entered_pin[current_position]);
577
578 }
579
580 // current position is the OK button
581 else if (current_position == pin_length)
582 {
583 display_digit(g_pin_frames_x_location[previous_position], g_pin_frames_y_location, entered_pin[previous_position]);
584 clear_digits_instructions();
585
586 display_selected_ok_button();
587 display_pin_instructions();
588 }
589
590 // both the previous and the current positions are PIN slots
591 else
592 {
593 display_digit(g_pin_frames_x_location[previous_position], g_pin_frames_y_location, entered_pin[previous_position]);
594
595 display_selected_digit(g_pin_frames_x_location[current_position], g_pin_frames_y_location, entered_pin[current_position]);
596 }
597
598 mdelay(MDTP_PRESSING_DELAY_MSEC);
Amit Blay6281ebc2015-01-11 14:44:08 +0200599 }
600 }
Reut Zysman18411272015-02-09 13:47:27 +0200601}
602
603/*----------------------------------------------------------------------------
604 * External Functions
605 * -------------------------------------------------------------------------*/
606
607/**
608 * Display the recovery PIN screen and set received buffer
609 * with the PIN the user has entered.
610 */
611void get_pin_from_user(char *entered_pin, uint32_t pin_length)
612{
613 display_get_pin_interface(entered_pin, pin_length);
Amit Blay6281ebc2015-01-11 14:44:08 +0200614
615 return;
616}
617
Reut Zysman18411272015-02-09 13:47:27 +0200618/**
619 * User has entered invalid PIN, display error message and
620 * allow the user to try again.
621 */
622void display_invalid_pin_msg()
Amit Blay6281ebc2015-01-11 14:44:08 +0200623{
Reut Zysman3f3eccd2016-04-20 22:05:36 +0300624 clear_pin_message();
625 display_ok_button();
Reut Zysman18411272015-02-09 13:47:27 +0200626
Reut Zysman3f3eccd2016-04-20 22:05:36 +0300627 display_invalid_pin();
Reut Zysman18411272015-02-09 13:47:27 +0200628
Reut Zysman3f3eccd2016-04-20 22:05:36 +0300629 mdelay(INVALID_PIN_DELAY_MSECONDS);
Amit Blay6281ebc2015-01-11 14:44:08 +0200630}
631
Reut Zysman18411272015-02-09 13:47:27 +0200632/**
633 * Display error message and stop boot process.
634 */
635void display_error_msg()
Amit Blay6281ebc2015-01-11 14:44:08 +0200636{
Reut Zysman33512bc2015-08-09 19:17:09 +0300637 init_mdtp_ui_data();
Amit Blay8e2731c2015-04-28 21:54:55 +0300638
639 if (fb_config)
640 {
641 fbcon_clear();
642 display_error_message(); // No point in checking the return value here
643 }
Reut Zysman18411272015-02-09 13:47:27 +0200644
645 // Invalid state. Nothing to be done but contacting the OEM.
646 // Stop boot process.
647 dprintf(CRITICAL,"ERROR: blocking boot process\n");
Amit Blay8e2731c2015-04-28 21:54:55 +0300648 for(;;);
Amit Blay6281ebc2015-01-11 14:44:08 +0200649}
650
Reut Zysmanff6bab92016-02-09 14:06:31 +0200651/**
652 * Display error message in case mdtp image is corrupted and stop boot process.
653 */
654void display_error_msg_mdtp()
655{
656 int big_factor = 8; // Font size
657 char* str = "Device unable to boot";
658 char* str2 = "\nError - mdtp image is corrupted\n";
659 fbcon_clear();
660 while(*str != 0) {
lijuang84dedfe2019-11-05 19:00:37 +0800661 fbcon_putc_factor(*str++, FBCON_COMMON_MSG, big_factor, 0);
Reut Zysmanff6bab92016-02-09 14:06:31 +0200662 }
663 fbcon_draw_line(FBCON_COMMON_MSG);
664 while(*str2 != 0) {
lijuang84dedfe2019-11-05 19:00:37 +0800665 fbcon_putc_factor(*str2++, FBCON_COMMON_MSG, big_factor, 0);
Reut Zysmanff6bab92016-02-09 14:06:31 +0200666 }
667 fbcon_draw_line(FBCON_COMMON_MSG);
668
669 // Invalid state. Nothing to be done but contacting the OEM.
670 // Stop boot process.
671 dprintf(CRITICAL,"ERROR: blocking boot process - mdtp image corrupted\n");
672 for(;;);
673
674}
675