Merge "Don't include AIDL NDK output if not needed" into main
diff --git a/data/etc/Android.bp b/data/etc/Android.bp
index e95432c..1418e1f 100644
--- a/data/etc/Android.bp
+++ b/data/etc/Android.bp
@@ -359,6 +359,12 @@
 }
 
 prebuilt_etc {
+    name: "android.software.opengles.deqp.level-latest.prebuilt.xml",
+    src: "android.software.opengles.deqp.level-latest.xml",
+    defaults: ["frameworks_native_data_etc_defaults"],
+}
+
+prebuilt_etc {
     name: "android.software.sip.voip.prebuilt.xml",
     src: "android.software.sip.voip.xml",
     defaults: ["frameworks_native_data_etc_defaults"],
@@ -389,6 +395,12 @@
 }
 
 prebuilt_etc {
+    name: "android.software.vulkan.deqp.level-latest.prebuilt.xml",
+    src: "android.software.vulkan.deqp.level-latest.xml",
+    defaults: ["frameworks_native_data_etc_defaults"],
+}
+
+prebuilt_etc {
     name: "aosp_excluded_hardware.prebuilt.xml",
     src: "aosp_excluded_hardware.xml",
     defaults: ["frameworks_native_data_etc_defaults"],
diff --git a/data/etc/android.software.opengles.deqp.level-latest.xml b/data/etc/android.software.opengles.deqp.level-latest.xml
new file mode 100644
index 0000000..bd15eb6
--- /dev/null
+++ b/data/etc/android.software.opengles.deqp.level-latest.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright 2023 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<!-- This is the standard feature indicating that the device passes OpenGL ES
+     dEQP tests associated with the most recent level for this Android version. -->
+<permissions>
+    <feature name="android.software.opengles.deqp.level" version="132580097" />
+</permissions>
diff --git a/data/etc/android.software.vulkan.deqp.level-latest.xml b/data/etc/android.software.vulkan.deqp.level-latest.xml
new file mode 100644
index 0000000..87be070
--- /dev/null
+++ b/data/etc/android.software.vulkan.deqp.level-latest.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright 2023 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<!-- This is the standard feature indicating that the device passes Vulkan
+     dEQP tests associated with the most recent level for this Android version. -->
+<permissions>
+    <feature name="android.software.vulkan.deqp.level" version="132580097" />
+</permissions>
diff --git a/data/etc/aosp_excluded_hardware.xml b/data/etc/aosp_excluded_hardware.xml
index c12f435..013f278 100644
--- a/data/etc/aosp_excluded_hardware.xml
+++ b/data/etc/aosp_excluded_hardware.xml
@@ -18,5 +18,4 @@
     <!-- This should be used to exclude this feature from aosp targets. As aosp configurations
     may or may not have a valid location provider -->
     <unavailable-feature name="android.hardware.location.network" />
-    <unavailable-feature name="android.software.device_id_attestation" />
 </permissions>
diff --git a/libs/binder/Android.bp b/libs/binder/Android.bp
index 67e92ca..620c23c 100644
--- a/libs/binder/Android.bp
+++ b/libs/binder/Android.bp
@@ -375,6 +375,22 @@
 }
 
 cc_library_static {
+    name: "libbinder_rpc_no_native_handle",
+    vendor_available: true,
+    defaults: [
+        "libbinder_common_defaults",
+        "libbinder_android_defaults",
+        "libbinder_kernel_defaults",
+    ],
+    cflags: [
+        "-DBINDER_DISABLE_NATIVE_HANDLE",
+    ],
+    visibility: [
+        ":__subpackages__",
+    ],
+}
+
+cc_library_static {
     name: "libbinder_rpc_single_threaded",
     defaults: [
         "libbinder_common_defaults",
diff --git a/libs/binder/Parcel.cpp b/libs/binder/Parcel.cpp
index a59b928..17bdc45 100644
--- a/libs/binder/Parcel.cpp
+++ b/libs/binder/Parcel.cpp
@@ -1436,6 +1436,7 @@
     return writeParcelable(*parcelable);
 }
 
+#ifndef BINDER_DISABLE_NATIVE_HANDLE
 status_t Parcel::writeNativeHandle(const native_handle* handle)
 {
     if (!handle || handle->version != sizeof(native_handle))
@@ -1458,6 +1459,7 @@
     err = write(handle->data + handle->numFds, sizeof(int)*handle->numInts);
     return err;
 }
+#endif
 
 status_t Parcel::writeFileDescriptor(int fd, bool takeOwnership) {
     if (auto* rpcFields = maybeRpcFields()) {
@@ -2239,6 +2241,7 @@
     return status.exceptionCode();
 }
 
+#ifndef BINDER_DISABLE_NATIVE_HANDLE
 native_handle* Parcel::readNativeHandle() const
 {
     int numFds, numInts;
@@ -2271,6 +2274,7 @@
     }
     return h;
 }
+#endif
 
 int Parcel::readFileDescriptor() const {
     if (const auto* rpcFields = maybeRpcFields()) {
diff --git a/libs/binder/include/binder/Parcel.h b/libs/binder/include/binder/Parcel.h
index b94267c..98d12bb 100644
--- a/libs/binder/include/binder/Parcel.h
+++ b/libs/binder/include/binder/Parcel.h
@@ -26,7 +26,9 @@
 #include <vector>
 
 #include <android-base/unique_fd.h>
+#ifndef BINDER_DISABLE_NATIVE_HANDLE
 #include <cutils/native_handle.h>
+#endif
 #include <utils/Errors.h>
 #include <utils/RefBase.h>
 #include <utils/String16.h>
@@ -324,11 +326,13 @@
     template<typename T>
     status_t            writeVectorSize(const std::unique_ptr<std::vector<T>>& val) __attribute__((deprecated("use std::optional version instead")));
 
+#ifndef BINDER_DISABLE_NATIVE_HANDLE
     // Place a native_handle into the parcel (the native_handle's file-
     // descriptors are dup'ed, so it is safe to delete the native_handle
     // when this function returns).
     // Doesn't take ownership of the native_handle.
     status_t            writeNativeHandle(const native_handle* handle);
+#endif
 
     // Place a file descriptor into the parcel.  The given fd must remain
     // valid for the lifetime of the parcel.
@@ -559,13 +563,14 @@
     // response headers rather than doing it by hand.
     int32_t             readExceptionCode() const;
 
+#ifndef BINDER_DISABLE_NATIVE_HANDLE
     // Retrieve native_handle from the parcel. This returns a copy of the
     // parcel's native_handle (the caller takes ownership). The caller
-    // must free the native_handle with native_handle_close() and 
+    // must free the native_handle with native_handle_close() and
     // native_handle_delete().
     native_handle*     readNativeHandle() const;
+#endif
 
-    
     // Retrieve a file descriptor from the parcel.  This returns the raw fd
     // in the parcel, which you do not own -- use dup() to get your own copy.
     int                 readFileDescriptor() const;
diff --git a/libs/binder/rust/src/lib.rs b/libs/binder/rust/src/lib.rs
index 8841fe6..ed870b6 100644
--- a/libs/binder/rust/src/lib.rs
+++ b/libs/binder/rust/src/lib.rs
@@ -144,6 +144,7 @@
 #[doc(hidden)]
 pub mod unstable_api {
     pub use crate::binder::AsNative;
+    pub use crate::error::status_result;
     pub use crate::proxy::unstable_api::new_spibinder;
     pub use crate::sys::AIBinder;
     pub use crate::sys::AParcel;
diff --git a/libs/nativewindow/rust/Android.bp b/libs/nativewindow/rust/Android.bp
index dc1575c..90d0a8e 100644
--- a/libs/nativewindow/rust/Android.bp
+++ b/libs/nativewindow/rust/Android.bp
@@ -19,7 +19,7 @@
 }
 
 rust_bindgen {
-    name: "libnativewindow_bindgen",
+    name: "libnativewindow_bindgen_internal",
     crate_name: "nativewindow_bindgen",
     wrapper_src: "sys/nativewindow_bindings.h",
     source_stem: "bindings",
@@ -28,13 +28,21 @@
         "--bitfield-enum=AHardwareBuffer_UsageFlags",
 
         "--allowlist-file=.*/nativewindow/include/.*\\.h",
+        "--blocklist-type",
+        "AParcel",
+        "--raw-line",
+        "use binder::unstable_api::AParcel;",
 
         "--with-derive-eq",
         "--with-derive-partialeq",
     ],
     shared_libs: [
+        "libbinder_ndk",
         "libnativewindow",
     ],
+    rustlibs: [
+        "libbinder_rs",
+    ],
 
     // Currently necessary for host builds
     // TODO(b/31559095): bionic on host should define this
@@ -44,12 +52,40 @@
         },
     },
     min_sdk_version: "VanillaIceCream",
+    vendor_available: true,
+}
+
+rust_library {
+    name: "libnativewindow_bindgen",
+    crate_name: "nativewindow_bindgen",
+    srcs: [":libnativewindow_bindgen_internal"],
+    shared_libs: [
+        "libbinder_ndk",
+        "libnativewindow",
+    ],
+    rustlibs: [
+        "libbinder_rs",
+    ],
+    lints: "none",
+    clippy_lints: "none",
+    // Currently necessary for host builds
+    // TODO(b/31559095): bionic on host should define this
+    target: {
+        darwin: {
+            enabled: false,
+        },
+    },
+    min_sdk_version: "VanillaIceCream",
+    vendor_available: true,
 }
 
 rust_test {
     name: "libnativewindow_bindgen_test",
-    srcs: [":libnativewindow_bindgen"],
+    srcs: [":libnativewindow_bindgen_internal"],
     crate_name: "nativewindow_bindgen_test",
+    rustlibs: [
+        "libbinder_rs",
+    ],
     test_suites: ["general-tests"],
     auto_gen_config: true,
     clippy_lints: "none",
@@ -60,6 +96,7 @@
     name: "libnativewindow_defaults",
     srcs: ["src/lib.rs"],
     rustlibs: [
+        "libbinder_rs",
         "libnativewindow_bindgen",
     ],
 }
