Merge "Add prebuilt_etc for secure_element XML files" into main
diff --git a/libs/binder/ndk/include_platform/android/binder_manager.h b/libs/binder/ndk/include_platform/android/binder_manager.h
index 89fd7a3..316a79c 100644
--- a/libs/binder/ndk/include_platform/android/binder_manager.h
+++ b/libs/binder/ndk/include_platform/android/binder_manager.h
@@ -120,7 +120,7 @@
 
 /**
  * Gets a binder object with this specific instance name. Efficiently waits for the service.
- * If the service is not declared, it will wait indefinitely. Requires the threadpool
+ * If the service is not ever registered, it will wait indefinitely. Requires the threadpool
  * to be started in the service.
  * This also implicitly calls AIBinder_incStrong (so the caller of this function is responsible
  * for calling AIBinder_decStrong).
diff --git a/libs/binder/rust/src/parcel.rs b/libs/binder/rust/src/parcel.rs
index 3c615ed..f9f135d 100644
--- a/libs/binder/rust/src/parcel.rs
+++ b/libs/binder/rust/src/parcel.rs
@@ -54,6 +54,10 @@
 
 /// Safety: This type guarantees that it owns the AParcel and that all access to
 /// the AParcel happens through the Parcel, so it is ok to send across threads.
+///
+/// It would not be okay to implement Sync, because that would allow you to call
+/// the reading methods from several threads in parallel, which would be a data
+/// race on the cursor position inside the AParcel.
 unsafe impl Send for Parcel {}
 
 /// Container for a message (data and object references) that can be sent
diff --git a/libs/binder/tests/parcel_fuzzer/random_parcel.cpp b/libs/binder/tests/parcel_fuzzer/random_parcel.cpp
index f0beed2..f367b41 100644
--- a/libs/binder/tests/parcel_fuzzer/random_parcel.cpp
+++ b/libs/binder/tests/parcel_fuzzer/random_parcel.cpp
@@ -66,6 +66,11 @@
                 },
                 // write FD
                 [&]() {
+                    // b/296516864 - Limit number of objects written to a parcel.
+                    if (p->objectsCount() > 100) {
+                        return;
+                    }
+
                     if (options->extraFds.size() > 0 && provider.ConsumeBool()) {
                         const base::unique_fd& fd = options->extraFds.at(
                                 provider.ConsumeIntegralInRange<size_t>(0,
@@ -82,7 +87,6 @@
                         CHECK(OK ==
                               p->writeFileDescriptor(fds.begin()->release(),
                                                      true /*takeOwnership*/));
-
                         options->extraFds.insert(options->extraFds.end(),
                                                  std::make_move_iterator(fds.begin() + 1),
                                                  std::make_move_iterator(fds.end()));
