Merge "sm: repoll after handling client callbacks" into main
diff --git a/aidl/gui/android/view/Surface.aidl b/aidl/gui/android/view/Surface.aidl
index bb3faaf..6686717 100644
--- a/aidl/gui/android/view/Surface.aidl
+++ b/aidl/gui/android/view/Surface.aidl
@@ -17,4 +17,4 @@
 
 package android.view;
 
-@JavaOnlyStableParcelable @NdkOnlyStableParcelable parcelable Surface cpp_header "gui/view/Surface.h" ndk_header "android/native_window_aidl.h";
+@JavaOnlyStableParcelable @NdkOnlyStableParcelable @RustOnlyStableParcelable parcelable Surface cpp_header "gui/view/Surface.h" ndk_header "android/native_window_aidl.h" rust_type "nativewindow::Surface";
diff --git a/cmds/dumpstate/dumpstate.cpp b/cmds/dumpstate/dumpstate.cpp
index 522442f..326f927 100644
--- a/cmds/dumpstate/dumpstate.cpp
+++ b/cmds/dumpstate/dumpstate.cpp
@@ -198,6 +198,7 @@
 static const std::string TOMBSTONE_FILE_PREFIX = "tombstone_";
 static const std::string ANR_DIR = "/data/anr/";
 static const std::string ANR_FILE_PREFIX = "anr_";
+static const std::string ANR_TRACE_FILE_PREFIX = "trace_";
 static const std::string SHUTDOWN_CHECKPOINTS_DIR = "/data/system/shutdown-checkpoints/";
 static const std::string SHUTDOWN_CHECKPOINTS_FILE_PREFIX = "checkpoints-";
 
@@ -1179,6 +1180,10 @@
     } else {
         printf("*** NO ANRs to dump in %s\n\n", ANR_DIR.c_str());
     }
+
+    // Add Java anr traces (such as generated by the Finalizer Watchdog).
+    AddDumps(ds.anr_trace_data_.begin(), ds.anr_trace_data_.end(), "JAVA ANR TRACES",
+             true /* add_to_zip */);
 }
 
 static void AddAnrTraceFiles() {
@@ -1905,6 +1910,7 @@
     if (!PropertiesHelper::IsDryRun()) {
         ds.tombstone_data_ = GetDumpFds(TOMBSTONE_DIR, TOMBSTONE_FILE_PREFIX);
         ds.anr_data_ = GetDumpFds(ANR_DIR, ANR_FILE_PREFIX);
+        ds.anr_trace_data_ = GetDumpFds(ANR_DIR, ANR_TRACE_FILE_PREFIX);
         ds.shutdown_checkpoints_ = GetDumpFds(
             SHUTDOWN_CHECKPOINTS_DIR, SHUTDOWN_CHECKPOINTS_FILE_PREFIX);
     }
@@ -3046,6 +3052,7 @@
     }
     tombstone_data_.clear();
     anr_data_.clear();
+    anr_trace_data_.clear();
     shutdown_checkpoints_.clear();
 
     // Instead of shutdown the pool, we delete temporary files directly since
@@ -3341,6 +3348,7 @@
 
     tombstone_data_.clear();
     anr_data_.clear();
+    anr_trace_data_.clear();
     shutdown_checkpoints_.clear();
 
     return (consent_callback_ != nullptr &&
diff --git a/cmds/dumpstate/dumpstate.h b/cmds/dumpstate/dumpstate.h
index 8a31c31..596aa76 100644
--- a/cmds/dumpstate/dumpstate.h
+++ b/cmds/dumpstate/dumpstate.h
@@ -526,6 +526,9 @@
     // List of open ANR dump files.
     std::vector<DumpData> anr_data_;
 
+    // List of open Java traces files in the anr directory.
+    std::vector<DumpData> anr_trace_data_;
+
     // List of open shutdown checkpoint files.
     std::vector<DumpData> shutdown_checkpoints_;
 
diff --git a/cmds/installd/InstalldNativeService.cpp b/cmds/installd/InstalldNativeService.cpp
index cad7787..71a8740 100644
--- a/cmds/installd/InstalldNativeService.cpp
+++ b/cmds/installd/InstalldNativeService.cpp
@@ -234,12 +234,12 @@
     return ok();
 }
 
