Welcome to mirror list, hosted at ThFree Co, Russian Federation.

desktop_view_pin_timeout.c « views « desktop « applications - github.com/ClusterM/flipperzero-firmware.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 7cc0860f3866d343adba80b233de12fcc407d412 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109

#include <furi.h>
#include <stdint.h>
#include <stdio.h>
#include <FreeRTOS.h>
#include <portmacro.h>
#include <projdefs.h>
#include <input/input.h>
#include <gui/canvas.h>
#include <gui/view.h>

#include "desktop_view_pin_timeout.h"

struct DesktopViewPinTimeout {
    View* view;
    TimerHandle_t timer;
    DesktopViewPinTimeoutDoneCallback callback;
    void* context;
};

typedef struct {
    uint32_t time_left;
} DesktopViewPinTimeoutModel;

void desktop_view_pin_timeout_set_callback(
    DesktopViewPinTimeout* instance,
    DesktopViewPinTimeoutDoneCallback callback,
    void* context) {
    furi_assert(instance);

    instance->callback = callback;
    instance->context = context;
}

static void desktop_view_pin_timeout_timer_callback(TimerHandle_t timer) {
    DesktopViewPinTimeout* instance = pvTimerGetTimerID(timer);
    bool stop = false;

    DesktopViewPinTimeoutModel* model = view_get_model(instance->view);
    if(model->time_left > 0) {
        --model->time_left;
    } else {
        stop = true;
    }
    view_commit_model(instance->view, true);

    if(stop) {
        xTimerStop(instance->timer, portMAX_DELAY);
        instance->callback(instance->context);
    }
}

static bool desktop_view_pin_timeout_input(InputEvent* event, void* context) {
    return true;
}

static void desktop_view_pin_timeout_draw(Canvas* canvas, void* _model) {
    furi_assert(canvas);
    furi_assert(_model);

    DesktopViewPinTimeoutModel* model = _model;

    canvas_set_font(canvas, FontPrimary);
    canvas_draw_str(canvas, 36, 31, "Wrong PIN!");

    canvas_set_font(canvas, FontSecondary);
    char str[30] = {0};
    snprintf(str, sizeof(str), "Timeout: %lds", model->time_left);
    canvas_draw_str_aligned(canvas, 64, 38, AlignCenter, AlignCenter, str);
}

void desktop_view_pin_timeout_free(DesktopViewPinTimeout* instance) {
    view_free(instance->view);
    xTimerDelete(instance->timer, portMAX_DELAY);

    free(instance);
}

DesktopViewPinTimeout* desktop_view_pin_timeout_alloc(void) {
    DesktopViewPinTimeout* instance = furi_alloc(sizeof(DesktopViewPinTimeout));
    instance->timer = xTimerCreate(
        NULL, pdMS_TO_TICKS(1000), pdTRUE, instance, desktop_view_pin_timeout_timer_callback);

    instance->view = view_alloc();
    view_allocate_model(instance->view, ViewModelTypeLockFree, sizeof(DesktopViewPinTimeoutModel));

    view_set_context(instance->view, instance);
    view_set_draw_callback(instance->view, desktop_view_pin_timeout_draw);
    view_set_input_callback(instance->view, desktop_view_pin_timeout_input);

    return instance;
}

void desktop_view_pin_timeout_start(DesktopViewPinTimeout* instance, uint32_t time_left) {
    furi_assert(instance);

    DesktopViewPinTimeoutModel* model = view_get_model(instance->view);
    // no race - always called when timer is stopped
    model->time_left = time_left;
    view_commit_model(instance->view, true);

    xTimerStart(instance->timer, portMAX_DELAY);
}

View* desktop_view_pin_timeout_get_view(DesktopViewPinTimeout* instance) {
    furi_assert(instance);

    return instance->view;
}