@@ -77,6 +114,7 @@
         },
     },
     min_sdk_version: "VanillaIceCream",
+    vendor_available: true,
 }
 
 rust_test {
diff --git a/libs/nativewindow/rust/src/lib.rs b/libs/nativewindow/rust/src/lib.rs
index 6eb3bbc..6f86c4a 100644
--- a/libs/nativewindow/rust/src/lib.rs
+++ b/libs/nativewindow/rust/src/lib.rs
@@ -16,13 +16,22 @@
 
 extern crate nativewindow_bindgen as ffi;
 
-pub use ffi::{AHardwareBuffer, AHardwareBuffer_Format, AHardwareBuffer_UsageFlags};
+pub use ffi::{AHardwareBuffer_Format, AHardwareBuffer_UsageFlags};
 
+use binder::{
+    binder_impl::{
+        BorrowedParcel, Deserialize, DeserializeArray, DeserializeOption, Serialize,
+        SerializeArray, SerializeOption, NON_NULL_PARCELABLE_FLAG, NULL_PARCELABLE_FLAG,
+    },
+    unstable_api::{status_result, AsNative},
+    StatusCode,
+};
+use ffi::{AHardwareBuffer, AHardwareBuffer_readFromParcel, AHardwareBuffer_writeToParcel};
 use std::fmt::{self, Debug, Formatter};
 use std::mem::ManuallyDrop;
-use std::ptr::{self, NonNull};
+use std::ptr::{self, null_mut, NonNull};
 
-/// Wrapper around an opaque C AHardwareBuffer.
+/// Wrapper around an opaque C `AHardwareBuffer`.
 #[derive(PartialEq, Eq)]
 pub struct HardwareBuffer(NonNull<AHardwareBuffer>);
 
@@ -120,8 +129,11 @@
     /// Available since API level 31.
     pub fn id(&self) -> u64 {
         let mut out_id = 0;
-        // SAFETY: Neither pointers can be null.
-        let status = unsafe { ffi::AHardwareBuffer_getId(self.0.as_ref(), &mut out_id) };
+        // SAFETY: The AHardwareBuffer pointer we pass is guaranteed to be non-null and valid
+        // because it must have been allocated by `AHardwareBuffer_allocate`,
+        // `AHardwareBuffer_readFromParcel` or the caller of `from_raw` and we have not yet
+        // released it. The id pointer must be valid because it comes from a reference.
+        let status = unsafe { ffi::AHardwareBuffer_getId(self.0.as_ptr(), &mut out_id) };
         assert_eq!(status, 0, "id() failed for AHardwareBuffer with error code: {status}");
 
         out_id
@@ -176,9 +188,10 @@
 
 impl Drop for HardwareBuffer {
     fn drop(&mut self) {
-        // SAFETY: self.0 will never be null. AHardwareBuffers allocated from within Rust will have
-        // a refcount of one, and there is a safety warning on taking an AHardwareBuffer from a raw
-        // pointer requiring callers to ensure the refcount is managed appropriately.
+        // SAFETY: The AHardwareBuffer pointer we pass is guaranteed to be non-null and valid
+        // because it must have been allocated by `AHardwareBuffer_allocate`,
+        // `AHardwareBuffer_readFromParcel` or the caller of `from_raw` and we have not yet
+        // released it.
         unsafe { ffi::AHardwareBuffer_release(self.0.as_ptr()) }
     }
 }
@@ -197,6 +210,82 @@
     }
 }
 
