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);
 }