desktop_view_pin_timeout.c 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. #include <furi.h>
  2. #include <stdint.h>
  3. #include <stdio.h>
  4. #include <FreeRTOS.h>
  5. #include <portmacro.h>
  6. #include <projdefs.h>
  7. #include <input/input.h>
  8. #include <gui/canvas.h>
  9. #include <gui/view.h>
  10. #include "desktop_view_pin_timeout.h"
  11. struct DesktopViewPinTimeout {
  12. View* view;
  13. TimerHandle_t timer;
  14. DesktopViewPinTimeoutDoneCallback callback;
  15. void* context;
  16. };
  17. typedef struct {
  18. uint32_t time_left;
  19. } DesktopViewPinTimeoutModel;
  20. void desktop_view_pin_timeout_set_callback(
  21. DesktopViewPinTimeout* instance,
  22. DesktopViewPinTimeoutDoneCallback callback,
  23. void* context) {
  24. furi_assert(instance);
  25. instance->callback = callback;
  26. instance->context = context;
  27. }
  28. static void desktop_view_pin_timeout_timer_callback(TimerHandle_t timer) {
  29. DesktopViewPinTimeout* instance = pvTimerGetTimerID(timer);
  30. bool stop = false;
  31. DesktopViewPinTimeoutModel* model = view_get_model(instance->view);
  32. if(model->time_left > 0) {
  33. --model->time_left;
  34. } else {
  35. stop = true;
  36. }
  37. view_commit_model(instance->view, true);
  38. if(stop) {
  39. xTimerStop(instance->timer, portMAX_DELAY);
  40. instance->callback(instance->context);
  41. }
  42. }
  43. static bool desktop_view_pin_timeout_input(InputEvent* event, void* context) {
  44. return true;
  45. }
  46. static void desktop_view_pin_timeout_draw(Canvas* canvas, void* _model) {
  47. furi_assert(canvas);
  48. furi_assert(_model);
  49. DesktopViewPinTimeoutModel* model = _model;
  50. canvas_set_font(canvas, FontPrimary);
  51. canvas_draw_str(canvas, 36, 31, "Wrong PIN!");
  52. canvas_set_font(canvas, FontSecondary);
  53. char str[30] = {0};
  54. snprintf(str, sizeof(str), "Timeout: %lds", model->time_left);
  55. canvas_draw_str_aligned(canvas, 64, 38, AlignCenter, AlignCenter, str);
  56. }
  57. void desktop_view_pin_timeout_free(DesktopViewPinTimeout* instance) {
  58. view_free(instance->view);
  59. xTimerDelete(instance->timer, portMAX_DELAY);
  60. free(instance);
  61. }
  62. DesktopViewPinTimeout* desktop_view_pin_timeout_alloc(void) {
  63. DesktopViewPinTimeout* instance = malloc(sizeof(DesktopViewPinTimeout));
  64. instance->timer = xTimerCreate(
  65. NULL, pdMS_TO_TICKS(1000), pdTRUE, instance, desktop_view_pin_timeout_timer_callback);
  66. instance->view = view_alloc();
  67. view_allocate_model(instance->view, ViewModelTypeLockFree, sizeof(DesktopViewPinTimeoutModel));
  68. view_set_context(instance->view, instance);
  69. view_set_draw_callback(instance->view, desktop_view_pin_timeout_draw);
  70. view_set_input_callback(instance->view, desktop_view_pin_timeout_input);
  71. return instance;
  72. }
  73. void desktop_view_pin_timeout_start(DesktopViewPinTimeout* instance, uint32_t time_left) {
  74. furi_assert(instance);
  75. DesktopViewPinTimeoutModel* model = view_get_model(instance->view);
  76. // no race - always called when timer is stopped
  77. model->time_left = time_left;
  78. view_commit_model(instance->view, true);
  79. xTimerStart(instance->timer, portMAX_DELAY);
  80. }
  81. View* desktop_view_pin_timeout_get_view(DesktopViewPinTimeout* instance) {
  82. furi_assert(instance);
  83. return instance->view;
  84. }