+impl Serialize for HardwareBuffer {
+    fn serialize(&self, parcel: &mut BorrowedParcel) -> Result<(), StatusCode> {
+        SerializeOption::serialize_option(Some(self), parcel)
+    }
+}
+
+impl SerializeOption for HardwareBuffer {
+    fn serialize_option(
+        this: Option<&Self>,
+        parcel: &mut BorrowedParcel,
+    ) -> Result<(), StatusCode> {
+        if let Some(this) = this {
+            parcel.write(&NON_NULL_PARCELABLE_FLAG)?;
+
+            let status =
+            // SAFETY: The AHardwareBuffer pointer we pass is guaranteed to be non-null and valid
+            // because it must have been allocated by `AHardwareBuffer_allocate`,
+            // `AHardwareBuffer_readFromParcel` or the caller of `from_raw` and we have not yet
+            // released it.
+                unsafe { AHardwareBuffer_writeToParcel(this.0.as_ptr(), parcel.as_native_mut()) };
+            status_result(status)
+        } else {
+            parcel.write(&NULL_PARCELABLE_FLAG)
+        }
+    }
+}
+
+impl Deserialize for HardwareBuffer {
+    type UninitType = Option<Self>;
+
+    fn uninit() -> Option<Self> {
+        None
+    }
+
+    fn from_init(value: Self) -> Option<Self> {
+        Some(value)
+    }
+
+    fn deserialize(parcel: &BorrowedParcel) -> Result<Self, StatusCode> {
+        DeserializeOption::deserialize_option(parcel)
+            .transpose()
+            .unwrap_or(Err(StatusCode::UNEXPECTED_NULL))
+    }
+}
+
+impl DeserializeOption for HardwareBuffer {
+    fn deserialize_option(parcel: &BorrowedParcel) -> Result<Option<Self>, StatusCode> {
+        let present: i32 = parcel.read()?;
+        match present {
+            NULL_PARCELABLE_FLAG => Ok(None),
+            NON_NULL_PARCELABLE_FLAG => {
+                let mut buffer = null_mut();
+
+                let status =
+                // SAFETY: Both pointers must be valid because they are obtained from references.
+                // `AHardwareBuffer_readFromParcel` doesn't store them or do anything else special
+                // with them. If it returns success then it will have allocated a new
+                // `AHardwareBuffer` and incremented the reference count, so we can use it until we
+                // release it.
+                    unsafe { AHardwareBuffer_readFromParcel(parcel.as_native(), &mut buffer) };
+
+                status_result(status)?;
+
+                Ok(Some(Self(NonNull::new(buffer).expect(
+                    "AHardwareBuffer_readFromParcel returned success but didn't allocate buffer",
+                ))))
+            }
+            _ => Err(StatusCode::BAD_VALUE),
+        }
+    }
+}
+
+impl SerializeArray for HardwareBuffer {}
+
+impl DeserializeArray for HardwareBuffer {}
+
 // SAFETY: The underlying *AHardwareBuffers can be moved between threads.
 unsafe impl Send for HardwareBuffer {}
 
