Use getrandom for device input event ID generation
On device, let's go back to using 'getrandom' for the generation of
random input event ids. This should be faster than reading from
/dev/urandom.
This is a partial revert of the previous patch. After this patch, we
will only use '/dev/urandom' on host.
We may be able to switch to 'getrandom' for both if we ever switch to
musl for host. We can revisit it then.
Bug: 254215895
Test: m && atest --host libinput_tests
Change-Id: Idc6241facbd93f3f71ae90567db831d96a5fc98b
diff --git a/libs/input/Input.cpp b/libs/input/Input.cpp
index a6f6b14..c1eb8e2 100644
--- a/libs/input/Input.cpp
+++ b/libs/input/Input.cpp
@@ -35,6 +35,9 @@
#ifdef __linux__
#include <binder/Parcel.h>
#endif
+#if defined(__ANDROID__)
+#include <sys/random.h>
+#endif
using android::base::StringPrintf;
@@ -110,8 +113,11 @@
}
// --- IdGenerator ---
-
-static status_t getRandomBytes(uint8_t* data, size_t size) {
+#if defined(__ANDROID__)
+[[maybe_unused]]
+#endif
+static status_t
+getRandomBytes(uint8_t* data, size_t size) {
int ret = TEMP_FAILURE_RETRY(open("/dev/urandom", O_RDONLY | O_CLOEXEC | O_NOFOLLOW));
if (ret == -1) {
return -errno;
@@ -130,7 +136,22 @@
constexpr uint32_t SEQUENCE_NUMBER_MASK = ~SOURCE_MASK;
int32_t id = 0;
+#if defined(__ANDROID__)
+ // On device, prefer 'getrandom' to '/dev/urandom' because it's faster.
+ constexpr size_t BUF_LEN = sizeof(id);
+ size_t totalBytes = 0;
+ while (totalBytes < BUF_LEN) {
+ ssize_t bytes = TEMP_FAILURE_RETRY(getrandom(&id, BUF_LEN, GRND_NONBLOCK));
+ if (CC_UNLIKELY(bytes < 0)) {
+ ALOGW("Failed to fill in random number for sequence number: %s.", strerror(errno));
+ id = 0;
+ break;
+ }
+ totalBytes += bytes;
+ }
+#else
#if defined(__linux__)
+ // On host, <sys/random.h> / GRND_NONBLOCK is not available
while (true) {
status_t result = getRandomBytes(reinterpret_cast<uint8_t*>(&id), sizeof(id));
if (result == OK) {
@@ -138,6 +159,7 @@
}
}
#endif // __linux__
+#endif // __ANDROID__
return (id & SEQUENCE_NUMBER_MASK) | static_cast<int32_t>(mSource);
}