-
Notifications
You must be signed in to change notification settings - Fork 10
/
ui.h
380 lines (306 loc) · 10.5 KB
/
ui.h
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
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
/*
* Copyright (C) 2011 The Android Open Source Project
* Copyright (C) 2019 The LineageOS Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef RECOVERY_UI_H
#define RECOVERY_UI_H
#include <linux/input.h>
#include <pthread.h>
#include <time.h>
#include <string>
#include <vector>
enum menu_type_t { MT_NONE, MT_LIST, MT_GRID };
class MenuItem {
public:
MenuItem() {}
explicit MenuItem(const std::string& text, const std::string& icon_name = "",
const std::string& icon_name_sel = "")
: text_(text), icon_name_(icon_name), icon_name_sel_(icon_name_sel) {}
const std::string& text() const {
return text_;
}
const std::string& icon_name() const {
return icon_name_;
}
const std::string& icon_name_sel() const {
return icon_name_sel_;
}
private:
std::string text_;
std::string icon_name_;
std::string icon_name_sel_;
};
typedef std::vector<MenuItem> MenuItemVector;
/*
* Simple representation of a (x,y) coordinate with convenience operators
*/
class Point {
public:
Point() : x_(0), y_(0) {}
Point(int x, int y) : x_(x), y_(y) {}
int x() const {
return x_;
}
int y() const {
return y_;
}
void x(int x) {
x_ = x;
}
void y(int y) {
y_ = y;
}
bool operator==(const Point& rhs) const {
return (x() == rhs.x() && y() == rhs.y());
}
bool operator!=(const Point& rhs) const {
return !(*this == rhs);
}
Point operator+(const Point& rhs) const {
Point tmp;
tmp.x_ = x_ + rhs.x_;
tmp.y_ = y_ + rhs.y_;
return tmp;
}
Point operator-(const Point& rhs) const {
Point tmp;
tmp.x_ = x_ - rhs.x_;
tmp.y_ = y_ - rhs.y_;
return tmp;
}
private:
int x_;
int y_;
};
// Abstract class for controlling the user interface during recovery.
class RecoveryUI {
public:
enum Icon {
NONE,
INSTALLING_UPDATE,
ERASING,
NO_COMMAND,
ERROR
};
enum ProgressType {
EMPTY,
INDETERMINATE,
DETERMINATE
};
enum KeyAction {
ENQUEUE,
TOGGLE,
REBOOT,
IGNORE
};
RecoveryUI();
virtual ~RecoveryUI() {}
// Initializes the object; called before anything else. UI texts will be initialized according to
// the given locale. Returns true on success.
virtual bool Init(const std::string& locale);
virtual void Stop();
// Shows a stage indicator. Called immediately after Init().
virtual void SetStage(int current, int max) = 0;
// Sets the overall recovery state ("background image").
virtual void SetBackground(Icon icon) = 0;
virtual void SetSystemUpdateText(bool security_update) = 0;
// --- progress indicator ---
virtual void SetProgressType(ProgressType determinate) = 0;
// Shows a progress bar and define the scope of the next operation:
// portion - fraction of the progress bar the next operation will use
// seconds - expected time interval (progress bar moves at this minimum rate)
virtual void ShowProgress(float portion, float seconds) = 0;
// Sets progress bar position (0.0 - 1.0 within the scope defined by the last call to
// ShowProgress).
virtual void SetProgress(float fraction) = 0;
// --- text log ---
virtual void ShowText(bool visible) = 0;
virtual bool IsTextVisible() = 0;
virtual bool WasTextEverVisible() = 0;
virtual void UpdateScreenOnPrint(bool update) = 0;
// Writes a message to the on-screen log (shown if the user has toggled on the text display).
// Print() will also dump the message to stdout / log file, while PrintOnScreenOnly() not.
virtual void Print(const char* fmt, ...) __printflike(2, 3) = 0;
virtual void PrintOnScreenOnly(const char* fmt, ...) __printflike(2, 3) = 0;
virtual int ShowFile(const char* filename) = 0;
virtual void Redraw() = 0;
// --- event handling ---
enum event_type_t { EVENT_TYPE_NONE, EVENT_TYPE_KEY, EVENT_TYPE_TOUCH };
class InputEvent {
public:
InputEvent() : type_(EVENT_TYPE_NONE), evt_({ 0 }) {}
explicit InputEvent(int key) : type_(EVENT_TYPE_KEY), evt_({ key }) {}
explicit InputEvent(const Point& pos) : type_(EVENT_TYPE_TOUCH), evt_({ 0 }) {
evt_.pos = pos;
}
event_type_t type() const {
return type_;
}
int key() const {
return evt_.key;
}
const Point& pos() const {
return evt_.pos;
}
private:
event_type_t type_;
union {
int key;
Point pos;
} evt_;
};
// Waits for a key and return it. May return -1 after timeout.
virtual InputEvent WaitInputEvent();
// Cancel a WaitKey()
virtual void CancelWaitKey();
virtual bool IsKeyPressed(int key);
virtual bool IsLongPress();
// Returns true if you have the volume up/down and power trio typical of phones and tablets, false
// otherwise.
virtual bool HasThreeButtons();
// Returns true if it has a power key.
virtual bool HasPowerKey() const;
// Returns true if it supports touch inputs.
virtual bool HasTouchScreen() const;
// Erases any queued-up keys.
virtual void FlushKeys();
// Called on each key press, even while operations are in progress. Return value indicates whether
// an immediate operation should be triggered (toggling the display, rebooting the device), or if
// the key should be enqueued for use by the main thread.
virtual KeyAction CheckKey(int key, bool is_long_press);
// Called when a key is held down long enough to have been a long-press (but before the key is
// released). This means that if the key is eventually registered (released without any other keys
// being pressed in the meantime), CheckKey will be called with 'is_long_press' true.
virtual void KeyLongPress(int key);
// Normally in recovery there's a key sequence that triggers immediate reboot of the device,
// regardless of what recovery is doing (with the default CheckKey implementation, it's pressing
// the power button 7 times in row). Call this to enable or disable that feature. It is enabled by
// default.
virtual void SetEnableReboot(bool enabled);
// --- menu display ---
// Display some header text followed by a menu of items, which appears at the top of the screen
// (in place of any scrolling ui_print() output, if necessary).
virtual void StartMenu(bool is_main, menu_type_t type, const char* const* headers,
const MenuItemVector& items, int initial_selection) = 0;
// Sets the menu highlight to the given index, wrapping if necessary. Returns the actual item
// selected.
virtual int SelectMenu(int sel) = 0;
virtual int SelectMenu(const Point& point) = 0;
// Scroll the view by increasing or lowering the first shown item
// If updown < 0, scroll up by |updown| items. If updown > 0, scroll down by |updown| items
// Returns the selected item, since scrolling past a selected item will change the selection to
// the closest on screen item
virtual int ScrollMenu(int updown) = 0;
// Ends menu mode, resetting the text overlay so that ui_print() statements will be displayed.
virtual void EndMenu() = 0;
// Notify of volume state change
void onVolumeChanged() {
volumes_changed_ = 1;
}
bool VolumesChanged();
virtual bool MenuShowing() const = 0;
virtual bool MenuScrollable() const = 0;
virtual int MenuItemStart() const = 0;
virtual int MenuItemHeight() const = 0;
protected:
void EnqueueKey(int key_code);
void EnqueueTouch(const Point& pos);
std::string android_version_;
std::string boot_slot_;
std::string lineage_version_;
// The normal and dimmed brightness percentages (default: 50 and 25, which means 50% and 25% of
// the max_brightness). Because the absolute values may vary across devices. These two values can
// be configured via subclassing. Setting brightness_normal_ to 0 to disable screensaver.
unsigned int brightness_normal_;
unsigned int brightness_dimmed_;
std::string brightness_file_;
std::string max_brightness_file_;
// Whether we should listen for touch inputs (default: true).
bool touch_screen_allowed_;
private:
enum class ScreensaverState {
DISABLED,
NORMAL,
DIMMED,
OFF
};
struct key_timer_t {
RecoveryUI* ui;
int key_code;
int count;
};
// The sensitivity when detecting a swipe.
const int kTouchLowThreshold;
const int kTouchHighThreshold;
void OnTouchDeviceDetected(int fd);
void OnKeyDetected(int key_code);
void CalibrateTouch(int fd);
void OnTouchPress();
void OnTouchTrack();
void OnTouchRelease();
int OnInputEvent(int fd, uint32_t epevents);
void ProcessKey(int key_code, int updown);
bool IsUsbConnected();
static void* time_key_helper(void* cookie);
void time_key(int key_code, int count);
bool InitScreensaver();
// Key event input queue
pthread_mutex_t event_queue_mutex;
pthread_cond_t event_queue_cond;
InputEvent event_queue[256];
int event_queue_len;
char key_pressed[KEY_MAX + 1]; // under event_queue_mutex
int key_last_down; // under event_queue_mutex
bool key_long_press; // under event_queue_mutex
int key_down_count; // under event_queue_mutex
bool enable_reboot; // under event_queue_mutex
int rel_sum;
int consecutive_power_keys;
int last_key;
bool has_power_key;
bool has_up_key;
bool has_down_key;
bool has_touch_screen;
struct vkey_t {
bool inside(const Point& p) const {
return (p.x() >= min_.x() && p.x() < max_.x() && p.y() >= min_.y() && p.y() < max_.y());
}
int keycode;
Point min_;
Point max_;
};
// Touch event related variables. See the comments in RecoveryUI::OnInputEvent().
int touch_slot_;
bool touch_finger_down_;
bool touch_saw_x_;
bool touch_saw_y_;
bool touch_reported_;
Point touch_pos_;
Point touch_start_;
Point touch_track_;
Point touch_max_;
Point touch_min_;
bool has_swiped_;
std::vector<vkey_t> virtual_keys_;
bool is_bootreason_recovery_ui_;
pthread_t input_thread_;
bool volumes_changed_;
ScreensaverState screensaver_state_;
// The following two contain the absolute values computed from brightness_normal_ and
// brightness_dimmed_ respectively.
unsigned int brightness_normal_value_;
unsigned int brightness_dimmed_value_;
};
#endif // RECOVERY_UI_H