Merge "Tuner HAL: fix a memcpy issue"
diff --git a/automotive/can/1.0/default/libnetdevice/NetlinkSocket.cpp b/automotive/can/1.0/default/libnetdevice/NetlinkSocket.cpp
index 22cdbdb..91149c0 100644
--- a/automotive/can/1.0/default/libnetdevice/NetlinkSocket.cpp
+++ b/automotive/can/1.0/default/libnetdevice/NetlinkSocket.cpp
@@ -27,7 +27,8 @@
  */
 static constexpr bool kSuperVerbose = false;
 
-NetlinkSocket::NetlinkSocket(int protocol) : mProtocol(protocol) {
+NetlinkSocket::NetlinkSocket(int protocol, unsigned int pid, uint32_t groups)
+    : mProtocol(protocol) {
     mFd.reset(socket(AF_NETLINK, SOCK_RAW, protocol));
     if (!mFd.ok()) {
         PLOG(ERROR) << "Can't open Netlink socket";
@@ -35,21 +36,23 @@
         return;
     }
 
-    struct sockaddr_nl sa = {};
+    sockaddr_nl sa = {};
     sa.nl_family = AF_NETLINK;
+    sa.nl_pid = pid;
+    sa.nl_groups = groups;
 
-    if (bind(mFd.get(), reinterpret_cast<struct sockaddr*>(&sa), sizeof(sa)) < 0) {
+    if (bind(mFd.get(), reinterpret_cast<sockaddr*>(&sa), sizeof(sa)) < 0) {
         PLOG(ERROR) << "Can't bind Netlink socket";
         mFd.reset();
         mFailed = true;
     }
 }
 
-bool NetlinkSocket::send(struct nlmsghdr* nlmsg, size_t totalLen) {
+bool NetlinkSocket::send(nlmsghdr* nlmsg, size_t totalLen) {
     if constexpr (kSuperVerbose) {
         nlmsg->nlmsg_seq = mSeq;
-        LOG(VERBOSE) << (mFailed ? "(not)" : "")
-                     << "sending Netlink message: " << toString(nlmsg, totalLen, mProtocol);
+        LOG(VERBOSE) << (mFailed ? "(not) " : "")
+                     << "sending Netlink message: " << toString({nlmsg, totalLen}, mProtocol);
     }
 
     if (mFailed) return false;
@@ -58,12 +61,12 @@
     nlmsg->nlmsg_seq = mSeq++;
     nlmsg->nlmsg_flags |= NLM_F_ACK;
 
-    struct iovec iov = {nlmsg, nlmsg->nlmsg_len};
+    iovec iov = {nlmsg, nlmsg->nlmsg_len};
 
-    struct sockaddr_nl sa = {};
+    sockaddr_nl sa = {};
     sa.nl_family = AF_NETLINK;
 
-    struct msghdr msg = {};
+    msghdr msg = {};
     msg.msg_name = &sa;
     msg.msg_namelen = sizeof(sa);
     msg.msg_iov = &iov;
@@ -76,15 +79,65 @@
     return true;
 }
 
+bool NetlinkSocket::send(const nlbuf<nlmsghdr>& msg, const sockaddr_nl& sa) {
+    if constexpr (kSuperVerbose) {
+        LOG(VERBOSE) << (mFailed ? "(not) " : "")
+                     << "sending Netlink message: " << toString(msg, mProtocol);
+    }
+
+    if (mFailed) return false;
+    const auto rawMsg = msg.getRaw();
+    const auto bytesSent = sendto(mFd.get(), rawMsg.ptr(), rawMsg.len(), 0,
+                                  reinterpret_cast<const sockaddr*>(&sa), sizeof(sa));
+    if (bytesSent < 0) {
+        PLOG(ERROR) << "Can't send Netlink message";
+        return false;
+    }
+    return true;
+}
+
+std::optional<nlbuf<nlmsghdr>> NetlinkSocket::receive(void* buf, size_t bufLen) {
+    sockaddr_nl sa = {};
+    return receive(buf, bufLen, sa);
+}
+
+std::optional<nlbuf<nlmsghdr>> NetlinkSocket::receive(void* buf, size_t bufLen, sockaddr_nl& sa) {
+    if (mFailed) return std::nullopt;
+
+    socklen_t saLen = sizeof(sa);
+    if (bufLen == 0) {
+        LOG(ERROR) << "Receive buffer has zero size!";
+        return std::nullopt;
+    }
+    const auto bytesReceived =
+            recvfrom(mFd.get(), buf, bufLen, MSG_TRUNC, reinterpret_cast<sockaddr*>(&sa), &saLen);
+    if (bytesReceived <= 0) {
+        PLOG(ERROR) << "Failed to receive Netlink message";
+        return std::nullopt;
+    } else if (unsigned(bytesReceived) > bufLen) {
+        PLOG(ERROR) << "Received data larger than the receive buffer! " << bytesReceived << " > "
+                    << bufLen;
+        return std::nullopt;
+    }
+
+    nlbuf<nlmsghdr> msg(reinterpret_cast<nlmsghdr*>(buf), bytesReceived);
+    if constexpr (kSuperVerbose) {
+        LOG(VERBOSE) << "received " << toString(msg, mProtocol);
+    }
+    return msg;
+}
+
+/* TODO(161389935): Migrate receiveAck to use nlmsg<> internally. Possibly reuse
+ * NetlinkSocket::receive(). */
 bool NetlinkSocket::receiveAck() {
     if (mFailed) return false;
 
     char buf[8192];
 
-    struct sockaddr_nl sa;
-    struct iovec iov = {buf, sizeof(buf)};
+    sockaddr_nl sa;
+    iovec iov = {buf, sizeof(buf)};
 
-    struct msghdr msg = {};
+    msghdr msg = {};
     msg.msg_name = &sa;
     msg.msg_namelen = sizeof(sa);
     msg.msg_iov = &iov;
@@ -102,11 +155,11 @@
         return false;
     }
 
-    for (auto nlmsg = reinterpret_cast<struct nlmsghdr*>(buf); NLMSG_OK(nlmsg, remainingLen);
+    for (auto nlmsg = reinterpret_cast<nlmsghdr*>(buf); NLMSG_OK(nlmsg, remainingLen);
          nlmsg = NLMSG_NEXT(nlmsg, remainingLen)) {
         if constexpr (kSuperVerbose) {
             LOG(VERBOSE) << "received Netlink response: "
-                         << toString(nlmsg, sizeof(buf), mProtocol);
+                         << toString({nlmsg, nlmsg->nlmsg_len}, mProtocol);
         }
 
         // We're looking for error/ack message only, ignoring others.
@@ -116,7 +169,7 @@
         }
 
         // Found error/ack message, return status.
-        auto nlerr = reinterpret_cast<struct nlmsgerr*>(NLMSG_DATA(nlmsg));
+        const auto nlerr = reinterpret_cast<nlmsgerr*>(NLMSG_DATA(nlmsg));
         if (nlerr->error != 0) {
             LOG(ERROR) << "Received Netlink error message: " << strerror(-nlerr->error);
             return false;
@@ -127,4 +180,14 @@
     return false;
 }
 
+std::optional<unsigned int> NetlinkSocket::getSocketPid() {
+    sockaddr_nl sa = {};
+    socklen_t sasize = sizeof(sa);
+    if (getsockname(mFd.get(), reinterpret_cast<sockaddr*>(&sa), &sasize) < 0) {
+        PLOG(ERROR) << "Failed to getsockname() for netlink_fd!";
+        return std::nullopt;
+    }
+    return sa.nl_pid;
+}
+
 }  // namespace android::netdevice
diff --git a/automotive/can/1.0/default/libnetdevice/common.cpp b/automotive/can/1.0/default/libnetdevice/common.cpp
index 387c91f..f2968fc 100644
--- a/automotive/can/1.0/default/libnetdevice/common.cpp
+++ b/automotive/can/1.0/default/libnetdevice/common.cpp
@@ -22,8 +22,6 @@
 
 namespace android::netdevice {
 
-socketparams::Params socketparams::current = general;
-
 unsigned int nametoindex(const std::string& ifname) {
     const auto ifidx = if_nametoindex(ifname.c_str());
     if (ifidx != 0) return ifidx;
diff --git a/automotive/can/1.0/default/libnetdevice/common.h b/automotive/can/1.0/default/libnetdevice/common.h
index b4f91bd..1e0d5b7 100644
--- a/automotive/can/1.0/default/libnetdevice/common.h
+++ b/automotive/can/1.0/default/libnetdevice/common.h
@@ -25,21 +25,6 @@
 
 namespace android::netdevice {
 
-namespace socketparams {
-
-struct Params {
-    int domain;
-    int type;
-    int protocol;
-};
-
-constexpr Params general = {AF_INET, SOCK_DGRAM, 0};
-constexpr Params can = {PF_CAN, SOCK_RAW, CAN_RAW};
-
-extern Params current;
-
-}  // namespace socketparams
-
 /**
  * Returns the index of a given network interface.
  *
diff --git a/automotive/can/1.0/default/libnetdevice/ifreqs.cpp b/automotive/can/1.0/default/libnetdevice/ifreqs.cpp
index 9335021..8df6434 100644
--- a/automotive/can/1.0/default/libnetdevice/ifreqs.cpp
+++ b/automotive/can/1.0/default/libnetdevice/ifreqs.cpp
@@ -21,11 +21,35 @@
 #include <android-base/logging.h>
 #include <android-base/unique_fd.h>
 
+#include <map>
+
 namespace android::netdevice::ifreqs {
 
+static constexpr int defaultSocketDomain = AF_INET;
+std::atomic_int socketDomain = defaultSocketDomain;
+
+struct SocketParams {
+    int domain;
+    int type;
+    int protocol;
+};
+
+static const std::map<int, SocketParams> socketParams = {
+        {AF_INET, {AF_INET, SOCK_DGRAM, 0}},
+        {AF_CAN, {AF_CAN, SOCK_RAW, CAN_RAW}},
+};
+
+static SocketParams getSocketParams(int domain) {
+    if (socketParams.count(domain)) return socketParams.find(domain)->second;
+
+    auto params = socketParams.find(defaultSocketDomain)->second;
+    params.domain = domain;
+    return params;
+}
+
 bool send(unsigned long request, struct ifreq& ifr) {
-    base::unique_fd sock(socket(socketparams::current.domain, socketparams::current.type,
-                                socketparams::current.protocol));
+    const auto sp = getSocketParams(socketDomain);
+    base::unique_fd sock(socket(sp.domain, sp.type, sp.protocol));
     if (!sock.ok()) {
         LOG(ERROR) << "Can't create socket";
         return false;
diff --git a/automotive/can/1.0/default/libnetdevice/ifreqs.h b/automotive/can/1.0/default/libnetdevice/ifreqs.h
index 25a40a6..74e5877 100644
--- a/automotive/can/1.0/default/libnetdevice/ifreqs.h
+++ b/automotive/can/1.0/default/libnetdevice/ifreqs.h
@@ -23,6 +23,11 @@
 namespace android::netdevice::ifreqs {
 
 /**
+ * \see useSocketDomain()
+ */
+extern std::atomic_int socketDomain;
+
+/**
  * Sends ioctl interface request.
  *
  * \param request Request type (such as SIOCGIFFLAGS)
diff --git a/automotive/can/1.0/default/libnetdevice/include/libnetdevice/NetlinkSocket.h b/automotive/can/1.0/default/libnetdevice/include/libnetdevice/NetlinkSocket.h
index 8900ff7..826b6b8 100644
--- a/automotive/can/1.0/default/libnetdevice/include/libnetdevice/NetlinkSocket.h
+++ b/automotive/can/1.0/default/libnetdevice/include/libnetdevice/NetlinkSocket.h
@@ -19,9 +19,12 @@
 #include <android-base/macros.h>
 #include <android-base/unique_fd.h>
 #include <libnetdevice/NetlinkRequest.h>
+#include <libnetdevice/nlbuf.h>
 
 #include <linux/netlink.h>
 
+#include <optional>
+
 namespace android::netdevice {
 
 /**
@@ -31,12 +34,23 @@
  * use multiple instances over multiple threads.
  */
 struct NetlinkSocket {
-    NetlinkSocket(int protocol);
+    /**
+     * NetlinkSocket constructor.
+     *
+     * \param protocol the Netlink protocol to use.
+     * \param pid port id. Default value of 0 allows the kernel to assign us a unique pid. (NOTE:
+     * this is NOT the same as process id!)
+     * \param groups Netlink multicast groups to listen to. This is a 32-bit bitfield, where each
+     * bit is a different group. Default value of 0 means no groups are selected. See man netlink.7
+     * for more details.
+     */
+    NetlinkSocket(int protocol, unsigned int pid = 0, uint32_t groups = 0);
 
     /**
-     * Send Netlink message to Kernel.
+     * Send Netlink message to Kernel. The sequence number will be automatically incremented, and
+     * the NLM_F_ACK (request ACK) flag will be set.
      *
-     * \param msg Message to send, nlmsg_seq will be set to next sequence number
+     * \param msg Message to send.
      * \return true, if succeeded
      */
     template <class T, unsigned int BUFSIZE>
@@ -46,12 +60,47 @@
     }
 
     /**
+     * Send Netlink message. The message will be sent as is, without any modification.
+     *
+     * \param msg Message to send.
+     * \param sa Destination address.
+     * \return true, if succeeded
+     */
+    bool send(const nlbuf<nlmsghdr>& msg, const sockaddr_nl& sa);
+
+    /**
+     * Receive Netlink data.
+     *
+     * \param buf buffer to hold message data.
+     * \param bufLen length of buf.
+     * \return nlbuf with message data, std::nullopt on error.
+     */
+    std::optional<nlbuf<nlmsghdr>> receive(void* buf, size_t bufLen);
+
+    /**
+     * Receive Netlink data with address info.
+     *
+     * \param buf buffer to hold message data.
+     * \param bufLen length of buf.
+     * \param sa Blank struct that recvfrom will populate with address info.
+     * \return nlbuf with message data, std::nullopt on error.
+     */
+    std::optional<nlbuf<nlmsghdr>> receive(void* buf, size_t bufLen, sockaddr_nl& sa);
+
+    /**
      * Receive Netlink ACK message from Kernel.
      *
      * \return true if received ACK message, false in case of error
      */
     bool receiveAck();
 
+    /**
+     * Gets the PID assigned to mFd.
+     *
+     * \return pid that mSocket is bound to.
+     */
+    std::optional<unsigned int> getSocketPid();
+
   private:
     const int mProtocol;
 
@@ -59,7 +108,7 @@
     base::unique_fd mFd;
     bool mFailed = false;
 
-    bool send(struct nlmsghdr* msg, size_t totalLen);
+    bool send(nlmsghdr* msg, size_t totalLen);
 
     DISALLOW_COPY_AND_ASSIGN(NetlinkSocket);
 };
diff --git a/automotive/can/1.0/default/libnetdevice/include/libnetdevice/libnetdevice.h b/automotive/can/1.0/default/libnetdevice/include/libnetdevice/libnetdevice.h
index 037618a..9a26ff1 100644
--- a/automotive/can/1.0/default/libnetdevice/include/libnetdevice/libnetdevice.h
+++ b/automotive/can/1.0/default/libnetdevice/include/libnetdevice/libnetdevice.h
@@ -27,15 +27,14 @@
 typedef std::array<uint8_t, ETH_ALEN> hwaddr_t;
 
 /**
- * Configures libnetdevice to use PF_CAN sockets instead of AF_INET,
+ * Configures libnetdevice to use other socket domain than AF_INET,
  * what requires less permissive SEPolicy rules for a given process.
  *
- * In such case, the process would only be able to control CAN interfaces.
- *
- * TODO(b/158011272): consider less hacky solution
- * \param yes true to use CAN sockets, false for general sockets
+ * In such case, the process would only be able to control interfaces of a given kind.
+
+ * \param domain Socket domain to use (e.g. AF_CAN), see socket(2) for details
  */
-void useCanSockets(bool yes);
+void useSocketDomain(int domain);
 
 /**
  * Checks, if the network interface exists.
diff --git a/automotive/can/1.0/default/libnetdevice/include/libnetdevice/nlbuf.h b/automotive/can/1.0/default/libnetdevice/include/libnetdevice/nlbuf.h
index f7e53be..17815f9 100644
--- a/automotive/can/1.0/default/libnetdevice/include/libnetdevice/nlbuf.h
+++ b/automotive/can/1.0/default/libnetdevice/include/libnetdevice/nlbuf.h
@@ -53,6 +53,12 @@
     static constexpr size_t hdrlen = align(sizeof(T));
 
   public:
+    /**
+     * Constructor for nlbuf.
+     *
+     * \param data A pointer to the data the nlbuf wraps.
+     * \param bufferLen Length of buffer.
+     */
     nlbuf(const T* data, size_t bufferLen) : mData(data), mBufferEnd(pointerAdd(data, bufferLen)) {}
 
     const T* operator->() const {
diff --git a/automotive/can/1.0/default/libnetdevice/include/libnetdevice/printer.h b/automotive/can/1.0/default/libnetdevice/include/libnetdevice/printer.h
index efeb6b1..071fa63 100644
--- a/automotive/can/1.0/default/libnetdevice/include/libnetdevice/printer.h
+++ b/automotive/can/1.0/default/libnetdevice/include/libnetdevice/printer.h
@@ -16,12 +16,22 @@
 
 #pragma once
 
+#include <libnetdevice/nlbuf.h>
+
 #include <linux/netlink.h>
 
 #include <string>
 
 namespace android::netdevice {
 
-std::string toString(const nlmsghdr* hdr, size_t bufLen, int protocol);
+/**
+ * Stringify a Netlink message.
+ *
+ * \param hdr Pointer to the message(s) to print.
+ * \param protocol Which Netlink protocol hdr uses.
+ * \param printPayload True will stringify message data, false will only stringify the header(s).
+ * \return Stringified message.
+ */
+std::string toString(const nlbuf<nlmsghdr> hdr, int protocol, bool printPayload = false);
 
 }  // namespace android::netdevice
diff --git a/automotive/can/1.0/default/libnetdevice/libnetdevice.cpp b/automotive/can/1.0/default/libnetdevice/libnetdevice.cpp
index 4bba5f6..4293cad 100644
--- a/automotive/can/1.0/default/libnetdevice/libnetdevice.cpp
+++ b/automotive/can/1.0/default/libnetdevice/libnetdevice.cpp
@@ -28,8 +28,8 @@
 
 namespace android::netdevice {
 
-void useCanSockets(bool yes) {
-    socketparams::current = yes ? socketparams::can : socketparams::general;
+void useSocketDomain(int domain) {
+    ifreqs::socketDomain = domain;
 }
 
 bool exists(std::string ifname) {
diff --git a/automotive/can/1.0/default/libnetdevice/printer.cpp b/automotive/can/1.0/default/libnetdevice/printer.cpp
index a8715da..0076dd6 100644
--- a/automotive/can/1.0/default/libnetdevice/printer.cpp
+++ b/automotive/can/1.0/default/libnetdevice/printer.cpp
@@ -62,13 +62,20 @@
 }
 
 static void toStream(std::stringstream& ss, const nlbuf<uint8_t> data) {
+    const auto rawData = data.getRaw();
+    const auto dataLen = rawData.len();
     ss << std::hex;
+    if (dataLen > 16) ss << std::endl << " 0000 ";
     int i = 0;
-    for (const auto byte : data.getRaw()) {
+    for (const auto byte : rawData) {
         if (i++ > 0) ss << ' ';
         ss << std::setw(2) << unsigned(byte);
+        if (i % 16 == 0) {
+            ss << std::endl << ' ' << std::dec << std::setw(4) << i << std::hex;
+        }
     }
     ss << std::dec;
+    if (dataLen > 16) ss << std::endl;
 }
 
 static void toStream(std::stringstream& ss, const nlbuf<nlattr> attr,
@@ -105,7 +112,7 @@
     }
 }
 
-static std::string toString(const nlbuf<nlmsghdr> hdr, int protocol) {
+std::string toString(const nlbuf<nlmsghdr> hdr, int protocol, bool printPayload) {
     if (!hdr.firstOk()) return "nlmsg{buffer overflow}";
 
     std::stringstream ss;
@@ -133,10 +140,13 @@
     }
     if (hdr->nlmsg_seq != 0) ss << ", seq=" << hdr->nlmsg_seq;
     if (hdr->nlmsg_pid != 0) ss << ", pid=" << hdr->nlmsg_pid;
+    ss << ", len=" << hdr->nlmsg_len;
 
     ss << ", crc=" << std::hex << std::setw(4) << crc16(hdr.data<uint8_t>()) << std::dec;
     ss << "} ";
 
+    if (!printPayload) return ss.str();
+
     if (!msgDescMaybe.has_value()) {
         toStream(ss, hdr.data<uint8_t>());
     } else {
@@ -161,8 +171,4 @@
     return ss.str();
 }
 
-std::string toString(const nlmsghdr* hdr, size_t bufLen, int protocol) {
-    return toString({hdr, bufLen}, protocol);
-}
-
 }  // namespace android::netdevice
diff --git a/automotive/can/1.0/default/libnetdevice/protocols/common/Error.cpp b/automotive/can/1.0/default/libnetdevice/protocols/common/Error.cpp
index d42a50a..25ae680 100644
--- a/automotive/can/1.0/default/libnetdevice/protocols/common/Error.cpp
+++ b/automotive/can/1.0/default/libnetdevice/protocols/common/Error.cpp
@@ -30,7 +30,7 @@
 
 void Error::toStream(std::stringstream& ss, const nlmsgerr& data) const {
     ss << "nlmsgerr{error=" << data.error
-       << ", msg=" << toString(&data.msg, sizeof(data.msg), mProtocol) << "}";
+       << ", msg=" << toString({&data.msg, sizeof(data.msg)}, mProtocol) << "}";
 }
 
 }  // namespace android::netdevice::protocols::base
diff --git a/automotive/can/1.0/default/service.cpp b/automotive/can/1.0/default/service.cpp
index b5801c0..9a9d322 100644
--- a/automotive/can/1.0/default/service.cpp
+++ b/automotive/can/1.0/default/service.cpp
@@ -28,7 +28,7 @@
     configureRpcThreadpool(16, true);
     LOG(DEBUG) << "CAN controller service starting...";
 
-    netdevice::useCanSockets(true);
+    netdevice::useSocketDomain(AF_CAN);
 
     sp<CanController> canController(new CanController);
     if (canController->registerAsService("socketcan") != OK) {
diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedUserHal.cpp b/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedUserHal.cpp
index 8c9ffb9..a5c2930 100644
--- a/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedUserHal.cpp
+++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedUserHal.cpp
@@ -155,6 +155,15 @@
     }
 
     if (value.areaId != 0) {
+        if (value.value.int32Values.size() >= 2 &&
+            static_cast<SwitchUserMessageType>(value.value.int32Values[1]) ==
+                    SwitchUserMessageType::VEHICLE_REQUEST) {
+            // User HAL can also request a user switch, so we need to check it first
+            ALOGD("set(SWITCH_USER) called from lshal to emulate a vehicle request: %s",
+                  toString(value).c_str());
+            return std::unique_ptr<VehiclePropValue>(new VehiclePropValue(value));
+        }
+        // Otherwise, we store it
         ALOGD("set(SWITCH_USER) called from lshal; storing it: %s", toString(value).c_str());
         mSwitchUserResponseFromCmd.reset(new VehiclePropValue(value));
         return {};
diff --git a/current.txt b/current.txt
index 6f0debd..6f5e559 100644
--- a/current.txt
+++ b/current.txt
@@ -770,6 +770,8 @@
 cd84ab19c590e0e73dd2307b591a3093ee18147ef95e6d5418644463a6620076 android.hardware.neuralnetworks@1.2::IDevice
 9625e85f56515ad2cf87b6a1847906db669f746ea4ab02cd3d4ca25abc9b0109 android.hardware.neuralnetworks@1.2::types
 9e758e208d14f7256e0885d6d8ad0b61121b21d8c313864f981727ae55bffd16 android.hardware.neuralnetworks@1.3::types
+38d65fb20c60a5b823298560fc0825457ecdc49603a4b4e94bf81511790737da android.hardware.radio@1.4::types
+954c334efd80e8869b66d1ce5fe2755712d96ba4b3c38d415739c330af5fb4cb android.hardware.radio@1.5::types
 
 # HALs released in Android S
 # NOTE: waiting to freeze HALs until later in the release
diff --git a/graphics/composer/2.4/vts/functional/VtsHalGraphicsComposerV2_4TargetTest.cpp b/graphics/composer/2.4/vts/functional/VtsHalGraphicsComposerV2_4TargetTest.cpp
index 00df7c7..f0de4f7 100644
--- a/graphics/composer/2.4/vts/functional/VtsHalGraphicsComposerV2_4TargetTest.cpp
+++ b/graphics/composer/2.4/vts/functional/VtsHalGraphicsComposerV2_4TargetTest.cpp
@@ -201,8 +201,12 @@
 
     void execute() { mComposerClient->execute(mReader.get(), mWriter.get()); }
 
-    void Test_setActiveConfigWithConstraints(
-            const IComposerClient::VsyncPeriodChangeConstraints& constraints, bool refreshMiss);
+    struct TestParameters {
+        nsecs_t delayForChange;
+        bool refreshMiss;
+    };
+
+    void Test_setActiveConfigWithConstraints(const TestParameters& params);
 
     void sendRefreshFrame(const VsyncPeriodChangeTimeline*);
 
@@ -453,9 +457,7 @@
 }
 
 void GraphicsComposerHidlCommandTest::Test_setActiveConfigWithConstraints(
-        const IComposerClient::VsyncPeriodChangeConstraints& constraints, bool refreshMiss) {
-    VsyncPeriodChangeTimeline timeline = {};
-
+        const TestParameters& params) {
     for (Display display : mComposerCallback->getDisplays()) {
         forEachTwoConfigs(display, [&](Config config1, Config config2) {
             mComposerClient->setActiveConfig(display, config1);
@@ -470,6 +472,10 @@
                 return;  // continue
             }
 
+            VsyncPeriodChangeTimeline timeline;
+            IComposerClient::VsyncPeriodChangeConstraints constraints = {
+                    .desiredTimeNanos = systemTime() + params.delayForChange,
+                    .seamlessRequired = false};
             EXPECT_EQ(Error::NONE, mComposerClient->setActiveConfigWithConstraints(
                                            display, config2, constraints, &timeline));
 
@@ -480,7 +486,7 @@
                         kReasonableTimeForChange.count());
 
             if (timeline.refreshRequired) {
-                if (refreshMiss) {
+                if (params.refreshMiss) {
                     // Miss the refresh frame on purpose to make sure the implementation sends a
                     // callback
                     std::this_thread::sleep_until(toTimePoint(timeline.refreshTimeNanos) + 100ms);
@@ -493,16 +499,16 @@
             // At this point the refresh rate should have changed already, however in rare
             // cases the implementation might have missed the deadline. In this case a new
             // timeline should have been provided.
-            auto newTimelime = mComposerCallback->takeLastVsyncPeriodChangeTimeline();
-            if (timeline.refreshRequired && refreshMiss) {
-                EXPECT_TRUE(newTimelime.has_value());
+            auto newTimeline = mComposerCallback->takeLastVsyncPeriodChangeTimeline();
+            if (timeline.refreshRequired && params.refreshMiss) {
+                EXPECT_TRUE(newTimeline.has_value());
             }
 
-            if (newTimelime.has_value()) {
-                if (timeline.refreshRequired) {
-                    sendRefreshFrame(&newTimelime.value());
+            if (newTimeline.has_value()) {
+                if (newTimeline->refreshRequired) {
+                    sendRefreshFrame(&newTimeline.value());
                 }
-                waitForVsyncPeriodChange(display, newTimelime.value(), constraints.desiredTimeNanos,
+                waitForVsyncPeriodChange(display, newTimeline.value(), constraints.desiredTimeNanos,
                                          vsyncPeriod1, vsyncPeriod2);
             }
 
@@ -515,28 +521,16 @@
 }
 
 TEST_P(GraphicsComposerHidlCommandTest, setActiveConfigWithConstraints) {
-    IComposerClient::VsyncPeriodChangeConstraints constraints;
-
-    constraints.seamlessRequired = false;
-    constraints.desiredTimeNanos = systemTime();
-    Test_setActiveConfigWithConstraints(constraints, false);
+    Test_setActiveConfigWithConstraints({.delayForChange = 0, .refreshMiss = false});
 }
 
 TEST_P(GraphicsComposerHidlCommandTest, setActiveConfigWithConstraints_Delayed) {
-    IComposerClient::VsyncPeriodChangeConstraints constraints;
-
-    constexpr nsecs_t kDelayForChange = 300'000'000;  // 300ms
-    constraints.seamlessRequired = false;
-    constraints.desiredTimeNanos = systemTime() + kDelayForChange;
-    Test_setActiveConfigWithConstraints(constraints, false);
+    Test_setActiveConfigWithConstraints({.delayForChange = 300'000'000,  // 300ms
+                                         .refreshMiss = false});
 }
 
 TEST_P(GraphicsComposerHidlCommandTest, setActiveConfigWithConstraints_MissRefresh) {
-    IComposerClient::VsyncPeriodChangeConstraints constraints;
-
-    constraints.seamlessRequired = false;
-    constraints.desiredTimeNanos = systemTime();
-    Test_setActiveConfigWithConstraints(constraints, true);
+    Test_setActiveConfigWithConstraints({.delayForChange = 0, .refreshMiss = true});
 }
 
 TEST_P(GraphicsComposerHidlTest, setAutoLowLatencyModeBadDisplay) {
diff --git a/health/1.0/default/convert.cpp b/health/1.0/default/convert.cpp
index 7f1e3c4..3680d4d 100644
--- a/health/1.0/default/convert.cpp
+++ b/health/1.0/default/convert.cpp
@@ -79,7 +79,7 @@
 
     hc->batteryCurrentAvgPath =
         android::String8(c.batteryCurrentAvgPath.c_str(),
-                         c.batteryCurrentNowPath.size());
+                         c.batteryCurrentAvgPath.size());
 
     hc->batteryChargeCounterPath =
         android::String8(c.batteryChargeCounterPath.c_str(),
diff --git a/radio/1.4/types.hal b/radio/1.4/types.hal
index 393716b..a830816 100644
--- a/radio/1.4/types.hal
+++ b/radio/1.4/types.hal
@@ -1847,9 +1847,9 @@
     /**
      * SS reference signal received quality, multipled by -1.
      *
-     * Reference: 3GPP TS 38.215.
+     * Reference: 3GPP TS 38.215, 3GPP TS 38.133 section 10.
      *
-     * Range [3, 20], INT_MAX means invalid/unreported.
+     * Range [-20 dB, 43 dB], INT_MAX means invalid/unreported.
      */
     int32_t ssRsrq;
 
diff --git a/radio/1.5/types.hal b/radio/1.5/types.hal
index b061bd5..c1f3f03 100644
--- a/radio/1.5/types.hal
+++ b/radio/1.5/types.hal
@@ -107,9 +107,9 @@
     SSRSRP = 6,
     /**
      * 5G SS reference signal received quality.
-     * Range: -20 dB to -3 dB.
+     * Range: -43 dB to 20 dB.
      * Used RAN: NGRAN
-     * Reference: 3GPP TS 38.215.
+     * Reference: 3GPP TS 38.215, 3GPP TS 38.133 section 10
      */
     SSRSRQ = 7,
     /**
diff --git a/tv/tuner/1.0/vts/functional/DescramblerTests.cpp b/tv/tuner/1.0/vts/functional/DescramblerTests.cpp
index d7440bc..2e27475 100644
--- a/tv/tuner/1.0/vts/functional/DescramblerTests.cpp
+++ b/tv/tuner/1.0/vts/functional/DescramblerTests.cpp
@@ -102,13 +102,13 @@
 
 AssertionResult DescramblerTests::setKeyToken(TunerKeyToken token) {
     Result status;
-    if (mDescrambler) {
+    if (!mDescrambler) {
         ALOGW("[vts] Descrambler is not opened yet.");
         return failure();
     }
 
     status = mDescrambler->setKeyToken(token);
-    if (status == Result::SUCCESS) {
+    if (status != Result::SUCCESS) {
         ALOGW("[vts] setKeyToken failed.");
         return failure();
     }
@@ -118,13 +118,13 @@
 
 AssertionResult DescramblerTests::addPid(DemuxPid pid, sp<IFilter> optionalSourceFilter) {
     Result status;
-    if (mDescrambler) {
+    if (!mDescrambler) {
         ALOGW("[vts] Descrambler is not opened yet.");
         return failure();
     }
 
     status = mDescrambler->addPid(pid, optionalSourceFilter);
-    if (status == Result::SUCCESS) {
+    if (status != Result::SUCCESS) {
         ALOGW("[vts] addPid failed.");
         return failure();
     }
@@ -134,13 +134,13 @@
 
 AssertionResult DescramblerTests::removePid(DemuxPid pid, sp<IFilter> optionalSourceFilter) {
     Result status;
-    if (mDescrambler) {
+    if (!mDescrambler) {
         ALOGW("[vts] Descrambler is not opened yet.");
         return failure();
     }
 
     status = mDescrambler->removePid(pid, optionalSourceFilter);
-    if (status == Result::SUCCESS) {
+    if (status != Result::SUCCESS) {
         ALOGW("[vts] removePid failed.");
         return failure();
     }
@@ -150,14 +150,14 @@
 
 AssertionResult DescramblerTests::closeDescrambler() {
     Result status;
-    if (mDescrambler) {
+    if (!mDescrambler) {
         ALOGW("[vts] Descrambler is not opened yet.");
         return failure();
     }
 
     status = mDescrambler->close();
     mDescrambler = nullptr;
-    if (status == Result::SUCCESS) {
+    if (status != Result::SUCCESS) {
         ALOGW("[vts] close Descrambler failed.");
         return failure();
     }
diff --git a/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.cpp b/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.cpp
index 9318bc4..078f5df 100644
--- a/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.cpp
+++ b/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.cpp
@@ -292,18 +292,18 @@
         ASSERT_TRUE(mFilterTests.configFilter((*config).settings, filterId));
         filterIds.insert(filterId);
     }
-    mDescramblerTests.openDescrambler(demuxId);
+    ASSERT_TRUE(mDescramblerTests.openDescrambler(demuxId));
     TunerKeyToken token;
     ASSERT_TRUE(mDescramblerTests.getKeyToken(descConfig.casSystemId, descConfig.provisionStr,
                                               descConfig.hidlPvtData, token));
-    mDescramblerTests.setKeyToken(token);
+    ASSERT_TRUE(mDescramblerTests.setKeyToken(token));
     vector<DemuxPid> pids;
     DemuxPid pid;
     for (config = mediaFilterConfs.begin(); config != mediaFilterConfs.end(); config++) {
         ASSERT_TRUE(mDescramblerTests.getDemuxPidFromFilterSettings((*config).type,
                                                                     (*config).settings, pid));
         pids.push_back(pid);
-        mDescramblerTests.addPid(pid, nullptr);
+        ASSERT_TRUE(mDescramblerTests.addPid(pid, nullptr));
     }
     for (id = filterIds.begin(); id != filterIds.end(); id++) {
         ASSERT_TRUE(mFilterTests.startFilter(*id));
@@ -316,9 +316,9 @@
         ASSERT_TRUE(mFilterTests.stopFilter(*id));
     }
     for (auto pid : pids) {
-        mDescramblerTests.removePid(pid, nullptr);
+        ASSERT_TRUE(mDescramblerTests.removePid(pid, nullptr));
     }
-    mDescramblerTests.closeDescrambler();
+    ASSERT_TRUE(mDescramblerTests.closeDescrambler());
     for (id = filterIds.begin(); id != filterIds.end(); id++) {
         ASSERT_TRUE(mFilterTests.closeFilter(*id));
     }
@@ -410,9 +410,9 @@
                                                filterArray[TS_PCR0].bufferSize));
     ASSERT_TRUE(mFilterTests.getNewlyOpenedFilterId(pcrFilterId));
     ASSERT_TRUE(mFilterTests.configFilter(filterArray[TS_PCR0].settings, pcrFilterId));
-    mDemuxTests.getAvSyncId(mediaFilter, avSyncHwId);
+    ASSERT_TRUE(mDemuxTests.getAvSyncId(mediaFilter, avSyncHwId));
     ASSERT_TRUE(pcrFilterId == avSyncHwId);
-    mDemuxTests.getAvSyncTime(pcrFilterId);
+    ASSERT_TRUE(mDemuxTests.getAvSyncTime(pcrFilterId));
     ASSERT_TRUE(mFilterTests.closeFilter(pcrFilterId));
     ASSERT_TRUE(mFilterTests.closeFilter(mediaFilterId));
     ASSERT_TRUE(mDemuxTests.closeDemux());
@@ -575,8 +575,8 @@
     ASSERT_TRUE(mFrontendTests.setFrontendCallback());
     ASSERT_TRUE(mDemuxTests.openDemux(demux, demuxId));
     ASSERT_TRUE(mDemuxTests.setDemuxFrontendDataSource(feId));
-    mDescramblerTests.openDescrambler(demuxId);
-    mDescramblerTests.closeDescrambler();
+    ASSERT_TRUE(mDescramblerTests.openDescrambler(demuxId));
+    ASSERT_TRUE(mDescramblerTests.closeDescrambler());
     ASSERT_TRUE(mDemuxTests.closeDemux());
     ASSERT_TRUE(mFrontendTests.closeFrontend());
 }
diff --git a/wifi/1.4/default/android.hardware.wifi@1.0-service-lazy.rc b/wifi/1.4/default/android.hardware.wifi@1.0-service-lazy.rc
index cf917b5..061689d 100644
--- a/wifi/1.4/default/android.hardware.wifi@1.0-service-lazy.rc
+++ b/wifi/1.4/default/android.hardware.wifi@1.0-service-lazy.rc
@@ -1,5 +1,9 @@
 service vendor.wifi_hal_legacy /vendor/bin/hw/android.hardware.wifi@1.0-service-lazy
     interface android.hardware.wifi@1.0::IWifi default
+    interface android.hardware.wifi@1.1::IWifi default
+    interface android.hardware.wifi@1.2::IWifi default
+    interface android.hardware.wifi@1.3::IWifi default
+    interface android.hardware.wifi@1.4::IWifi default
     oneshot
     disabled
     class hal