blob: ed14e65591a4e40ff3ff750d4b702d61f8975748 [file] [log] [blame]
Reut Zysmanff6bab92016-02-09 14:06:31 +02001/* Copyright (c) 2015-2016, 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>
Amit Blay6281ebc2015-01-11 14:44:08 +020038#include "mdtp.h"
Reut Zysman561d81a2015-08-26 17:37:28 +030039#include "mdtp_defs.h"
Reut Zysmanff6bab92016-02-09 14:06:31 +020040#include "mdtp_fs.h"
Reut Zysman18411272015-02-09 13:47:27 +020041
42// Image releative locations
43#define ERROR_MESSAGE_RELATIVE_Y_LOCATION (0.18)
44#define MAIN_TEXT_RELATIVE_Y_LOCATION (0.33)
45#define PIN_RELATIVE_Y_LOCATION (0.47)
46#define PIN_TEXT_RELATIVE_Y_LOCATION (0.57)
47#define OK_BUTTON_RELATIVE_Y_LOCATION (0.75)
48#define OK_TEXT_RELATIVE_Y_LOCATION (0.82)
49
Reut Zysman18411272015-02-09 13:47:27 +020050#define MDTP_PRESSING_DELAY_MSEC (400)
51#define MDTP_MAX_IMAGE_SIZE (1183000) //size in bytes, includes some extra bytes since we round up to block size in read
52#define RGB888_BLACK (0x000000)
53#define BITS_PER_BYTE (8)
54
55
Amit Blay8e2731c2015-04-28 21:54:55 +030056#define CENTER_IMAGE_ON_X_AXIS(image_width,screen_width) (((screen_width)-(image_width))/2)
Reut Zysman18411272015-02-09 13:47:27 +020057
Reut Zysman18411272015-02-09 13:47:27 +020058extern uint32_t target_volume_up();
59extern uint32_t target_volume_down();
Amit Blayf43af752015-11-10 19:13:37 +020060extern int msm_display_on();
Amit Blay6281ebc2015-01-11 14:44:08 +020061
Reut Zysman18411272015-02-09 13:47:27 +020062struct mdtp_fbimage {
Reut Zysman3f3eccd2016-04-20 22:05:36 +030063 uint32_t width;
64 uint32_t height;
65 uint8_t image[MDTP_MAX_IMAGE_SIZE];
Reut Zysman18411272015-02-09 13:47:27 +020066};
Amit Blay6281ebc2015-01-11 14:44:08 +020067
Reut Zysman18411272015-02-09 13:47:27 +020068/*----------------------------------------------------------------------------
69 * Global Variables
70 * -------------------------------------------------------------------------*/
Amit Blay6281ebc2015-01-11 14:44:08 +020071
Amir Kotzer20716f12016-02-24 10:31:18 +020072static uint32_t g_pin_frames_x_location[MDTP_PIN_LEN] = {0};
Reut Zysman18411272015-02-09 13:47:27 +020073static uint32_t g_pin_frames_y_location = 0;
Reut Zysman3f3eccd2016-04-20 22:05:36 +030074static bool g_diplay_pin = false;
Reut Zysman18411272015-02-09 13:47:27 +020075
76static bool g_initial_screen_displayed = false;
77
Rami Butsteinfaecf7f2015-06-04 16:39:30 +030078static struct mdtp_fbimage *g_mdtp_header = NULL;
Reut Zysman18411272015-02-09 13:47:27 +020079static struct fbcon_config *fb_config = NULL;
80
Reut Zysman561d81a2015-08-26 17:37:28 +030081
Reut Zysman18411272015-02-09 13:47:27 +020082/*----------------------------------------------------------------------------
83 * Local Functions
84 * -------------------------------------------------------------------------*/
85
86/**
Rami Butsteinfaecf7f2015-06-04 16:39:30 +030087 * Allocate mdtp image
88 */
89static void alloc_mdtp_image() {
90 if (!g_mdtp_header) {
91 g_mdtp_header = (struct mdtp_fbimage *)malloc(sizeof(struct mdtp_fbimage));
92 ASSERT(g_mdtp_header);
93 }
94}
95
96/**
97 * Free mdtp image
98 */
99void free_mdtp_image() {
100 if (g_mdtp_header) {
101 free(g_mdtp_header);
102 g_mdtp_header = NULL;
103 }
104}
105
106/**
Reut Zysman18411272015-02-09 13:47:27 +0200107 * Load images from EMMC
108 */
109static struct mdtp_fbimage* mdtp_read_mmc_image(uint32_t offset, uint32_t width, uint32_t height)
Amit Blay6281ebc2015-01-11 14:44:08 +0200110{
111 int index = INVALID_PTN;
112 unsigned long long ptn = 0;
Rami Butsteinfaecf7f2015-06-04 16:39:30 +0300113 struct mdtp_fbimage *logo = g_mdtp_header;
Amit Blaydf42d2f2015-02-03 16:37:09 +0200114 uint32_t block_size = mmc_get_device_blocksize();
Amit Blay6281ebc2015-01-11 14:44:08 +0200115
116 index = partition_get_index("mdtp");
117 if (index == 0) {
118 dprintf(CRITICAL, "ERROR: mdtp Partition table not found\n");
119 return NULL;
120 }
121
122 ptn = partition_get_offset(index);
123 if (ptn == 0) {
124 dprintf(CRITICAL, "ERROR: mdtp Partition invalid\n");
125 return NULL;
126 }
127
Reut Zysman18411272015-02-09 13:47:27 +0200128 if (fb_config)
Amit Blay6281ebc2015-01-11 14:44:08 +0200129 {
Reut Zysman18411272015-02-09 13:47:27 +0200130 uint8_t *base = logo->image;
Amit Blay8e2731c2015-04-28 21:54:55 +0300131 unsigned bytes_per_bpp = ((fb_config->bpp) / BITS_PER_BYTE);
Amit Blay6281ebc2015-01-11 14:44:08 +0200132
Amit Blay8e2731c2015-04-28 21:54:55 +0300133 if (mmc_read(ptn+offset, (void*)base, ROUNDUP(width*height*bytes_per_bpp, block_size))) {
Reut Zysman3f3eccd2016-04-20 22:05:36 +0300134 fbcon_clear();
135 dprintf(CRITICAL, "ERROR: mdtp image read failed\n");
136 return NULL;
Amit Blay6281ebc2015-01-11 14:44:08 +0200137 }
Amit Blay4418fb42015-05-05 08:45:13 +0300138
Reut Zysman18411272015-02-09 13:47:27 +0200139 logo->width = width;
140 logo->height = height;
Amit Blay6281ebc2015-01-11 14:44:08 +0200141 }
142
143 return logo;
144}
145
Reut Zysman18411272015-02-09 13:47:27 +0200146/**
147 * flush fbcon display
148 *
149 * The function is duplicated from fbcon.c
150 */
151static void fbcon_flush(void)
Amit Blay6281ebc2015-01-11 14:44:08 +0200152{
Reut Zysman18411272015-02-09 13:47:27 +0200153 if (fb_config->update_start)
154 fb_config->update_start();
155 if (fb_config->update_done)
156 while (!fb_config->update_done());
157}
Amit Blay6281ebc2015-01-11 14:44:08 +0200158
Reut Zysman18411272015-02-09 13:47:27 +0200159/**
160 * Clear complete section on the screen.
161 * The section is of section_height, and is located from the y
162 * coordinate and down.
163 */
164static void fbcon_clear_section(uint32_t y, uint32_t section_height)
165{
166 unsigned image_base;
167 unsigned bytes_per_bpp;
Amit Blay6281ebc2015-01-11 14:44:08 +0200168
Reut Zysman18411272015-02-09 13:47:27 +0200169 if (fb_config)
Amit Blay6281ebc2015-01-11 14:44:08 +0200170 {
Reut Zysman3f3eccd2016-04-20 22:05:36 +0300171 image_base = (y *(fb_config->width));
Reut Zysman18411272015-02-09 13:47:27 +0200172 bytes_per_bpp = ((fb_config->bpp) / BITS_PER_BYTE);
Amit Blay6281ebc2015-01-11 14:44:08 +0200173
Reut Zysman18411272015-02-09 13:47:27 +0200174 unsigned count = fb_config->width*section_height;
175 memset(fb_config->base + image_base*bytes_per_bpp, RGB888_BLACK, count*bytes_per_bpp);
176
177 fbcon_flush();
Amit Blay6281ebc2015-01-11 14:44:08 +0200178 }
Reut Zysman18411272015-02-09 13:47:27 +0200179 else
Amit Blay6281ebc2015-01-11 14:44:08 +0200180 {
Reut Zysman3f3eccd2016-04-20 22:05:36 +0300181 dprintf(CRITICAL,"ERROR: fbcon_config struct is NULL\n");
182 display_error_msg(); /* This will never return */
Amit Blay6281ebc2015-01-11 14:44:08 +0200183 }
Amit Blay6281ebc2015-01-11 14:44:08 +0200184}
185
Reut Zysman18411272015-02-09 13:47:27 +0200186/**
187 * Put image at a specific (x,y) location on the screen.
188 * Duplicated from fbcon.c, with modifications to allow (x,y) location (instead of a centered image),
189 * and display bmp images properly (order of copying the lines to the screen was reversed)
190 */
191static void fbcon_putImage_in_location(struct mdtp_fbimage *fbimg, uint32_t x, uint32_t y)
Amit Blay6281ebc2015-01-11 14:44:08 +0200192{
Reut Zysman3f3eccd2016-04-20 22:05:36 +0300193 unsigned i = 0;
194 unsigned bytes_per_bpp;
195 unsigned image_base;
196 unsigned width, pitch, height;
197 unsigned char *logo_base = NULL;
Amit Blay6281ebc2015-01-11 14:44:08 +0200198
Reut Zysman3f3eccd2016-04-20 22:05:36 +0300199 if (!fb_config) {
Reut Zysman18411272015-02-09 13:47:27 +0200200 dprintf(CRITICAL,"ERROR: NULL configuration, image cannot be displayed\n");
201 return;
Amit Blay6281ebc2015-01-11 14:44:08 +0200202 }
203
Reut Zysman18411272015-02-09 13:47:27 +0200204 if(fbimg) {
205 width = pitch = fbimg->width;
206 height = fbimg->height;
207 logo_base = (unsigned char *)fbimg->image;
208 }
209 else {
Reut Zysman3f3eccd2016-04-20 22:05:36 +0300210 dprintf(CRITICAL,"ERROR: invalid image struct\n");
211 return;
Amit Blay6281ebc2015-01-11 14:44:08 +0200212 }
213
Reut Zysman18411272015-02-09 13:47:27 +0200214 bytes_per_bpp = ((fb_config->bpp) / BITS_PER_BYTE);
215
216#if DISPLAY_TYPE_MIPI
217 if (bytes_per_bpp == 3)
Amit Blay6281ebc2015-01-11 14:44:08 +0200218 {
Reut Zysman18411272015-02-09 13:47:27 +0200219 if (fbimg->width == fb_config->width && fbimg->height == fb_config->height)
Reut Zysman18411272015-02-09 13:47:27 +0200220 {
Amit Blay8e2731c2015-04-28 21:54:55 +0300221 dprintf(CRITICAL,"ERROR: full screen image, cannot be displayed\n");
222 return;
223 }
224
225 if (fbimg->width > fb_config->width || fbimg->height > fb_config->height ||
Reut Zysman3f3eccd2016-04-20 22:05:36 +0300226 (x > (fb_config->width - fbimg->width)) || (y > (fb_config->height - fbimg->height)))
Amit Blay8e2731c2015-04-28 21:54:55 +0300227 {
Reut Zysman3f3eccd2016-04-20 22:05:36 +0300228 dprintf(CRITICAL,"ERROR: invalid image size, larger than the screen or exceeds its margins\n");
229 return;
Amit Blay6281ebc2015-01-11 14:44:08 +0200230 }
Reut Zysman18411272015-02-09 13:47:27 +0200231
232 image_base = ( (y *(fb_config->width)) + x);
233 for (i = 0; i < height; i++) {
234 memcpy (fb_config->base + ((image_base + (i * (fb_config->width))) * bytes_per_bpp),
Reut Zysman3f3eccd2016-04-20 22:05:36 +0300235 logo_base + ((height - 1 - i) * pitch * bytes_per_bpp), width * bytes_per_bpp);
Reut Zysman18411272015-02-09 13:47:27 +0200236 }
Amit Blay6281ebc2015-01-11 14:44:08 +0200237 }
Amit Blay8e2731c2015-04-28 21:54:55 +0300238 else
239 {
240 dprintf(CRITICAL,"ERROR: invalid bpp value\n");
241 display_error_msg(); /* This will never return */
242 }
Amit Blay6281ebc2015-01-11 14:44:08 +0200243
Amit Blay4418fb42015-05-05 08:45:13 +0300244 /* Flush the contents to memory before giving the data to dma */
245 arch_clean_invalidate_cache_range((addr_t) fb_config->base, (fb_config->height * fb_config->width * bytes_per_bpp));
246
Reut Zysman18411272015-02-09 13:47:27 +0200247 fbcon_flush();
Amit Blayf43af752015-11-10 19:13:37 +0200248 msm_display_on();
Reut Zysman18411272015-02-09 13:47:27 +0200249
Reut Zysman18411272015-02-09 13:47:27 +0200250#endif
Amit Blay6281ebc2015-01-11 14:44:08 +0200251}
252
Reut Zysman18411272015-02-09 13:47:27 +0200253/**
254 * Display main error message
255 */
256static int display_error_message()
Amit Blay6281ebc2015-01-11 14:44:08 +0200257{
Reut Zysman3f3eccd2016-04-20 22:05:36 +0300258 struct mdtp_fbimage *fbimg;
Amit Blay6281ebc2015-01-11 14:44:08 +0200259
Reut Zysman3f3eccd2016-04-20 22:05:36 +0300260 if (fb_config)
Reut Zysman18411272015-02-09 13:47:27 +0200261 {
Reut Zysman3f3eccd2016-04-20 22:05:36 +0300262 uint32_t x = CENTER_IMAGE_ON_X_AXIS(get_image_width(ALERT_MESSAGE),fb_config->width);
Reut Zysman18411272015-02-09 13:47:27 +0200263 uint32_t y = ((fb_config->height)*ERROR_MESSAGE_RELATIVE_Y_LOCATION);
Reut Zysman3f3eccd2016-04-20 22:05:36 +0300264 fbimg = mdtp_read_mmc_image(get_image_offset(ALERT_MESSAGE),get_image_width(ALERT_MESSAGE), get_image_height(ALERT_MESSAGE));
265 if (NULL == fbimg)
266 {
267 dprintf(CRITICAL,"ERROR: failed to read error image from mmc\n");
268 return -1;
269 }
Reut Zysman18411272015-02-09 13:47:27 +0200270
Reut Zysman3f3eccd2016-04-20 22:05:36 +0300271 fbcon_putImage_in_location(fbimg, x, y);
Reut Zysman18411272015-02-09 13:47:27 +0200272
273 return 0;
274 }
275 else
276 {
Reut Zysman3f3eccd2016-04-20 22:05:36 +0300277 dprintf(CRITICAL,"ERROR: fbcon_config struct is NULL\n");
Reut Zysman18411272015-02-09 13:47:27 +0200278 return -1;
279 }
Amit Blay6281ebc2015-01-11 14:44:08 +0200280}
281
Reut Zysman18411272015-02-09 13:47:27 +0200282/**
283 * Read from mmc the image in the given offset, of the given width and height.
284 * Then, display the image on the screen in the given (x,y) location.
285 */
286static 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 +0200287{
Reut Zysman3f3eccd2016-04-20 22:05:36 +0300288 struct mdtp_fbimage *fbimg;
Amit Blay6281ebc2015-01-11 14:44:08 +0200289
Reut Zysman3f3eccd2016-04-20 22:05:36 +0300290 if (fb_config)
291 {
292 fbimg = mdtp_read_mmc_image(offset, width, height);
293 if (NULL == fbimg)
294 {
295 dprintf(CRITICAL,"ERROR: failed to read image from mmc\n");
296 display_error_msg(); /* This will never return */
297 }
Amit Blay6281ebc2015-01-11 14:44:08 +0200298
Reut Zysman3f3eccd2016-04-20 22:05:36 +0300299 fbcon_putImage_in_location(fbimg, x, y);
300 }
301 else
302 {
303 dprintf(CRITICAL,"ERROR: fbcon_config struct is NULL\n");
304 display_error_msg(); /* This will never return */
305 }
Amit Blay6281ebc2015-01-11 14:44:08 +0200306}
307
Reut Zysman18411272015-02-09 13:47:27 +0200308/**
309 * Display initial delay message
310 */
311static void display_initial_delay()
Amit Blay6281ebc2015-01-11 14:44:08 +0200312{
Reut Zysmanff6bab92016-02-09 14:06:31 +0200313 uint32_t x = CENTER_IMAGE_ON_X_AXIS(get_image_width(MAINTEXT_5SECONDS),fb_config->width);
Reut Zysman18411272015-02-09 13:47:27 +0200314 uint32_t y = (fb_config->height)*MAIN_TEXT_RELATIVE_Y_LOCATION;
Reut Zysmanff6bab92016-02-09 14:06:31 +0200315 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 +0200316}
317
Reut Zysman18411272015-02-09 13:47:27 +0200318/**
319 * Display "enter PIN" message
320 */
321static void display_enter_pin()
Amit Blay6281ebc2015-01-11 14:44:08 +0200322{
Reut Zysmanff6bab92016-02-09 14:06:31 +0200323 uint32_t x = CENTER_IMAGE_ON_X_AXIS(get_image_width(MAINTEXT_ENTERPIN),fb_config->width);
Reut Zysman18411272015-02-09 13:47:27 +0200324 uint32_t y = (fb_config->height)*MAIN_TEXT_RELATIVE_Y_LOCATION;
Reut Zysmanff6bab92016-02-09 14:06:31 +0200325 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 +0200326}
327
Reut Zysman18411272015-02-09 13:47:27 +0200328/**
329 * Display invalid PIN message
330 */
331static void display_invalid_pin()
Amit Blay6281ebc2015-01-11 14:44:08 +0200332{
Reut Zysman3f3eccd2016-04-20 22:05:36 +0300333 uint32_t x = CENTER_IMAGE_ON_X_AXIS(get_image_width(MAINTEXT_INCORRECTPIN),fb_config->width);
Reut Zysman18411272015-02-09 13:47:27 +0200334 uint32_t y = (fb_config->height)*MAIN_TEXT_RELATIVE_Y_LOCATION;
Amit Blay6281ebc2015-01-11 14:44:08 +0200335
Reut Zysmanff6bab92016-02-09 14:06:31 +0200336 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 +0200337}
338
Reut Zysman18411272015-02-09 13:47:27 +0200339/**
340 * Clear digits instructions
341 */
342static void display_digits_instructions()
Amit Blay6281ebc2015-01-11 14:44:08 +0200343{
Reut Zysman3f3eccd2016-04-20 22:05:36 +0300344 uint32_t x = CENTER_IMAGE_ON_X_AXIS(get_image_width(PINTEXT),fb_config->width);
Reut Zysman18411272015-02-09 13:47:27 +0200345 uint32_t y = (fb_config->height)*PIN_TEXT_RELATIVE_Y_LOCATION;
346
Reut Zysmanff6bab92016-02-09 14:06:31 +0200347 display_image(get_image_offset(PINTEXT), get_image_width(PINTEXT), get_image_height(PINTEXT), x, y);
Reut Zysman18411272015-02-09 13:47:27 +0200348}
349
350/**
351 * Clear digits instructions
352 */
353static void clear_digits_instructions()
354{
Reut Zysman3f3eccd2016-04-20 22:05:36 +0300355 uint32_t y = (fb_config->height)*PIN_TEXT_RELATIVE_Y_LOCATION;
356 fbcon_clear_section(y, get_image_height(PINTEXT));
Reut Zysman18411272015-02-09 13:47:27 +0200357}
358
359/**
360 * Display a digit as un-selected.
361 */
362static void display_digit(uint32_t x, uint32_t y, uint32_t digit)
363{
Reut Zysman3f3eccd2016-04-20 22:05:36 +0300364 if (g_diplay_pin == false)
365 return;
366
367 display_image(get_image_offset(PIN_UNSELECTED_0 + digit),
368 get_image_width(PIN_UNSELECTED_0 + digit), get_image_height(PIN_UNSELECTED_0 + digit), x, y);
Reut Zysman18411272015-02-09 13:47:27 +0200369}
370
371/**
372 * Display a digit as selected.
373 */
374static void display_selected_digit(uint32_t x, uint32_t y, uint32_t digit)
375{
Reut Zysman3f3eccd2016-04-20 22:05:36 +0300376 if (g_diplay_pin == false)
377 return;
378
Reut Zysmanff6bab92016-02-09 14:06:31 +0200379 display_image(get_image_offset(PIN_SELECTED_0 + digit),
380 get_image_width(PIN_SELECTED_0 + digit),
381 get_image_height(PIN_SELECTED_0 + digit), x, y);
Reut Zysman18411272015-02-09 13:47:27 +0200382}
383
384/**
385 * Display OK button as un-selected.
386 */
387static void display_ok_button()
388{
Reut Zysman3f3eccd2016-04-20 22:05:36 +0300389 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 +0200390 uint32_t ok_y = (fb_config->height)*OK_BUTTON_RELATIVE_Y_LOCATION;
391
Reut Zysmanff6bab92016-02-09 14:06:31 +0200392 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 +0200393}
394
395/**
396 * Display OK button as selected.
397 */
398static void display_selected_ok_button()
399{
Reut Zysman3f3eccd2016-04-20 22:05:36 +0300400 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 +0200401 uint32_t ok_y = (fb_config->height)*OK_BUTTON_RELATIVE_Y_LOCATION;
402
Reut Zysmanff6bab92016-02-09 14:06:31 +0200403 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 +0200404}
405
Reut Zysmanff6bab92016-02-09 14:06:31 +0200406
Reut Zysman18411272015-02-09 13:47:27 +0200407/**
408 * Display the instructions for the OK button.
409 */
410static void display_pin_instructions()
411{
Reut Zysman3f3eccd2016-04-20 22:05:36 +0300412 uint32_t x = CENTER_IMAGE_ON_X_AXIS(get_image_width(ACCEPTEDIT_TEXT),fb_config->width);
Reut Zysman18411272015-02-09 13:47:27 +0200413 uint32_t y = (fb_config->height)*OK_TEXT_RELATIVE_Y_LOCATION;
414
Reut Zysmanff6bab92016-02-09 14:06:31 +0200415 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 +0200416}
417
418/**
419 * Clear the instructions for the OK button.
420 */
421static void clear_pin_message()
422{
Reut Zysman3f3eccd2016-04-20 22:05:36 +0300423 uint32_t y = (fb_config->height)*OK_TEXT_RELATIVE_Y_LOCATION;
Reut Zysman18411272015-02-09 13:47:27 +0200424
Reut Zysmanff6bab92016-02-09 14:06:31 +0200425 fbcon_clear_section(y,get_image_height(ACCEPTEDIT_TEXT));
Reut Zysman33512bc2015-08-09 19:17:09 +0300426}
427
428/**
429 * Initialize data structures required for MDTP UI.
430 */
431static void init_mdtp_ui_data()
432{
433 fb_config = fbcon_display();
434 alloc_mdtp_image();
Reut Zysman18411272015-02-09 13:47:27 +0200435}
436
437/**
438 * Display the basic layout of the screen (done only once).
439 */
440static void display_initial_screen(uint32_t pin_length)
441{
Rami Butsteinfaecf7f2015-06-04 16:39:30 +0300442 if (g_initial_screen_displayed == true)
Reut Zysman18411272015-02-09 13:47:27 +0200443 return;
444
Reut Zysman33512bc2015-08-09 19:17:09 +0300445 init_mdtp_ui_data();
Reut Zysman18411272015-02-09 13:47:27 +0200446
Rami Butsteinfaecf7f2015-06-04 16:39:30 +0300447 if (fb_config)
Reut Zysman18411272015-02-09 13:47:27 +0200448 {
449 fbcon_clear();
450
451 if (display_error_message())
Reut Zysman3f3eccd2016-04-20 22:05:36 +0300452 display_error_msg(); /* This will never return */
Reut Zysman18411272015-02-09 13:47:27 +0200453 display_initial_delay();
454
455 mdelay(INITIAL_DELAY_MSECONDS);
456
457 g_pin_frames_y_location = ((fb_config->height)*PIN_RELATIVE_Y_LOCATION);
458
Reut Zysmanff6bab92016-02-09 14:06:31 +0200459 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 +0200460
Reut Zysman3f3eccd2016-04-20 22:05:36 +0300461 if (fb_config->width > total_pin_length)
Reut Zysman18411272015-02-09 13:47:27 +0200462 {
Reut Zysman3f3eccd2016-04-20 22:05:36 +0300463 g_diplay_pin = true;
464
465 uint32_t complete_pin_centered = (fb_config->width - total_pin_length)/2;
466
467 for (uint32_t i=0; i<pin_length; i++)
468 {
469 g_pin_frames_x_location[i] = complete_pin_centered + i*(mdtp_fs_get_param(DIGIT_SPACE) + get_image_width(PIN_UNSELECTED_0));
470 }
471
472 for (uint32_t i=0; i<pin_length; i++)
473 {
474 display_digit(g_pin_frames_x_location[i], g_pin_frames_y_location, 0);
475 }
Reut Zysman18411272015-02-09 13:47:27 +0200476 }
Reut Zysman3f3eccd2016-04-20 22:05:36 +0300477 else
Reut Zysman18411272015-02-09 13:47:27 +0200478 {
Reut Zysman3f3eccd2016-04-20 22:05:36 +0300479 dprintf(CRITICAL,"ERROR: screen is not wide enough, PIN digits can't be displayed\n");
Reut Zysman18411272015-02-09 13:47:27 +0200480 }
481
482 display_ok_button();
483
484 g_initial_screen_displayed = true;
485 }
486 else
487 {
Reut Zysman3f3eccd2016-04-20 22:05:36 +0300488 dprintf(CRITICAL,"ERROR: fbcon_config struct is NULL\n");
489 display_error_msg(); /* This will never return */
Reut Zysman18411272015-02-09 13:47:27 +0200490 }
491}
492
493/**
494 * Display the recovery PIN screen and set received buffer
495 * with the PIN the user has entered.
496 * The entered PIN will be validated by the calling function.
497 */
498static void display_get_pin_interface(char *entered_pin, uint32_t pin_length)
499{
500 uint32_t previous_position = 0, current_position = 0;
501
502 display_initial_screen(pin_length);
503 display_enter_pin();
504
505 // Convert ascii to digits
506 for (uint32_t i=0; i<pin_length; i++)
507 {
508 entered_pin[i] -= '0';
509 }
510 display_selected_digit(g_pin_frames_x_location[0], g_pin_frames_y_location, entered_pin[0]);
511 display_digits_instructions();
Amit Blay6281ebc2015-01-11 14:44:08 +0200512
513 while (1)
514 {
Reut Zysman18411272015-02-09 13:47:27 +0200515 if (target_volume_up())
Amit Blay6281ebc2015-01-11 14:44:08 +0200516 {
Reut Zysman18411272015-02-09 13:47:27 +0200517 // current position is the OK button
518 if (current_position == pin_length)
519 {
520 // Convert digits to ascii and
521 // validate entered PIN in the calling function
522 for (uint32_t i=0; i<pin_length; i++)
523 {
524 entered_pin[i] += '0';
525 }
526 return;
527 }
528
529 // current position is a PIN slot
530 entered_pin[current_position] = (entered_pin[current_position]+1) % 10;
531 display_selected_digit(g_pin_frames_x_location[current_position], g_pin_frames_y_location, entered_pin[current_position]);
532 mdelay(MDTP_PRESSING_DELAY_MSEC);
533 }
534 if (target_volume_down())
535 {
536 previous_position = current_position;
537 current_position = (current_position+1) % (pin_length+1);
538
539 // previous position was the OK button
540 if (previous_position == pin_length)
541 {
542 clear_pin_message();
543 display_ok_button();
544
545 display_digits_instructions();
546 display_selected_digit(g_pin_frames_x_location[current_position], g_pin_frames_y_location, entered_pin[current_position]);
547
548 }
549
550 // current position is the OK button
551 else if (current_position == pin_length)
552 {
553 display_digit(g_pin_frames_x_location[previous_position], g_pin_frames_y_location, entered_pin[previous_position]);
554 clear_digits_instructions();
555
556 display_selected_ok_button();
557 display_pin_instructions();
558 }
559
560 // both the previous and the current positions are PIN slots
561 else
562 {
563 display_digit(g_pin_frames_x_location[previous_position], g_pin_frames_y_location, entered_pin[previous_position]);
564
565 display_selected_digit(g_pin_frames_x_location[current_position], g_pin_frames_y_location, entered_pin[current_position]);
566 }
567
568 mdelay(MDTP_PRESSING_DELAY_MSEC);
Amit Blay6281ebc2015-01-11 14:44:08 +0200569 }
570 }
Reut Zysman18411272015-02-09 13:47:27 +0200571}
572
573/*----------------------------------------------------------------------------
574 * External Functions
575 * -------------------------------------------------------------------------*/
576
577/**
578 * Display the recovery PIN screen and set received buffer
579 * with the PIN the user has entered.
580 */
581void get_pin_from_user(char *entered_pin, uint32_t pin_length)
582{
583 display_get_pin_interface(entered_pin, pin_length);
Amit Blay6281ebc2015-01-11 14:44:08 +0200584
585 return;
586}
587
Reut Zysman18411272015-02-09 13:47:27 +0200588/**
589 * User has entered invalid PIN, display error message and
590 * allow the user to try again.
591 */
592void display_invalid_pin_msg()
Amit Blay6281ebc2015-01-11 14:44:08 +0200593{
Reut Zysman3f3eccd2016-04-20 22:05:36 +0300594 clear_pin_message();
595 display_ok_button();
Reut Zysman18411272015-02-09 13:47:27 +0200596
Reut Zysman3f3eccd2016-04-20 22:05:36 +0300597 display_invalid_pin();
Reut Zysman18411272015-02-09 13:47:27 +0200598
Reut Zysman3f3eccd2016-04-20 22:05:36 +0300599 mdelay(INVALID_PIN_DELAY_MSECONDS);
Amit Blay6281ebc2015-01-11 14:44:08 +0200600}
601
Reut Zysman18411272015-02-09 13:47:27 +0200602/**
603 * Display error message and stop boot process.
604 */
605void display_error_msg()
Amit Blay6281ebc2015-01-11 14:44:08 +0200606{
Reut Zysman33512bc2015-08-09 19:17:09 +0300607 init_mdtp_ui_data();
Amit Blay8e2731c2015-04-28 21:54:55 +0300608
609 if (fb_config)
610 {
611 fbcon_clear();
612 display_error_message(); // No point in checking the return value here
613 }
Reut Zysman18411272015-02-09 13:47:27 +0200614
615 // Invalid state. Nothing to be done but contacting the OEM.
616 // Stop boot process.
617 dprintf(CRITICAL,"ERROR: blocking boot process\n");
Amit Blay8e2731c2015-04-28 21:54:55 +0300618 for(;;);
Amit Blay6281ebc2015-01-11 14:44:08 +0200619}
620
Reut Zysmanff6bab92016-02-09 14:06:31 +0200621/**
622 * Display error message in case mdtp image is corrupted and stop boot process.
623 */
624void display_error_msg_mdtp()
625{
626 int big_factor = 8; // Font size
627 char* str = "Device unable to boot";
628 char* str2 = "\nError - mdtp image is corrupted\n";
629 fbcon_clear();
630 while(*str != 0) {
631 fbcon_putc_factor(*str++, FBCON_COMMON_MSG, big_factor);
632 }
633 fbcon_draw_line(FBCON_COMMON_MSG);
634 while(*str2 != 0) {
635 fbcon_putc_factor(*str2++, FBCON_COMMON_MSG, big_factor);
636 }
637 fbcon_draw_line(FBCON_COMMON_MSG);
638
639 // Invalid state. Nothing to be done but contacting the OEM.
640 // Stop boot process.
641 dprintf(CRITICAL,"ERROR: blocking boot process - mdtp image corrupted\n");
642 for(;;);
643
644}
645