diff --git a/libs/nativewindow/rust/sys/nativewindow_bindings.h b/libs/nativewindow/rust/sys/nativewindow_bindings.h
index e652aee..4525a42 100644
--- a/libs/nativewindow/rust/sys/nativewindow_bindings.h
+++ b/libs/nativewindow/rust/sys/nativewindow_bindings.h
@@ -16,5 +16,6 @@
 
 #include <android/data_space.h>
 #include <android/hardware_buffer.h>
+#include <android/hardware_buffer_aidl.h>
 #include <android/hdr_metadata.h>
 #include <android/native_window.h>
diff --git a/opengl/libs/EGL/Loader.cpp b/opengl/libs/EGL/Loader.cpp
index 654e5b7..04e2fff 100644
--- a/opengl/libs/EGL/Loader.cpp
+++ b/opengl/libs/EGL/Loader.cpp
@@ -41,24 +41,44 @@
 /*
  * EGL userspace drivers must be provided either:
  * - as a single library:
- *      /vendor/lib/egl/libGLES.so
+ *      /vendor/${LIB}/egl/libGLES.so
  *
  * - as separate libraries:
- *      /vendor/lib/egl/libEGL.so
- *      /vendor/lib/egl/libGLESv1_CM.so
- *      /vendor/lib/egl/libGLESv2.so
+ *      /vendor/${LIB}/egl/libEGL.so
+ *      /vendor/${LIB}/egl/libGLESv1_CM.so
+ *      /vendor/${LIB}/egl/libGLESv2.so
  *
  * For backward compatibility and to facilitate the transition to
  * this new naming scheme, the loader will additionally look for:
  *
- *      /{vendor|system}/lib/egl/lib{GLES | [EGL|GLESv1_CM|GLESv2]}_*.so
+ *      /vendor/${LIB}/egl/lib{GLES | [EGL|GLESv1_CM|GLESv2]}_${SUFFIX}.so
  *
  */
 
