Merge "Reapply "Define vintf_fragments as modules"" into main
diff --git a/Android.bp b/Android.bp
index 223a1a9..baf3291 100644
--- a/Android.bp
+++ b/Android.bp
@@ -51,7 +51,6 @@
     // Lists all dependencies that can *not* be expected on the device.
     static_libs: [
         "VtsHalHidlTestUtils",
-        "libhidlbase",
         "libhidl-gen-utils",
     ],
 
@@ -64,6 +63,7 @@
         "libbase",
         // All the following are dependencies of any HAL definition library.
         "libcutils",
+        "libhidlbase",
         "liblog",
         "libutils",
     ],
@@ -72,14 +72,6 @@
         "-g",
     ],
 
-    target: {
-        android: {
-            shared_libs: [
-                "libvndksupport",
-            ],
-        },
-    },
-
     require_root: true,
 }
 
diff --git a/audio/aidl/android/hardware/audio/core/StreamDescriptor.aidl b/audio/aidl/android/hardware/audio/core/StreamDescriptor.aidl
index 65ea9ef..cfe001e 100644
--- a/audio/aidl/android/hardware/audio/core/StreamDescriptor.aidl
+++ b/audio/aidl/android/hardware/audio/core/StreamDescriptor.aidl
@@ -386,14 +386,23 @@
          * For input streams: the moment when data at the specified stream position
          *   was acquired (i.e. capture position).
          *
