Merge "Use getrandom for device input event ID generation"
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);
}