-binder::Status checkUidInAppRange(int32_t appUid) {
-    if (FIRST_APPLICATION_UID <= appUid && appUid <= LAST_APPLICATION_UID) {
+binder::Status checkArgumentAppId(int32_t appId) {
+    if (FIRST_APPLICATION_UID <= appId && appId <= LAST_APPLICATION_UID) {
         return ok();
     }
     return exception(binder::Status::EX_ILLEGAL_ARGUMENT,
-                     StringPrintf("UID %d is outside of the range", appUid));
+                     StringPrintf("appId %d is outside of the range", appId));
 }
 
 #define ENFORCE_UID(uid) {                                  \
@@ -302,12 +302,12 @@
         }                                                      \
     }
 
-#define CHECK_ARGUMENT_UID_IN_APP_RANGE(uid)               \
-    {                                                      \
-        binder::Status status = checkUidInAppRange((uid)); \
-        if (!status.isOk()) {                              \
-            return status;                                 \
-        }                                                  \
+#define CHECK_ARGUMENT_APP_ID(appId)                         \
+    {                                                        \
+        binder::Status status = checkArgumentAppId((appId)); \
+        if (!status.isOk()) {                                \
+            return status;                                   \
+        }                                                    \
     }
 
 #ifdef GRANULAR_LOCKS
@@ -411,7 +411,7 @@
 }  // namespace
 
 binder::Status InstalldNativeService::FsveritySetupAuthToken::authenticate(
-        const ParcelFileDescriptor& authFd, int32_t appUid, int32_t userId) {
+        const ParcelFileDescriptor& authFd, int32_t uid) {
     int open_flags = fcntl(authFd.get(), F_GETFL);
     if (open_flags < 0) {
         return exception(binder::Status::EX_SERVICE_SPECIFIC, "fcntl failed");
@@ -426,9 +426,8 @@
         return exception(binder::Status::EX_SECURITY, "Not a regular file");
     }
     // Don't accept a file owned by a different app.
-    uid_t uid = multiuser_get_uid(userId, appUid);
-    if (this->mStatFromAuthFd.st_uid != uid) {
-        return exception(binder::Status::EX_SERVICE_SPECIFIC, "File not owned by appUid");
+    if (this->mStatFromAuthFd.st_uid != (uid_t)uid) {
+        return exception(binder::Status::EX_SERVICE_SPECIFIC, "File not owned by uid");
     }
     return ok();
 }
@@ -3986,7 +3985,7 @@
 // attacker-in-the-middle cannot enable fs-verity on arbitrary app files. If the FD is not writable,
 // return null.
 //
-// appUid and userId are passed for additional ownership check, such that one app can not be
+// app process uid is passed for additional ownership check, such that one app can not be
 // authenticated for another app's file. These parameters are assumed trusted for this purpose of
 // consistency check.
 //
@@ -3994,13 +3993,13 @@
 // Since enabling fs-verity to a file requires no outstanding writable FD, passing the authFd to the
 // server allows the server to hold the only reference (as long as the client app doesn't).
 binder::Status InstalldNativeService::createFsveritySetupAuthToken(
-        const ParcelFileDescriptor& authFd, int32_t appUid, int32_t userId,
+        const ParcelFileDescriptor& authFd, int32_t uid,
         sp<IFsveritySetupAuthToken>* _aidl_return) {
-    CHECK_ARGUMENT_UID_IN_APP_RANGE(appUid);
-    ENFORCE_VALID_USER(userId);
+    CHECK_ARGUMENT_APP_ID(multiuser_get_app_id(uid));
+    ENFORCE_VALID_USER(multiuser_get_user_id(uid));
 
     auto token = sp<FsveritySetupAuthToken>::make();
-    binder::Status status = token->authenticate(authFd, appUid, userId);
+    binder::Status status = token->authenticate(authFd, uid);
     if (!status.isOk()) {
         return status;
     }
diff --git a/cmds/installd/InstalldNativeService.h b/cmds/installd/InstalldNativeService.h
index 1ec092d..88caba7 100644
--- a/cmds/installd/InstalldNativeService.h
+++ b/cmds/installd/InstalldNativeService.h
@@ -44,8 +44,7 @@
     public:
         FsveritySetupAuthToken() : mStatFromAuthFd() {}
 
-        binder::Status authenticate(const android::os::ParcelFileDescriptor& authFd, int32_t appUid,
-                                    int32_t userId);
+        binder::Status authenticate(const android::os::ParcelFileDescriptor& authFd, int32_t uid);
         bool isSameStat(const struct stat& st) const;
 
     private:
@@ -213,7 +212,7 @@
                                      int32_t* _aidl_return);
 
     binder::Status createFsveritySetupAuthToken(const android::os::ParcelFileDescriptor& authFd,
-                                                int32_t appUid, int32_t userId,
+                                                int32_t uid,
                                                 android::sp<IFsveritySetupAuthToken>* _aidl_return);
     binder::Status enableFsverity(const android::sp<IFsveritySetupAuthToken>& authToken,
                                   const std::string& filePath, const std::string& packageName,
diff --git a/cmds/installd/binder/android/os/IInstalld.aidl b/cmds/installd/binder/android/os/IInstalld.aidl
index 8893e38..120d61d 100644
--- a/cmds/installd/binder/android/os/IInstalld.aidl
+++ b/cmds/installd/binder/android/os/IInstalld.aidl
@@ -145,8 +145,7 @@
         //
         // We don't necessarily need a method here, so it's left blank intentionally.
     }
-    IFsveritySetupAuthToken createFsveritySetupAuthToken(in ParcelFileDescriptor authFd, int appUid,
-            int userId);
+    IFsveritySetupAuthToken createFsveritySetupAuthToken(in ParcelFileDescriptor authFd, int uid);
     int enableFsverity(in IFsveritySetupAuthToken authToken, @utf8InCpp String filePath,
             @utf8InCpp String packageName);
 
diff --git a/cmds/installd/tests/installd_service_test.cpp b/cmds/installd/tests/installd_service_test.cpp
index 4bc92af..f2b578a 100644
--- a/cmds/installd/tests/installd_service_test.cpp
+++ b/cmds/installd/tests/installd_service_test.cpp
@@ -548,8 +548,7 @@
         unique_fd ufd(open(path.c_str(), open_mode));
         EXPECT_GE(ufd.get(), 0) << "open failed: " << strerror(errno);
         ParcelFileDescriptor rfd(std::move(ufd));
-        return service->createFsveritySetupAuthToken(std::move(rfd), kTestAppId, kTestUserId,
-                                                     _aidl_return);
+        return service->createFsveritySetupAuthToken(std::move(rfd), kTestAppId, _aidl_return);
     }
 };
 