-Loader& Loader::getInstance() {
-    static Loader loader;
-    return loader;
-}
+#ifndef SYSTEM_LIB_PATH
+#if defined(__LP64__)
+#define SYSTEM_LIB_PATH "/system/lib64"
+#else
+#define SYSTEM_LIB_PATH "/system/lib"
+#endif
+#endif
+
+static const char* PERSIST_DRIVER_SUFFIX_PROPERTY = "persist.graphics.egl";
+static const char* RO_DRIVER_SUFFIX_PROPERTY = "ro.hardware.egl";
+static const char* RO_BOARD_PLATFORM_PROPERTY = "ro.board.platform";
+
+static const char* HAL_SUBNAME_KEY_PROPERTIES[3] = {
+        PERSIST_DRIVER_SUFFIX_PROPERTY,
+        RO_DRIVER_SUFFIX_PROPERTY,
+        RO_BOARD_PLATFORM_PROPERTY,
+};
+
+static const char* const VENDOR_LIB_EGL_DIR =
+#if defined(__LP64__)
+        "/vendor/lib64/egl";
+#else
+        "/vendor/lib/egl";
+#endif
 
 static void* do_dlopen(const char* path, int mode) {
     ATRACE_CALL();
@@ -80,6 +100,17 @@
     return android_unload_sphal_library(dso);
 }
 
