release-request-64fc473b-7e45-48f5-b2f7-3c916e338608-for-git_pi-release-4249735 snap-temp-L34700000089732387
Change-Id: I06d72832174de02d104eda1d6876fc698908fd04
This commit is contained in:
+12
@@ -108,6 +108,18 @@ else
|
||||
LOCAL_CFLAGS += -DRECOVERY_UI_MARGIN_WIDTH=0
|
||||
endif
|
||||
|
||||
ifneq ($(TARGET_RECOVERY_UI_TOUCH_LOW_THRESHOLD),)
|
||||
LOCAL_CFLAGS += -DRECOVERY_UI_TOUCH_LOW_THRESHOLD=$(TARGET_RECOVERY_UI_TOUCH_LOW_THRESHOLD)
|
||||
else
|
||||
LOCAL_CFLAGS += -DRECOVERY_UI_TOUCH_LOW_THRESHOLD=50
|
||||
endif
|
||||
|
||||
ifneq ($(TARGET_RECOVERY_UI_TOUCH_HIGH_THRESHOLD),)
|
||||
LOCAL_CFLAGS += -DRECOVERY_UI_TOUCH_HIGH_THRESHOLD=$(TARGET_RECOVERY_UI_TOUCH_HIGH_THRESHOLD)
|
||||
else
|
||||
LOCAL_CFLAGS += -DRECOVERY_UI_TOUCH_HIGH_THRESHOLD=90
|
||||
endif
|
||||
|
||||
ifneq ($(TARGET_RECOVERY_UI_VR_STEREO_OFFSET),)
|
||||
LOCAL_CFLAGS += -DRECOVERY_UI_VR_STEREO_OFFSET=$(TARGET_RECOVERY_UI_VR_STEREO_OFFSET)
|
||||
else
|
||||
|
||||
@@ -127,7 +127,8 @@ libimgdiff_src_files := imgdiff.cpp
|
||||
# libbsdiff is compiled with -D_FILE_OFFSET_BITS=64.
|
||||
libimgdiff_cflags := \
|
||||
-Werror \
|
||||
-D_FILE_OFFSET_BITS=64
|
||||
-D_FILE_OFFSET_BITS=64 \
|
||||
-DZLIB_CONST
|
||||
|
||||
libimgdiff_static_libraries := \
|
||||
libbsdiff \
|
||||
|
||||
+614
-439
File diff suppressed because it is too large
Load Diff
+36
-11
@@ -53,36 +53,37 @@ static bool test_bit(size_t bit, unsigned long* array) { // NOLINT
|
||||
return (array[bit/BITS_PER_LONG] & (1UL << (bit % BITS_PER_LONG))) != 0;
|
||||
}
|
||||
|
||||
int ev_init(ev_callback input_cb) {
|
||||
bool epollctlfail = false;
|
||||
|
||||
int ev_init(ev_callback input_cb, bool allow_touch_inputs) {
|
||||
g_epoll_fd = epoll_create(MAX_DEVICES + MAX_MISC_FDS);
|
||||
if (g_epoll_fd == -1) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
bool epollctlfail = false;
|
||||
DIR* dir = opendir("/dev/input");
|
||||
if (dir != NULL) {
|
||||
if (dir != nullptr) {
|
||||
dirent* de;
|
||||
while ((de = readdir(dir))) {
|
||||
// Use unsigned long to match ioctl's parameter type.
|
||||
unsigned long ev_bits[BITS_TO_LONGS(EV_MAX)]; // NOLINT
|
||||
|
||||
// fprintf(stderr,"/dev/input/%s\n", de->d_name);
|
||||
if (strncmp(de->d_name, "event", 5)) continue;
|
||||
int fd = openat(dirfd(dir), de->d_name, O_RDONLY);
|
||||
if (fd == -1) continue;
|
||||
|
||||
// Use unsigned long to match ioctl's parameter type.
|
||||
unsigned long ev_bits[BITS_TO_LONGS(EV_MAX)]; // NOLINT
|
||||
|
||||
// Read the evbits of the input device.
|
||||
if (ioctl(fd, EVIOCGBIT(0, sizeof(ev_bits)), ev_bits) == -1) {
|
||||
close(fd);
|
||||
continue;
|
||||
}
|
||||
|
||||
// We assume that only EV_KEY, EV_REL, and EV_SW event types are ever needed.
|
||||
// We assume that only EV_KEY, EV_REL, and EV_SW event types are ever needed. EV_ABS is also
|
||||
// allowed if allow_touch_inputs is set.
|
||||
if (!test_bit(EV_KEY, ev_bits) && !test_bit(EV_REL, ev_bits) && !test_bit(EV_SW, ev_bits)) {
|
||||
close(fd);
|
||||
continue;
|
||||
if (!allow_touch_inputs || !test_bit(EV_ABS, ev_bits)) {
|
||||
close(fd);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
epoll_event ev;
|
||||
@@ -231,3 +232,27 @@ void ev_iterate_available_keys(const std::function<void(int)>& f) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ev_iterate_touch_inputs(const std::function<void(int)>& action) {
|
||||
for (size_t i = 0; i < ev_dev_count; ++i) {
|
||||
// Use unsigned long to match ioctl's parameter type.
|
||||
unsigned long ev_bits[BITS_TO_LONGS(EV_MAX)] = {}; // NOLINT
|
||||
if (ioctl(ev_fdinfo[i].fd, EVIOCGBIT(0, sizeof(ev_bits)), ev_bits) == -1) {
|
||||
continue;
|
||||
}
|
||||
if (!test_bit(EV_ABS, ev_bits)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
unsigned long key_bits[BITS_TO_LONGS(KEY_MAX)] = {}; // NOLINT
|
||||
if (ioctl(ev_fdinfo[i].fd, EVIOCGBIT(EV_ABS, KEY_MAX), key_bits) == -1) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for (int key_code = 0; key_code <= KEY_MAX; ++key_code) {
|
||||
if (test_bit(key_code, key_bits)) {
|
||||
action(key_code);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -74,10 +74,11 @@ struct input_event;
|
||||
using ev_callback = std::function<int(int fd, uint32_t epevents)>;
|
||||
using ev_set_key_callback = std::function<int(int code, int value)>;
|
||||
|
||||
int ev_init(ev_callback input_cb);
|
||||
int ev_init(ev_callback input_cb, bool allow_touch_inputs = false);
|
||||
void ev_exit();
|
||||
int ev_add_fd(int fd, ev_callback cb);
|
||||
void ev_iterate_available_keys(const std::function<void(int)>& f);
|
||||
void ev_iterate_touch_inputs(const std::function<void(int)>& action);
|
||||
int ev_sync_key_state(const ev_set_key_callback& set_key_cb);
|
||||
|
||||
// 'timeout' has the same semantics as poll(2).
|
||||
|
||||
@@ -54,6 +54,9 @@ RecoveryUI::RecoveryUI()
|
||||
rtl_locale_(false),
|
||||
brightness_normal_(50),
|
||||
brightness_dimmed_(25),
|
||||
touch_screen_allowed_(false),
|
||||
kTouchLowThreshold(RECOVERY_UI_TOUCH_LOW_THRESHOLD),
|
||||
kTouchHighThreshold(RECOVERY_UI_TOUCH_HIGH_THRESHOLD),
|
||||
key_queue_len(0),
|
||||
key_last_down(-1),
|
||||
key_long_press(false),
|
||||
@@ -64,6 +67,9 @@ RecoveryUI::RecoveryUI()
|
||||
has_power_key(false),
|
||||
has_up_key(false),
|
||||
has_down_key(false),
|
||||
has_touch_screen(false),
|
||||
touch_slot_(0),
|
||||
is_bootreason_recovery_ui_(false),
|
||||
screensaver_state_(ScreensaverState::DISABLED) {
|
||||
pthread_mutex_init(&key_queue_mutex, nullptr);
|
||||
pthread_cond_init(&key_queue_cond, nullptr);
|
||||
@@ -77,6 +83,8 @@ void RecoveryUI::OnKeyDetected(int key_code) {
|
||||
has_down_key = true;
|
||||
} else if (key_code == KEY_UP || key_code == KEY_VOLUMEUP) {
|
||||
has_up_key = true;
|
||||
} else if (key_code == ABS_MT_POSITION_X || key_code == ABS_MT_POSITION_Y) {
|
||||
has_touch_screen = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -128,10 +136,28 @@ bool RecoveryUI::Init(const std::string& locale) {
|
||||
// Set up the locale info.
|
||||
SetLocale(locale);
|
||||
|
||||
ev_init(std::bind(&RecoveryUI::OnInputEvent, this, std::placeholders::_1, std::placeholders::_2));
|
||||
ev_init(std::bind(&RecoveryUI::OnInputEvent, this, std::placeholders::_1, std::placeholders::_2),
|
||||
touch_screen_allowed_);
|
||||
|
||||
ev_iterate_available_keys(std::bind(&RecoveryUI::OnKeyDetected, this, std::placeholders::_1));
|
||||
|
||||
if (touch_screen_allowed_) {
|
||||
ev_iterate_touch_inputs(std::bind(&RecoveryUI::OnKeyDetected, this, std::placeholders::_1));
|
||||
|
||||
// Parse /proc/cmdline to determine if it's booting into recovery with a bootreason of
|
||||
// "recovery_ui". This specific reason is set by some (wear) bootloaders, to allow an easier way
|
||||
// to turn on text mode. It will only be set if the recovery boot is triggered from fastboot, or
|
||||
// with 'adb reboot recovery'. Note that this applies to all build variants. Otherwise the text
|
||||
// mode will be turned on automatically on debuggable builds, even without a swipe.
|
||||
std::string cmdline;
|
||||
if (android::base::ReadFileToString("/proc/cmdline", &cmdline)) {
|
||||
is_bootreason_recovery_ui_ = cmdline.find("bootreason=recovery_ui") != std::string::npos;
|
||||
} else {
|
||||
// Non-fatal, and won't affect Init() result.
|
||||
PLOG(WARNING) << "Failed to read /proc/cmdline";
|
||||
}
|
||||
}
|
||||
|
||||
if (!InitScreensaver()) {
|
||||
LOG(INFO) << "Screensaver disabled";
|
||||
}
|
||||
@@ -140,15 +166,91 @@ bool RecoveryUI::Init(const std::string& locale) {
|
||||
return true;
|
||||
}
|
||||
|
||||
void RecoveryUI::OnTouchDetected(int dx, int dy) {
|
||||
enum SwipeDirection { UP, DOWN, RIGHT, LEFT } direction;
|
||||
|
||||
// We only consider a valid swipe if:
|
||||
// - the delta along one axis is below kTouchLowThreshold;
|
||||
// - and the delta along the other axis is beyond kTouchHighThreshold.
|
||||
if (abs(dy) < kTouchLowThreshold && abs(dx) > kTouchHighThreshold) {
|
||||
direction = dx < 0 ? SwipeDirection::LEFT : SwipeDirection::RIGHT;
|
||||
} else if (abs(dx) < kTouchLowThreshold && abs(dy) > kTouchHighThreshold) {
|
||||
direction = dy < 0 ? SwipeDirection::UP : SwipeDirection::DOWN;
|
||||
} else {
|
||||
LOG(DEBUG) << "Ignored " << dx << " " << dy << " (low: " << kTouchLowThreshold
|
||||
<< ", high: " << kTouchHighThreshold << ")";
|
||||
return;
|
||||
}
|
||||
|
||||
// Allow turning on text mode with any swipe, if bootloader has set a bootreason of recovery_ui.
|
||||
if (is_bootreason_recovery_ui_ && !IsTextVisible()) {
|
||||
ShowText(true);
|
||||
return;
|
||||
}
|
||||
|
||||
LOG(DEBUG) << "Swipe direction=" << direction;
|
||||
switch (direction) {
|
||||
case SwipeDirection::UP:
|
||||
ProcessKey(KEY_UP, 1); // press up key
|
||||
ProcessKey(KEY_UP, 0); // and release it
|
||||
break;
|
||||
|
||||
case SwipeDirection::DOWN:
|
||||
ProcessKey(KEY_DOWN, 1); // press down key
|
||||
ProcessKey(KEY_DOWN, 0); // and release it
|
||||
break;
|
||||
|
||||
case SwipeDirection::LEFT:
|
||||
case SwipeDirection::RIGHT:
|
||||
ProcessKey(KEY_POWER, 1); // press power key
|
||||
ProcessKey(KEY_POWER, 0); // and release it
|
||||
break;
|
||||
};
|
||||
}
|
||||
|
||||
int RecoveryUI::OnInputEvent(int fd, uint32_t epevents) {
|
||||
struct input_event ev;
|
||||
if (ev_get_input(fd, epevents, &ev) == -1) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Touch inputs handling.
|
||||
//
|
||||
// We handle the touch inputs by tracking the position changes between initial contacting and
|
||||
// upon lifting. touch_start_X/Y record the initial positions, with touch_finger_down set. Upon
|
||||
// detecting the lift, we unset touch_finger_down and detect a swipe based on position changes.
|
||||
//
|
||||
// Per the doc Multi-touch Protocol at below, there are two protocols.
|
||||
// https://www.kernel.org/doc/Documentation/input/multi-touch-protocol.txt
|
||||
//
|
||||
// The main difference between the stateless type A protocol and the stateful type B slot protocol
|
||||
// lies in the usage of identifiable contacts to reduce the amount of data sent to userspace. The
|
||||
// slot protocol (i.e. type B) sends ABS_MT_TRACKING_ID with a unique id on initial contact, and
|
||||
// sends ABS_MT_TRACKING_ID -1 upon lifting the contact. Protocol A doesn't send
|
||||
// ABS_MT_TRACKING_ID -1 on lifting, but the driver may additionally report BTN_TOUCH event.
|
||||
//
|
||||
// For protocol A, we rely on BTN_TOUCH to recognize lifting, while for protocol B we look for
|
||||
// ABS_MT_TRACKING_ID being -1.
|
||||
//
|
||||
// Touch input events will only be available if touch_screen_allowed_ is set.
|
||||
|
||||
if (ev.type == EV_SYN) {
|
||||
if (touch_screen_allowed_ && ev.code == SYN_REPORT) {
|
||||
// There might be multiple SYN_REPORT events. We should only detect a swipe after lifting the
|
||||
// contact.
|
||||
if (touch_finger_down_ && !touch_swiping_) {
|
||||
touch_start_X_ = touch_X_;
|
||||
touch_start_Y_ = touch_Y_;
|
||||
touch_swiping_ = true;
|
||||
} else if (!touch_finger_down_ && touch_swiping_) {
|
||||
touch_swiping_ = false;
|
||||
OnTouchDetected(touch_X_ - touch_start_X_, touch_Y_ - touch_start_Y_);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
} else if (ev.type == EV_REL) {
|
||||
}
|
||||
|
||||
if (ev.type == EV_REL) {
|
||||
if (ev.code == REL_Y) {
|
||||
// accumulate the up or down motion reported by
|
||||
// the trackball. When it exceeds a threshold
|
||||
@@ -169,7 +271,48 @@ int RecoveryUI::OnInputEvent(int fd, uint32_t epevents) {
|
||||
rel_sum = 0;
|
||||
}
|
||||
|
||||
if (touch_screen_allowed_ && ev.type == EV_ABS) {
|
||||
if (ev.code == ABS_MT_SLOT) {
|
||||
touch_slot_ = ev.value;
|
||||
}
|
||||
// Ignore other fingers.
|
||||
if (touch_slot_ > 0) return 0;
|
||||
|
||||
switch (ev.code) {
|
||||
case ABS_MT_POSITION_X:
|
||||
touch_X_ = ev.value;
|
||||
touch_finger_down_ = true;
|
||||
break;
|
||||
|
||||
case ABS_MT_POSITION_Y:
|
||||
touch_Y_ = ev.value;
|
||||
touch_finger_down_ = true;
|
||||
break;
|
||||
|
||||
case ABS_MT_TRACKING_ID:
|
||||
// Protocol B: -1 marks lifting the contact.
|
||||
if (ev.value < 0) touch_finger_down_ = false;
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (ev.type == EV_KEY && ev.code <= KEY_MAX) {
|
||||
if (touch_screen_allowed_) {
|
||||
if (ev.code == BTN_TOUCH) {
|
||||
// A BTN_TOUCH with value 1 indicates the start of contact (protocol A), with 0 means
|
||||
// lifting the contact.
|
||||
touch_finger_down_ = (ev.value == 1);
|
||||
}
|
||||
|
||||
// Intentionally ignore BTN_TOUCH and BTN_TOOL_FINGER, which would otherwise trigger
|
||||
// additional scrolling (because in ScreenRecoveryUI::ShowFile(), we consider keys other than
|
||||
// KEY_POWER and KEY_UP as KEY_DOWN).
|
||||
if (ev.code == BTN_TOUCH || ev.code == BTN_TOOL_FINGER) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
ProcessKey(ev.code, ev.value);
|
||||
}
|
||||
|
||||
@@ -365,6 +508,14 @@ bool RecoveryUI::HasThreeButtons() {
|
||||
return has_power_key && has_up_key && has_down_key;
|
||||
}
|
||||
|
||||
bool RecoveryUI::HasPowerKey() const {
|
||||
return has_power_key;
|
||||
}
|
||||
|
||||
bool RecoveryUI::HasTouchScreen() const {
|
||||
return has_touch_screen;
|
||||
}
|
||||
|
||||
void RecoveryUI::FlushKeys() {
|
||||
pthread_mutex_lock(&key_queue_mutex);
|
||||
key_queue_len = 0;
|
||||
@@ -377,8 +528,8 @@ RecoveryUI::KeyAction RecoveryUI::CheckKey(int key, bool is_long_press) {
|
||||
pthread_mutex_unlock(&key_queue_mutex);
|
||||
|
||||
// If we have power and volume up keys, that chord is the signal to toggle the text display.
|
||||
if (HasThreeButtons()) {
|
||||
if (key == KEY_VOLUMEUP && IsKeyPressed(KEY_POWER)) {
|
||||
if (HasThreeButtons() || (HasPowerKey() && HasTouchScreen() && touch_screen_allowed_)) {
|
||||
if ((key == KEY_VOLUMEUP || key == KEY_UP) && IsKeyPressed(KEY_POWER)) {
|
||||
return TOGGLE;
|
||||
}
|
||||
} else {
|
||||
|
||||
@@ -82,6 +82,12 @@ class RecoveryUI {
|
||||
// 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();
|
||||
|
||||
@@ -129,7 +135,14 @@ class RecoveryUI {
|
||||
unsigned int brightness_normal_;
|
||||
unsigned int brightness_dimmed_;
|
||||
|
||||
// Whether we should listen for touch inputs (default: false).
|
||||
bool touch_screen_allowed_;
|
||||
|
||||
private:
|
||||
// The sensitivity when detecting a swipe.
|
||||
const int kTouchLowThreshold;
|
||||
const int kTouchHighThreshold;
|
||||
|
||||
// Key event input queue
|
||||
pthread_mutex_t key_queue_mutex;
|
||||
pthread_cond_t key_queue_cond;
|
||||
@@ -147,6 +160,17 @@ class RecoveryUI {
|
||||
bool has_power_key;
|
||||
bool has_up_key;
|
||||
bool has_down_key;
|
||||
bool has_touch_screen;
|
||||
|
||||
// Touch event related variables. See the comments in RecoveryUI::OnInputEvent().
|
||||
int touch_slot_;
|
||||
int touch_X_;
|
||||
int touch_Y_;
|
||||
int touch_start_X_;
|
||||
int touch_start_Y_;
|
||||
bool touch_finger_down_;
|
||||
bool touch_swiping_;
|
||||
bool is_bootreason_recovery_ui_;
|
||||
|
||||
struct key_timer_t {
|
||||
RecoveryUI* ui;
|
||||
@@ -157,6 +181,7 @@ class RecoveryUI {
|
||||
pthread_t input_thread_;
|
||||
|
||||
void OnKeyDetected(int key_code);
|
||||
void OnTouchDetected(int dx, int dy);
|
||||
int OnInputEvent(int fd, uint32_t epevents);
|
||||
void ProcessKey(int key_code, int updown);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user