diff --git a/include/android/input.h b/include/android/input.h
index 9a0eb4d..16d86af 100644
--- a/include/android/input.h
+++ b/include/android/input.h
@@ -54,16 +54,12 @@
 #include <stdint.h>
 #include <sys/types.h>
 #include <android/keycodes.h>
-
-// This file is included by modules that have host support but android/looper.h is not supported
-// on host. __REMOVED_IN needs to be defined in order for android/looper.h to be compiled.
-#ifndef __BIONIC__
-#define __REMOVED_IN(x) __attribute__((deprecated))
-#endif
 #include <android/looper.h>
 
 #include <jni.h>
 
+// This file may also be built on glibc or on Windows/MacOS libc's, so no-op
+// definitions are provided.
 #if !defined(__INTRODUCED_IN)
 #define __INTRODUCED_IN(__api_level) /* nothing */
 #endif
diff --git a/include/android/looper.h b/include/android/looper.h
index 4fe142a..e50730d 100644
--- a/include/android/looper.h
+++ b/include/android/looper.h
@@ -26,10 +26,18 @@
 #ifndef ANDROID_LOOPER_H
 #define ANDROID_LOOPER_H
 
+#include <sys/cdefs.h>
+
 #ifdef __cplusplus
 extern "C" {
 #endif
 
+// This file may also be built on glibc or on Windows/MacOS libc's, so
+// deprecated definitions are provided.
+#if !defined(__REMOVED_IN)
+#define __REMOVED_IN(__api_level) __attribute__((__deprecated__))
+#endif
+
 struct ALooper;
 /**
  * ALooper
diff --git a/include/android/sensor.h b/include/android/sensor.h
index 16c5dde..0cc7834 100644
--- a/include/android/sensor.h
+++ b/include/android/sensor.h
@@ -29,6 +29,8 @@
 #ifndef ANDROID_SENSOR_H
 #define ANDROID_SENSOR_H
 
+#include <sys/cdefs.h>
+
 /******************************************************************
  *
  * IMPORTANT NOTICE:
@@ -45,11 +47,6 @@
  *   - DO NOT CHANGE THE LAYOUT OR SIZE OF STRUCTURES
  */
 
-// This file is included by modules that have host support but android/looper.h is not supported
-// on host. __REMOVED_IN needs to be defined in order for android/looper.h to be compiled.
-#ifndef __BIONIC__
-#define __REMOVED_IN(x) __attribute__((deprecated))
-#endif
 #include <android/looper.h>
 
 #include <stdbool.h>
@@ -57,6 +54,8 @@
 #include <math.h>
 #include <stdint.h>
 
+// This file may also be built on glibc or on Windows/MacOS libc's, so no-op
+// and deprecated definitions are provided.
 #if !defined(__INTRODUCED_IN)
 #define __INTRODUCED_IN(__api_level) /* nothing */
 #endif
diff --git a/libs/input/Android.bp b/libs/input/Android.bp
index 022dfad..a67ed29 100644
--- a/libs/input/Android.bp
+++ b/libs/input/Android.bp
@@ -221,7 +221,7 @@
         "liblog",
         "libPlatformProperties",
         "libtinyxml2",
-        "libvintf",
+        "libz", // needed by libkernelconfigs
     ],
 
     ldflags: [
@@ -238,6 +238,7 @@
         "inputconstants-cpp",
         "libui-types",
         "libtflite_static",
+        "libkernelconfigs",
     ],
 
     whole_static_libs: [
diff --git a/libs/input/KeyLayoutMap.cpp b/libs/input/KeyLayoutMap.cpp
index 3c1ae3e..ab8c341 100644
--- a/libs/input/KeyLayoutMap.cpp
+++ b/libs/input/KeyLayoutMap.cpp
@@ -27,8 +27,7 @@
 #include <utils/Timers.h>
 #include <utils/Tokenizer.h>
 #if defined(__ANDROID__)
-#include <vintf/RuntimeInfo.h>
-#include <vintf/VintfObject.h>
+#include <vintf/KernelConfigs.h>
 #endif
 
 #include <cstdlib>
@@ -98,12 +97,10 @@
 
 bool kernelConfigsArePresent(const std::set<std::string>& configs) {
 #if defined(__ANDROID__)
-    std::shared_ptr<const android::vintf::RuntimeInfo> runtimeInfo =
-            android::vintf::VintfObject::GetInstance()->getRuntimeInfo(
-                    vintf::RuntimeInfo::FetchFlag::CONFIG_GZ);
-    LOG_ALWAYS_FATAL_IF(runtimeInfo == nullptr, "Kernel configs could not be fetched");
+    std::map<std::string, std::string> kernelConfigs;
+    const status_t result = android::kernelconfigs::LoadKernelConfigs(&kernelConfigs);
+    LOG_ALWAYS_FATAL_IF(result != OK, "Kernel configs could not be fetched");
 
-    const std::map<std::string, std::string>& kernelConfigs = runtimeInfo->kernelConfigs();
     for (const std::string& requiredConfig : configs) {
         const auto configIt = kernelConfigs.find(requiredConfig);
         if (configIt == kernelConfigs.end()) {
diff --git a/libs/input/tests/Android.bp b/libs/input/tests/Android.bp
index e7224ff..3fc7d9d 100644
--- a/libs/input/tests/Android.bp
+++ b/libs/input/tests/Android.bp
@@ -36,8 +36,10 @@
         "libgmock",
         "libgui_window_info_static",
         "libinput",
+        "libkernelconfigs",
         "libtflite_static",
         "libui-types",
+        "libz", // needed by libkernelconfigs
     ],
     cflags: [
         "-Wall",
@@ -61,7 +63,6 @@
         "libPlatformProperties",
         "libtinyxml2",
         "libutils",
-        "libvintf",
     ],
     data: [
         "data/*",
diff --git a/libs/nativewindow/include/android/data_space.h b/libs/nativewindow/include/android/data_space.h
index eab21fb..9f8ae86 100644
--- a/libs/nativewindow/include/android/data_space.h
+++ b/libs/nativewindow/include/android/data_space.h
@@ -29,6 +29,7 @@
 #define ANDROID_DATA_SPACE_H
 
 #include <inttypes.h>
+#include <stdint.h>
 
 #include <sys/cdefs.h>
 
@@ -37,7 +38,7 @@
 /**
  * ADataSpace.
  */
-enum ADataSpace {
+enum ADataSpace : int32_t {
     /**
      * Default-assumption data space, when not explicitly specified.
      *
diff --git a/libs/nativewindow/rust/src/lib.rs b/libs/nativewindow/rust/src/lib.rs
index aab7df0..22ad834 100644
--- a/libs/nativewindow/rust/src/lib.rs
+++ b/libs/nativewindow/rust/src/lib.rs
@@ -16,6 +16,8 @@
 
 extern crate nativewindow_bindgen as ffi;
 
+pub mod surface;
+
 pub use ffi::{AHardwareBuffer_Format, AHardwareBuffer_UsageFlags};
 
 use binder::{
@@ -210,7 +212,7 @@
 }
 
 impl Debug for HardwareBuffer {
-    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
+    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
         f.debug_struct("HardwareBuffer").field("id", &self.id()).finish()
     }
 }
diff --git a/libs/nativewindow/rust/src/surface.rs b/libs/nativewindow/rust/src/surface.rs
new file mode 100644
index 0000000..c812612
--- /dev/null
+++ b/libs/nativewindow/rust/src/surface.rs
@@ -0,0 +1,140 @@
+// Copyright (C) 2024 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.
+
+//! Rust wrapper for `ANativeWindow` and related types.
+
+use binder::{
+    binder_impl::{BorrowedParcel, UnstructuredParcelable},
+    impl_deserialize_for_unstructured_parcelable, impl_serialize_for_unstructured_parcelable,
+    unstable_api::{status_result, AsNative},
+    StatusCode,
+};
+use nativewindow_bindgen::{
+    AHardwareBuffer_Format, ANativeWindow, ANativeWindow_acquire, ANativeWindow_getFormat,
+    ANativeWindow_getHeight, ANativeWindow_getWidth, ANativeWindow_readFromParcel,
+    ANativeWindow_release, ANativeWindow_writeToParcel,
+};
+use std::error::Error;
+use std::fmt::{self, Debug, Display, Formatter};
+use std::ptr::{null_mut, NonNull};
+
+/// Wrapper around an opaque C `ANativeWindow`.
+#[derive(PartialEq, Eq)]
+pub struct Surface(NonNull<ANativeWindow>);
+
+impl Surface {
+    /// Returns the current width in pixels of the window surface.
+    pub fn width(&self) -> Result<u32, ErrorCode> {
+        // SAFETY: The ANativeWindow pointer we pass is guaranteed to be non-null and valid because
+        // it must have been allocated by `ANativeWindow_allocate` or `ANativeWindow_readFromParcel`
+        // and we have not yet released it.
+        let width = unsafe { ANativeWindow_getWidth(self.0.as_ptr()) };
+        width.try_into().map_err(|_| ErrorCode(width))
+    }
+
+    /// Returns the current height in pixels of the window surface.
+    pub fn height(&self) -> Result<u32, ErrorCode> {
+        // SAFETY: The ANativeWindow pointer we pass is guaranteed to be non-null and valid because
+        // it must have been allocated by `ANativeWindow_allocate` or `ANativeWindow_readFromParcel`
+        // and we have not yet released it.
+        let height = unsafe { ANativeWindow_getHeight(self.0.as_ptr()) };
+        height.try_into().map_err(|_| ErrorCode(height))
+    }
+
+    /// Returns the current pixel format of the window surface.
+    pub fn format(&self) -> Result<AHardwareBuffer_Format::Type, ErrorCode> {
+        // SAFETY: The ANativeWindow pointer we pass is guaranteed to be non-null and valid because
+        // it must have been allocated by `ANativeWindow_allocate` or `ANativeWindow_readFromParcel`
+        // and we have not yet released it.
+        let format = unsafe { ANativeWindow_getFormat(self.0.as_ptr()) };
+        format.try_into().map_err(|_| ErrorCode(format))
+    }
+}
+
+impl Drop for Surface {
+    fn drop(&mut self) {
+        // SAFETY: The ANativeWindow pointer we pass is guaranteed to be non-null and valid because
+        // it must have been allocated by `ANativeWindow_allocate` or `ANativeWindow_readFromParcel`
+        // and we have not yet released it.
+        unsafe { ANativeWindow_release(self.0.as_ptr()) }
+    }
+}
+
+impl Debug for Surface {
+    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
+        f.debug_struct("Surface")
+            .field("width", &self.width())
+            .field("height", &self.height())
+            .field("format", &self.format())
+            .finish()
+    }
+}
+
+impl Clone for Surface {
+    fn clone(&self) -> Self {
+        // SAFETY: The ANativeWindow pointer we pass is guaranteed to be non-null and valid because
+        // it must have been allocated by `ANativeWindow_allocate` or `ANativeWindow_readFromParcel`
+        // and we have not yet released it.
+        unsafe { ANativeWindow_acquire(self.0.as_ptr()) };
+        Self(self.0)
+    }
+}
+
+impl UnstructuredParcelable for Surface {
+    fn write_to_parcel(&self, parcel: &mut BorrowedParcel) -> Result<(), StatusCode> {
+        let status =
+        // SAFETY: The ANativeWindow pointer we pass is guaranteed to be non-null and valid because
+        // it must have been allocated by `ANativeWindow_allocate` or `ANativeWindow_readFromParcel`
+        // and we have not yet released it.
+        unsafe { ANativeWindow_writeToParcel(self.0.as_ptr(), parcel.as_native_mut()) };
+        status_result(status)
+    }
+
+    fn from_parcel(parcel: &BorrowedParcel) -> Result<Self, StatusCode> {
+        let mut buffer = null_mut();
+
+        let status =
+        // SAFETY: Both pointers must be valid because they are obtained from references.
+        // `ANativeWindow_readFromParcel` doesn't store them or do anything else special
+        // with them. If it returns success then it will have allocated a new
+        // `ANativeWindow` and incremented the reference count, so we can use it until we
+        // release it.
+            unsafe { ANativeWindow_readFromParcel(parcel.as_native(), &mut buffer) };
+
+        status_result(status)?;
+
+        Ok(Self(
+            NonNull::new(buffer)
+                .expect("ANativeWindow_readFromParcel returned success but didn't allocate buffer"),
+        ))
+    }
+}
+
+impl_deserialize_for_unstructured_parcelable!(Surface);
+impl_serialize_for_unstructured_parcelable!(Surface);
+
+// SAFETY: The underlying *ANativeWindow can be moved between threads.
+unsafe impl Send for Surface {}
+
+/// An error code returned by methods on [`Surface`].
+#[derive(Copy, Clone, Debug, Eq, PartialEq)]
+pub struct ErrorCode(i32);
+
+impl Error for ErrorCode {}
+
+impl Display for ErrorCode {
+    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
+        write!(f, "Error {}", self.0)
+    }
+}
diff --git a/libs/nativewindow/rust/sys/nativewindow_bindings.h b/libs/nativewindow/rust/sys/nativewindow_bindings.h
index 4525a42..5689f7d 100644
--- a/libs/nativewindow/rust/sys/nativewindow_bindings.h
+++ b/libs/nativewindow/rust/sys/nativewindow_bindings.h
@@ -19,3 +19,4 @@
 #include <android/hardware_buffer_aidl.h>
 #include <android/hdr_metadata.h>
 #include <android/native_window.h>
+#include <android/native_window_aidl.h>