+static void* load_wrapper(const char* path) {
+    void* so = do_dlopen(path, RTLD_NOW | RTLD_LOCAL);
+    ALOGE_IF(!so, "dlopen(\"%s\") failed: %s", path, dlerror());
+    return so;
+}
+
+Loader& Loader::getInstance() {
+    static Loader loader;
+    return loader;
+}
+
 Loader::driver_t::driver_t(void* gles)
 {
     dso[0] = gles;
@@ -123,30 +154,6 @@
 Loader::~Loader() {
 }
 
-static void* load_wrapper(const char* path) {
-    void* so = do_dlopen(path, RTLD_NOW | RTLD_LOCAL);
-    ALOGE_IF(!so, "dlopen(\"%s\") failed: %s", path, dlerror());
-    return so;
-}
-
-#ifndef EGL_WRAPPER_DIR
-#if defined(__LP64__)
-#define EGL_WRAPPER_DIR "/system/lib64"
-#else
-#define EGL_WRAPPER_DIR "/system/lib"
-#endif
-#endif
-
-static const char* PERSIST_DRIVER_SUFFIX_PROPERTY = "persist.graphics.egl";
-static const char* RO_DRIVER_SUFFIX_PROPERTY = "ro.hardware.egl";
-static const char* RO_BOARD_PLATFORM_PROPERTY = "ro.board.platform";
-
-static const char* HAL_SUBNAME_KEY_PROPERTIES[3] = {
-        PERSIST_DRIVER_SUFFIX_PROPERTY,
-        RO_DRIVER_SUFFIX_PROPERTY,
-        RO_BOARD_PLATFORM_PROPERTY,
-};
-
 // Check whether the loaded system drivers should be unloaded in order to
 // load ANGLE or the updatable graphics drivers.
 // If ANGLE namespace is set, it means the application is identified to run on top of ANGLE.
@@ -323,13 +330,13 @@
                         HAL_SUBNAME_KEY_PROPERTIES[2]);
 
     if (!cnx->libEgl) {
-        cnx->libEgl = load_wrapper(EGL_WRAPPER_DIR "/libEGL.so");
+        cnx->libEgl = load_wrapper(SYSTEM_LIB_PATH "/libEGL.so");
     }
     if (!cnx->libGles1) {
-        cnx->libGles1 = load_wrapper(EGL_WRAPPER_DIR "/libGLESv1_CM.so");
+        cnx->libGles1 = load_wrapper(SYSTEM_LIB_PATH "/libGLESv1_CM.so");
     }
     if (!cnx->libGles2) {
-        cnx->libGles2 = load_wrapper(EGL_WRAPPER_DIR "/libGLESv2.so");
+        cnx->libGles2 = load_wrapper(SYSTEM_LIB_PATH "/libGLESv2.so");
     }
 
     if (!cnx->libEgl || !cnx->libGles2 || !cnx->libGles1) {
@@ -432,31 +439,19 @@
     class MatchFile {
     public:
         static std::string find(const char* libraryName, const bool exact) {
-            const char* const searchPaths[] = {
-#if defined(__LP64__)
-                    "/vendor/lib64/egl",
-                    "/system/lib64/egl"
-#else
-                    "/vendor/lib/egl",
-                    "/system/lib/egl"
-#endif
-            };
-
-            for (auto dir : searchPaths) {
-                std::string absolutePath;
-                if (find(absolutePath, libraryName, dir, exact)) {
-                    return absolutePath;
-                }
+            std::string absolutePath;
+            if (findLibPath(absolutePath, libraryName, exact)) {
+                return absolutePath;
             }
 
             // Driver not found. gah.
             return std::string();
         }
     private:
-        static bool find(std::string& result,
-                const std::string& pattern, const char* const search, bool exact) {
+        static bool findLibPath(std::string& result, const std::string& pattern, bool exact) {
+            const std::string vendorLibEglDirString = std::string(VENDOR_LIB_EGL_DIR);
             if (exact) {
-                std::string absolutePath = std::string(search) + "/" + pattern + ".so";
+                std::string absolutePath = vendorLibEglDirString + "/" + pattern + ".so";
                 if (!access(absolutePath.c_str(), R_OK)) {
                     result = absolutePath;
                     return true;
@@ -464,7 +459,7 @@
                 return false;
             }
 
-            DIR* d = opendir(search);
+            DIR* d = opendir(VENDOR_LIB_EGL_DIR);
             if (d != nullptr) {
                 struct dirent* e;
                 while ((e = readdir(d)) != nullptr) {
@@ -477,7 +472,7 @@
                     }
                     if (strstr(e->d_name, pattern.c_str()) == e->d_name) {
                         if (!strcmp(e->d_name + strlen(e->d_name) - 3, ".so")) {
-                            result = std::string(search) + "/" + e->d_name;
+                            result = vendorLibEglDirString + "/" + e->d_name;
                             closedir(d);
                             return true;
                         }
diff --git a/opengl/libs/EGL/egl_angle_platform.cpp b/opengl/libs/EGL/egl_angle_platform.cpp
index 9a6bb7a..ee605c2 100644
--- a/opengl/libs/EGL/egl_angle_platform.cpp
+++ b/opengl/libs/EGL/egl_angle_platform.cpp
@@ -35,6 +35,7 @@
 
 namespace angle {
 
+constexpr char kAngleEs2Lib[] = "libGLESv2_angle.so";
 constexpr int kAngleDlFlags = RTLD_LOCAL | RTLD_NOW;
 
 static GetDisplayPlatformFunc angleGetDisplayPlatform = nullptr;
@@ -115,8 +116,6 @@
     android_namespace_t* ns = android::GraphicsEnv::getInstance().getAngleNamespace();
     void* so = nullptr;
     if (ns) {
-        // Loading from an APK, so hard-code the suffix to "_angle".
-        constexpr char kAngleEs2Lib[] = "libGLESv2_angle.so";
         const android_dlextinfo dlextinfo = {
                 .flags = ANDROID_DLEXT_USE_NAMESPACE,
                 .library_namespace = ns,
@@ -130,19 +129,11 @@
         }
     } else {
         // If we are here, ANGLE is loaded as built-in gl driver in the sphal.
-        // Get the specified ANGLE library filename suffix.
-        std::string angleEs2LibSuffix = android::base::GetProperty("ro.hardware.egl", "");
-        if (angleEs2LibSuffix.empty()) {
-            ALOGE("%s failed to get valid ANGLE library filename suffix!", __FUNCTION__);
-            return false;
-        }
-
-        std::string angleEs2LibName = "libGLESv2_" + angleEs2LibSuffix + ".so";
-        so = android_load_sphal_library(angleEs2LibName.c_str(), kAngleDlFlags);
+        so = android_load_sphal_library(kAngleEs2Lib, kAngleDlFlags);
         if (so) {
-            ALOGD("dlopen (%s) success at %p", angleEs2LibName.c_str(), so);
+            ALOGD("dlopen (%s) success at %p", kAngleEs2Lib, so);
         } else {
-            ALOGE("%s failed to dlopen %s!", __FUNCTION__, angleEs2LibName.c_str());
+            ALOGE("%s failed to dlopen %s: %s!", __FUNCTION__, kAngleEs2Lib, dlerror());
             return false;
         }
     }