-         * The observable position must never be reset by the HAL module.
-         * The data type of the frame counter is large enough to support
-         * continuous counting for years of operation.
+         * The observable position must never be reset by the HAL module,
+         * providing an abstraction of continuous audio data flow. The data
+         * type of the frame counter is large enough to support continuous
+         * counting for years of operation.
          */
         Position observable;
         /**
          * Used only for MMap streams to provide the hardware read / write
          * position for audio data in the shared memory buffer 'audio.mmap'.
+         * Similar to the observable position, the 'Position::UNKNOWN' value
+         * can be returned when the HAL module is unable to retrieve the current
+         * position.
+         *
+         * The hardware position must never be reset by the HAL module,
+         * providing an abstraction of continuous audio data flow. The data
+         * type of the frame counter is large enough to support continuous
+         * counting for years of operation.
          */
         Position hardware;
         /**
diff --git a/health/utils/libhealthloop/HealthLoop.cpp b/health/utils/libhealthloop/HealthLoop.cpp
index d43c2d5..691d896 100644
--- a/health/utils/libhealthloop/HealthLoop.cpp
+++ b/health/utils/libhealthloop/HealthLoop.cpp
@@ -43,6 +43,8 @@
 namespace hardware {
 namespace health {
 
+static constexpr uint32_t kUeventMsgLen = 2048;
+
 HealthLoop::HealthLoop() {
     InitHealthdConfig(&healthd_config_);
     awake_poll_interval_ = -1;
@@ -61,14 +63,13 @@
                                           EventHandler{this, fd, std::move(func)}))
                                   .get();
 
-    struct epoll_event ev;
-
-    ev.events = EPOLLIN;
+    struct epoll_event ev = {
+        .events = EPOLLIN,
+        .data.ptr = reinterpret_cast<void*>(event_handler),
+    };
 
     if (wakeup == EVENT_WAKEUP_FD) ev.events |= EPOLLWAKEUP;
 
-    ev.data.ptr = reinterpret_cast<void*>(event_handler);
-
     if (epoll_ctl(epollfd_, EPOLL_CTL_ADD, fd, &ev) == -1) {
         KLOG_ERROR(LOG_TAG, "epoll_ctl failed; errno=%d\n", errno);
         return -1;
@@ -121,32 +122,39 @@
     ScheduleBatteryUpdate();
 }
 
-#define UEVENT_MSG_LEN 2048
-void HealthLoop::UeventEvent(uint32_t /*epevents*/) {
-    // No need to lock because uevent_fd_ is guaranteed to be initialized.
-
-    char msg[UEVENT_MSG_LEN + 2];
-    char* cp;
-    int n;
-
-    n = uevent_kernel_multicast_recv(uevent_fd_, msg, UEVENT_MSG_LEN);
-    if (n <= 0) return;
-    if (n >= UEVENT_MSG_LEN) /* overflow -- discard */
-        return;
-
-    msg[n] = '\0';
-    msg[n + 1] = '\0';
-    cp = msg;
-
-    while (*cp) {
-        if (!strcmp(cp, "SUBSYSTEM=power_supply")) {
-            ScheduleBatteryUpdate();
-            break;
+// Returns true if and only if the battery statistics should be updated.
+bool HealthLoop::RecvUevents() {
+    bool update_stats = false;
+    for (;;) {
+        char msg[kUeventMsgLen + 2];
+        int n = uevent_kernel_multicast_recv(uevent_fd_, msg, kUeventMsgLen);
+        if (n <= 0) return update_stats;
+        if (n >= kUeventMsgLen) {
+            // too long -- discard
+            continue;
+        }
+        if (update_stats) {
+            continue;
         }
 
-        /* advance to after the next \0 */
-        while (*cp++)
-            ;
+        msg[n] = '\0';
+        msg[n + 1] = '\0';
+        for (char* cp = msg; *cp;) {
+            if (strcmp(cp, "SUBSYSTEM=power_supply") == 0) {
+                update_stats = true;
+                break;
+            }
+
+            /* advance to after the next \0 */
+            while (*cp++) {
+            }
+        }
+    }
+}
+
+void HealthLoop::UeventEvent(uint32_t /*epevents*/) {
+    if (RecvUevents()) {
+        ScheduleBatteryUpdate();
     }
 }
 
@@ -183,9 +191,9 @@
         std::string error_msg = attach_result.error().message();
         error_msg +=
                 ". This is expected in recovery mode and also for kernel versions before 5.10.";
-        KLOG_WARNING(LOG_TAG, "%s", error_msg.c_str());
+        KLOG_WARNING(LOG_TAG, "%s\n", error_msg.c_str());
     } else {
-        KLOG_INFO(LOG_TAG, "Successfully attached the BPF filter to the uevent socket");
+        KLOG_INFO(LOG_TAG, "Successfully attached the BPF filter to the uevent socket\n");
     }
 
     if (RegisterEvent(uevent_fd_, &HealthLoop::UeventEvent, EVENT_WAKEUP_FD))
diff --git a/health/utils/libhealthloop/filterPowerSupplyEventsTest.cpp b/health/utils/libhealthloop/filterPowerSupplyEventsTest.cpp
index e885f0b..04b8bcd 100644
--- a/health/utils/libhealthloop/filterPowerSupplyEventsTest.cpp
+++ b/health/utils/libhealthloop/filterPowerSupplyEventsTest.cpp
@@ -192,16 +192,21 @@
     bpf_object__close(obj);
 }
 
+static constexpr char input0[] = "a";
+static constexpr char input1[] = "abc\0SUBSYSTEM=block\0";
+static constexpr char input2[] = "\0SUBSYSTEM=block";
+static constexpr char input3[] = "\0SUBSYSTEM=power_supply";
+static constexpr char input4[] = "\0SUBSYSTEM=power_supply\0";
+static constexpr char input5[] =
+        "012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789"
+        "012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789"
+        "012345678901234567890123456789012345678901234567890123456789\0SUBSYSTEM=block\0";
+
 INSTANTIATE_TEST_SUITE_P(
         filterPse, filterPseTest,
-        testing::Values(test_data{false, "a"},
-                        test_data{true, std::string_view("abc\0SUBSYSTEM=block\0", 20)},
-                        test_data{true, std::string_view("\0SUBSYSTEM=block", 16)},
-                        test_data{true, std::string_view("\0SUBSYSTEM=power_supply", 23)},
-                        test_data{false, std::string_view("\0SUBSYSTEM=power_supply\0", 24)},
-                        test_data{
-                                false,
-                                "012345678901234567890123456789012345678901234567890123456789012345"
-                                "678901234567890123456789012345678901234567890123456789012345678901"
-                                "234567890123456789012345678901234567890123456789012345678901234567"
-                                "890123456789012345678901234567890123456789\0SUBSYSTEM=block\0"}));
+        testing::Values(test_data{false, std::string_view(input0, sizeof(input0) - 1)},
+                        test_data{true, std::string_view(input1, sizeof(input1) - 1)},
+                        test_data{true, std::string_view(input2, sizeof(input2) - 1)},
+                        test_data{true, std::string_view(input3, sizeof(input3) - 1)},
+                        test_data{false, std::string_view(input4, sizeof(input4) - 1)},
+                        test_data{false, std::string_view(input5, sizeof(input5) - 1)}));
diff --git a/health/utils/libhealthloop/include/health/HealthLoop.h b/health/utils/libhealthloop/include/health/HealthLoop.h
index 1af7274..43c38dc 100644
--- a/health/utils/libhealthloop/include/health/HealthLoop.h
+++ b/health/utils/libhealthloop/include/health/HealthLoop.h
@@ -93,6 +93,7 @@
     void WakeAlarmInit();
     void WakeAlarmEvent(uint32_t);
     void UeventInit();
+    bool RecvUevents();
     void UeventEvent(uint32_t);
     void WakeAlarmSetInterval(int interval);
     void PeriodicChores();