@@ -90,6 +94,11 @@
                 },
                 // write binder
                 [&]() {
+                    // b/296516864 - Limit number of objects written to a parcel.
+                    if (p->objectsCount() > 100) {
+                        return;
+                    }
+
                     sp<IBinder> binder;
                     if (options->extraBinders.size() > 0 && provider.ConsumeBool()) {
                         binder = options->extraBinders.at(
diff --git a/opengl/libs/EGL/MultifileBlobCache.cpp b/opengl/libs/EGL/MultifileBlobCache.cpp
index 7ffdac7..ed3c616 100644
--- a/opengl/libs/EGL/MultifileBlobCache.cpp
+++ b/opengl/libs/EGL/MultifileBlobCache.cpp
@@ -48,9 +48,8 @@
 void freeHotCacheEntry(android::MultifileHotCache& entry) {
     if (entry.entryFd != -1) {
         // If we have an fd, then this entry was added to hot cache via INIT or GET
-        // We need to unmap and close the entry
+        // We need to unmap the entry
         munmap(entry.entryBuffer, entry.entrySize);
-        close(entry.entryFd);
     } else {
         // Otherwise, this was added to hot cache during SET, so it was never mapped
         // and fd was only on the deferred thread.
@@ -143,6 +142,7 @@
                 if (result != sizeof(MultifileHeader)) {
                     ALOGE("Error reading MultifileHeader from cache entry (%s): %s",
                           fullPath.c_str(), std::strerror(errno));
+                    close(fd);
                     return;
                 }
 
@@ -152,6 +152,7 @@
                     if (remove(fullPath.c_str()) != 0) {
                         ALOGE("Error removing %s: %s", fullPath.c_str(), std::strerror(errno));
                     }
+                    close(fd);
                     continue;
                 }
 
@@ -161,6 +162,10 @@
                 // Memory map the file
                 uint8_t* mappedEntry = reinterpret_cast<uint8_t*>(
                         mmap(nullptr, fileSize, PROT_READ, MAP_PRIVATE, fd, 0));
+
+                // We can close the file now and the mmap will remain
+                close(fd);
+
                 if (mappedEntry == MAP_FAILED) {
                     ALOGE("Failed to mmap cacheEntry, error: %s", std::strerror(errno));
                     return;
@@ -206,13 +211,11 @@
                     if (!addToHotCache(entryHash, fd, mappedEntry, fileSize)) {
                         ALOGE("INIT Failed to add %u to hot cache", entryHash);
                         munmap(mappedEntry, fileSize);
-                        close(fd);
                         return;
                     }
                 } else {
                     // If we're not keeping it in hot cache, unmap it now
                     munmap(mappedEntry, fileSize);
-                    close(fd);
                 }
             }
             closedir(dir);
@@ -401,9 +404,12 @@
         // Memory map the file
         cacheEntry =
                 reinterpret_cast<uint8_t*>(mmap(nullptr, fileSize, PROT_READ, MAP_PRIVATE, fd, 0));
+
+        // We can close the file now and the mmap will remain
+        close(fd);
+
         if (cacheEntry == MAP_FAILED) {
             ALOGE("Failed to mmap cacheEntry, error: %s", std::strerror(errno));
-            close(fd);
             return 0;
         }
 
diff --git a/opengl/libs/EGL/MultifileBlobCache_test.cpp b/opengl/libs/EGL/MultifileBlobCache_test.cpp
index dbee13b..1639be6 100644
--- a/opengl/libs/EGL/MultifileBlobCache_test.cpp
+++ b/opengl/libs/EGL/MultifileBlobCache_test.cpp
@@ -42,6 +42,8 @@
 
     virtual void TearDown() { mMBC.reset(); }
 
+    int getFileDescriptorCount();
+
     std::unique_ptr<TemporaryFile> mTempFile;
     std::unique_ptr<MultifileBlobCache> mMBC;
 };
@@ -216,4 +218,56 @@
     ASSERT_EQ('y', buf[0]);
 }
 
+int MultifileBlobCacheTest::getFileDescriptorCount() {
+    DIR* directory = opendir("/proc/self/fd");
+
+    int fileCount = 0;
+    struct dirent* entry;
+    while ((entry = readdir(directory)) != NULL) {
+        fileCount++;
+        // printf("File: %s\n", entry->d_name);
+    }
+
+    closedir(directory);
+    return fileCount;
+}
+
+TEST_F(MultifileBlobCacheTest, EnsureFileDescriptorsClosed) {
+    // Populate the cache with a bunch of entries
+    size_t kLargeNumberOfEntries = 1024;
+    for (int i = 0; i < kLargeNumberOfEntries; i++) {
+        // printf("Caching: %i", i);
+
+        // Use the index as the key and value
+        mMBC->set(&i, sizeof(i), &i, sizeof(i));
+
+        int result = 0;
+        ASSERT_EQ(sizeof(i), mMBC->get(&i, sizeof(i), &result, sizeof(result)));
+        ASSERT_EQ(i, result);
+    }
+
+    // Ensure we don't have a bunch of open fds
+    ASSERT_LT(getFileDescriptorCount(), kLargeNumberOfEntries / 2);
+
+    // Close the cache so everything writes out
+    mMBC->finish();
+    mMBC.reset();
+
+    // Now open it again and ensure we still don't have a bunch of open fds
+    mMBC.reset(
+            new MultifileBlobCache(kMaxKeySize, kMaxValueSize, kMaxTotalSize, &mTempFile->path[0]));
+
+    // Check after initialization
+    ASSERT_LT(getFileDescriptorCount(), kLargeNumberOfEntries / 2);
+
+    for (int i = 0; i < kLargeNumberOfEntries; i++) {
+        int result = 0;
+        ASSERT_EQ(sizeof(i), mMBC->get(&i, sizeof(i), &result, sizeof(result)));
+        ASSERT_EQ(i, result);
+    }
+
+    // And again after we've actually used it
+    ASSERT_LT(getFileDescriptorCount(), kLargeNumberOfEntries / 2);
+}
+
 } // namespace android
diff --git a/services/inputflinger/InputListener.cpp b/services/inputflinger/InputListener.cpp
index aa55873..ca5d5a1 100644
--- a/services/inputflinger/InputListener.cpp
+++ b/services/inputflinger/InputListener.cpp
@@ -39,7 +39,7 @@
 
 // Helper to std::visit with lambdas.
 template <typename... V>
-struct Visitor : V... {};
+struct Visitor : V... { using V::operator()...; };
 // explicit deduction guide (not needed as of C++20)
 template <typename... V>
 Visitor(V...) -> Visitor<V...>;
diff --git a/services/inputflinger/NotifyArgs.cpp b/services/inputflinger/NotifyArgs.cpp
index 408fbed..35d60ea 100644
--- a/services/inputflinger/NotifyArgs.cpp
+++ b/services/inputflinger/NotifyArgs.cpp
@@ -233,7 +233,7 @@
 
 // Helper to std::visit with lambdas.
 template <typename... V>
-struct Visitor : V... {};
+struct Visitor : V... { using V::operator()...; };
 // explicit deduction guide (not needed as of C++20)
 template <typename... V>
 Visitor(V...) -> Visitor<V...>;
diff --git a/services/inputflinger/reader/mapper/gestures/PropertyProvider.cpp b/services/inputflinger/reader/mapper/gestures/PropertyProvider.cpp
index be2bfed..69264f8 100644
--- a/services/inputflinger/reader/mapper/gestures/PropertyProvider.cpp
+++ b/services/inputflinger/reader/mapper/gestures/PropertyProvider.cpp
@@ -239,7 +239,7 @@
 
 // Helper to std::visit with lambdas.
 template <typename... V>
-struct Visitor : V... {};
+struct Visitor : V... { using V::operator()...; };
 // explicit deduction guide (not needed as of C++20)
 template <typename... V>
 Visitor(V...) -> Visitor<V...>;