[automerger skipped] Merge "Adds VTS test for setAllowedNetworkTypesBitmap" am: 8d1e7b9c7c am: 9cb8f92e2e -s ours am: 12d6a13bbe -s ours am: d561da1776 -s ours

am skip reason: Merged-In I1b7d85ddd70a2d116a3b54a10d168c20804f2524 with SHA-1 c3d2bd4c56 is already in history

Original change: https://android-review.googlesource.com/c/platform/hardware/interfaces/+/1729179

Change-Id: I48091ddc531d946d22c55809c225eddb74828ccb
diff --git a/automotive/can/1.0/default/libnl++/Android.bp b/automotive/can/1.0/default/libnl++/Android.bp
index 790adcd..2ebd1b4 100644
--- a/automotive/can/1.0/default/libnl++/Android.bp
+++ b/automotive/can/1.0/default/libnl++/Android.bp
@@ -35,6 +35,7 @@
         "protocols/generic/Generic.cpp",
         "protocols/generic/GenericMessageBase.cpp",
         "protocols/generic/Unknown.cpp",
+        "protocols/generic/families/Mac80211hwsim.cpp",
         "protocols/generic/families/Nl80211.cpp",
         "protocols/route/Link.cpp",
         "protocols/route/Route.cpp",
@@ -42,6 +43,7 @@
         "protocols/MessageDefinition.cpp",
         "protocols/NetlinkProtocol.cpp",
         "protocols/all.cpp",
+        "protocols/structs.cpp",
         "Attributes.cpp",
         "MessageFactory.cpp",
         "MessageMutator.cpp",
diff --git a/automotive/can/1.0/default/libnl++/MessageMutator.cpp b/automotive/can/1.0/default/libnl++/MessageMutator.cpp
index 00b48a6..de2a2b1 100644
--- a/automotive/can/1.0/default/libnl++/MessageMutator.cpp
+++ b/automotive/can/1.0/default/libnl++/MessageMutator.cpp
@@ -19,7 +19,7 @@
 namespace android::nl {
 
 MessageMutator::MessageMutator(nlmsghdr* buffer, size_t totalLen)
-    : mConstBuffer(buffer, totalLen), mMutableBuffer(buffer) {
+    : mMutableBuffer(buffer), mTotalLen(totalLen) {
     CHECK(totalLen >= sizeof(nlmsghdr));
 }
 
@@ -27,8 +27,12 @@
     return mMutableBuffer;
 }
 
+Buffer<nlmsghdr> MessageMutator::constBuffer() const {
+    return {mMutableBuffer, mTotalLen};
+}
+
 MessageMutator::operator Buffer<nlmsghdr>() const {
-    return mConstBuffer;
+    return constBuffer();
 }
 
 uint64_t MessageMutator::read(Buffer<nlattr> attr) const {
@@ -37,7 +41,8 @@
 
 void MessageMutator::write(Buffer<nlattr> attr, uint64_t val) const {
     const auto attrData = attr.data<uint64_t>();
-    const auto offset = mConstBuffer.getOffset(attrData);
+    // TODO(b/177251183): deduplicate this code against fragment()
+    const auto offset = constBuffer().getOffset(attrData);
     CHECK(offset.has_value()) << "Trying to write attribute that's not a member of this message";
 
     const auto writeableBuffer = reinterpret_cast<uint8_t*>(mMutableBuffer) + *offset;
@@ -47,4 +52,40 @@
     memcpy(writeableBuffer, &val, std::min(sizeof(val), attrSize));
 }
 
+MessageMutator MessageMutator::fragment(Buffer<nlmsghdr> buf) const {
+    const auto offset = constBuffer().getOffset(buf);
+    CHECK(offset.has_value()) << "Trying to modify a fragment outside of buffer range";
+
+    const auto writeableBuffer = reinterpret_cast<nlmsghdr*>(uintptr_t(mMutableBuffer) + *offset);
+    const auto len = buf.getRaw().len();
+    CHECK(len <= mTotalLen - *offset);
+
+    return {writeableBuffer, len};
+}
+
+MessageMutator::iterator MessageMutator::begin() const {
+    return {*this, constBuffer().begin()};
+}
+
+MessageMutator::iterator MessageMutator::end() const {
+    return {*this, constBuffer().end()};
+}
+
+MessageMutator::iterator::iterator(const MessageMutator& container,
+                                   Buffer<nlmsghdr>::iterator current)
+    : mContainer(container), mCurrent(current) {}
+
+MessageMutator::iterator MessageMutator::iterator::operator++() {
+    ++mCurrent;
+    return *this;
+}
+
+bool MessageMutator::iterator::operator==(const iterator& other) const {
+    return other.mCurrent == mCurrent;
+}
+
+const MessageMutator MessageMutator::iterator::operator*() const {
+    return mContainer.fragment(*mCurrent);
+}
+
 }  // namespace android::nl
diff --git a/automotive/can/1.0/default/libnl++/Socket.cpp b/automotive/can/1.0/default/libnl++/Socket.cpp
index 514d9bb..b0e67be 100644
--- a/automotive/can/1.0/default/libnl++/Socket.cpp
+++ b/automotive/can/1.0/default/libnl++/Socket.cpp
@@ -68,6 +68,11 @@
     return true;
 }
 
+bool Socket::send(const Buffer<nlmsghdr>& msg, uint32_t destination) {
+    sockaddr_nl sa = {.nl_family = AF_NETLINK, .nl_pad = 0, .nl_pid = destination, .nl_groups = 0};
+    return send(msg, sa);
+}
+
 bool Socket::increaseReceiveBuffer(size_t maxSize) {
     if (maxSize == 0) {
         LOG(ERROR) << "Maximum receive size should not be zero";
diff --git a/automotive/can/1.0/default/libnl++/include/libnl++/Buffer.h b/automotive/can/1.0/default/libnl++/include/libnl++/Buffer.h
index d759a0a..4cabb9a 100644
--- a/automotive/can/1.0/default/libnl++/include/libnl++/Buffer.h
+++ b/automotive/can/1.0/default/libnl++/include/libnl++/Buffer.h
@@ -138,7 +138,7 @@
     class raw_iterator : public iterator {
       public:
         iterator operator++() {
-            this->mCurrent.mData++;  // ignore alignment
+            ++this->mCurrent.mData;  // ignore alignment
             return *this;
         }
         const T& operator*() const { return *this->mCurrent.mData; }
diff --git a/automotive/can/1.0/default/libnl++/include/libnl++/Message.h b/automotive/can/1.0/default/libnl++/include/libnl++/Message.h
index 50b3c4b..29f397d 100644
--- a/automotive/can/1.0/default/libnl++/include/libnl++/Message.h
+++ b/automotive/can/1.0/default/libnl++/include/libnl++/Message.h
@@ -34,7 +34,7 @@
  * a single instance can only be used by a single thread - the one owning the underlying buffer).
  */
 template <typename T>
-class Message {
+class Message : public Buffer<nlmsghdr> {
   public:
     /**
      * Validate buffer contents as a message carrying T data and create instance of parsed message.
@@ -51,7 +51,7 @@
 
         const auto attributes = buf.data<nlattr>(sizeof(T));
 
-        return Message<T>(nlHeader, dataHeader, attributes);
+        return Message<T>(buf, nlHeader, dataHeader, attributes);
     }
 
     /**
@@ -94,8 +94,9 @@
     const T* operator->() const { return &data; }
 
   private:
-    Message(const nlmsghdr& nlHeader, const T& dataHeader, Attributes attributes)
-        : header(nlHeader), data(dataHeader), attributes(attributes) {}
+    Message(Buffer<nlmsghdr> buffer, const nlmsghdr& nlHeader, const T& dataHeader,
+            Attributes attributes)
+        : Buffer<nlmsghdr>(buffer), header(nlHeader), data(dataHeader), attributes(attributes) {}
 };
 
 }  // namespace android::nl
diff --git a/automotive/can/1.0/default/libnl++/include/libnl++/MessageMutator.h b/automotive/can/1.0/default/libnl++/include/libnl++/MessageMutator.h
index 7d495e9..baadc44 100644
--- a/automotive/can/1.0/default/libnl++/include/libnl++/MessageMutator.h
+++ b/automotive/can/1.0/default/libnl++/include/libnl++/MessageMutator.h
@@ -53,9 +53,27 @@
      */
     void write(Buffer<nlattr> attr, uint64_t val) const;
 
+    class iterator {
+      public:
+        iterator(const MessageMutator& container, Buffer<nlmsghdr>::iterator current);
+
+        iterator operator++();
+        bool operator==(const iterator& other) const;
+        const MessageMutator operator*() const;
+
+      protected:
+        const MessageMutator& mContainer;
+        Buffer<nlmsghdr>::iterator mCurrent;
+    };
+    iterator begin() const;
+    iterator end() const;
+
   private:
-    const Buffer<nlmsghdr> mConstBuffer;
     nlmsghdr* mMutableBuffer;
+    size_t mTotalLen;
+
+    Buffer<nlmsghdr> constBuffer() const;
+    MessageMutator fragment(Buffer<nlmsghdr> buf) const;
 };
 
 }  // namespace android::nl
diff --git a/automotive/can/1.0/default/libnl++/include/libnl++/Socket.h b/automotive/can/1.0/default/libnl++/include/libnl++/Socket.h
index 8ea3575..118b9f7 100644
--- a/automotive/can/1.0/default/libnl++/include/libnl++/Socket.h
+++ b/automotive/can/1.0/default/libnl++/include/libnl++/Socket.h
@@ -95,6 +95,15 @@
     bool send(const Buffer<nlmsghdr>& msg, const sockaddr_nl& sa);
 
     /**
+     * Send Netlink message.
+     *
+     * \param msg Message to send.
+     * \param destination Destination PID.
+     * \return true, if succeeded.
+     */
+    bool send(const Buffer<nlmsghdr>& msg, uint32_t destination);
+
+    /**
      * Receive one or multiple Netlink messages.
      *
      * WARNING: the underlying buffer is owned by Socket class and the data is valid until the next
diff --git a/automotive/can/1.0/default/libnl++/include/libnl++/generic/families/mac80211_hwsim.h b/automotive/can/1.0/default/libnl++/include/libnl++/generic/families/mac80211_hwsim.h
new file mode 100644
index 0000000..9b811f8
--- /dev/null
+++ b/automotive/can/1.0/default/libnl++/include/libnl++/generic/families/mac80211_hwsim.h
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+// API definitions from kernel drivers/net/wireless/mac80211_hwsim.h
+
+#define BIT(n) (1 << (n))
+
+enum hwsim_tx_control_flags {
+    HWSIM_TX_CTL_REQ_TX_STATUS = BIT(0),
+    HWSIM_TX_CTL_NO_ACK = BIT(1),
+    HWSIM_TX_STAT_ACK = BIT(2),
+};
+
+enum {
+    HWSIM_CMD_UNSPEC,
+    HWSIM_CMD_REGISTER,
+    HWSIM_CMD_FRAME,
+    HWSIM_CMD_TX_INFO_FRAME,
+    HWSIM_CMD_NEW_RADIO,
+    HWSIM_CMD_DEL_RADIO,
+    HWSIM_CMD_GET_RADIO,
+    HWSIM_CMD_ADD_MAC_ADDR,
+    HWSIM_CMD_DEL_MAC_ADDR,
+};
+
+enum {
+    HWSIM_ATTR_UNSPEC,
+    HWSIM_ATTR_ADDR_RECEIVER,
+    HWSIM_ATTR_ADDR_TRANSMITTER,
+    HWSIM_ATTR_FRAME,
+    HWSIM_ATTR_FLAGS,
+    HWSIM_ATTR_RX_RATE,
+    HWSIM_ATTR_SIGNAL,
+    HWSIM_ATTR_TX_INFO,
+    HWSIM_ATTR_COOKIE,
+    HWSIM_ATTR_CHANNELS,
+    HWSIM_ATTR_RADIO_ID,
+    HWSIM_ATTR_REG_HINT_ALPHA2,
+    HWSIM_ATTR_REG_CUSTOM_REG,
+    HWSIM_ATTR_REG_STRICT_REG,
+    HWSIM_ATTR_SUPPORT_P2P_DEVICE,
+    HWSIM_ATTR_USE_CHANCTX,
+    HWSIM_ATTR_DESTROY_RADIO_ON_CLOSE,
+    HWSIM_ATTR_RADIO_NAME,
+    HWSIM_ATTR_NO_VIF,
+    HWSIM_ATTR_FREQ,
+    HWSIM_ATTR_PAD,
+    HWSIM_ATTR_TX_INFO_FLAGS,
+    HWSIM_ATTR_PERM_ADDR,
+    HWSIM_ATTR_IFTYPE_SUPPORT,
+    HWSIM_ATTR_CIPHER_SUPPORT,
+};
+
+struct hwsim_tx_rate {
+    int8_t idx;
+    uint8_t count;
+} __packed;
+static_assert(sizeof(hwsim_tx_rate) == 2);
+
+#undef BIT
diff --git a/automotive/can/1.0/default/libnl++/printer.cpp b/automotive/can/1.0/default/libnl++/printer.cpp
index f08897e..d540482 100644
--- a/automotive/can/1.0/default/libnl++/printer.cpp
+++ b/automotive/can/1.0/default/libnl++/printer.cpp
@@ -154,16 +154,19 @@
     }
 }
 
-std::string toString(const Buffer<nlmsghdr> hdr, int protocol, bool printPayload) {
-    if (!hdr.firstOk()) return "nlmsg{buffer overflow}";
+static void toStream(std::stringstream& ss, const Buffer<nlmsghdr> hdr, int protocol,
+                     bool printPayload) {
+    if (!hdr.firstOk()) {
+        ss << "nlmsg{buffer overflow}";
+        return;
+    }
 
-    std::stringstream ss;
     ss << std::setfill('0');
 
     auto protocolMaybe = protocols::get(protocol);
     if (!protocolMaybe.has_value()) {
         ss << "nlmsg{protocol=" << protocol << "}";
-        return ss.str();
+        return;
     }
     protocols::NetlinkProtocol& protocolDescr = *protocolMaybe;
 
@@ -187,7 +190,7 @@
     ss << ", crc=" << std::hex << std::setw(4) << crc16(hdr.data<uint8_t>()) << std::dec;
     ss << '}';
 
-    if (!printPayload) return ss.str();
+    if (!printPayload) return;
     ss << ' ';
 
     if (!msgDescMaybe.has_value()) {
@@ -210,6 +213,17 @@
     }
 
     ss << "}";
+}
+
+std::string toString(const Buffer<nlmsghdr> hdrs, int protocol, bool printPayload) {
+    std::stringstream ss;
+    bool first = true;
+    for (const auto hdr : hdrs) {
+        if (!first) ss << std::endl;
+        first = false;
+
+        toStream(ss, hdr, protocol, printPayload);
+    }
 
     return ss.str();
 }
diff --git a/automotive/can/1.0/default/libnl++/protocols/generic/Ctrl.cpp b/automotive/can/1.0/default/libnl++/protocols/generic/Ctrl.cpp
index 1e1ad12..478c383 100644
--- a/automotive/can/1.0/default/libnl++/protocols/generic/Ctrl.cpp
+++ b/automotive/can/1.0/default/libnl++/protocols/generic/Ctrl.cpp
@@ -16,6 +16,7 @@
 
 #include "Ctrl.h"
 
+#include "families/Mac80211hwsim.h"
 #include "families/Nl80211.h"
 
 #include <libnl++/Message.h>
@@ -68,12 +69,15 @@
     const auto familyId = msg.attributes.get<uint16_t>(CTRL_ATTR_FAMILY_ID);
     const auto familyName = msg.attributes.get<std::string>(CTRL_ATTR_FAMILY_NAME);
 
-    /* For now, we support just a single family. But if you add more, please define proper
+    /* For now, we support just two families. But if you add more, please define proper
      * abstraction and not hardcode every name and class here.
      */
     if (familyName == "nl80211") {
         mFamilyRegister[familyId] = std::make_shared<families::Nl80211>(familyId);
     }
+    if (familyName == "MAC80211_HWSIM") {
+        mFamilyRegister[familyId] = std::make_shared<families::Mac80211hwsim>(familyId);
+    }
 }
 
 }  // namespace android::nl::protocols::generic
diff --git a/automotive/can/1.0/default/libnl++/protocols/generic/GenericMessageBase.cpp b/automotive/can/1.0/default/libnl++/protocols/generic/GenericMessageBase.cpp
index b7b811b..f92d6c0 100644
--- a/automotive/can/1.0/default/libnl++/protocols/generic/GenericMessageBase.cpp
+++ b/automotive/can/1.0/default/libnl++/protocols/generic/GenericMessageBase.cpp
@@ -40,9 +40,9 @@
 
     ss << "genlmsghdr{";
     if (commandName.has_value()) {
-        ss << "cmd=" << unsigned(data.cmd);
-    } else {
         ss << "cmd=" << *commandName;
+    } else {
+        ss << "cmd=" << unsigned(data.cmd);
     }
     ss << ", version=" << unsigned(data.version);
     if (data.reserved != 0) ss << ", reserved=" << data.reserved;
diff --git a/automotive/can/1.0/default/libnl++/protocols/generic/families/Mac80211hwsim.cpp b/automotive/can/1.0/default/libnl++/protocols/generic/families/Mac80211hwsim.cpp
new file mode 100644
index 0000000..f85309e
--- /dev/null
+++ b/automotive/can/1.0/default/libnl++/protocols/generic/families/Mac80211hwsim.cpp
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+#include "Mac80211hwsim.h"
+
+#include "../../structs.h"
+#include "common.h"
+
+#include <libnl++/generic/families/mac80211_hwsim.h>
+
+namespace android::nl::protocols::generic::families {
+
+using DataType = AttributeDefinition::DataType;
+using Flags = AttributeDefinition::Flags;
+
+static void hwsim_tx_rateToStream(std::stringstream& ss, const Buffer<nlattr> attr);
+
+static const FlagsMap txControlFlags{
+        {HWSIM_TX_CTL_REQ_TX_STATUS, "REQ_TX"},
+        {HWSIM_TX_CTL_NO_ACK, "NO_ACK"},
+        {HWSIM_TX_STAT_ACK, "ACK"},
+};
+
+// clang-format off
+Mac80211hwsim::Mac80211hwsim(nlmsgtype_t familyId) : GenericMessageBase(familyId, "hwsim", {
+    {HWSIM_CMD_UNSPEC, "UNSPEC"},
+    {HWSIM_CMD_REGISTER, "REGISTER"},
+    {HWSIM_CMD_FRAME, "FRAME"},
+    {HWSIM_CMD_TX_INFO_FRAME, "TX_INFO_FRAME"},
+    {HWSIM_CMD_NEW_RADIO, "NEW_RADIO"},
+    {HWSIM_CMD_DEL_RADIO, "DEL_RADIO"},
+    {HWSIM_CMD_GET_RADIO, "GET_RADIO"},
+    {HWSIM_CMD_ADD_MAC_ADDR, "ADD_MAC_ADDR"},
+    {HWSIM_CMD_DEL_MAC_ADDR, "DEL_MAC_ADDR"},
+}, {
+    {HWSIM_ATTR_UNSPEC, {"UNSPEC"}},
+    {HWSIM_ATTR_ADDR_RECEIVER, {"ADDR_RECEIVER", DataType::Struct, hwaddrToStream}},
+    {HWSIM_ATTR_ADDR_TRANSMITTER, {"ADDR_TRANSMITTER", DataType::Struct, hwaddrToStream}},
+    {HWSIM_ATTR_FRAME, {"FRAME", DataType::Raw, AttributeMap{}, Flags::Verbose}},
+    {HWSIM_ATTR_FLAGS, {"FLAGS", DataType::Struct, flagsToStream(txControlFlags)}},
+    {HWSIM_ATTR_RX_RATE, {"RX_RATE", DataType::Uint}},
+    {HWSIM_ATTR_SIGNAL, {"SIGNAL", DataType::Uint}},
+    {HWSIM_ATTR_TX_INFO, {"TX_INFO", DataType::Struct, hwsim_tx_rateToStream}},
+    {HWSIM_ATTR_COOKIE, {"COOKIE", DataType::Uint}},
+    {HWSIM_ATTR_CHANNELS, {"CHANNELS", DataType::Uint}},
+    {HWSIM_ATTR_RADIO_ID, {"RADIO_ID", DataType::Uint}},
+    {HWSIM_ATTR_REG_HINT_ALPHA2, {"REG_HINT_ALPHA2", DataType::String}},
+    {HWSIM_ATTR_REG_CUSTOM_REG, {"REG_CUSTOM_REG", DataType::Uint}},
+    {HWSIM_ATTR_REG_STRICT_REG, {"REG_STRICT_REG", DataType::Flag}},
+    {HWSIM_ATTR_SUPPORT_P2P_DEVICE, {"SUPPORT_P2P_DEVICE", DataType::Flag}},
+    {HWSIM_ATTR_USE_CHANCTX, {"USE_CHANCTX", DataType::Flag}},
+    {HWSIM_ATTR_DESTROY_RADIO_ON_CLOSE, {"DESTROY_RADIO_ON_CLOSE", DataType::Flag}},
+    {HWSIM_ATTR_RADIO_NAME, {"RADIO_NAME", DataType::String}},
+    {HWSIM_ATTR_NO_VIF, {"NO_VIF", DataType::Flag}},
+    {HWSIM_ATTR_FREQ, {"FREQ", DataType::Uint}},
+    {HWSIM_ATTR_PAD, {"PAD", DataType::Uint}},
+    {HWSIM_ATTR_TX_INFO_FLAGS, {"TX_INFO_FLAGS"}},  // hwsim_tx_rate_flag
+    {HWSIM_ATTR_PERM_ADDR, {"PERM_ADDR"}},
+    {HWSIM_ATTR_IFTYPE_SUPPORT, {"IFTYPE_SUPPORT", DataType::Uint}},  // NL80211_IFTYPE_STATION etc
+    {HWSIM_ATTR_CIPHER_SUPPORT, {"CIPHER_SUPPORT", DataType::Struct, arrayToStream<int32_t>}},
+}) {}
+// clang-format on
+
+static void hwsim_tx_rateToStream(std::stringstream& ss, const Buffer<nlattr> attr) {
+    ss << '{';
+    bool first = true;
+    for (const auto rate : attr.data<hwsim_tx_rate>().getRaw()) {
+        if (rate.idx == -1) continue;
+
+        ss << (int)rate.idx << ": " << (unsigned)rate.count;
+
+        if (!first) ss << ", ";
+        first = false;
+    }
+    ss << '}';
+}
+
+}  // namespace android::nl::protocols::generic::families
diff --git a/automotive/can/1.0/default/libnl++/protocols/generic/families/Mac80211hwsim.h b/automotive/can/1.0/default/libnl++/protocols/generic/families/Mac80211hwsim.h
new file mode 100644
index 0000000..c01eb93
--- /dev/null
+++ b/automotive/can/1.0/default/libnl++/protocols/generic/families/Mac80211hwsim.h
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+#pragma once
+
+#include "../GenericMessageBase.h"
+
+namespace android::nl::protocols::generic::families {
+
+class Mac80211hwsim : public GenericMessageBase {
+  public:
+    Mac80211hwsim(nlmsgtype_t familyId);
+};
+
+}  // namespace android::nl::protocols::generic::families
diff --git a/automotive/can/1.0/default/libnl++/protocols/structs.cpp b/automotive/can/1.0/default/libnl++/protocols/structs.cpp
new file mode 100644
index 0000000..8ff71f0
--- /dev/null
+++ b/automotive/can/1.0/default/libnl++/protocols/structs.cpp
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+#include "structs.h"
+
+#include <iomanip>
+
+namespace android::nl::protocols {
+
+AttributeDefinition::ToStream flagsToStream(FlagsMap flags) {
+    return [flags](std::stringstream& ss, const Buffer<nlattr> attr) {
+        auto val = attr.data<uint64_t>().copyFirst();
+
+        bool first = true;
+        for (const auto& [flag, name] : flags) {
+            if ((val & flag) != flag) continue;
+            val &= ~flag;
+
+            if (!first) ss << '|';
+            first = false;
+
+            ss << name;
+        }
+
+        if (val == 0) return;
+
+        if (!first) ss << '|';
+        ss << std::hex << val << std::dec;
+    };
+}
+
+void hwaddrToStream(std::stringstream& ss, const Buffer<nlattr> attr) {
+    ss << std::hex;
+    bool first = true;
+    for (const auto byte : attr.data<uint8_t>().getRaw()) {
+        if (!first) ss << ':';
+        first = false;
+
+        ss << std::setw(2) << unsigned(byte);
+    }
+    ss << std::dec;
+}
+
+}  // namespace android::nl::protocols
diff --git a/automotive/can/1.0/default/libnl++/protocols/structs.h b/automotive/can/1.0/default/libnl++/protocols/structs.h
index 44c17b8..f3a8c44 100644
--- a/automotive/can/1.0/default/libnl++/protocols/structs.h
+++ b/automotive/can/1.0/default/libnl++/protocols/structs.h
@@ -16,6 +16,8 @@
 
 #pragma once
 
+#include "MessageDefinition.h"
+
 #include <sstream>
 
 namespace android::nl::protocols {
@@ -30,4 +32,9 @@
     ss << '}';
 }
 
+typedef std::map<uint64_t, std::string> FlagsMap;
+AttributeDefinition::ToStream flagsToStream(FlagsMap flags);
+
+void hwaddrToStream(std::stringstream& ss, const Buffer<nlattr> attr);
+
 }  // namespace android::nl::protocols
diff --git a/automotive/vehicle/2.0/default/Android.bp b/automotive/vehicle/2.0/default/Android.bp
index ffa0c13..ea42c3e 100644
--- a/automotive/vehicle/2.0/default/Android.bp
+++ b/automotive/vehicle/2.0/default/Android.bp
@@ -182,6 +182,15 @@
     ],
     shared_libs: [
         "libbase",
+        "libcutils",
+    ],
+    exclude_shared_libs: [
+        "android.automotive.watchdog-V2-ndk_platform",
+        "android.hardware.automotive.vehicle@2.0",
+    ],
+    static_libs: [
+        "android.automotive.watchdog-V2-ndk_platform",
+        "android.hardware.automotive.vehicle@2.0",
     ],
     header_libs: ["libbase_headers"],
     test_suites: ["general-tests"],
@@ -195,10 +204,16 @@
         "impl/vhal_v2_0/tests/ProtoMessageConverter_test.cpp",
     ],
     static_libs: [
+        "android.automotive.watchdog-V2-ndk_platform",
+        "android.hardware.automotive.vehicle@2.0",
         "android.hardware.automotive.vehicle@2.0-default-impl-lib",
         "android.hardware.automotive.vehicle@2.0-libproto-native",
         "libprotobuf-cpp-lite",
     ],
+    exclude_shared_libs: [
+        "android.automotive.watchdog-V2-ndk_platform",
+        "android.hardware.automotive.vehicle@2.0",
+    ],
     test_suites: ["general-tests"],
 }
 
diff --git a/automotive/vehicle/2.0/default/TEST_MAPPING b/automotive/vehicle/2.0/default/TEST_MAPPING
new file mode 100644
index 0000000..bb58700
--- /dev/null
+++ b/automotive/vehicle/2.0/default/TEST_MAPPING
@@ -0,0 +1,10 @@
+{
+  "presubmit": [
+    {
+      "name": "android.hardware.automotive.vehicle@2.0-manager-unit-tests"
+    },
+    {
+      "name": "android.hardware.automotive.vehicle@2.0-default-impl-unit-tests"
+    }
+  ]
+}
diff --git a/automotive/vehicle/2.0/default/common/include/vhal_v2_0/VehicleHalManager.h b/automotive/vehicle/2.0/default/common/include/vhal_v2_0/VehicleHalManager.h
index fcfe761..6706258 100644
--- a/automotive/vehicle/2.0/default/common/include/vhal_v2_0/VehicleHalManager.h
+++ b/automotive/vehicle/2.0/default/common/include/vhal_v2_0/VehicleHalManager.h
@@ -76,6 +76,9 @@
     Return<void> debug(const hidl_handle& fd, const hidl_vec<hidl_string>& options) override;
 
   private:
+    // Set unit test class as friend class to test private functions.
+    friend class VehicleHalManagerTestHelper;
+
     using VehiclePropValuePtr = VehicleHal::VehiclePropValuePtr;
     // Returns true if needs to call again shortly.
     using RetriableAction = std::function<bool()>;
@@ -105,14 +108,20 @@
     void cmdDumpOneProperty(int fd, int32_t prop, int32_t areaId);
     void cmdDumpOneProperty(int fd, int rowNumber, const VehiclePropConfig& config);
 
+    bool cmdSetOneProperty(int fd, const hidl_vec<hidl_string>& options);
+
     static bool checkArgumentsSize(int fd, const hidl_vec<hidl_string>& options, size_t minSize);
     static bool checkCallerHasWritePermissions(int fd);
-    static bool safelyParseInt(int fd, int index, std::string s, int* out);
+    template <typename T>
+    static bool safelyParseInt(int fd, int index, const std::string& s, T* out);
+    static bool safelyParseFloat(int fd, int index, const std::string& s, float* out);
+    // Parses "s" as a hex string and populate "*bytes". The hex string must be in the format of
+    // valid hex format, e.g. "0xABCD".
+    static bool parseHexString(int fd, const std::string& s, std::vector<uint8_t>* bytes);
     void cmdHelp(int fd) const;
     void cmdListAllProperties(int fd) const;
     void cmdDumpAllProperties(int fd);
     void cmdDumpSpecificProperties(int fd, const hidl_vec<hidl_string>& options);
-    void cmdSetOneProperty(int fd, const hidl_vec<hidl_string>& options);
 
     static bool isSubscribable(const VehiclePropConfig& config,
                                SubscribeFlags flags);
@@ -120,7 +129,18 @@
     static float checkSampleRate(const VehiclePropConfig& config,
                                  float sampleRate);
     static ClientId getClientId(const sp<IVehicleCallback>& callback);
-private:
+
+    // Parses the cmdline options for "--set" command. "*prop" would be populated with the
+    // the properties to be set. Returns true when the cmdline options are valid, false otherwise.
+    static bool parseSetPropOptions(int fd, const hidl_vec<hidl_string>& options,
+                                    VehiclePropValue* prop);
+    // Parses the options and get the values for the current option specified by "*index". "*index"
+    // would advance to the next option field (e.g., the next "-f"). Returns a list of values for
+    // the current option.
+    static std::vector<std::string> getOptionValues(const hidl_vec<hidl_string>& options,
+                                                    size_t* index);
+
+  private:
     VehicleHal* mHal;
     std::unique_ptr<VehiclePropConfigIndex> mConfigIndex;
     SubscriptionManager mSubscriptionManager;
diff --git a/automotive/vehicle/2.0/default/common/src/VehicleHalManager.cpp b/automotive/vehicle/2.0/default/common/src/VehicleHalManager.cpp
index dc5d3d3..e34e692 100644
--- a/automotive/vehicle/2.0/default/common/src/VehicleHalManager.cpp
+++ b/automotive/vehicle/2.0/default/common/src/VehicleHalManager.cpp
@@ -20,7 +20,9 @@
 
 #include <cmath>
 #include <fstream>
+#include <unordered_set>
 
+#include <android-base/parsedouble.h>
 #include <android-base/parseint.h>
 #include <android-base/strings.h>
 #include <android/hardware/automotive/vehicle/2.0/BpHwVehicleCallback.h>
@@ -44,15 +46,34 @@
 using ::android::hardware::hidl_handle;
 using ::android::hardware::hidl_string;
 
+namespace {
+
 constexpr std::chrono::milliseconds kHalEventBatchingTimeWindow(10);
 
 const VehiclePropValue kEmptyValue{};
 
+// A list of supported options for "--set" command.
+const std::unordered_set<std::string> kSetPropOptions = {
+        // integer.
+        "-i",
+        // 64bit integer.
+        "-i64",
+        // float.
+        "-f",
+        // string.
+        "-s",
+        // bytes in hex format, e.g. 0xDEADBEEF.
+        "-b",
+        // Area id in integer.
+        "-a"};
+
+}  // namespace
+
 /**
  * Indicates what's the maximum size of hidl_vec<VehiclePropValue> we want
  * to store in reusable object pool.
  */
-constexpr auto kMaxHidlVecOfVehiclPropValuePoolSize = 20;
+constexpr auto kMaxHidlVecOfVehiclePropValuePoolSize = 20;
 
 Return<void> VehicleHalManager::getAllPropConfigs(getAllPropConfigs_cb _hidl_cb) {
     ALOGI("getAllPropConfigs called");
@@ -213,6 +234,11 @@
     } else if (EqualsIgnoreCase(option, "--get")) {
         cmdDumpSpecificProperties(fd, options);
     } else if (EqualsIgnoreCase(option, "--set")) {
+        if (!checkCallerHasWritePermissions(fd)) {
+            dprintf(fd, "Caller does not have write permission\n");
+            return;
+        }
+        // Ignore the return value for this.
         cmdSetOneProperty(fd, options);
     } else {
         dprintf(fd, "Invalid option: %s\n", option.c_str());
@@ -239,7 +265,8 @@
     return false;
 }
 
-bool VehicleHalManager::safelyParseInt(int fd, int index, std::string s, int* out) {
+template <typename T>
+bool VehicleHalManager::safelyParseInt(int fd, int index, const std::string& s, T* out) {
     if (!android::base::ParseInt(s, out)) {
         dprintf(fd, "non-integer argument at index %d: %s\n", index, s.c_str());
         return false;
@@ -247,19 +274,27 @@
     return true;
 }
 
+bool VehicleHalManager::safelyParseFloat(int fd, int index, const std::string& s, float* out) {
+    if (!android::base::ParseFloat(s, out)) {
+        dprintf(fd, "non-float argument at index %d: %s\n", index, s.c_str());
+        return false;
+    }
+    return true;
+}
+
 void VehicleHalManager::cmdHelp(int fd) const {
     dprintf(fd, "Usage: \n\n");
     dprintf(fd, "[no args]: dumps (id and value) all supported properties \n");
     dprintf(fd, "--help: shows this help\n");
     dprintf(fd, "--list: lists the ids of all supported properties\n");
     dprintf(fd, "--get <PROP1> [PROP2] [PROPN]: dumps the value of specific properties \n");
-    // TODO: support other formats (int64, float, bytes)
     dprintf(fd,
-            "--set <PROP> <i|s> <VALUE_1> [<i|s> <VALUE_N>] [a AREA_ID] : sets the value of "
-            "property PROP, using arbitrary number of key/value parameters (i for int32, "
-            "s for string) and an optional area.\n"
-            "Notice that the string value can be set just once, while the other can have multiple "
-            "values (so they're used in the respective array)\n");
+            "--set <PROP> [-i INT_VALUE [INT_VALUE ...]] [-i64 INT64_VALUE [INT64_VALUE ...]] "
+            "[-f FLOAT_VALUE [FLOAT_VALUE ...]] [-s STR_VALUE] "
+            "[-b BYTES_VALUE] [-a AREA_ID] : sets the value of property PROP. "
+            "Notice that the string, bytes and area value can be set just once, while the other can"
+            " have multiple values (so they're used in the respective array), "
+            "BYTES_VALUE is in the form of 0xXXXX, e.g. 0xdeadbeef.\n");
 }
 
 void VehicleHalManager::cmdListAllProperties(int fd) const {
@@ -337,102 +372,49 @@
     VehiclePropValue input;
     input.prop = prop;
     input.areaId = areaId;
-    auto callback = [&](StatusCode status, const VehiclePropValue& output) {
+    auto callback = [&fd, &prop](StatusCode status, const VehiclePropValue& output) {
         if (status == StatusCode::OK) {
             dprintf(fd, "%s\n", toString(output).c_str());
         } else {
             dprintf(fd, "Could not get property %d. Error: %s\n", prop, toString(status).c_str());
         }
     };
-    get(input, callback);
+
+    StatusCode status;
+    auto value = mHal->get(input, &status);
+    callback(status, value.get() ? *value : kEmptyValue);
 }
 
-void VehicleHalManager::cmdSetOneProperty(int fd, const hidl_vec<hidl_string>& options) {
-    if (!checkCallerHasWritePermissions(fd) || !checkArgumentsSize(fd, options, 3)) return;
-
-    size_t size = options.size();
-
-    // Syntax is --set PROP Type1 Value1 TypeN ValueN, so number of arguments must be even
-    if (size % 2 != 0) {
-        dprintf(fd, "must pass even number of arguments (passed %zu)\n", size);
-        return;
+bool VehicleHalManager::cmdSetOneProperty(int fd, const hidl_vec<hidl_string>& options) {
+    if (!checkArgumentsSize(fd, options, 4)) {
+        dprintf(fd, "Requires at least 4 options, see help\n");
+        return false;
     }
-    int numberValues = (size - 2) / 2;
 
-    VehiclePropValue prop;
-    if (!safelyParseInt(fd, 1, options[1], &prop.prop)) return;
-    prop.timestamp = elapsedRealtimeNano();
-    prop.status = VehiclePropertyStatus::AVAILABLE;
-
-    // First pass: calculate sizes
-    int sizeInt32 = 0;
-    int stringIndex = 0;
-    int areaIndex = 0;
-    for (int i = 2, kv = 1; kv <= numberValues; kv++) {
-        // iterate through the kv=1..n key/value pairs, accessing indexes i / i+1 at each step
-        std::string type = options[i];
-        std::string value = options[i + 1];
-        if (EqualsIgnoreCase(type, "i")) {
-            sizeInt32++;
-        } else if (EqualsIgnoreCase(type, "s")) {
-            if (stringIndex != 0) {
-                dprintf(fd,
-                        "defining string value (%s) again at index %d (already defined at %d=%s"
-                        ")\n",
-                        value.c_str(), i, stringIndex, options[stringIndex + 1].c_str());
-                return;
-            }
-            stringIndex = i;
-        } else if (EqualsIgnoreCase(type, "a")) {
-            if (areaIndex != 0) {
-                dprintf(fd,
-                        "defining area value (%s) again at index %d (already defined at %d=%s"
-                        ")\n",
-                        value.c_str(), i, areaIndex, options[areaIndex + 1].c_str());
-                return;
-            }
-            areaIndex = i;
-        } else {
-            dprintf(fd, "invalid (%s) type at index %d\n", type.c_str(), i);
-            return;
-        }
-        i += 2;
-    }
-    prop.value.int32Values.resize(sizeInt32);
-
-    // Second pass: populate it
-    int indexInt32 = 0;
-    for (int i = 2, kv = 1; kv <= numberValues; kv++) {
-        // iterate through the kv=1..n key/value pairs, accessing indexes i / i+1 at each step
-        int valueIndex = i + 1;
-        std::string type = options[i];
-        std::string value = options[valueIndex];
-        if (EqualsIgnoreCase(type, "i")) {
-            int safeInt;
-            if (!safelyParseInt(fd, valueIndex, value, &safeInt)) return;
-            prop.value.int32Values[indexInt32++] = safeInt;
-        } else if (EqualsIgnoreCase(type, "s")) {
-            prop.value.stringValue = value;
-        } else if (EqualsIgnoreCase(type, "a")) {
-            if (!safelyParseInt(fd, valueIndex, value, &prop.areaId)) return;
-        }
-        i += 2;
+    VehiclePropValue prop = {};
+    if (!parseSetPropOptions(fd, options, &prop)) {
+        return false;
     }
     ALOGD("Setting prop %s", toString(prop).c_str());
-    auto status = set(prop);
+
+    // Do not use VehicleHalManager::set here because we don't want to check write permission.
+    // Caller should be able to use the debug interface to set read-only properties.
+    handlePropertySetEvent(prop);
+    auto status = mHal->set(prop);
+
     if (status == StatusCode::OK) {
         dprintf(fd, "Set property %s\n", toString(prop).c_str());
-    } else {
-        dprintf(fd, "Failed to set property %s: %s\n", toString(prop).c_str(),
-                toString(status).c_str());
+        return true;
     }
+    dprintf(fd, "Failed to set property %s: %s\n", toString(prop).c_str(),
+            toString(status).c_str());
+    return false;
 }
 
 void VehicleHalManager::init() {
     ALOGI("VehicleHalManager::init");
 
-    mHidlVecOfVehiclePropValuePool.resize(kMaxHidlVecOfVehiclPropValuePoolSize);
-
+    mHidlVecOfVehiclePropValuePool.resize(kMaxHidlVecOfVehiclePropValuePoolSize);
 
     mBatchingConsumer.run(&mEventQueue,
                           kHalEventBatchingTimeWindow,
@@ -486,7 +468,7 @@
     for (const HalClientValues& cv : clientValues) {
         auto vecSize = cv.values.size();
         hidl_vec<VehiclePropValue> vec;
-        if (vecSize < kMaxHidlVecOfVehiclPropValuePoolSize) {
+        if (vecSize < kMaxHidlVecOfVehiclePropValuePoolSize) {
             vec.setToExternal(&mHidlVecOfVehiclePropValuePool[0], vecSize);
         } else {
             vec.resize(vecSize);
@@ -595,6 +577,158 @@
     }
 }
 
+std::vector<std::string> VehicleHalManager::getOptionValues(const hidl_vec<hidl_string>& options,
+                                                            size_t* index) {
+    std::vector<std::string> values;
+    while (*index < options.size()) {
+        std::string option = options[*index];
+        if (kSetPropOptions.find(option) != kSetPropOptions.end()) {
+            return std::move(values);
+        }
+        values.push_back(option);
+        (*index)++;
+    }
+    return std::move(values);
+}
+
+bool VehicleHalManager::parseSetPropOptions(int fd, const hidl_vec<hidl_string>& options,
+                                            VehiclePropValue* prop) {
+    // Options format:
+    // --set PROP [-f f1 f2...] [-i i1 i2...] [-i64 i1 i2...] [-s s1 s2...] [-b b1 b2...] [-a a]
+    size_t optionIndex = 1;
+    int propValue;
+    if (!safelyParseInt(fd, optionIndex, options[optionIndex], &propValue)) {
+        dprintf(fd, "property value: \"%s\" is not a valid int\n", options[optionIndex].c_str());
+        return false;
+    }
+    prop->prop = propValue;
+    prop->timestamp = elapsedRealtimeNano();
+    prop->status = VehiclePropertyStatus::AVAILABLE;
+    optionIndex++;
+    std::unordered_set<std::string> parsedOptions;
+
+    while (optionIndex < options.size()) {
+        std::string type = options[optionIndex];
+        optionIndex++;
+        size_t currentIndex = optionIndex;
+        std::vector<std::string> values = getOptionValues(options, &optionIndex);
+        if (parsedOptions.find(type) != parsedOptions.end()) {
+            dprintf(fd, "duplicate \"%s\" options\n", type.c_str());
+            return false;
+        }
+        parsedOptions.insert(type);
+        if (EqualsIgnoreCase(type, "-i")) {
+            if (values.size() == 0) {
+                dprintf(fd, "no values specified when using \"-i\"\n");
+                return false;
+            }
+            prop->value.int32Values.resize(values.size());
+            for (size_t i = 0; i < values.size(); i++) {
+                int32_t safeInt;
+                if (!safelyParseInt(fd, currentIndex + i, values[i], &safeInt)) {
+                    dprintf(fd, "value: \"%s\" is not a valid int\n", values[i].c_str());
+                    return false;
+                }
+                prop->value.int32Values[i] = safeInt;
+            }
+        } else if (EqualsIgnoreCase(type, "-i64")) {
+            if (values.size() == 0) {
+                dprintf(fd, "no values specified when using \"-i64\"\n");
+                return false;
+            }
+            prop->value.int64Values.resize(values.size());
+            for (size_t i = 0; i < values.size(); i++) {
+                int64_t safeInt;
+                if (!safelyParseInt(fd, currentIndex + i, values[i], &safeInt)) {
+                    dprintf(fd, "value: \"%s\" is not a valid int64\n", values[i].c_str());
+                    return false;
+                }
+                prop->value.int64Values[i] = safeInt;
+            }
+        } else if (EqualsIgnoreCase(type, "-f")) {
+            if (values.size() == 0) {
+                dprintf(fd, "no values specified when using \"-f\"\n");
+                return false;
+            }
+            prop->value.floatValues.resize(values.size());
+            for (size_t i = 0; i < values.size(); i++) {
+                float safeFloat;
+                if (!safelyParseFloat(fd, currentIndex + i, values[i], &safeFloat)) {
+                    dprintf(fd, "value: \"%s\" is not a valid float\n", values[i].c_str());
+                    return false;
+                }
+                prop->value.floatValues[i] = safeFloat;
+            }
+        } else if (EqualsIgnoreCase(type, "-s")) {
+            if (values.size() != 1) {
+                dprintf(fd, "expect exact one value when using \"-s\"\n");
+                return false;
+            }
+            prop->value.stringValue = values[0];
+        } else if (EqualsIgnoreCase(type, "-b")) {
+            if (values.size() != 1) {
+                dprintf(fd, "expect exact one value when using \"-b\"\n");
+                return false;
+            }
+            std::vector<uint8_t> bytes;
+            if (!parseHexString(fd, values[0], &bytes)) {
+                dprintf(fd, "value: \"%s\" is not a valid hex string\n", values[0].c_str());
+                return false;
+            }
+            prop->value.bytes = bytes;
+        } else if (EqualsIgnoreCase(type, "-a")) {
+            if (values.size() != 1) {
+                dprintf(fd, "expect exact one value when using \"-a\"\n");
+                return false;
+            }
+            if (!safelyParseInt(fd, currentIndex, values[0], &(prop->areaId))) {
+                dprintf(fd, "area ID: \"%s\" is not a valid int\n", values[0].c_str());
+                return false;
+            }
+        } else {
+            dprintf(fd, "unknown option: %s\n", type.c_str());
+            return false;
+        }
+    }
+
+    return true;
+}
+
+bool VehicleHalManager::parseHexString(int fd, const std::string& s, std::vector<uint8_t>* bytes) {
+    if (s.size() % 2 != 0) {
+        dprintf(fd, "invalid hex string: %s, should have even size\n", s.c_str());
+        return false;
+    }
+    if (strncmp(s.substr(0, 2).c_str(), "0x", 2)) {
+        dprintf(fd, "hex string should start with \"0x\", got %s\n", s.c_str());
+        return false;
+    }
+    std::string subs = s.substr(2);
+    std::transform(subs.begin(), subs.end(), subs.begin(),
+                   [](unsigned char c) { return std::tolower(c); });
+
+    bool highDigit = true;
+    for (size_t i = 0; i < subs.size(); i++) {
+        char c = subs[i];
+        uint8_t v;
+        if (c >= '0' && c <= '9') {
+            v = c - '0';
+        } else if (c >= 'a' && c <= 'f') {
+            v = c - 'a' + 10;
+        } else {
+            dprintf(fd, "invalid character %c in hex string %s\n", c, subs.c_str());
+            return false;
+        }
+        if (highDigit) {
+            (*bytes).push_back(v * 16);
+        } else {
+            (*bytes)[bytes->size() - 1] += v;
+        }
+        highDigit = !highDigit;
+    }
+    return true;
+}
+
 }  // namespace V2_0
 }  // namespace vehicle
 }  // namespace automotive
diff --git a/automotive/vehicle/2.0/default/tests/RecurrentTimer_test.cpp b/automotive/vehicle/2.0/default/tests/RecurrentTimer_test.cpp
index 9fc17c6..d7547f6 100644
--- a/automotive/vehicle/2.0/default/tests/RecurrentTimer_test.cpp
+++ b/automotive/vehicle/2.0/default/tests/RecurrentTimer_test.cpp
@@ -41,7 +41,8 @@
 
     timer.registerRecurrentEvent(milliseconds(1), 0xdead);
     std::this_thread::sleep_for(milliseconds(100));
-    ASSERT_EQ_WITH_TOLERANCE(100, counter.load(), 20);
+    // This test is unstable, so set the tolerance to 50.
+    ASSERT_EQ_WITH_TOLERANCE(100, counter.load(), 50);
 }
 
 TEST(RecurrentTimerTest, multipleIntervals) {
@@ -66,7 +67,8 @@
     timer.registerRecurrentEvent(milliseconds(5), 0xbeef);
 
     std::this_thread::sleep_for(milliseconds(100));
-    ASSERT_EQ_WITH_TOLERANCE(100, counter1ms.load(), 20);
+    // This test is unstable, so set the tolerance to 50.
+    ASSERT_EQ_WITH_TOLERANCE(100, counter1ms.load(), 50);
     ASSERT_EQ_WITH_TOLERANCE(20, counter5ms.load(), 5);
 }
 
diff --git a/automotive/vehicle/2.0/default/tests/VehicleHalManager_test.cpp b/automotive/vehicle/2.0/default/tests/VehicleHalManager_test.cpp
index 0975071..bdf46fb 100644
--- a/automotive/vehicle/2.0/default/tests/VehicleHalManager_test.cpp
+++ b/automotive/vehicle/2.0/default/tests/VehicleHalManager_test.cpp
@@ -18,6 +18,7 @@
 #include <iostream>
 
 #include <android-base/macros.h>
+#include <cutils/native_handle.h>
 #include <utils/SystemClock.h>
 
 #include <gtest/gtest.h>
@@ -32,6 +33,18 @@
 namespace vehicle {
 namespace V2_0 {
 
+// A simple helper class to expose 'cmdSetOneProperty' to the unit tests.
+class VehicleHalManagerTestHelper {
+  public:
+    VehicleHalManagerTestHelper(VehicleHalManager* manager) { mManager = manager; }
+    bool cmdSetOneProperty(int fd, const hidl_vec<hidl_string>& options) {
+        return mManager->cmdSetOneProperty(fd, options);
+    }
+
+  public:
+    VehicleHalManager* mManager;
+};
+
 namespace {
 
 using namespace std::placeholders;
@@ -57,33 +70,21 @@
         auto property = static_cast<VehicleProperty>(requestedPropValue.prop);
         int32_t areaId = requestedPropValue.areaId;
 
-        switch (property) {
-            case VehicleProperty::INFO_MAKE:
-                pValue = getValuePool()->obtainString(kCarMake);
-                break;
-            case VehicleProperty::INFO_FUEL_CAPACITY:
-                if (fuelCapacityAttemptsLeft-- > 0) {
-                    // Emulate property not ready yet.
-                    *outStatus = StatusCode::TRY_AGAIN;
-                } else {
-                    pValue = getValuePool()->obtainFloat(42.42);
-                }
-                break;
-            default:
-                if (requestedPropValue.prop == kCustomComplexProperty) {
-                    pValue = getValuePool()->obtainComplex();
-                    pValue->value.int32Values = hidl_vec<int32_t> { 10, 20 };
-                    pValue->value.int64Values = hidl_vec<int64_t> { 30, 40 };
-                    pValue->value.floatValues = hidl_vec<float_t> { 1.1, 2.2 };
-                    pValue->value.bytes = hidl_vec<uint8_t> { 1, 2, 3 };
-                    pValue->value.stringValue = kCarMake;
-                    break;
-                }
-                auto key = makeKey(toInt(property), areaId);
-                if (mValues.count(key) == 0) {
-                    ALOGW("");
-                }
-                pValue = getValuePool()->obtain(mValues[key]);
+        if (property == VehicleProperty::INFO_FUEL_CAPACITY) {
+            if (fuelCapacityAttemptsLeft-- > 0) {
+                // Emulate property not ready yet.
+                *outStatus = StatusCode::TRY_AGAIN;
+            } else {
+                pValue = getValuePool()->obtainFloat(42.42);
+            }
+        } else {
+            auto key = makeKey(requestedPropValue);
+            if (mValues.count(key) == 0) {
+                ALOGW("key not found\n");
+                *outStatus = StatusCode::INVALID_ARG;
+                return pValue;
+            }
+            pValue = getValuePool()->obtain(mValues[key]);
         }
 
         if (*outStatus == StatusCode::OK && pValue.get() != nullptr) {
@@ -100,7 +101,6 @@
                 && mirrorFoldAttemptsLeft-- > 0) {
             return StatusCode::TRY_AGAIN;
         }
-
         mValues[makeKey(propValue)] = propValue;
         return StatusCode::OK;
     }
@@ -181,6 +181,18 @@
         actualStatusCode = refStatus;
     }
 
+    MockedVehicleHal::VehiclePropValuePtr getComplexProperty() {
+        auto pValue = objectPool->obtainComplex();
+        pValue->prop = kCustomComplexProperty;
+        pValue->areaId = 0;
+        pValue->value.int32Values = hidl_vec<int32_t>{10, 20};
+        pValue->value.int64Values = hidl_vec<int64_t>{30, 40};
+        pValue->value.floatValues = hidl_vec<float_t>{1.1, 2.2};
+        pValue->value.bytes = hidl_vec<uint8_t>{1, 2, 3};
+        pValue->value.stringValue = kCarMake;
+        return pValue;
+    }
+
 public:
     VehiclePropValue actualValue;
     StatusCode actualStatusCode;
@@ -308,6 +320,8 @@
 }
 
 TEST_F(VehicleHalManagerTest, get_Complex) {
+    ASSERT_EQ(StatusCode::OK, hal->set(*getComplexProperty().get()));
+
     invokeGet(kCustomComplexProperty, 0);
 
     ASSERT_EQ(StatusCode::OK, actualStatusCode);
@@ -334,6 +348,11 @@
 }
 
 TEST_F(VehicleHalManagerTest, get_StaticString) {
+    auto pValue = objectPool->obtainString(kCarMake);
+    pValue->prop = toInt(VehicleProperty::INFO_MAKE);
+    pValue->areaId = 0;
+    ASSERT_EQ(StatusCode::OK, hal->set(*pValue.get()));
+
     invokeGet(toInt(VehicleProperty::INFO_MAKE), 0);
 
     ASSERT_EQ(StatusCode::OK, actualStatusCode);
@@ -458,6 +477,138 @@
     ASSERT_TRUE(clients.isEmpty());
 }
 
+TEST_F(VehicleHalManagerTest, debug) {
+    hidl_handle fd = {};
+    fd.setTo(native_handle_create(/*numFds=*/1, /*numInts=*/0), /*shouldOwn=*/true);
+
+    // Because debug function returns void, so no way to check return value.
+    manager->debug(fd, {});
+    manager->debug(fd, {"--help"});
+    manager->debug(fd, {"--list"});
+    manager->debug(fd, {"--get"});
+    manager->debug(fd, {"--set"});
+    manager->debug(fd, {"invalid"});
+}
+
+struct SetPropTestCase {
+    std::string test_name;
+    const hidl_vec<hidl_string> configs;
+    bool success;
+};
+
+class VehicleHalManagerSetPropTest : public VehicleHalManagerTest,
+                                     public testing::WithParamInterface<SetPropTestCase> {};
+
+TEST_P(VehicleHalManagerSetPropTest, cmdSetOneProperty) {
+    const SetPropTestCase& tc = GetParam();
+    VehicleHalManagerTestHelper helper(manager.get());
+    ASSERT_EQ(tc.success, helper.cmdSetOneProperty(STDERR_FILENO, tc.configs));
+}
+
+std::vector<SetPropTestCase> GenSetPropParams() {
+    char infoMakeProperty[100] = {};
+    snprintf(infoMakeProperty, sizeof(infoMakeProperty), "%d", toInt(VehicleProperty::INFO_MAKE));
+    return {
+            {"success_set_string", {"--set", infoMakeProperty, "-s", kCarMake}, true},
+            {"success_set_bytes", {"--set", infoMakeProperty, "-b", "0xdeadbeef"}, true},
+            {"success_set_bytes_caps", {"--set", infoMakeProperty, "-b", "0xDEADBEEF"}, true},
+            {"success_set_int", {"--set", infoMakeProperty, "-i", "2147483647"}, true},
+            {"success_set_ints",
+             {"--set", infoMakeProperty, "-i", "2147483647", "0", "-2147483648"},
+             true},
+            {"success_set_int64",
+             {"--set", infoMakeProperty, "-i64", "-9223372036854775808"},
+             true},
+            {"success_set_int64s",
+             {"--set", infoMakeProperty, "-i64", "-9223372036854775808", "0",
+              "9223372036854775807"},
+             true},
+            {"success_set_float", {"--set", infoMakeProperty, "-f", "1.175494351E-38"}, true},
+            {"success_set_floats",
+             {"--set", infoMakeProperty, "-f", "-3.402823466E+38", "0", "3.402823466E+38"},
+             true},
+            {"success_set_area", {"--set", infoMakeProperty, "-a", "2147483647"}, true},
+            {"fail_no_options", {}, false},
+            {"fail_less_than_4_options", {"--set", infoMakeProperty, "-i"}, false},
+            {"fail_unknown_options", {"--set", infoMakeProperty, "-s", kCarMake, "-abcd"}, false},
+            {"fail_invalid_property", {"--set", "not valid", "-s", kCarMake}, false},
+            {"fail_duplicate_string",
+             {"--set", infoMakeProperty, "-s", kCarMake, "-s", kCarMake},
+             false},
+            {"fail_multiple_strings", {"--set", infoMakeProperty, "-s", kCarMake, kCarMake}, false},
+            {"fail_no_string_value", {"--set", infoMakeProperty, "-s", "-a", "1234"}, false},
+            {"fail_duplicate_bytes",
+             {"--set", infoMakeProperty, "-b", "0xdeadbeef", "-b", "0xdeadbeef"},
+             false},
+            {"fail_multiple_bytes",
+             {"--set", infoMakeProperty, "-b", "0xdeadbeef", "0xdeadbeef"},
+             false},
+            {"fail_invalid_bytes", {"--set", infoMakeProperty, "-b", "0xgood"}, false},
+            {"fail_invalid_bytes_no_prefix", {"--set", infoMakeProperty, "-b", "deadbeef"}, false},
+            {"fail_invalid_int", {"--set", infoMakeProperty, "-i", "abc"}, false},
+            {"fail_int_out_of_range", {"--set", infoMakeProperty, "-i", "2147483648"}, false},
+            {"fail_no_int_value", {"--set", infoMakeProperty, "-i", "-s", kCarMake}, false},
+            {"fail_invalid_int64", {"--set", infoMakeProperty, "-i64", "abc"}, false},
+            {"fail_int64_out_of_range",
+             {"--set", infoMakeProperty, "-i64", "-9223372036854775809"},
+             false},
+            {"fail_no_int64_value", {"--set", infoMakeProperty, "-i64", "-s", kCarMake}, false},
+            {"fail_invalid_float", {"--set", infoMakeProperty, "-f", "abc"}, false},
+            {"fail_float_out_of_range",
+             {"--set", infoMakeProperty, "-f", "-3.402823466E+39"},
+             false},
+            {"fail_no_float_value", {"--set", infoMakeProperty, "-f", "-s", kCarMake}, false},
+            {"fail_multiple_areas", {"--set", infoMakeProperty, "-a", "2147483648", "0"}, false},
+            {"fail_invalid_area", {"--set", infoMakeProperty, "-a", "abc"}, false},
+            {"fail_area_out_of_range", {"--set", infoMakeProperty, "-a", "2147483648"}, false},
+            {"fail_no_area_value", {"--set", infoMakeProperty, "-a", "-s", kCarMake}, false},
+    };
+}
+
+INSTANTIATE_TEST_SUITE_P(
+        VehicleHalManagerSetPropTests, VehicleHalManagerSetPropTest,
+        testing::ValuesIn(GenSetPropParams()),
+        [](const testing::TestParamInfo<VehicleHalManagerSetPropTest::ParamType>& info) {
+            return info.param.test_name;
+        });
+
+TEST_F(VehicleHalManagerTest, SetComplexPropTest) {
+    char infoMakeProperty[100] = {};
+    snprintf(infoMakeProperty, sizeof(infoMakeProperty), "%d", toInt(VehicleProperty::INFO_MAKE));
+    VehicleHalManagerTestHelper helper(manager.get());
+    ASSERT_TRUE(helper.cmdSetOneProperty(
+            STDERR_FILENO, {"--set", infoMakeProperty,      "-s",   kCarMake,
+                            "-b",    "0xdeadbeef",          "-i",   "2147483647",
+                            "0",     "-2147483648",         "-i64", "-9223372036854775808",
+                            "0",     "9223372036854775807", "-f",   "-3.402823466E+38",
+                            "0",     "3.402823466E+38",     "-a",   "123"}));
+    StatusCode status = StatusCode::OK;
+    VehiclePropValue requestProp;
+    requestProp.prop = toInt(VehicleProperty::INFO_MAKE);
+    requestProp.areaId = 123;
+    auto value = hal->get(requestProp, &status);
+    ASSERT_EQ(StatusCode::OK, status);
+    ASSERT_EQ(value->prop, toInt(VehicleProperty::INFO_MAKE));
+    ASSERT_EQ(value->areaId, 123);
+    ASSERT_STREQ(kCarMake, value->value.stringValue.c_str());
+    uint8_t bytes[] = {0xde, 0xad, 0xbe, 0xef};
+    ASSERT_FALSE(memcmp(bytes, value->value.bytes.data(), sizeof(bytes)));
+    ASSERT_EQ(3u, value->value.int32Values.size());
+    ASSERT_EQ(2147483647, value->value.int32Values[0]);
+    ASSERT_EQ(0, value->value.int32Values[1]);
+    ASSERT_EQ(-2147483648, value->value.int32Values[2]);
+    ASSERT_EQ(3u, value->value.int64Values.size());
+    // -9223372036854775808 is not a valid literal since '-' and '9223372036854775808' would be two
+    // tokens and the later does not fit in unsigned long long.
+    ASSERT_EQ(-9223372036854775807 - 1, value->value.int64Values[0]);
+    ASSERT_EQ(0, value->value.int64Values[1]);
+    ASSERT_EQ(9223372036854775807, value->value.int64Values[2]);
+    ASSERT_EQ(3u, value->value.floatValues.size());
+    ASSERT_EQ(-3.402823466E+38f, value->value.floatValues[0]);
+    ASSERT_EQ(0.0f, value->value.floatValues[1]);
+    ASSERT_EQ(3.402823466E+38f, value->value.floatValues[2]);
+}
+
 }  // namespace anonymous
 
 }  // namespace V2_0
diff --git a/automotive/vehicle/2.0/default/tests/VehicleObjectPool_test.cpp b/automotive/vehicle/2.0/default/tests/VehicleObjectPool_test.cpp
index 4e3ade1..0968166 100644
--- a/automotive/vehicle/2.0/default/tests/VehicleObjectPool_test.cpp
+++ b/automotive/vehicle/2.0/default/tests/VehicleObjectPool_test.cpp
@@ -58,10 +58,12 @@
 
 TEST_F(VehicleObjectPoolTest, valuePoolBasicCorrectness) {
     auto value = valuePool->obtain(VehiclePropertyType::INT32);
-    // At this point, v1 should be recycled and the only object in the pool.
-    ASSERT_EQ(value.get(), valuePool->obtain(VehiclePropertyType::INT32).get());
+    void* raw = value.get();
+    value.reset();
+    // At this point, value should be recycled and the only object in the pool.
+    ASSERT_EQ(raw, valuePool->obtain(VehiclePropertyType::INT32).get());
     // Obtaining value of another type - should return a new object
-    ASSERT_NE(value.get(), valuePool->obtain(VehiclePropertyType::FLOAT).get());
+    ASSERT_NE(raw, valuePool->obtain(VehiclePropertyType::FLOAT).get());
 
     ASSERT_EQ(3u, stats->Obtained);
     ASSERT_EQ(2u, stats->Created);
diff --git a/automotive/vehicle/aidl/Android.bp b/automotive/vehicle/aidl/Android.bp
new file mode 100644
index 0000000..56a85b9
--- /dev/null
+++ b/automotive/vehicle/aidl/Android.bp
@@ -0,0 +1,40 @@
+// Copyright (C) 2021 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.
+
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "hardware_interfaces_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["hardware_interfaces_license"],
+}
+
+aidl_interface {
+    name: "android.hardware.automotive.vehicle",
+    vendor_available: true,
+    srcs: [
+        "android/hardware/automotive/vehicle/**/*.aidl",
+    ],
+    // TODO(b/148703287) Make it stable with new APIs
+    unstable: true,
+    backend: {
+        cpp: {
+            enabled: true,
+        },
+        java: {
+            enabled: true,
+        },
+    },
+}
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/CreateUserRequest.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/CreateUserRequest.aidl
new file mode 100644
index 0000000..95537dc
--- /dev/null
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/CreateUserRequest.aidl
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+package android.hardware.automotive.vehicle;
+
+import android.hardware.automotive.vehicle.UserInfo;
+import android.hardware.automotive.vehicle.UsersInfo;
+
+/**
+ * Defines the format of a CREATE_USER property.
+ *
+ * NOTE: this struct is not used in the HAL properties directly, it must be converted to
+ * VehiclePropValue.RawValue through libraries provided by the default Vehicle HAL implementation.
+ */
+// @VintfStability
+parcelable CreateUserRequest {
+    /**
+     * Arbitrary id used to map the response to the request.
+     */
+    int requestId;
+    /**
+     * Basic information about Android user that was created.
+     */
+    UserInfo newUserInfo;
+    /**
+     * Name of the new Android user.
+     */
+    @utf8InCpp String newUserName;
+    /**
+     * Information about the current state of the Android system.
+     */
+    UsersInfo usersInfo;
+}
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/CreateUserResponse.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/CreateUserResponse.aidl
new file mode 100644
index 0000000..0588052
--- /dev/null
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/CreateUserResponse.aidl
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+package android.hardware.automotive.vehicle;
+
+import android.hardware.automotive.vehicle.CreateUserStatus;
+
+/**
+ * Defines the result of a CreateUserRequest.
+ *
+ * NOTE: this struct is not used in the HAL properties directly, it must be converted to
+ * VehiclePropValue.RawValue through libraries provided by the default Vehicle HAL implementation.
+ */
+// @VintfStability
+parcelable CreateUserResponse {
+    /**
+     * Id of the request being responded.
+     */
+    int requestId;
+    /**
+     * Status of the request.
+     */
+    CreateUserStatus status;
+    /**
+     * HAL-specific error message.
+     *
+     * This argument is optional, and when defined, it's passed "as-is" to the caller. It could be
+     * used to show custom error messages to the end user.
+     */
+    @utf8InCpp String errorMessage;
+}
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/CreateUserStatus.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/CreateUserStatus.aidl
new file mode 100644
index 0000000..f841ff6
--- /dev/null
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/CreateUserStatus.aidl
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+package android.hardware.automotive.vehicle;
+
+/**
+ * Status of the response to a CreateUserRequest.
+ */
+// @VintfStability
+@Backing(type="int")
+enum CreateUserStatus {
+    /**
+     * The request succeeded (for example, HAL created a new internal user, or associated the
+     * Android user to an existing internal user).
+     */
+    SUCCESS = 1,
+    /**
+     * The request failed (and Android will remove the Android user).
+     */
+    FAILURE = 2,
+}
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/CustomInputType.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/CustomInputType.aidl
new file mode 100644
index 0000000..1335eea
--- /dev/null
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/CustomInputType.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+package android.hardware.automotive.vehicle;
+
+/**
+ * Input code values for HW_CUSTOM_INPUT.
+ */
+// @VintfStability
+@Backing(type="int")
+enum CustomInputType {
+    /**
+     * Ten functions representing the custom input code to be defined and implemented by OEM
+     * partners.
+     *
+     * OEMs need to formally contact Android team if more than 10 functions are required.
+     */
+    CUSTOM_EVENT_F1 = 1001,
+    CUSTOM_EVENT_F2 = 1002,
+    CUSTOM_EVENT_F3 = 1003,
+    CUSTOM_EVENT_F4 = 1004,
+    CUSTOM_EVENT_F5 = 1005,
+    CUSTOM_EVENT_F6 = 1006,
+    CUSTOM_EVENT_F7 = 1007,
+    CUSTOM_EVENT_F8 = 1008,
+    CUSTOM_EVENT_F9 = 1009,
+    CUSTOM_EVENT_F10 = 1010,
+}
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/DiagnosticFloatSensorIndex.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/DiagnosticFloatSensorIndex.aidl
new file mode 100644
index 0000000..017589f
--- /dev/null
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/DiagnosticFloatSensorIndex.aidl
@@ -0,0 +1,314 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+package android.hardware.automotive.vehicle;
+
+/**
+ * This enum provides the canonical mapping for sensor properties that have a floating-point value.
+ * The ordering of the values is taken from the OBD2 specification.
+ * Any value greater than the last reserved index is available to vendors to map their extensions.
+ * While these values do not directly map to SAE J1979 PIDs, an equivalence is listed next
+ * to each one to aid implementors.
+ */
+// @VintfStability
+@Backing(type="int")
+enum DiagnosticFloatSensorIndex {
+    CALCULATED_ENGINE_LOAD = 0,
+    /*
+     * PID 0x04
+     */
+    ENGINE_COOLANT_TEMPERATURE = 1,
+    /*
+     * PID 0x05
+     */
+    SHORT_TERM_FUEL_TRIM_BANK1 = 2,
+    /*
+     * PID 0x06
+     */
+    LONG_TERM_FUEL_TRIM_BANK1 = 3,
+    /*
+     * PID 0x07
+     */
+    SHORT_TERM_FUEL_TRIM_BANK2 = 4,
+    /*
+     * PID 0x08
+     */
+    LONG_TERM_FUEL_TRIM_BANK2 = 5,
+    /*
+     * PID 0x09
+     */
+    FUEL_PRESSURE = 6,
+    /*
+     * PID 0x0A
+     */
+    INTAKE_MANIFOLD_ABSOLUTE_PRESSURE = 7,
+    /*
+     * PID 0x0B
+     */
+    ENGINE_RPM = 8,
+    /*
+     * PID 0x0C
+     */
+    VEHICLE_SPEED = 9,
+    /*
+     * PID 0x0D
+     */
+    TIMING_ADVANCE = 10,
+    /*
+     * PID 0x0E
+     */
+    MAF_AIR_FLOW_RATE = 11,
+    /*
+     * PID 0x10
+     */
+    THROTTLE_POSITION = 12,
+    /*
+     * PID 0x11
+     */
+    OXYGEN_SENSOR1_VOLTAGE = 13,
+    /*
+     * PID 0x14
+     */
+    OXYGEN_SENSOR1_SHORT_TERM_FUEL_TRIM = 14,
+    /*
+     * PID 0x14
+     */
+    OXYGEN_SENSOR1_FUEL_AIR_EQUIVALENCE_RATIO = 15,
+    /*
+     * PID 0x24
+     */
+    OXYGEN_SENSOR2_VOLTAGE = 16,
+    /*
+     * PID 0x15
+     */
+    OXYGEN_SENSOR2_SHORT_TERM_FUEL_TRIM = 17,
+    /*
+     * PID 0x15
+     */
+    OXYGEN_SENSOR2_FUEL_AIR_EQUIVALENCE_RATIO = 18,
+    /*
+     * PID 0x25
+     */
+    OXYGEN_SENSOR3_VOLTAGE = 19,
+    /*
+     * PID 0x16
+     */
+    OXYGEN_SENSOR3_SHORT_TERM_FUEL_TRIM = 20,
+    /*
+     * PID 0x16
+     */
+    OXYGEN_SENSOR3_FUEL_AIR_EQUIVALENCE_RATIO = 21,
+    /*
+     * PID 0x26
+     */
+    OXYGEN_SENSOR4_VOLTAGE = 22,
+    /*
+     * PID 0x17
+     */
+    OXYGEN_SENSOR4_SHORT_TERM_FUEL_TRIM = 23,
+    /*
+     * PID 0x17
+     */
+    OXYGEN_SENSOR4_FUEL_AIR_EQUIVALENCE_RATIO = 24,
+    /*
+     * PID 0x27
+     */
+    OXYGEN_SENSOR5_VOLTAGE = 25,
+    /*
+     * PID 0x18
+     */
+    OXYGEN_SENSOR5_SHORT_TERM_FUEL_TRIM = 26,
+    /*
+     * PID 0x18
+     */
+    OXYGEN_SENSOR5_FUEL_AIR_EQUIVALENCE_RATIO = 27,
+    /*
+     * PID 0x28
+     */
+    OXYGEN_SENSOR6_VOLTAGE = 28,
+    /*
+     * PID 0x19
+     */
+    OXYGEN_SENSOR6_SHORT_TERM_FUEL_TRIM = 29,
+    /*
+     * PID 0x19
+     */
+    OXYGEN_SENSOR6_FUEL_AIR_EQUIVALENCE_RATIO = 30,
+    /*
+     * PID 0x29
+     */
+    OXYGEN_SENSOR7_VOLTAGE = 31,
+    /*
+     * PID 0x1A
+     */
+    OXYGEN_SENSOR7_SHORT_TERM_FUEL_TRIM = 32,
+    /*
+     * PID 0x1A
+     */
+    OXYGEN_SENSOR7_FUEL_AIR_EQUIVALENCE_RATIO = 33,
+    /*
+     * PID 0x2A
+     */
+    OXYGEN_SENSOR8_VOLTAGE = 34,
+    /*
+     * PID 0x1B
+     */
+    OXYGEN_SENSOR8_SHORT_TERM_FUEL_TRIM = 35,
+    /*
+     * PID 0x1B
+     */
+    OXYGEN_SENSOR8_FUEL_AIR_EQUIVALENCE_RATIO = 36,
+    /*
+     * PID 0x2B
+     */
+    FUEL_RAIL_PRESSURE = 37,
+    /*
+     * PID 0x22
+     */
+    FUEL_RAIL_GAUGE_PRESSURE = 38,
+    /*
+     * PID 0x23
+     */
+    COMMANDED_EXHAUST_GAS_RECIRCULATION = 39,
+    /*
+     * PID 0x2C
+     */
+    EXHAUST_GAS_RECIRCULATION_ERROR = 40,
+    /*
+     * PID 0x2D
+     */
+    COMMANDED_EVAPORATIVE_PURGE = 41,
+    /*
+     * PID 0x2E
+     */
+    FUEL_TANK_LEVEL_INPUT = 42,
+    /*
+     * PID 0x2F
+     */
+    EVAPORATION_SYSTEM_VAPOR_PRESSURE = 43,
+    /*
+     * PID 0x32
+     */
+    CATALYST_TEMPERATURE_BANK1_SENSOR1 = 44,
+    /*
+     * PID 0x3C
+     */
+    CATALYST_TEMPERATURE_BANK2_SENSOR1 = 45,
+    /*
+     * PID 0x3D
+     */
+    CATALYST_TEMPERATURE_BANK1_SENSOR2 = 46,
+    /*
+     * PID 0x3E
+     */
+    CATALYST_TEMPERATURE_BANK2_SENSOR2 = 47,
+    /*
+     * PID 0x3F
+     */
+    ABSOLUTE_LOAD_VALUE = 48,
+    /*
+     * PID 0x43
+     */
+    FUEL_AIR_COMMANDED_EQUIVALENCE_RATIO = 49,
+    /*
+     * PID 0x44
+     */
+    RELATIVE_THROTTLE_POSITION = 50,
+    /*
+     * PID 0x45
+     */
+    ABSOLUTE_THROTTLE_POSITION_B = 51,
+    /*
+     * PID 0x47
+     */
+    ABSOLUTE_THROTTLE_POSITION_C = 52,
+    /*
+     * PID 0x48
+     */
+    ACCELERATOR_PEDAL_POSITION_D = 53,
+    /*
+     * PID 0x49
+     */
+    ACCELERATOR_PEDAL_POSITION_E = 54,
+    /*
+     * PID 0x4A
+     */
+    ACCELERATOR_PEDAL_POSITION_F = 55,
+    /*
+     * PID 0x4B
+     */
+    COMMANDED_THROTTLE_ACTUATOR = 56,
+    /*
+     * PID 0x4C
+     */
+    ETHANOL_FUEL_PERCENTAGE = 57,
+    /*
+     * PID 0x52
+     */
+    ABSOLUTE_EVAPORATION_SYSTEM_VAPOR_PRESSURE = 58,
+    /*
+     * PID 0x53
+     */
+    SHORT_TERM_SECONDARY_OXYGEN_SENSOR_TRIM_BANK1 = 59,
+    /*
+     * PID 0x55
+     */
+    SHORT_TERM_SECONDARY_OXYGEN_SENSOR_TRIM_BANK2 = 60,
+    /*
+     * PID 0x57
+     */
+    SHORT_TERM_SECONDARY_OXYGEN_SENSOR_TRIM_BANK3 = 61,
+    /*
+     * PID 0x55
+     */
+    SHORT_TERM_SECONDARY_OXYGEN_SENSOR_TRIM_BANK4 = 62,
+    /*
+     * PID 0x57
+     */
+    LONG_TERM_SECONDARY_OXYGEN_SENSOR_TRIM_BANK1 = 63,
+    /*
+     * PID 0x56
+     */
+    LONG_TERM_SECONDARY_OXYGEN_SENSOR_TRIM_BANK2 = 64,
+    /*
+     * PID 0x58
+     */
+    LONG_TERM_SECONDARY_OXYGEN_SENSOR_TRIM_BANK3 = 65,
+    /*
+     * PID 0x56
+     */
+    LONG_TERM_SECONDARY_OXYGEN_SENSOR_TRIM_BANK4 = 66,
+    /*
+     * PID 0x58
+     */
+    RELATIVE_ACCELERATOR_PEDAL_POSITION = 67,
+    /*
+     * PID 0x5A
+     */
+    HYBRID_BATTERY_PACK_REMAINING_LIFE = 68,
+    /*
+     * PID 0x5B
+     */
+    FUEL_INJECTION_TIMING = 69,
+    /*
+     * PID 0x5D
+     */
+    ENGINE_FUEL_RATE = 70,
+    /*
+     * PID 0x5E
+     */
+    // LAST_SYSTEM_INDEX = ENGINE_FUEL_RATE,
+}
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/DiagnosticIntegerSensorIndex.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/DiagnosticIntegerSensorIndex.aidl
new file mode 100644
index 0000000..86c8a45
--- /dev/null
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/DiagnosticIntegerSensorIndex.aidl
@@ -0,0 +1,178 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+package android.hardware.automotive.vehicle;
+
+/**
+ * This enum provides the canonical mapping for sensor properties that have an integer value.
+ * The ordering of the values is taken from the OBD2 specification.
+ * Some of the properties are represented as an integer mapping to another enum. In those cases
+ * expect a comment by the property definition describing the enum to look at for the mapping.
+ * Any value greater than the last reserved index is available to vendors to map their extensions.
+ * While these values do not directly map to SAE J1979 PIDs, an equivalence is listed next
+ * to each one to aid implementors.
+ */
+// @VintfStability
+@Backing(type="int")
+enum DiagnosticIntegerSensorIndex {
+    /**
+     * refer to FuelSystemStatus for a description of this value.
+     */
+    FUEL_SYSTEM_STATUS = 0,
+    /*
+     * PID 0x03
+     */
+    MALFUNCTION_INDICATOR_LIGHT_ON = 1,
+    /*
+     * PID 0x01
+     *
+     *
+     * refer to IgnitionMonitorKind for a description of this value.
+     */
+    IGNITION_MONITORS_SUPPORTED = 2,
+    /*
+     * PID 0x01
+     *
+     *
+     * The value of this sensor is a bitmask that specifies whether ignition-specific
+     * tests are available and whether they are complete. The semantics of the individual
+     * bits in this value are given by, respectively, SparkIgnitionMonitors and
+     * CompressionIgnitionMonitors depending on the value of IGNITION_MONITORS_SUPPORTED.
+     */
+    IGNITION_SPECIFIC_MONITORS = 3,
+    /*
+     * PID 0x01
+     */
+    INTAKE_AIR_TEMPERATURE = 4,
+    /*
+     * PID 0x0F
+     *
+     *
+     * refer to SecondaryAirStatus for a description of this value.
+     */
+    COMMANDED_SECONDARY_AIR_STATUS = 5,
+    /*
+     * PID 0x12
+     */
+    NUM_OXYGEN_SENSORS_PRESENT = 6,
+    /*
+     * PID 0x13
+     */
+    RUNTIME_SINCE_ENGINE_START = 7,
+    /*
+     * PID 0x1F
+     */
+    DISTANCE_TRAVELED_WITH_MALFUNCTION_INDICATOR_LIGHT_ON = 8,
+    /*
+     * PID 0x21
+     */
+    WARMUPS_SINCE_CODES_CLEARED = 9,
+    /*
+     * PID 0x30
+     */
+    DISTANCE_TRAVELED_SINCE_CODES_CLEARED = 10,
+    /*
+     * PID 0x31
+     */
+    ABSOLUTE_BAROMETRIC_PRESSURE = 11,
+    /*
+     * PID 0x33
+     */
+    CONTROL_MODULE_VOLTAGE = 12,
+    /*
+     * PID 0x42
+     */
+    AMBIENT_AIR_TEMPERATURE = 13,
+    /*
+     * PID 0x46
+     */
+    TIME_WITH_MALFUNCTION_LIGHT_ON = 14,
+    /*
+     * PID 0x4D
+     */
+    TIME_SINCE_TROUBLE_CODES_CLEARED = 15,
+    /*
+     * PID 0x4E
+     */
+    MAX_FUEL_AIR_EQUIVALENCE_RATIO = 16,
+    /*
+     * PID 0x4F
+     */
+    MAX_OXYGEN_SENSOR_VOLTAGE = 17,
+    /*
+     * PID 0x4F
+     */
+    MAX_OXYGEN_SENSOR_CURRENT = 18,
+    /*
+     * PID 0x4F
+     */
+    MAX_INTAKE_MANIFOLD_ABSOLUTE_PRESSURE = 19,
+    /*
+     * PID 0x4F
+     */
+    MAX_AIR_FLOW_RATE_FROM_MASS_AIR_FLOW_SENSOR = 20,
+    /*
+     * PID 0x50
+     *
+     *
+     * refer to FuelType for a description of this value.
+     */
+    FUEL_TYPE = 21,
+    /*
+     * PID 0x51
+     */
+    FUEL_RAIL_ABSOLUTE_PRESSURE = 22,
+    /*
+     * PID 0x59
+     */
+    ENGINE_OIL_TEMPERATURE = 23,
+    /*
+     * PID 0x5C
+     */
+    DRIVER_DEMAND_PERCENT_TORQUE = 24,
+    /*
+     * PID 0x61
+     */
+    ENGINE_ACTUAL_PERCENT_TORQUE = 25,
+    /*
+     * PID 0x62
+     */
+    ENGINE_REFERENCE_PERCENT_TORQUE = 26,
+    /*
+     * PID 0x63
+     */
+    ENGINE_PERCENT_TORQUE_DATA_IDLE = 27,
+    /*
+     * PID 0x64
+     */
+    ENGINE_PERCENT_TORQUE_DATA_POINT1 = 28,
+    /*
+     * PID 0x64
+     */
+    ENGINE_PERCENT_TORQUE_DATA_POINT2 = 29,
+    /*
+     * PID 0x64
+     */
+    ENGINE_PERCENT_TORQUE_DATA_POINT3 = 30,
+    /*
+     * PID 0x64
+     */
+    ENGINE_PERCENT_TORQUE_DATA_POINT4 = 31,
+    /*
+     * PID 0x64
+     */
+    // LAST_SYSTEM_INDEX = 31,
+}
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/ElectronicTollCollectionCardStatus.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/ElectronicTollCollectionCardStatus.aidl
new file mode 100644
index 0000000..cb55ffa
--- /dev/null
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/ElectronicTollCollectionCardStatus.aidl
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+package android.hardware.automotive.vehicle;
+
+/**
+ * Used by ELECTRONIC_TOLL_COLLECTION_CARD_STATUS.
+ */
+// @VintfStability
+@Backing(type="int")
+enum ElectronicTollCollectionCardStatus {
+    UNKNOWN = 0,
+    ELECTRONIC_TOLL_COLLECTION_CARD_VALID = 1,
+    ELECTRONIC_TOLL_COLLECTION_CARD_INVALID = 2,
+    ELECTRONIC_TOLL_COLLECTION_CARD_NOT_INSERTED = 3,
+}
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/ElectronicTollCollectionCardType.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/ElectronicTollCollectionCardType.aidl
new file mode 100644
index 0000000..78254fb
--- /dev/null
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/ElectronicTollCollectionCardType.aidl
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+package android.hardware.automotive.vehicle;
+
+/**
+ * Used by ELECTRONIC_TOLL_COLLECTION_CARD_TYPE.
+ */
+// @VintfStability
+@Backing(type="int")
+enum ElectronicTollCollectionCardType {
+    UNKNOWN = 0,
+    JP_ELECTRONIC_TOLL_COLLECTION_CARD = 1,
+    JP_ELECTRONIC_TOLL_COLLECTION_CARD_V2 = 2,
+}
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/EvConnectorType.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/EvConnectorType.aidl
new file mode 100644
index 0000000..fc95bb0
--- /dev/null
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/EvConnectorType.aidl
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+package android.hardware.automotive.vehicle;
+
+/**
+ * Used by INFO_EV_CONNECTOR_TYPE to enumerate the type of connectors
+ * available to charge the vehicle.
+ */
+// @VintfStability
+@Backing(type="int")
+enum EvConnectorType {
+    /**
+     * Default type if the vehicle does not know or report the EV connector
+     * type.
+     */
+    UNKNOWN = 0,
+    IEC_TYPE_1_AC = 1,
+    IEC_TYPE_2_AC = 2,
+    IEC_TYPE_3_AC = 3,
+    IEC_TYPE_4_DC = 4,
+    IEC_TYPE_1_CCS_DC = 5,
+    IEC_TYPE_2_CCS_DC = 6,
+    TESLA_ROADSTER = 7,
+    TESLA_HPWC = 8,
+    TESLA_SUPERCHARGER = 9,
+    GBT_AC = 10,
+    GBT_DC = 11,
+    /**
+     * Connector type to use when no other types apply. Before using this
+     * value, work with Google to see if the EvConnectorType enum can be
+     * extended with an appropriate value.
+     */
+    OTHER = 101,
+}
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/EvsServiceRequestIndex.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/EvsServiceRequestIndex.aidl
new file mode 100644
index 0000000..6853ccd
--- /dev/null
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/EvsServiceRequestIndex.aidl
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+package android.hardware.automotive.vehicle;
+
+/**
+ * Index in int32VAlues for VehicleProperty#EVS_SERVICE_REQUEST property.
+ */
+// @VintfStability
+@Backing(type="int")
+enum EvsServiceRequestIndex {
+    TYPE = 0,
+    STATE = 1,
+}
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/EvsServiceState.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/EvsServiceState.aidl
new file mode 100644
index 0000000..e351949
--- /dev/null
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/EvsServiceState.aidl
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+package android.hardware.automotive.vehicle;
+
+/**
+ * Used by EVS_SERVICE_REQUEST to enumerate the service's state.
+ */
+// @VintfStability
+@Backing(type="int")
+enum EvsServiceState {
+    OFF = 0,
+    ON = 1,
+}
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/EvsServiceType.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/EvsServiceType.aidl
new file mode 100644
index 0000000..4ca241a
--- /dev/null
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/EvsServiceType.aidl
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+package android.hardware.automotive.vehicle;
+
+/**
+ * Used by EVS_SERVICE_REQUEST to enumerate the service's type.
+ */
+// @VintfStability
+@Backing(type="int")
+enum EvsServiceType {
+    REARVIEW = 0,
+    SURROUNDVIEW = 1,
+}
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/FuelType.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/FuelType.aidl
new file mode 100644
index 0000000..131ac14
--- /dev/null
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/FuelType.aidl
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+package android.hardware.automotive.vehicle;
+
+/**
+ * Used by INFO_FUEL_TYPE to enumerate the type of fuels this vehicle uses.
+ * Consistent with projection protocol.
+ */
+// @VintfStability
+@Backing(type="int")
+enum FuelType {
+    /**
+     * Fuel type to use if the HU does not know on which types of fuel the vehicle
+     * runs. The use of this value is generally discouraged outside of aftermarket units.
+     */
+    FUEL_TYPE_UNKNOWN = 0,
+    /**
+     * Unleaded gasoline
+     */
+    FUEL_TYPE_UNLEADED = 1,
+    /**
+     * Leaded gasoline
+     */
+    FUEL_TYPE_LEADED = 2,
+    /**
+     * Diesel #1
+     */
+    FUEL_TYPE_DIESEL_1 = 3,
+    /**
+     * Diesel #2
+     */
+    FUEL_TYPE_DIESEL_2 = 4,
+    /**
+     * Biodiesel
+     */
+    FUEL_TYPE_BIODIESEL = 5,
+    /**
+     * 85% ethanol/gasoline blend
+     */
+    FUEL_TYPE_E85 = 6,
+    /**
+     * Liquified petroleum gas
+     */
+    FUEL_TYPE_LPG = 7,
+    /**
+     * Compressed natural gas
+     */
+    FUEL_TYPE_CNG = 8,
+    /**
+     * Liquified natural gas
+     */
+    FUEL_TYPE_LNG = 9,
+    /**
+     * Electric
+     */
+    FUEL_TYPE_ELECTRIC = 10,
+    /**
+     * Hydrogen fuel cell
+     */
+    FUEL_TYPE_HYDROGEN = 11,
+    /**
+     * Fuel type to use when no other types apply. Before using this value, work with
+     * Google to see if the FuelType enum can be extended with an appropriate value.
+     */
+    FUEL_TYPE_OTHER = 12,
+}
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/IVehicle.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/IVehicle.aidl
new file mode 100644
index 0000000..acb8409
--- /dev/null
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/IVehicle.aidl
@@ -0,0 +1,115 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+package android.hardware.automotive.vehicle;
+
+import android.hardware.automotive.vehicle.IVehicleCallback;
+import android.hardware.automotive.vehicle.StatusCode;
+import android.hardware.automotive.vehicle.SubscribeOptions;
+import android.hardware.automotive.vehicle.VehiclePropConfig;
+import android.hardware.automotive.vehicle.VehiclePropValue;
+
+// @VintfStability
+interface IVehicle {
+    // Adding return type to method instead of out param String s since there is only one return
+    // value.
+    /**
+     * Print out debugging state for the vehicle hal.
+     *
+     * The text must be in ASCII encoding only.
+     *
+     * Performance requirements:
+     *
+     * The HAL must return from this call in less than 10ms. This call must avoid
+     * deadlocks, as it may be called at any point of operation. Any synchronization
+     * primitives used (such as mutex locks or semaphores) must be acquired
+     * with a timeout.
+     *
+     */
+    String debugDump();
+
+    /**
+     * Get a vehicle property value.
+     *
+     * For VehiclePropertyChangeMode::STATIC properties, this method must always
+     * return the same value always.
+     * For VehiclePropertyChangeMode::ON_CHANGE properties, it must return the
+     * latest available value.
+     *
+     * Some properties like RADIO_PRESET requires to pass additional data in
+     * GET request in VehiclePropValue object.
+     *
+     * If there is no data available yet, which can happen during initial stage,
+     * this call must return immediately with an error code of
+     * StatusCode::TRY_AGAIN.
+     */
+    StatusCode get(in VehiclePropValue requestedPropValue, out VehiclePropValue propValue);
+
+    // Adding return type to method instead of out param VehiclePropConfig[] propConfigs since there
+    // is only one return value.
+    /**
+     * Returns a list of all property configurations supported by this vehicle
+     * HAL.
+     */
+    VehiclePropConfig[] getAllPropConfigs();
+
+    /**
+     * Returns a list of property configurations for given properties.
+     *
+     * If requested VehicleProperty wasn't found it must return
+     * StatusCode::INVALID_ARG, otherwise a list of vehicle property
+     * configurations with StatusCode::OK
+     */
+    StatusCode getPropConfigs(in int[] props, out VehiclePropConfig[] propConfigs);
+
+    // Adding return type to method instead of out param StatusCode status since there is only one
+    // return value.
+    /**
+     * Set a vehicle property value.
+     *
+     * Timestamp of data must be ignored for set operation.
+     *
+     * Setting some properties require having initial state available. If initial
+     * data is not available yet this call must return StatusCode::TRY_AGAIN.
+     * For a property with separate power control this call must return
+     * StatusCode::NOT_AVAILABLE error if property is not powered on.
+     */
+    StatusCode set(in VehiclePropValue propValue);
+
+    // Adding return type to method instead of out param StatusCode status since there is only one
+    // return value.
+    /**
+     * Subscribes to property events.
+     *
+     * Clients must be able to subscribe to multiple properties at a time
+     * depending on data provided in options argument.
+     *
+     * @param listener This client must be called on appropriate event.
+     * @param options List of options to subscribe. SubscribeOption contains
+     *                information such as property Id, area Id, sample rate, etc.
+     */
+    StatusCode subscribe(in IVehicleCallback callback, in SubscribeOptions[] options);
+
+    // Adding return type to method instead of out param StatusCode status since there is only one
+    // return value.
+    /**
+     * Unsubscribes from property events.
+     *
+     * If this client wasn't subscribed to the given property, this method
+     * must return StatusCode::INVALID_ARG.
+     */
+    StatusCode unsubscribe(in IVehicleCallback callback, in int propId);
+}
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/IVehicleCallback.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/IVehicleCallback.aidl
new file mode 100644
index 0000000..1b5a1e2
--- /dev/null
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/IVehicleCallback.aidl
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+package android.hardware.automotive.vehicle;
+
+import android.hardware.automotive.vehicle.StatusCode;
+import android.hardware.automotive.vehicle.VehiclePropValue;
+
+// @VintfStability
+interface IVehicleCallback {
+    /**
+     * Event callback happens whenever a variable that the API user has
+     * subscribed to needs to be reported. This may be based purely on
+     * threshold and frequency (a regular subscription, see subscribe call's
+     * arguments) or when the IVehicle#set method was called and the actual
+     * change needs to be reported.
+     *
+     * These callbacks are chunked.
+     *
+     * @param values that has been updated.
+     */
+    oneway void onPropertyEvent(in VehiclePropValue[] propValues);
+
+    /**
+     * This method gets called if the client was subscribed to a property using
+     * SubscribeFlags::EVENTS_FROM_ANDROID flag and IVehicle#set(...) method was called.
+     *
+     * These events must be delivered to subscriber immediately without any
+     * batching.
+     *
+     * @param value Value that was set by a client.
+     */
+    oneway void onPropertySet(in VehiclePropValue propValue);
+
+    /**
+     * Set property value is usually asynchronous operation. Thus even if
+     * client received StatusCode::OK from the IVehicle::set(...) this
+     * doesn't guarantee that the value was successfully propagated to the
+     * vehicle network. If such rare event occurs this method must be called.
+     *
+     * @param errorCode - any value from StatusCode enum.
+     * @param property - a property where error has happened.
+     * @param areaId - bitmask that specifies in which areas the problem has
+     *                 occurred, must be 0 for global properties
+     */
+    oneway void onPropertySetError(in StatusCode errorCode, in int propId, in int areaId);
+}
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/InitialUserInfoRequest.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/InitialUserInfoRequest.aidl
new file mode 100644
index 0000000..12746ce
--- /dev/null
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/InitialUserInfoRequest.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+package android.hardware.automotive.vehicle;
+
+import android.hardware.automotive.vehicle.InitialUserInfoRequestType;
+import android.hardware.automotive.vehicle.UsersInfo;
+
+/**
+ * Defines the format of a INITIAL_USER_INFO request made by the Android system.
+ *
+ * NOTE: this struct is not used in the HAL properties directly, it must be converted to
+ * VehiclePropValue.RawValue through libraries provided by the default Vehicle HAL implementation.
+ */
+// @VintfStability
+parcelable InitialUserInfoRequest {
+    /**
+     * Arbitrary id used to map the HAL response to the request.
+     */
+    int requestId;
+    /**
+     * Type of request.
+     */
+    InitialUserInfoRequestType requestType;
+    /**
+     * Information about the current state of the Android system.
+     */
+    UsersInfo usersInfo;
+}
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/InitialUserInfoRequestType.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/InitialUserInfoRequestType.aidl
new file mode 100644
index 0000000..12fec24
--- /dev/null
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/InitialUserInfoRequestType.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+package android.hardware.automotive.vehicle;
+
+/**
+ * Defines when a INITIAL_USER_INFO request was made.
+ */
+// @VintfStability
+@Backing(type="int")
+enum InitialUserInfoRequestType {
+    /**
+     * At the first time Android was booted (or after a factory reset).
+     */
+    FIRST_BOOT = 1,
+    /**
+     * At the first time Android was booted after the system was updated.
+     */
+    FIRST_BOOT_AFTER_OTA = 2,
+    /**
+     * When Android was booted "from scratch".
+     */
+    COLD_BOOT = 3,
+    /**
+     * When Android was resumed after the system was suspended to memory.
+     */
+    RESUME = 4,
+}
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/InitialUserInfoResponse.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/InitialUserInfoResponse.aidl
new file mode 100644
index 0000000..34d9062
--- /dev/null
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/InitialUserInfoResponse.aidl
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+package android.hardware.automotive.vehicle;
+
+import android.hardware.automotive.vehicle.InitialUserInfoResponseAction;
+import android.hardware.automotive.vehicle.UserInfo;
+
+/**
+ * Defines the format of a HAL response to a INITIAL_USER_INFO request.
+ *
+ * NOTE: this struct is not used in the HAL properties directly, it must be converted to
+ * VehiclePropValue.RawValue through libraries provided by the default Vehicle HAL implementation.
+ */
+// @VintfStability
+parcelable InitialUserInfoResponse {
+    /**
+     * Id of the request being responded.
+     */
+    int requestId;
+    /**
+     * which action the Android system should take.
+     */
+    InitialUserInfoResponseAction action;
+    /**
+     * Information about the user that should be switched to or created.
+     */
+    UserInfo userToSwitchOrCreate;
+    /**
+     * System locales of the initial user (value will be passed as-is to
+     * android.provider.Settings.System.SYSTEM_LOCALES)
+     */
+    @utf8InCpp String userLocales;
+    /**
+     * Name of the user that should be created.
+     */
+    @utf8InCpp String userNameToCreate;
+}
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/InitialUserInfoResponseAction.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/InitialUserInfoResponseAction.aidl
new file mode 100644
index 0000000..e35fa9a
--- /dev/null
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/InitialUserInfoResponseAction.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+package android.hardware.automotive.vehicle;
+
+/**
+ * Defines which action the Android system should take in an INITIAL_USER_INFO request.
+ */
+// @VintfStability
+@Backing(type="int")
+enum InitialUserInfoResponseAction {
+    /**
+     * Let the Android System decide what to do.
+     *
+     * For example, it might create a new user on first boot, and switch to the last
+     * active user afterwards.
+     */
+    DEFAULT = 0,
+    /**
+     * Switch to an existing Android user.
+     */
+    SWITCH = 1,
+    /**
+     * Create a new Android user (and switch to it).
+     */
+    CREATE = 2,
+}
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/Obd2CommonIgnitionMonitors.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/Obd2CommonIgnitionMonitors.aidl
new file mode 100644
index 0000000..775d531
--- /dev/null
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/Obd2CommonIgnitionMonitors.aidl
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+package android.hardware.automotive.vehicle;
+
+/**
+ * Ignition monitors common to both SPARK and COMPRESSION.
+ * These values come from the SAE J1979 standard.
+ */
+// @VintfStability
+@Backing(type="int")
+enum Obd2CommonIgnitionMonitors {
+    COMPONENTS_AVAILABLE = 0x1 << 0,
+    COMPONENTS_INCOMPLETE = 0x1 << 1,
+    FUEL_SYSTEM_AVAILABLE = 0x1 << 2,
+    FUEL_SYSTEM_INCOMPLETE = 0x1 << 3,
+    MISFIRE_AVAILABLE = 0x1 << 4,
+    MISFIRE_INCOMPLETE = 0x1 << 5,
+}
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/Obd2CompressionIgnitionMonitors.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/Obd2CompressionIgnitionMonitors.aidl
new file mode 100644
index 0000000..ab444e1
--- /dev/null
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/Obd2CompressionIgnitionMonitors.aidl
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+package android.hardware.automotive.vehicle;
+
+import android.hardware.automotive.vehicle.Obd2CommonIgnitionMonitors;
+
+/**
+ * Ignition monitors only available for COMPRESSION vehicles.
+ * These values come from the SAE J1979 standard.
+ */
+// @VintfStability
+@Backing(type="int")
+enum Obd2CompressionIgnitionMonitors {
+    COMPONENTS_AVAILABLE = 0x1 << 0,
+    COMPONENTS_INCOMPLETE = 0x1 << 1,
+    FUEL_SYSTEM_AVAILABLE = 0x1 << 2,
+    FUEL_SYSTEM_INCOMPLETE = 0x1 << 3,
+    MISFIRE_AVAILABLE = 0x1 << 4,
+    MISFIRE_INCOMPLETE = 0x1 << 5,
+    EGR_OR_VVT_AVAILABLE = 0x1 << 6,
+    EGR_OR_VVT_INCOMPLETE = 0x1 << 7,
+    PM_FILTER_AVAILABLE = 0x1 << 8,
+    PM_FILTER_INCOMPLETE = 0x1 << 9,
+    EXHAUST_GAS_SENSOR_AVAILABLE = 0x1 << 10,
+    EXHAUST_GAS_SENSOR_INCOMPLETE = 0x1 << 11,
+    BOOST_PRESSURE_AVAILABLE = 0x1 << 12,
+    BOOST_PRESSURE_INCOMPLETE = 0x1 << 13,
+    NOx_SCR_AVAILABLE = 0x1 << 14,
+    NOx_SCR_INCOMPLETE = 0x1 << 15,
+    NMHC_CATALYST_AVAILABLE = 0x1 << 16,
+    NMHC_CATALYST_INCOMPLETE = 0x1 << 17,
+}
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/Obd2FuelSystemStatus.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/Obd2FuelSystemStatus.aidl
new file mode 100644
index 0000000..9b4ce8f
--- /dev/null
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/Obd2FuelSystemStatus.aidl
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+package android.hardware.automotive.vehicle;
+
+/**
+ * The status of the vehicle's fuel system.
+ * These values come from the SAE J1979 standard.
+ */
+// @VintfStability
+@Backing(type="int")
+enum Obd2FuelSystemStatus {
+    OPEN_INSUFFICIENT_ENGINE_TEMPERATURE = 1,
+    CLOSED_LOOP = 2,
+    OPEN_ENGINE_LOAD_OR_DECELERATION = 4,
+    OPEN_SYSTEM_FAILURE = 8,
+    CLOSED_LOOP_BUT_FEEDBACK_FAULT = 16,
+}
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/Obd2FuelType.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/Obd2FuelType.aidl
new file mode 100644
index 0000000..1428f2c
--- /dev/null
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/Obd2FuelType.aidl
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+package android.hardware.automotive.vehicle;
+
+/**
+ * The fuel type(s) supported by a vehicle.
+ * These values come from the SAE J1979 standard.
+ */
+// @VintfStability
+@Backing(type="int")
+enum Obd2FuelType {
+    NOT_AVAILABLE = 0,
+    GASOLINE = 1,
+    METHANOL = 2,
+    ETHANOL = 3,
+    DIESEL = 4,
+    LPG = 5,
+    CNG = 6,
+    PROPANE = 7,
+    ELECTRIC = 8,
+    BIFUEL_RUNNING_GASOLINE = 9,
+    BIFUEL_RUNNING_METHANOL = 10,
+    BIFUEL_RUNNING_ETHANOL = 11,
+    BIFUEL_RUNNING_LPG = 12,
+    BIFUEL_RUNNING_CNG = 13,
+    BIFUEL_RUNNING_PROPANE = 14,
+    BIFUEL_RUNNING_ELECTRIC = 15,
+    BIFUEL_RUNNING_ELECTRIC_AND_COMBUSTION = 16,
+    HYBRID_GASOLINE = 17,
+    HYBRID_ETHANOL = 18,
+    HYBRID_DIESEL = 19,
+    HYBRID_ELECTRIC = 20,
+    HYBRID_RUNNING_ELECTRIC_AND_COMBUSTION = 21,
+    HYBRID_REGENERATIVE = 22,
+    BIFUEL_RUNNING_DIESEL = 23,
+}
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/Obd2IgnitionMonitorKind.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/Obd2IgnitionMonitorKind.aidl
new file mode 100644
index 0000000..477b38d
--- /dev/null
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/Obd2IgnitionMonitorKind.aidl
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+package android.hardware.automotive.vehicle;
+
+/**
+ * Defines which ignition monitors are available to be read.
+ */
+// @VintfStability
+@Backing(type="int")
+enum Obd2IgnitionMonitorKind {
+    SPARK = 0,
+    COMPRESSION = 1,
+}
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/Obd2SecondaryAirStatus.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/Obd2SecondaryAirStatus.aidl
new file mode 100644
index 0000000..f257164
--- /dev/null
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/Obd2SecondaryAirStatus.aidl
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+package android.hardware.automotive.vehicle;
+
+/**
+ * The status of the vehicle's secondary air system.
+ * These values come from the SAE J1979 standard.
+ */
+// @VintfStability
+@Backing(type="int")
+enum Obd2SecondaryAirStatus {
+    UPSTREAM = 1,
+    DOWNSTREAM_OF_CATALYCIC_CONVERTER = 2,
+    FROM_OUTSIDE_OR_OFF = 4,
+    PUMP_ON_FOR_DIAGNOSTICS = 8,
+}
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/Obd2SparkIgnitionMonitors.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/Obd2SparkIgnitionMonitors.aidl
new file mode 100644
index 0000000..75504df
--- /dev/null
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/Obd2SparkIgnitionMonitors.aidl
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+package android.hardware.automotive.vehicle;
+
+import android.hardware.automotive.vehicle.Obd2CommonIgnitionMonitors;
+
+/**
+ * Ignition monitors available for SPARK vehicles.
+ * These values come from the SAE J1979 standard.
+ */
+// @VintfStability
+@Backing(type="int")
+enum Obd2SparkIgnitionMonitors {
+    COMPONENTS_AVAILABLE = 0x1 << 0,
+    COMPONENTS_INCOMPLETE = 0x1 << 1,
+    FUEL_SYSTEM_AVAILABLE = 0x1 << 2,
+    FUEL_SYSTEM_INCOMPLETE = 0x1 << 3,
+    MISFIRE_AVAILABLE = 0x1 << 4,
+    MISFIRE_INCOMPLETE = 0x1 << 5,
+    EGR_AVAILABLE = 0x1 << 6,
+    EGR_INCOMPLETE = 0x1 << 7,
+    OXYGEN_SENSOR_HEATER_AVAILABLE = 0x1 << 8,
+    OXYGEN_SENSOR_HEATER_INCOMPLETE = 0x1 << 9,
+    OXYGEN_SENSOR_AVAILABLE = 0x1 << 10,
+    OXYGEN_SENSOR_INCOMPLETE = 0x1 << 11,
+    AC_REFRIGERANT_AVAILABLE = 0x1 << 12,
+    AC_REFRIGERANT_INCOMPLETE = 0x1 << 13,
+    SECONDARY_AIR_SYSTEM_AVAILABLE = 0x1 << 14,
+    SECONDARY_AIR_SYSTEM_INCOMPLETE = 0x1 << 15,
+    EVAPORATIVE_SYSTEM_AVAILABLE = 0x1 << 16,
+    EVAPORATIVE_SYSTEM_INCOMPLETE = 0x1 << 17,
+    HEATED_CATALYST_AVAILABLE = 0x1 << 18,
+    HEATED_CATALYST_INCOMPLETE = 0x1 << 19,
+    CATALYST_AVAILABLE = 0x1 << 20,
+    CATALYST_INCOMPLETE = 0x1 << 21,
+}
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/PortLocationType.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/PortLocationType.aidl
new file mode 100644
index 0000000..260dd42
--- /dev/null
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/PortLocationType.aidl
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+package android.hardware.automotive.vehicle;
+
+/**
+ * Used by INFO_FUEL_DOOR_LOCATION/INFO_CHARGE_PORT_LOCATION to enumerate fuel door or
+ * ev port location.
+ */
+// @VintfStability
+@Backing(type="int")
+enum PortLocationType {
+    /**
+     * Default type if the vehicle does not know or report the Fuel door
+     * and ev port location.
+     */
+    UNKNOWN = 0,
+    FRONT_LEFT = 1,
+    FRONT_RIGHT = 2,
+    REAR_RIGHT = 3,
+    REAR_LEFT = 4,
+    FRONT = 5,
+    REAR = 6,
+}
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/ProcessTerminationReason.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/ProcessTerminationReason.aidl
new file mode 100644
index 0000000..e54a08b
--- /dev/null
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/ProcessTerminationReason.aidl
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+package android.hardware.automotive.vehicle;
+
+/**
+ * The reason why a process is terminated by car watchdog.
+ * This is used with WATCHDOG_TERMINATED_PROCESS property.
+ */
+// @VintfStability
+@Backing(type="int")
+enum ProcessTerminationReason {
+    /**
+     * A process doesn't respond to car watchdog within the timeout.
+     */
+    NOT_RESPONDING = 1,
+    /**
+     * A process uses more IO operations than what is allowed.
+     */
+    IO_OVERUSE = 2,
+    /**
+     * A process uses more memory space than what is allowed.
+     */
+    MEMORY_OVERUSE = 3,
+}
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/RemoveUserRequest.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/RemoveUserRequest.aidl
new file mode 100644
index 0000000..79a8c59
--- /dev/null
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/RemoveUserRequest.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+package android.hardware.automotive.vehicle;
+
+import android.hardware.automotive.vehicle.UserInfo;
+import android.hardware.automotive.vehicle.UsersInfo;
+
+/**
+ * Defines the format of a REMOVE_USER property.
+ *
+ * NOTE: this struct is not used in the HAL properties directly, it must be converted to
+ * VehiclePropValue.RawValue through libraries provided by the default Vehicle HAL implementation.
+ */
+// @VintfStability
+parcelable RemoveUserRequest {
+    /**
+     * Arbitrary id used to map the response to the request.
+     */
+    int requestId;
+    /**
+     * Information about the Android user that was removed.
+     */
+    UserInfo removedUserInfo;
+    /**
+     * Information about the current state of the Android system.
+     */
+    UsersInfo usersInfo;
+}
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/RotaryInputType.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/RotaryInputType.aidl
new file mode 100644
index 0000000..eca703a
--- /dev/null
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/RotaryInputType.aidl
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+package android.hardware.automotive.vehicle;
+
+/**
+ * A rotary control which can rotate without limits. These controls use HW_ROTARY_INPUT to report
+ * relative clockwise or counterclockwise motion. They have no absolute position.
+ */
+// @VintfStability
+@Backing(type="int")
+enum RotaryInputType {
+    /**
+     * Main rotary control, typically in the center console, used to navigate the user interface.
+     */
+    ROTARY_INPUT_TYPE_SYSTEM_NAVIGATION = 0,
+    /**
+     * Volume control for adjusting audio volume.
+     */
+    ROTARY_INPUT_TYPE_AUDIO_VOLUME = 1,
+}
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/StatusCode.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/StatusCode.aidl
new file mode 100644
index 0000000..9b29229
--- /dev/null
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/StatusCode.aidl
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+package android.hardware.automotive.vehicle;
+
+/**
+ * Error codes used in vehicle HAL interface.
+ */
+// @VintfStability
+@Backing(type="int")
+enum StatusCode {
+    OK = 0,
+    /**
+     * Try again.
+     */
+    TRY_AGAIN = 1,
+    /**
+     * Invalid argument provided.
+     */
+    INVALID_ARG = 2,
+    /**
+     * This code must be returned when device that associated with the vehicle
+     * property is not available. For example, when client tries to set HVAC
+     * temperature when the whole HVAC unit is turned OFF.
+     */
+    NOT_AVAILABLE = 3,
+    /**
+     * Access denied
+     */
+    ACCESS_DENIED = 4,
+    /**
+     * Something unexpected has happened in Vehicle HAL
+     */
+    INTERNAL_ERROR = 5,
+}
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/SubscribeFlags.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/SubscribeFlags.aidl
new file mode 100644
index 0000000..d997990
--- /dev/null
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/SubscribeFlags.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+package android.hardware.automotive.vehicle;
+
+// @VintfStability
+@Backing(type="int")
+enum SubscribeFlags {
+    UNDEFINED = 0x0,
+
+    /**
+     * Subscribe to event that was originated in vehicle HAL
+     * (most likely this event came from the vehicle itself).
+     */
+    EVENTS_FROM_CAR = 0x1,
+
+    /**
+     * Use this flag to subscribe on events when IVehicle#set(...) was called by
+     * vehicle HAL's client (e.g. Car Service).
+     */
+    EVENTS_FROM_ANDROID = 0x2,
+
+    /**
+     * Property event for this property should be passed through shared memory with only this
+     * property's data included. This can be helpful for reducing memory copy in upper layer
+     * for data with bigger payload. If payload size is small, VHAL can send this through non-shared
+     * memory path instead.
+     */
+    EXCLUSIVE_SHARED_MEMORY = 0x4,
+}
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/SubscribeOptions.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/SubscribeOptions.aidl
new file mode 100644
index 0000000..0769f28
--- /dev/null
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/SubscribeOptions.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+package android.hardware.automotive.vehicle;
+
+import android.hardware.automotive.vehicle.SubscribeFlags;
+
+/**
+ * Encapsulates information about subscription to vehicle property events.
+ */
+// @VintfStability
+parcelable SubscribeOptions {
+    /** Property to subscribe */
+    int propId;
+
+    /**
+     * Sample rate in Hz.
+     *
+     * Must be provided for properties with
+     * VehiclePropertyChangeMode::CONTINUOUS. The value must be within
+     * VehiclePropConfig#minSamplingRate .. VehiclePropConfig#maxSamplingRate
+     * for a given property.
+     * This value indicates how many updates per second client wants to receive.
+     */
+    float sampleRate;
+
+    /** Flags that indicate to which event sources to listen. */
+    SubscribeFlags flags;
+}
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/SwitchUserMessageType.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/SwitchUserMessageType.aidl
new file mode 100644
index 0000000..c0b5d68
--- /dev/null
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/SwitchUserMessageType.aidl
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+package android.hardware.automotive.vehicle;
+
+/**
+ * Defines the reason a SWITCH_USER call was made.
+ *
+ * The meaning of each constant is explained in that property.
+ */
+// @VintfStability
+@Backing(type="int")
+enum SwitchUserMessageType {
+    LEGACY_ANDROID_SWITCH = 1,
+    ANDROID_SWITCH = 2,
+    VEHICLE_RESPONSE = 3,
+    VEHICLE_REQUEST = 4,
+    ANDROID_POST_SWITCH = 5,
+}
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/SwitchUserRequest.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/SwitchUserRequest.aidl
new file mode 100644
index 0000000..9a324f4
--- /dev/null
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/SwitchUserRequest.aidl
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+package android.hardware.automotive.vehicle;
+
+import android.hardware.automotive.vehicle.SwitchUserMessageType;
+import android.hardware.automotive.vehicle.UserInfo;
+import android.hardware.automotive.vehicle.UsersInfo;
+
+/**
+ * Defines the format of a SWITCH_USER property.
+ *
+ * NOTE: this struct is not used in the HAL properties directly, it must be converted to
+ * VehiclePropValue.RawValue through libraries provided by the default Vehicle HAL implementation.
+ */
+// @VintfStability
+parcelable SwitchUserRequest {
+    /**
+     * Arbitrary id used to map the response to the request.
+     */
+    int requestId;
+    /**
+     * Type of message.
+     */
+    SwitchUserMessageType messageType;
+    /**
+     * Information about the Android user being switched to.
+     *
+     * Only the user id (but not the flags) should be set when the request is made by HAL.
+     */
+    UserInfo targetUser;
+    /**
+     * Information about the current state of the Android system.
+     *
+     * Should not be set when the request is made by HAL.
+     */
+    UsersInfo usersInfo;
+}
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/SwitchUserResponse.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/SwitchUserResponse.aidl
new file mode 100644
index 0000000..175859d
--- /dev/null
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/SwitchUserResponse.aidl
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+package android.hardware.automotive.vehicle;
+
+import android.hardware.automotive.vehicle.SwitchUserMessageType;
+import android.hardware.automotive.vehicle.SwitchUserStatus;
+
+/**
+ * Defines the result of a SwitchUserRequest.
+ *
+ * NOTE: this struct is not used in the HAL properties directly, it must be converted to
+ * VehiclePropValue.RawValue through libraries provided by the default Vehicle HAL implementation.
+ */
+// @VintfStability
+parcelable SwitchUserResponse {
+    /**
+     * Id of the request being responded.
+     */
+    int requestId;
+    /**
+     * Type of message.
+     */
+    SwitchUserMessageType messageType;
+    /**
+     * Status of the request.
+     */
+    SwitchUserStatus status;
+    /**
+     * HAL-specific error message.
+     *
+     * This argument is optional, and when defined, it's passed "as-is" to the caller. It could be
+     * used to show custom error messages to the end user.
+     */
+    @utf8InCpp String errorMessage;
+}
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/SwitchUserStatus.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/SwitchUserStatus.aidl
new file mode 100644
index 0000000..11dc5f2
--- /dev/null
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/SwitchUserStatus.aidl
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+package android.hardware.automotive.vehicle;
+
+/**
+ * Status of the response to a SwitchUserRequest.
+ */
+// @VintfStability
+@Backing(type="int")
+enum SwitchUserStatus {
+    /**
+     * The request succeeded and the HAL user was switched.
+     */
+    SUCCESS = 1,
+    /**
+     * The request failed and the HAL user remained the same.
+     */
+    FAILURE = 2,
+}
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/UserFlags.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/UserFlags.aidl
new file mode 100644
index 0000000..8daa0c1
--- /dev/null
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/UserFlags.aidl
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+package android.hardware.automotive.vehicle;
+
+/**
+ * Flags used to define the characteristics of an Android user.
+ */
+// @VintfStability
+@Backing(type="int")
+enum UserFlags {
+    /**
+     * No flags.
+     */
+    NONE = 0x0,
+    /**
+     * System user.
+     * On automotive, that user is always running, although never on foreground (except during
+     * boot or exceptional circumstances).
+     */
+    SYSTEM = 0x01,
+    /**
+     * Guest users have restrictions.
+     */
+    GUEST = 0x02,
+    /**
+     * Ephemeral users have non-persistent state.
+     */
+    EPHEMERAL = 0x04,
+    /**
+     * Admin users have additional privileges such as permission to create other users.
+     */
+    ADMIN = 0x08,
+    /**
+     * Disabled users are marked for deletion.
+     */
+    DISABLED = 0x10,
+    /**
+     * Profile user is a profile of another user.
+     */
+    PROFILE = 0x20,
+}
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/UserIdentificationAssociation.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/UserIdentificationAssociation.aidl
new file mode 100644
index 0000000..9531bb3
--- /dev/null
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/UserIdentificationAssociation.aidl
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+package android.hardware.automotive.vehicle;
+
+import android.hardware.automotive.vehicle.UserIdentificationAssociationType;
+import android.hardware.automotive.vehicle.UserIdentificationAssociationValue;
+
+/**
+ * Helper struct used when getting a user/identification association type.
+ */
+// @VintfStability
+parcelable UserIdentificationAssociation {
+    UserIdentificationAssociationType type = UserIdentificationAssociationType.INVALID;
+    UserIdentificationAssociationValue value = UserIdentificationAssociationValue.UNKNOWN;
+}
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/UserIdentificationAssociationSetValue.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/UserIdentificationAssociationSetValue.aidl
new file mode 100644
index 0000000..5be7f99
--- /dev/null
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/UserIdentificationAssociationSetValue.aidl
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+package android.hardware.automotive.vehicle;
+
+/**
+ * Used to set a UserIdentificationAssociationType with an Android user.
+ */
+// @VintfStability
+@Backing(type="int")
+enum UserIdentificationAssociationSetValue {
+    INVALID = 0,
+    /**
+     * Associate the identification type with the current foreground Android user.
+     */
+    ASSOCIATE_CURRENT_USER = 1,
+    /**
+     * Disassociate the identification type from the current foreground Android user.
+     */
+    DISASSOCIATE_CURRENT_USER = 2,
+    /**
+     * Disassociate the identification type from all Android users.
+     */
+    DISASSOCIATE_ALL_USERS = 3,
+}
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/UserIdentificationAssociationType.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/UserIdentificationAssociationType.aidl
new file mode 100644
index 0000000..141aca8
--- /dev/null
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/UserIdentificationAssociationType.aidl
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+package android.hardware.automotive.vehicle;
+
+/**
+ * Types of mechanisms used to identify an Android user.
+ *
+ * See USER_IDENTIFICATION_ASSOCIATION for more details and example.
+ */
+// @VintfStability
+@Backing(type="int")
+enum UserIdentificationAssociationType {
+    INVALID = 0,
+    /**
+     * Key used to unlock the car.
+     */
+    KEY_FOB = 1,
+    /**
+     * Custom mechanism defined by the OEM.
+     */
+    CUSTOM_1 = 101,
+    /**
+     * Custom mechanism defined by the OEM.
+     */
+    CUSTOM_2 = 102,
+    /**
+     * Custom mechanism defined by the OEM.
+     */
+    CUSTOM_3 = 103,
+    /**
+     * Custom mechanism defined by the OEM.
+     */
+    CUSTOM_4 = 104,
+}
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/UserIdentificationAssociationValue.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/UserIdentificationAssociationValue.aidl
new file mode 100644
index 0000000..c11ad2a
--- /dev/null
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/UserIdentificationAssociationValue.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+package android.hardware.automotive.vehicle;
+
+/**
+ * Whether a UserIdentificationAssociationType is associate with an Android user.
+ */
+// @VintfStability
+@Backing(type="int")
+enum UserIdentificationAssociationValue {
+    /**
+     * Used when the status of an association could not be determined.
+     *
+     * For example, in a set() request, it would indicate a failure to set the given type.
+     */
+    UNKNOWN = 1,
+    /**
+     * The identification type is associated with the current foreground Android user.
+     */
+    ASSOCIATED_CURRENT_USER = 2,
+    /**
+     * The identification type is associated with another Android user.
+     */
+    ASSOCIATED_ANOTHER_USER = 3,
+    /**
+     * The identification type is not associated with any Android user.
+     */
+    NOT_ASSOCIATED_ANY_USER = 4,
+}
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/UserIdentificationGetRequest.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/UserIdentificationGetRequest.aidl
new file mode 100644
index 0000000..cb4b8cf
--- /dev/null
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/UserIdentificationGetRequest.aidl
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+package android.hardware.automotive.vehicle;
+
+import android.hardware.automotive.vehicle.UserIdentificationAssociationType;
+import android.hardware.automotive.vehicle.UserInfo;
+
+/**
+ * Defines the format of a get() call to USER_IDENTIFICATION_ASSOCIATION.
+ *
+ * NOTE: this struct is not used in the HAL properties directly, it must be converted to
+ * VehiclePropValue.RawValue through libraries provided by the default Vehicle HAL implementation.
+ */
+// @VintfStability
+parcelable UserIdentificationGetRequest {
+    /**
+     * Id of the request being responded.
+     */
+    int requestId;
+    /**
+     * Information about the current foreground Android user.
+     */
+    UserInfo userInfo;
+    /**
+     * Number of association being queried.
+     */
+    int numberAssociationTypes;
+    /**
+     * Types of association being queried.
+     */
+    UserIdentificationAssociationType[] associationTypes;
+}
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/UserIdentificationResponse.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/UserIdentificationResponse.aidl
new file mode 100644
index 0000000..e8eb3a3
--- /dev/null
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/UserIdentificationResponse.aidl
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+package android.hardware.automotive.vehicle;
+
+import android.hardware.automotive.vehicle.UserIdentificationAssociation;
+
+/**
+ * Defines the result of a USER_IDENTIFICATION_ASSOCIATION - both for get() and set().
+ *
+ * NOTE: this struct is not used in the HAL properties directly, it must be converted to
+ * VehiclePropValue.RawValue through libraries provided by the default Vehicle HAL implementation.
+ */
+// @VintfStability
+parcelable UserIdentificationResponse {
+    /**
+     * Id of the request being responded.
+     */
+    int requestId;
+    /**
+     * Number of associations being returned.
+     */
+    int numberAssociation;
+    /**
+     * Values associated with the user.
+     */
+    UserIdentificationAssociation[] associations;
+    /**
+     * HAL-specific error message.
+     *
+     * This argument is optional, and when defined, it's passed "as-is" to the caller. It could be
+     * used to show custom error messages to the end user.
+     */
+    @utf8InCpp String errorMessage;
+}
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/UserIdentificationSetAssociation.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/UserIdentificationSetAssociation.aidl
new file mode 100644
index 0000000..392ae99
--- /dev/null
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/UserIdentificationSetAssociation.aidl
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+package android.hardware.automotive.vehicle;
+
+import android.hardware.automotive.vehicle.UserIdentificationAssociationSetValue;
+import android.hardware.automotive.vehicle.UserIdentificationAssociationType;
+
+/**
+ * Helper struct used when setting a user/identification association type.
+ */
+// @VintfStability
+parcelable UserIdentificationSetAssociation {
+    UserIdentificationAssociationType type = UserIdentificationAssociationType.INVALID;
+    UserIdentificationAssociationSetValue value = UserIdentificationAssociationSetValue.INVALID;
+}
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/UserIdentificationSetRequest.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/UserIdentificationSetRequest.aidl
new file mode 100644
index 0000000..dafb1d1
--- /dev/null
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/UserIdentificationSetRequest.aidl
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+package android.hardware.automotive.vehicle;
+
+import android.hardware.automotive.vehicle.UserIdentificationSetAssociation;
+import android.hardware.automotive.vehicle.UserInfo;
+
+/**
+ * Defines the format of a set() call to USER_IDENTIFICATION_ASSOCIATION.
+ *
+ * NOTE: this struct is not used in the HAL properties directly, it must be converted to
+ * VehiclePropValue.RawValue through libraries provided by the default Vehicle HAL implementation.
+ */
+// @VintfStability
+parcelable UserIdentificationSetRequest {
+    /**
+     * Id of the request being responded.
+     */
+    int requestId;
+    /**
+     * Information about the current foreground Android user.
+     */
+    UserInfo userInfo;
+    /**
+     * Number of association being set.
+     */
+    int numberAssociations;
+    /**
+     * Associations being set.
+     */
+    UserIdentificationSetAssociation[] associations;
+}
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/UserInfo.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/UserInfo.aidl
new file mode 100644
index 0000000..0a84308
--- /dev/null
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/UserInfo.aidl
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+package android.hardware.automotive.vehicle;
+
+import android.hardware.automotive.vehicle.UserFlags;
+
+/**
+ * Information about a specific Android user.
+ */
+// @VintfStability
+parcelable UserInfo {
+    int userId = 0;
+    UserFlags flags = UserFlags.NONE;
+}
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/UsersInfo.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/UsersInfo.aidl
new file mode 100644
index 0000000..28b3f95
--- /dev/null
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/UsersInfo.aidl
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+package android.hardware.automotive.vehicle;
+
+import android.hardware.automotive.vehicle.UserInfo;
+
+/**
+ * Information about all Android users.
+ *
+ * NOTE: this struct is not used in the HAL properties directly, it's part of other structs, which
+ * in turn are converted to a VehiclePropValue.RawValue through libraries provided by the default
+ * Vehicle HAL implementation.
+ */
+// @VintfStability
+parcelable UsersInfo {
+    /**
+     * The current foreground user.
+     */
+    UserInfo currentUser;
+    /**
+     * Number of existing users; includes the current user, recently removed users (with DISABLED
+     * flag), and profile users (with PROFILE flag).
+     */
+    int numberUsers;
+    /**
+     * List of existing users; includes the current user, recently removed users (with DISABLED
+     * flag), and profile users (with PROFILE flag).
+     */
+    UserInfo[] existingUsers;
+}
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleApPowerStateConfigFlag.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleApPowerStateConfigFlag.aidl
new file mode 100644
index 0000000..9e593c5
--- /dev/null
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleApPowerStateConfigFlag.aidl
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+package android.hardware.automotive.vehicle;
+
+// @VintfStability
+@Backing(type="int")
+enum VehicleApPowerStateConfigFlag {
+    /**
+     * AP can enter deep sleep state. If not set, AP will always shutdown from
+     * VehicleApPowerState#SHUTDOWN_PREPARE power state.
+     */
+    ENABLE_DEEP_SLEEP_FLAG = 0x1,
+    /**
+     * The power controller can power on AP from off state after timeout
+     * specified in VehicleApPowerSet VEHICLE_AP_POWER_SET_SHUTDOWN_READY message.
+     */
+    CONFIG_SUPPORT_TIMER_POWER_ON_FLAG = 0x2,
+}
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleApPowerStateReport.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleApPowerStateReport.aidl
new file mode 100644
index 0000000..b6cc70d
--- /dev/null
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleApPowerStateReport.aidl
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+package android.hardware.automotive.vehicle;
+
+// @VintfStability
+@Backing(type="int")
+enum VehicleApPowerStateReport {
+    /**
+     * The device has booted. CarService has initialized and is ready to accept commands
+     * from VHAL. The user is not logged in, and vendor apps and services are expected to
+     * control the display and audio.
+     * After reporting this state, AP will accept VehicleApPowerStateReq#ON or
+     * VehicleApPowerStateReq#SHUTDOWN_PREPARE. Other power state requests are ignored.
+     */
+    WAIT_FOR_VHAL = 0x1,
+    /**
+     * AP is ready to suspend.
+     * The AP will not send any more state reports after this.
+     * After reporting this state, AP will accept VehicleApPowerStateReq#FINISHED.
+     * Other power state requests are ignored.
+     *
+     * int32Values[1]: Time to turn AP back on, in seconds. Power controller should turn on
+     *                 AP after the specified time has elapsed, so AP can run tasks like
+     *                 update. If this value is 0, no wake up is requested. The power
+     *                 controller may not necessarily support timed wake-up.
+     */
+    DEEP_SLEEP_ENTRY = 0x2,
+    /**
+     * AP is exiting from deep sleep state.
+     * After reporting this state, AP will accept VehicleApPowerStateReq#ON or
+     * VehicleApPowerStateReq#SHUTDOWN_PREPARE. Other power state requests are ignored.
+     */
+    DEEP_SLEEP_EXIT = 0x3,
+    /**
+     * AP sends this message repeatedly while cleanup and idle tasks execute.
+     * After reporting this state, AP will accept VehicleApPowerStateReq#SHUTDOWN_PREPARE
+     * requesting immediate shutdown or VehicleApPowerStateReq#CANCEL_SHUTDOWN. Other
+     * power state requests are ignored.
+     *
+     * int32Values[1]: Time to postpone shutdown in ms. Maximum value is
+     *                 5000 ms.
+     *                 If AP needs more time, it will send another SHUTDOWN_POSTPONE
+     *                 message before the previous one expires.
+     */
+    SHUTDOWN_POSTPONE = 0x4,
+    /**
+     * AP is ready to shutdown.
+     * The AP will not send any more state reports after this.
+     * After reporting this state, AP will accept VehicleApPowerStateReq#FINISHED.
+     * Other power state requests are ignored.
+     *
+     * int32Values[1]: Time to turn AP back on, in seconds. Power controller should turn on
+     *                 AP after the specified time has elapsed so AP can run tasks like
+     *                 update. If this value is 0, no wake up is specified. The power
+     *                 controller may not necessarily support timed wake-up.
+     */
+    SHUTDOWN_START = 0x5,
+    /**
+     * AP is entering its normal operating state.
+     * After reporting this state, AP will accept VehicleApPowerStateReq#SHUTDOWN_PREPARE.
+     * Other power state requests are ignored.
+     */
+    ON = 0x6,
+    /**
+     * AP is preparing to shut down. In this state, Garage Mode is active and idle
+     * tasks are allowed to run.
+     * After reporting this state, AP will accept VehicleApPowerStateReq#SHUTDOWN_PREPARE
+     * requesting immediate shutdown or VehicleApPowerStateReq#CANCEL_SHUTDOWN. Other
+     * power state requests are ignored.
+     */
+    SHUTDOWN_PREPARE = 0x7,
+    /**
+     * AP has stopped preparing to shut down.
+     * After reporting this state, AP will accept VehicleApPowerStateReq#ON or
+     * VehicleApPowerStateReq#SHUTDOWN_PREPARE. Other power state requests are ignored.
+     */
+    SHUTDOWN_CANCELLED = 0x8,
+}
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleApPowerStateReq.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleApPowerStateReq.aidl
new file mode 100644
index 0000000..06bc073
--- /dev/null
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleApPowerStateReq.aidl
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+package android.hardware.automotive.vehicle;
+
+// @VintfStability
+@Backing(type="int")
+enum VehicleApPowerStateReq {
+    /**
+     * This requests Android to enter its normal operating state.
+     * This may be sent after the AP has reported
+     * VehicleApPowerStateReport#DEEP_SLEEP_EXIT,
+     * VehicleApPowerStateReport#SHUTDOWN_CANCELLED, or
+     * VehicleApPowerStateReport#WAIT_FOR_VHAL.
+     */
+    ON = 0,
+    /**
+     * The power controller issues this request to shutdown the system.
+     * This may be sent after the AP has reported
+     * VehicleApPowerStateReport#DEEP_SLEEP_EXIT,
+     * VehicleApPowerStateReport#ON,
+     * VehicleApPowerStateReport#SHUTDOWN_CANCELLED,
+     * VehicleApPowerStateReport#SHUTDOWN_POSTPONE,
+     * VehicleApPowerStateReport#SHUTDOWN_PREPARE, or
+     * VehicleApPowerStateReport#WAIT_FOR_VHAL.
+     *
+     * int32Values[1] : One of VehicleApPowerStateShutdownParam.
+     *                  This parameter indicates if the AP should shut
+     *                  down fully or sleep. This parameter also
+     *                  indicates if the shutdown should be immediate
+     *                  or if it can be postponed. If the shutdown can
+     *                  be postponed, AP requests postponing by sending
+     *                  VehicleApPowerStateReport#SHUTDOWN_POSTPONE.
+     */
+    SHUTDOWN_PREPARE = 1,
+    /**
+     * Cancel the shutdown.
+     * This may be sent after the AP has reported
+     * VehicleApPowerStateReport#SHUTDOWN_POSTPONE or
+     * VehicleApPowerStateReport#SHUTDOWN_PREPARE.
+     * After receiving this request, the AP will report
+     * VehicleApPowerStateReport#WAIT_FOR_VHAL in preparation to going ON.
+     */
+    CANCEL_SHUTDOWN = 2,
+    /**
+     * Completes the shutdown process.
+     * This may be sent after the AP has reported
+     * VehicleApPowerStateReport#DEEP_SLEEP_ENTRY or
+     * VehicleApPowerStateReport#SHUTDOWN_START. The AP will not report new
+     * state information after receiving this request.
+     */
+    FINISHED = 3,
+}
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleApPowerStateReqIndex.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleApPowerStateReqIndex.aidl
new file mode 100644
index 0000000..a3d6c7f
--- /dev/null
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleApPowerStateReqIndex.aidl
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+package android.hardware.automotive.vehicle;
+
+/**
+ * Index in int32Values for VehicleProperty#AP_POWER_STATE_REQ property.
+ */
+// @VintfStability
+@Backing(type="int")
+enum VehicleApPowerStateReqIndex {
+    STATE = 0,
+    ADDITIONAL = 1,
+}
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleApPowerStateShutdownParam.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleApPowerStateShutdownParam.aidl
new file mode 100644
index 0000000..f4ab080
--- /dev/null
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleApPowerStateShutdownParam.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+package android.hardware.automotive.vehicle;
+
+// @VintfStability
+@Backing(type="int")
+enum VehicleApPowerStateShutdownParam {
+    /**
+     * AP must shutdown immediately. Postponing is not allowed.
+     */
+    SHUTDOWN_IMMEDIATELY = 1,
+    /**
+     * AP can enter deep sleep instead of shutting down completely.
+     */
+    CAN_SLEEP = 2,
+    /**
+     * AP can only shutdown with postponing allowed.
+     */
+    SHUTDOWN_ONLY = 3,
+    /**
+     * AP may enter deep sleep, but must either sleep or shut down immediately.
+     * Postponing is not allowed.
+     */
+    SLEEP_IMMEDIATELY = 4,
+}
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleArea.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleArea.aidl
new file mode 100644
index 0000000..53b85eb
--- /dev/null
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleArea.aidl
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+package android.hardware.automotive.vehicle;
+
+// @VintfStability
+@Backing(type="int")
+enum VehicleArea {
+    GLOBAL = 0x01000000,
+    /** WINDOW maps to enum VehicleAreaWindow */
+    WINDOW = 0x03000000,
+    /** MIRROR maps to enum VehicleAreaMirror */
+    MIRROR = 0x04000000,
+    /** SEAT maps to enum VehicleAreaSeat */
+    SEAT = 0x05000000,
+    /** DOOR maps to enum VehicleAreaDoor */
+    DOOR = 0x06000000,
+    /** WHEEL maps to enum VehicleAreaWheel */
+    WHEEL = 0x07000000,
+
+    MASK = 0x0f000000,
+}
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleAreaConfig.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleAreaConfig.aidl
new file mode 100644
index 0000000..0a688c0
--- /dev/null
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleAreaConfig.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+package android.hardware.automotive.vehicle;
+
+// @VintfStability
+parcelable VehicleAreaConfig {
+    /**
+     * Area id is ignored for VehiclePropertyGroup:GLOBAL properties.
+     */
+    int areaId;
+
+    /**
+     * If the property has @data_enum, leave the range to zero.
+     *
+     * Range will be ignored in the following cases:
+     *    - The VehiclePropertyType is not INT32, INT64 or FLOAT.
+     *    - Both of min value and max value are zero.
+     */
+
+    int minInt32Value;
+    int maxInt32Value;
+
+    long minInt64Value;
+    long maxInt64Value;
+
+    float minFloatValue;
+    float maxFloatValue;
+}
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleAreaDoor.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleAreaDoor.aidl
new file mode 100644
index 0000000..c85b171
--- /dev/null
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleAreaDoor.aidl
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+package android.hardware.automotive.vehicle;
+
+// @VintfStability
+@Backing(type="int")
+enum VehicleAreaDoor {
+    ROW_1_LEFT = 0x00000001,
+    ROW_1_RIGHT = 0x00000004,
+    ROW_2_LEFT = 0x00000010,
+    ROW_2_RIGHT = 0x00000040,
+    ROW_3_LEFT = 0x00000100,
+    ROW_3_RIGHT = 0x00000400,
+    HOOD = 0x10000000,
+    REAR = 0x20000000,
+}
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleAreaMirror.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleAreaMirror.aidl
new file mode 100644
index 0000000..daecf0b
--- /dev/null
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleAreaMirror.aidl
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+package android.hardware.automotive.vehicle;
+
+// @VintfStability
+@Backing(type="int")
+enum VehicleAreaMirror {
+    DRIVER_LEFT = 0x00000001,
+    DRIVER_RIGHT = 0x00000002,
+    DRIVER_CENTER = 0x00000004,
+}
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleAreaSeat.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleAreaSeat.aidl
new file mode 100644
index 0000000..9d16c86
--- /dev/null
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleAreaSeat.aidl
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+package android.hardware.automotive.vehicle;
+
+/**
+ * Various Seats in the car.
+ */
+// @VintfStability
+@Backing(type="int")
+enum VehicleAreaSeat {
+    ROW_1_LEFT = 0x0001,
+    ROW_1_CENTER = 0x0002,
+    ROW_1_RIGHT = 0x0004,
+    ROW_2_LEFT = 0x0010,
+    ROW_2_CENTER = 0x0020,
+    ROW_2_RIGHT = 0x0040,
+    ROW_3_LEFT = 0x0100,
+    ROW_3_CENTER = 0x0200,
+    ROW_3_RIGHT = 0x0400,
+}
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleAreaWheel.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleAreaWheel.aidl
new file mode 100644
index 0000000..0e5b995
--- /dev/null
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleAreaWheel.aidl
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+package android.hardware.automotive.vehicle;
+
+// @VintfStability
+@Backing(type="int")
+enum VehicleAreaWheel {
+    UNKNOWN = 0x0,
+    LEFT_FRONT = 0x1,
+    RIGHT_FRONT = 0x2,
+    LEFT_REAR = 0x4,
+    RIGHT_REAR = 0x8,
+}
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleAreaWindow.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleAreaWindow.aidl
new file mode 100644
index 0000000..bab0a3f
--- /dev/null
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleAreaWindow.aidl
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+package android.hardware.automotive.vehicle;
+
+/**
+ * Various windshields/windows in the car.
+ */
+// @VintfStability
+@Backing(type="int")
+enum VehicleAreaWindow {
+    FRONT_WINDSHIELD = 0x00000001,
+    REAR_WINDSHIELD = 0x00000002,
+    ROW_1_LEFT = 0x00000010,
+    ROW_1_RIGHT = 0x00000040,
+    ROW_2_LEFT = 0x00000100,
+    ROW_2_RIGHT = 0x00000400,
+    ROW_3_LEFT = 0x00001000,
+    ROW_3_RIGHT = 0x00004000,
+    ROOF_TOP_1 = 0x00010000,
+    ROOF_TOP_2 = 0x00020000,
+}
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleDisplay.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleDisplay.aidl
new file mode 100644
index 0000000..a7531c4
--- /dev/null
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleDisplay.aidl
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+package android.hardware.automotive.vehicle;
+
+// @VintfStability
+@Backing(type="int")
+enum VehicleDisplay {
+    /**
+     * The primary Android display (for example, center console)
+     */
+    MAIN = 0,
+    INSTRUMENT_CLUSTER = 1,
+}
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleGear.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleGear.aidl
new file mode 100644
index 0000000..8b08ff8
--- /dev/null
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleGear.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+package android.hardware.automotive.vehicle;
+
+/**
+ * Various gears which can be selected by user and chosen in system.
+ */
+// @VintfStability
+@Backing(type="int")
+enum VehicleGear {
+    GEAR_UNKNOWN = 0x0000,
+    GEAR_NEUTRAL = 0x0001,
+    GEAR_REVERSE = 0x0002,
+    GEAR_PARK = 0x0004,
+    GEAR_DRIVE = 0x0008,
+    GEAR_1 = 0x0010,
+    GEAR_2 = 0x0020,
+    GEAR_3 = 0x0040,
+    GEAR_4 = 0x0080,
+    GEAR_5 = 0x0100,
+    GEAR_6 = 0x0200,
+    GEAR_7 = 0x0400,
+    GEAR_8 = 0x0800,
+    GEAR_9 = 0x1000,
+}
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleHvacFanDirection.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleHvacFanDirection.aidl
new file mode 100644
index 0000000..1967679
--- /dev/null
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleHvacFanDirection.aidl
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+package android.hardware.automotive.vehicle;
+
+/**
+ * Bit flags for fan direction
+ */
+// @VintfStability
+@Backing(type="int")
+enum VehicleHvacFanDirection {
+    UNKNOWN = 0x0,
+    FACE = 0x1,
+    FLOOR = 0x2,
+    /**
+     * FACE_AND_FLOOR = FACE | FLOOR
+     */
+    FACE_AND_FLOOR = 0x3,
+    DEFROST = 0x4,
+    /**
+     * DEFROST_AND_FLOOR = DEFROST | FLOOR
+     */
+    DEFROST_AND_FLOOR = 0x06,
+}
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleHwKeyInputAction.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleHwKeyInputAction.aidl
new file mode 100644
index 0000000..2dfd070
--- /dev/null
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleHwKeyInputAction.aidl
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+package android.hardware.automotive.vehicle;
+
+// @VintfStability
+@Backing(type="int")
+enum VehicleHwKeyInputAction {
+    /**
+     * Key down
+     */
+    ACTION_DOWN = 0,
+    /**
+     * Key up
+     */
+    ACTION_UP = 1,
+}
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleIgnitionState.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleIgnitionState.aidl
new file mode 100644
index 0000000..cf9db97
--- /dev/null
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleIgnitionState.aidl
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+package android.hardware.automotive.vehicle;
+
+// @VintfStability
+@Backing(type="int")
+enum VehicleIgnitionState {
+    UNDEFINED = 0,
+    /**
+     * Steering wheel is locked
+     */
+    LOCK = 1,
+    /**
+     * Steering wheel is not locked, engine and all accessories are OFF. If
+     * car can be in LOCK and OFF state at the same time than HAL must report
+     * LOCK state.
+     */
+    OFF,
+    /**
+     * Typically in this state accessories become available (e.g. radio).
+     * Instrument cluster and engine are turned off
+     */
+    ACC,
+    /**
+     * Ignition is in state ON. Accessories and instrument cluster available,
+     * engine might be running or ready to be started.
+     */
+    ON,
+    /**
+     * Typically in this state engine is starting (cranking).
+     */
+    START,
+}
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleLightState.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleLightState.aidl
new file mode 100644
index 0000000..bfe9163
--- /dev/null
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleLightState.aidl
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+package android.hardware.automotive.vehicle;
+
+/**
+ * Used by lights state properties to enumerate the current state of the lights.
+ *
+ * Most XXX_LIGHTS_STATE properties will only report ON and OFF states.  Only
+ * the HEADLIGHTS_STATE property will report DAYTIME_RUNNING.
+ */
+// @VintfStability
+@Backing(type="int")
+enum VehicleLightState {
+    OFF = 0,
+    ON = 1,
+    DAYTIME_RUNNING = 2,
+}
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleLightSwitch.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleLightSwitch.aidl
new file mode 100644
index 0000000..061f85d
--- /dev/null
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleLightSwitch.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+package android.hardware.automotive.vehicle;
+
+/**
+ * Used by lights switch properties to enumerate user selected switch setting.
+ *
+ * XXX_LIGHTS_SWITCH properties report the switch settings that the user
+ * selects.  The switch setting may be decoupled from the state reported if the
+ * user selects AUTOMATIC.
+ */
+// @VintfStability
+@Backing(type="int")
+enum VehicleLightSwitch {
+    OFF = 0,
+    ON = 1,
+    /**
+     * Daytime running lights mode.  Most cars automatically use DRL but some
+     * cars allow the user to activate them manually.
+     */
+    DAYTIME_RUNNING = 2,
+    /**
+     * Allows the vehicle ECU to set the lights automatically
+     */
+    AUTOMATIC = 0x100,
+}
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleOilLevel.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleOilLevel.aidl
new file mode 100644
index 0000000..8ea6293
--- /dev/null
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleOilLevel.aidl
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+package android.hardware.automotive.vehicle;
+
+// @VintfStability
+@Backing(type="int")
+enum VehicleOilLevel {
+    /**
+     * Oil level values
+     */
+    CRITICALLY_LOW = 0,
+    LOW = 1,
+    NORMAL = 2,
+    HIGH = 3,
+    ERROR = 4,
+}
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehiclePropConfig.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehiclePropConfig.aidl
new file mode 100644
index 0000000..3b4e10a
--- /dev/null
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehiclePropConfig.aidl
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+package android.hardware.automotive.vehicle;
+
+import android.hardware.automotive.vehicle.VehicleAreaConfig;
+import android.hardware.automotive.vehicle.VehiclePropertyAccess;
+import android.hardware.automotive.vehicle.VehiclePropertyChangeMode;
+
+// @VintfStability
+parcelable VehiclePropConfig {
+    /** Property identifier */
+    int prop;
+
+    /**
+     * Defines if the property is read or write or both.
+     */
+    VehiclePropertyAccess access = VehiclePropertyAccess.NONE;
+
+    /**
+     * Defines the change mode of the property.
+     */
+    VehiclePropertyChangeMode changeMode = VehiclePropertyChangeMode.STATIC;
+
+    /**
+     * Contains per-area configuration.
+     */
+    VehicleAreaConfig[] areaConfigs;
+
+    /** Contains additional configuration parameters */
+    int[] configArray;
+
+    /**
+     * Some properties may require additional information passed over this
+     * string. Most properties do not need to set this.
+     */
+    @utf8InCpp String configString;
+
+    /**
+     * Min sample rate in Hz.
+     * Must be defined for VehiclePropertyChangeMode::CONTINUOUS
+     */
+    float minSampleRate;
+
+    /**
+     * Must be defined for VehiclePropertyChangeMode::CONTINUOUS
+     * Max sample rate in Hz.
+     */
+    float maxSampleRate;
+}
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehiclePropValue.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehiclePropValue.aidl
new file mode 100644
index 0000000..4d403f9
--- /dev/null
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehiclePropValue.aidl
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+package android.hardware.automotive.vehicle;
+
+import android.hardware.automotive.vehicle.VehiclePropertyStatus;
+
+/**
+ * Encapsulates the property name and the associated value. It
+ * is used across various API calls to set values, get values or to register for
+ * events.
+ */
+// @VintfStability
+parcelable VehiclePropValue {
+    /** Time is elapsed nanoseconds since boot */
+    long timestamp;
+
+    /**
+     * Area type(s) for non-global property it must be one of the value from
+     * VehicleArea* enums or 0 for global properties.
+     */
+    int areaId;
+
+    /** Property identifier */
+    int prop;
+
+    /** Status of the property */
+    VehiclePropertyStatus status;
+
+    /**
+     * This is used for properties of types VehiclePropertyType#INT
+     * and VehiclePropertyType#INT_VEC
+     */
+    int[] int32Values;
+
+    /**
+     * This is used for properties of types VehiclePropertyType#FLOAT
+     * and VehiclePropertyType#FLOAT_VEC
+     */
+    float[] floatValues;
+
+    /** This is used for properties of type VehiclePropertyType#INT64 */
+    long[] int64Values;
+
+    /** This is used for properties of type VehiclePropertyType#BYTES */
+    byte[] byteValues;
+
+    /** This is used for properties of type VehiclePropertyType#STRING */
+    @utf8InCpp String stringValue;
+}
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehiclePropValueRawValue.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehiclePropValueRawValue.aidl
new file mode 100644
index 0000000..325b7f0
--- /dev/null
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehiclePropValueRawValue.aidl
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+package android.hardware.automotive.vehicle;
+
+/**
+ * Contains value for a single property. Depending on property data type of
+ * this property (VehiclePropetyType) one field of this structure must be filled in.
+ */
+// @VintfStability
+parcelable VehiclePropValueRawValue {
+    /**
+     * This is used for properties of types VehiclePropertyType#INT
+     * and VehiclePropertyType#INT_VEC
+     */
+    int[] int32Values;
+    /**
+     * This is used for properties of types VehiclePropertyType#FLOAT
+     * and VehiclePropertyType#FLOAT_VEC
+     */
+    float[] floatValues;
+    /**
+     * This is used for properties of type VehiclePropertyType#INT64
+     */
+    long[] int64Values;
+    /**
+     * This is used for properties of type VehiclePropertyType#BYTES
+     */
+    byte[] bytes;
+    /**
+     * This is used for properties of type VehiclePropertyType#STRING
+     */
+    @utf8InCpp String stringValue;
+}
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleProperty.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleProperty.aidl
new file mode 100644
index 0000000..a3a4b3d
--- /dev/null
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleProperty.aidl
@@ -0,0 +1,2587 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+package android.hardware.automotive.vehicle;
+
+import android.hardware.automotive.vehicle.VehiclePropertyType;
+/**
+ * Declares all vehicle properties. VehicleProperty has a bitwise structure.
+ * Each property must have:
+ *  - a unique id from range 0x0100 - 0xffff
+ *  - associated data type using VehiclePropertyType
+ *  - property group (VehiclePropertyGroup)
+ *  - vehicle area (VehicleArea)
+ *
+ * Vendors are allowed to extend this enum with their own properties. In this
+ * case they must use VehiclePropertyGroup:VENDOR flag when the property is
+ * declared.
+ *
+ * When a property's status field is not set to AVAILABLE:
+ *  - IVehicle#set may return StatusCode::NOT_AVAILABLE.
+ *  - IVehicle#get is not guaranteed to work.
+ *
+ * Properties set to values out of range must be ignored and no action taken
+ * in response to such ill formed requests.
+ */
+// @VintfStability
+@Backing(type="int")
+enum VehicleProperty {
+    /**
+     * Undefined property.
+     */
+    INVALID = 0x00000000,
+    /**
+     * VIN of vehicle
+     *
+     * @change_mode VehiclePropertyChangeMode:STATIC
+     * @access VehiclePropertyAccess:READ
+     */
+    INFO_VIN = 0x0100 + 0x10000000 + 0x01000000
+            + 0x00100000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:STRING
+    /**
+     * Manufacturer of vehicle
+     *
+     * @change_mode VehiclePropertyChangeMode:STATIC
+     * @access VehiclePropertyAccess:READ
+     */
+    INFO_MAKE = 0x0101 + 0x10000000 + 0x01000000
+            + 0x00100000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:STRING
+    /**
+     * Model of vehicle
+     *
+     * @change_mode VehiclePropertyChangeMode:STATIC
+     * @access VehiclePropertyAccess:READ
+     */
+    INFO_MODEL = 0x0102 + 0x10000000 + 0x01000000
+            + 0x00100000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:STRING
+    /**
+     * Model year of vehicle.
+     *
+     * @change_mode VehiclePropertyChangeMode:STATIC
+     * @access VehiclePropertyAccess:READ
+     * @unit VehicleUnit:YEAR
+     */
+    INFO_MODEL_YEAR = 0x0103 + 0x10000000 + 0x01000000
+            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
+    /**
+     * Fuel capacity of the vehicle in milliliters
+     *
+     * @change_mode VehiclePropertyChangeMode:STATIC
+     * @access VehiclePropertyAccess:READ
+     * @unit VehicleUnit:MILLILITER
+     */
+    INFO_FUEL_CAPACITY = 0x0104 + 0x10000000 + 0x01000000
+            + 0x00600000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:FLOAT
+    /**
+     * List of fuels the vehicle may use
+     *
+     * @change_mode VehiclePropertyChangeMode:STATIC
+     * @access VehiclePropertyAccess:READ
+     * @data_enum FuelType
+     */
+    INFO_FUEL_TYPE = 0x0105 + 0x10000000 + 0x01000000
+            + 0x00410000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32_VEC
+    /**
+     * Battery capacity of the vehicle, if EV or hybrid.  This is the nominal
+     * battery capacity when the vehicle is new.
+     *
+     * @change_mode VehiclePropertyChangeMode:STATIC
+     * @access VehiclePropertyAccess:READ
+     * @unit VehicleUnit:WH
+     */
+    INFO_EV_BATTERY_CAPACITY = 0x0106 + 0x10000000 + 0x01000000
+            + 0x00600000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:FLOAT
+    /**
+     * List of connectors this EV may use
+     *
+     * @change_mode VehiclePropertyChangeMode:STATIC
+     * @data_enum EvConnectorType
+     * @access VehiclePropertyAccess:READ
+     */
+    INFO_EV_CONNECTOR_TYPE = 0x0107 + 0x10000000 + 0x01000000
+            + 0x00410000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32_VEC
+    /**
+     * Fuel door location
+     *
+     * @change_mode VehiclePropertyChangeMode:STATIC
+     * @data_enum PortLocationType
+     * @access VehiclePropertyAccess:READ
+     */
+    INFO_FUEL_DOOR_LOCATION = 0x0108 + 0x10000000 + 0x01000000
+            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
+    /**
+     * EV port location
+     *
+     * @change_mode VehiclePropertyChangeMode:STATIC
+     * @access VehiclePropertyAccess:READ
+     * @data_enum PortLocationType
+     */
+    INFO_EV_PORT_LOCATION = 0x0109 + 0x10000000 + 0x01000000
+            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
+    /**
+     * Driver's seat location
+     * VHAL implementations must ignore the areaId. Use VehicleArea:GLOBAL.
+     *
+     * @change_mode VehiclePropertyChangeMode:STATIC
+     * @data_enum VehicleAreaSeat
+     * @access VehiclePropertyAccess:READ
+     */
+    INFO_DRIVER_SEAT = 0x010A + 0x10000000 + 0x05000000
+            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
+    /**
+     * Exterior dimensions of vehicle.
+     *
+     *  int32Values[0] = height
+     *  int32Values[1] = length
+     *  int32Values[2] = width
+     *  int32Values[3] = width including mirrors
+     *  int32Values[4] = wheel base
+     *  int32Values[5] = track width front
+     *  int32Values[6] = track width rear
+     *  int32Values[7] = curb to curb turning radius
+     *
+     * @change_mode VehiclePropertyChangeMode:STATIC
+     * @access VehiclePropertyAccess:READ
+     * @unit VehicleUnit:MILLIMETER
+     */
+    INFO_EXTERIOR_DIMENSIONS = 0x010B + 0x10000000 + 0x01000000
+            + 0x00410000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32_VEC
+    /**
+     * Multiple EV port locations
+     *
+     * Implement this property if the vehicle has multiple EV ports.
+     * Port locations are defined in PortLocationType.
+     * For example, a car has one port in front left and one port in rear left:
+     *   int32Values[0] = PortLocationType::FRONT_LEFT
+     *   int32Values[0] = PortLocationType::REAR_LEFT
+     *
+     * @change_mode VehiclePropertyChangeMode:STATIC
+     * @access VehiclePropertyAccess:READ
+     * @data_enum PortLocationType
+     */
+    INFO_MULTI_EV_PORT_LOCATIONS = 0x010C + 0x10000000 + 0x01000000
+            + 0x00410000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32_VEC
+    /**
+     * Current odometer value of the vehicle
+     *
+     * @change_mode VehiclePropertyChangeMode:CONTINUOUS
+     * @access VehiclePropertyAccess:READ
+     * @unit VehicleUnit:KILOMETER
+     */
+    PERF_ODOMETER = 0x0204 + 0x10000000 + 0x01000000
+            + 0x00600000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:FLOAT
+    /**
+     * Speed of the vehicle
+     *
+     * The value must be positive when the vehicle is moving forward and negative when
+     * the vehicle is moving backward. This value is independent of gear value
+     * (CURRENT_GEAR or GEAR_SELECTION), for example, if GEAR_SELECTION is GEAR_NEUTRAL,
+     * PERF_VEHICLE_SPEED is positive when the vehicle is moving forward, negative when moving
+     * backward, and zero when not moving.
+     *
+     * @change_mode VehiclePropertyChangeMode:CONTINUOUS
+     * @access VehiclePropertyAccess:READ
+     * @unit VehicleUnit:METER_PER_SEC
+     */
+    PERF_VEHICLE_SPEED = 0x0207 + 0x10000000 + 0x01000000
+            + 0x00600000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:FLOAT
+    /**
+     * Speed of the vehicle for displays
+     *
+     * Some cars display a slightly slower speed than the actual speed.  This is
+     * usually displayed on the speedometer.
+     *
+     * @change_mode VehiclePropertyChangeMode:CONTINUOUS
+     * @access VehiclePropertyAccess:READ
+     * @unit VehicleUnit:METER_PER_SEC
+     */
+    PERF_VEHICLE_SPEED_DISPLAY = 0x0208 + 0x10000000 + 0x01000000
+            + 0x00600000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:FLOAT
+    /**
+     * Front bicycle model steering angle for vehicle
+     *
+     * Angle is in degrees.  Left is negative.
+     *
+     * @change_mode VehiclePropertyChangeMode:CONTINUOUS
+     * @access VehiclePropertyAccess:READ
+     * @unit VehicleUnit:DEGREES
+     */
+    PERF_STEERING_ANGLE = 0x0209 + 0x10000000 + 0x01000000
+            + 0x00600000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:FLOAT
+    /**
+     * Rear bicycle model steering angle for vehicle
+     *
+     * Angle is in degrees.  Left is negative.
+     *
+     * @change_mode VehiclePropertyChangeMode:CONTINUOUS
+     * @access VehiclePropertyAccess:READ
+     * @unit VehicleUnit:DEGREES
+     */
+    PERF_REAR_STEERING_ANGLE = 0x0210 + 0x10000000 + 0x01000000
+            + 0x00600000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:FLOAT
+    /**
+     * Temperature of engine coolant
+     *
+     * @change_mode VehiclePropertyChangeMode:CONTINUOUS
+     * @access VehiclePropertyAccess:READ
+     * @unit VehicleUnit:CELSIUS
+     */
+    ENGINE_COOLANT_TEMP = 0x0301 + 0x10000000 + 0x01000000
+            + 0x00600000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:FLOAT
+    /**
+     * Engine oil level
+     *
+     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
+     * @access VehiclePropertyAccess:READ
+     * @data_enum VehicleOilLevel
+     */
+    ENGINE_OIL_LEVEL = 0x0303 + 0x10000000 + 0x01000000
+            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
+    /**
+     * Temperature of engine oil
+     *
+     * @change_mode VehiclePropertyChangeMode:CONTINUOUS
+     * @access VehiclePropertyAccess:READ
+     * @unit VehicleUnit:CELSIUS
+     */
+    ENGINE_OIL_TEMP = 0x0304 + 0x10000000 + 0x01000000
+            + 0x00600000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:FLOAT
+    /**
+     * Engine rpm
+     *
+     * @change_mode VehiclePropertyChangeMode:CONTINUOUS
+     * @access VehiclePropertyAccess:READ
+     * @unit VehicleUnit:RPM
+     */
+    ENGINE_RPM = 0x0305 + 0x10000000 + 0x01000000
+            + 0x00600000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:FLOAT
+    /**
+     * Reports wheel ticks
+     *
+     * The first element in the vector is a reset count.  A reset indicates
+     * previous tick counts are not comparable with this and future ones.  Some
+     * sort of discontinuity in tick counting has occurred.
+     *
+     * The next four elements represent ticks for individual wheels in the
+     * following order: front left, front right, rear right, rear left.  All
+     * tick counts are cumulative.  Tick counts increment when the vehicle
+     * moves forward, and decrement when vehicles moves in reverse.  The ticks
+     * should be reset to 0 when the vehicle is started by the user.
+     *
+     *  int64Values[0] = reset count
+     *  int64Values[1] = front left ticks
+     *  int64Values[2] = front right ticks
+     *  int64Values[3] = rear right ticks
+     *  int64Values[4] = rear left ticks
+     *
+     * configArray is used to indicate the micrometers-per-wheel-tick value and
+     * which wheels are supported.  configArray is set as follows:
+     *
+     *  configArray[0], bits [0:3] = supported wheels.  Uses enum Wheel.
+     *  configArray[1] = micrometers per front left wheel tick
+     *  configArray[2] = micrometers per front right wheel tick
+     *  configArray[3] = micrometers per rear right wheel tick
+     *  configArray[4] = micrometers per rear left wheel tick
+     *
+     * NOTE:  If a wheel is not supported, its value shall always be set to 0.
+     *
+     * VehiclePropValue.timestamp must be correctly filled in.
+     *
+     * @change_mode VehiclePropertyChangeMode:CONTINUOUS
+     * @access VehiclePropertyAccess:READ
+     */
+    WHEEL_TICK = 0x0306 + 0x10000000 + 0x01000000
+            + 0x00510000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT64_VEC
+    /**
+     * Fuel remaining in the vehicle, in milliliters
+     *
+     * Value may not exceed INFO_FUEL_CAPACITY
+     *
+     * @change_mode VehiclePropertyChangeMode:CONTINUOUS
+     * @access VehiclePropertyAccess:READ
+     * @unit VehicleUnit:MILLILITER
+     */
+    FUEL_LEVEL = 0x0307 + 0x10000000 + 0x01000000
+            + 0x00600000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:FLOAT
+    /**
+     * Fuel door open
+     *
+     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
+     * @access VehiclePropertyAccess:READ_WRITE
+     */
+    FUEL_DOOR_OPEN = 0x0308 + 0x10000000 + 0x01000000
+            + 0x00200000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:BOOLEAN
+    /**
+     * EV battery level in WH, if EV or hybrid
+     *
+     * Value may not exceed INFO_EV_BATTERY_CAPACITY
+     *
+     * @change_mode VehiclePropertyChangeMode:CONTINUOUS
+     * @access VehiclePropertyAccess:READ
+     * @unit VehicleUnit:WH
+     */
+    EV_BATTERY_LEVEL = 0x0309 + 0x10000000 + 0x01000000
+            + 0x00600000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:FLOAT
+    /**
+     * EV charge port open
+     *
+     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
+     * @access VehiclePropertyAccess:READ_WRITE
+     */
+    EV_CHARGE_PORT_OPEN = 0x030A + 0x10000000 + 0x01000000
+            + 0x00200000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:BOOLEAN
+    /**
+     * EV charge port connected
+     *
+     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
+     * @access VehiclePropertyAccess:READ
+     */
+    EV_CHARGE_PORT_CONNECTED = 0x030B + 0x10000000 + 0x01000000
+            + 0x00200000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:BOOLEAN
+    /**
+     * EV instantaneous charge rate in milliwatts
+     *
+     * Positive value indicates battery is being charged.
+     * Negative value indicates battery being discharged.
+     *
+     * @change_mode VehiclePropertyChangeMode:CONTINUOUS
+     * @access VehiclePropertyAccess:READ
+     * @unit VehicleUnit:MW
+     */
+    EV_BATTERY_INSTANTANEOUS_CHARGE_RATE = 0x030C + 0x10000000 + 0x01000000
+            + 0x00600000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:FLOAT
+    /**
+     * Range remaining
+     *
+     * Meters remaining of fuel and charge.  Range remaining shall account for
+     * all energy sources in a vehicle.  For example, a hybrid car's range will
+     * be the sum of the ranges based on fuel and battery.
+     *
+     * @change_mode VehiclePropertyChangeMode:CONTINUOUS
+     * @access VehiclePropertyAccess:READ_WRITE
+     * @unit VehicleUnit:METER
+     */
+    RANGE_REMAINING = 0x0308 + 0x10000000 + 0x01000000
+            + 0x00600000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:FLOAT
+    /**
+     * Tire pressure
+     *
+     * Each tires is identified by its areaConfig.areaId config and their
+     * minFloatValue/maxFloatValue are used to store OEM recommended pressure
+     * range.
+     * The Min value in the areaConfig data represents the lower bound of
+     * the recommended tire pressure.
+     * The Max value in the areaConfig data represents the upper bound of
+     * the recommended tire pressure.
+     * For example:
+     * The following areaConfig indicates the recommended tire pressure
+     * of left_front tire is from 200.0 KILOPASCAL to 240.0 KILOPASCAL.
+     * .areaConfigs = {
+     *      VehicleAreaConfig {
+     *          .areaId = VehicleAreaWheel::LEFT_FRONT,
+     *          .minFloatValue = 200.0,
+     *          .maxFloatValue = 240.0,
+     *      }
+     * },
+     *
+     * @change_mode VehiclePropertyChangeMode:CONTINUOUS
+     * @access VehiclePropertyAccess:READ
+     * @unit VehicleUnit:KILOPASCAL
+     */
+    TIRE_PRESSURE = 0x0309 + 0x10000000 + 0x07000000
+            + 0x00600000, // VehiclePropertyGroup:SYSTEM,VehicleArea:WHEEL,VehiclePropertyType:FLOAT
+    /**
+     * Critically low tire pressure
+     *
+     * This property indicates the critically low pressure threshold for each tire.
+     * It indicates when it is time for tires to be replaced or fixed. The value
+     * must be less than or equal to minFloatValue in TIRE_PRESSURE.
+     * Minimum and maximum property values (that is, minFloatValue, maxFloatValue)
+     * are not applicable to this property.
+     *
+     * @change_mode VehiclePropertyChangeMode:STATIC
+     * @access VehiclePropertyAccess:READ
+     * @unit VehicleUnit:KILOPASCAL
+     */
+    CRITICALLY_LOW_TIRE_PRESSURE = 0x030A + 0x10000000 + 0x07000000
+            + 0x00600000, // VehiclePropertyGroup:SYSTEM,VehicleArea:WHEEL,VehiclePropertyType:FLOAT
+    /**
+     * Currently selected gear
+     *
+     * This is the gear selected by the user.
+     *
+     * Values in the config data must represent the list of supported gears
+     * for this vehicle.  For example, config data for an automatic transmission
+     * must contain {GEAR_NEUTRAL, GEAR_REVERSE, GEAR_PARK, GEAR_DRIVE,
+     * GEAR_1, GEAR_2,...} and for manual transmission the list must be
+     * {GEAR_NEUTRAL, GEAR_REVERSE, GEAR_1, GEAR_2,...}
+     *
+     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
+     * @access VehiclePropertyAccess:READ
+     * @data_enum VehicleGear
+     */
+    GEAR_SELECTION = 0x0400 + 0x10000000 + 0x01000000
+            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
+    /**
+     * Current gear. In non-manual case, selected gear may not
+     * match the current gear. For example, if the selected gear is GEAR_DRIVE,
+     * the current gear will be one of GEAR_1, GEAR_2 etc, which reflects
+     * the actual gear the transmission is currently running in.
+     *
+     * Values in the config data must represent the list of supported gears
+     * for this vehicle.  For example, config data for an automatic transmission
+     * must contain {GEAR_NEUTRAL, GEAR_REVERSE, GEAR_PARK, GEAR_1, GEAR_2,...}
+     * and for manual transmission the list must be
+     * {GEAR_NEUTRAL, GEAR_REVERSE, GEAR_1, GEAR_2,...}. This list need not be the
+     * same as that of the supported gears reported in GEAR_SELECTION.
+     *
+     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
+     * @access VehiclePropertyAccess:READ
+     * @data_enum VehicleGear
+     */
+    CURRENT_GEAR = 0x0401 + 0x10000000 + 0x01000000
+            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
+    /**
+     * Parking brake state.
+     *
+     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
+     * @access VehiclePropertyAccess:READ
+     */
+    PARKING_BRAKE_ON = 0x0402 + 0x10000000 + 0x01000000
+            + 0x00200000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:BOOLEAN
+    /**
+     * Auto-apply parking brake.
+     *
+     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
+     * @access VehiclePropertyAccess:READ
+     */
+    PARKING_BRAKE_AUTO_APPLY = 0x0403 + 0x10000000 + 0x01000000
+            + 0x00200000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:BOOLEAN
+    /**
+     * Warning for fuel low level.
+     *
+     * This property corresponds to the low fuel warning on the dashboard.
+     * Once FUEL_LEVEL_LOW is set, it should not be cleared until more fuel is
+     * added to the vehicle.  This property may take into account all fuel
+     * sources for a vehicle - for example:
+     *
+     *   For a gas powered vehicle, this property is based soley on gas level.
+     *   For a battery powered vehicle, this property is based solely on battery level.
+     *   For a hybrid vehicle, this property may be based on the combination of gas and battery
+     *      levels, at the OEM's discretion.
+     *
+     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
+     * @access VehiclePropertyAccess:READ
+     */
+    FUEL_LEVEL_LOW = 0x0405 + 0x10000000 + 0x01000000
+            + 0x00200000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:BOOLEAN
+    /**
+     * Night mode
+     *
+     * True indicates that the night mode sensor has detected that the car cabin environment has
+     * low light. The platform could use this, for example, to enable appropriate UI for
+     * better viewing in dark or low light environments.
+     *
+     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
+     * @access VehiclePropertyAccess:READ
+     */
+    NIGHT_MODE = 0x0407 + 0x10000000 + 0x01000000
+            + 0x00200000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:BOOLEAN
+    /**
+     * State of the vehicles turn signals
+     *
+     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
+     * @access VehiclePropertyAccess:READ
+     * @data_enum VehicleTurnSignal
+     */
+    TURN_SIGNAL_STATE = 0x0408 + 0x10000000 + 0x01000000
+            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
+    /**
+     * Represents ignition state
+     *
+     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
+     * @access VehiclePropertyAccess:READ
+     * @data_enum VehicleIgnitionState
+     */
+    IGNITION_STATE = 0x0409 + 0x10000000 + 0x01000000
+            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
+    /**
+     * ABS is active
+     *
+     * Set to true when ABS is active.  Reset to false when ABS is off.  This
+     * property may be intermittently set (pulsing) based on the real-time
+     * state of the ABS system.
+     *
+     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
+     * @access VehiclePropertyAccess:READ
+     */
+    ABS_ACTIVE = 0x040A + 0x10000000 + 0x01000000
+            + 0x00200000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:BOOLEAN
+    /**
+     * Traction Control is active
+     *
+     * Set to true when traction control (TC) is active.  Reset to false when
+     * TC is off.  This property may be intermittently set (pulsing) based on
+     * the real-time state of the TC system.
+     *
+     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
+     * @access VehiclePropertyAccess:READ
+     */
+    TRACTION_CONTROL_ACTIVE = 0x040B + 0x10000000 + 0x01000000
+            + 0x00200000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:BOOLEAN
+    /*
+     * HVAC Properties
+     *
+     * Additional rules for mapping a zoned HVAC property (except
+     * HVAC_MAX_DEFROST_ON) to AreaIDs:
+     *  - Every seat in VehicleAreaSeat that is available in the car, must be
+     *    part of an AreaID in the AreaID array.
+     *
+     * Example 1: A car has two front seats (ROW_1_LEFT, ROW_1_RIGHT) and three
+     *  back seats (ROW_2_LEFT, ROW_2_CENTER, ROW_2_RIGHT). There are two
+     *  temperature control units -- driver side and passenger side.
+     *   - A valid mapping set of AreaIDs for HVAC_TEMPERATURE_SET would be a
+     *     two element array:
+     *      - ROW_1_LEFT  | ROW_2_LEFT
+     *      - ROW_1_RIGHT | ROW_2_CENTER | ROW_2_RIGHT
+     *   - An alternative mapping for the same hardware configuration would be:
+     *      - ROW_1_LEFT  | ROW_2_CENTER | ROW_2_LEFT
+     *      - ROW_1_RIGHT | ROW_2_RIGHT
+     *  The temperature controllers are assigned to the seats which they
+     *  "most influence", but every seat must be included exactly once. The
+     *  assignment of the center rear seat to the left or right AreaID may seem
+     *  arbitrary, but the inclusion of every seat in exactly one AreaID ensures
+     *  that the seats in the car are all expressed and that a "reasonable" way
+     *  to affect each seat is available.
+     *
+     * Example 2: A car has three seat rows with two seats in the front row (ROW_1_LEFT,
+     *  ROW_1_RIGHT) and three seats in the second (ROW_2_LEFT, ROW_2_CENTER,
+     *  ROW_2_RIGHT) and third rows (ROW_3_LEFT, ROW_3_CENTER, ROW_3_RIGHT). There
+     *  are three temperature control units -- driver side, passenger side, and rear.
+     *   - A reasonable way to map HVAC_TEMPERATURE_SET to AreaIDs is a three
+     *     element array:
+     *     - ROW_1_LEFT
+     *     - ROW_1_RIGHT
+     *     - ROW_2_LEFT | ROW_2_CENTER | ROW_2_RIGHT | ROW_3_LEFT | ROW_3_CENTER | ROW_3_RIGHT
+     *
+     *
+     * Fan speed setting
+     *
+     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
+     * @access VehiclePropertyAccess:READ_WRITE
+     */
+    HVAC_FAN_SPEED = 0x0500 + 0x10000000 + 0x05000000
+            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
+    /**
+     * Fan direction setting
+     *
+     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
+     * @access VehiclePropertyAccess:READ_WRITE
+     * @data_enum VehicleHvacFanDirection
+     */
+    HVAC_FAN_DIRECTION = 0x0501 + 0x10000000 + 0x05000000
+            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
+    /**
+     * HVAC current temperature.
+     *
+     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
+     * @access VehiclePropertyAccess:READ
+     * @unit VehicleUnit:CELSIUS
+     */
+    HVAC_TEMPERATURE_CURRENT = 0x0502 + 0x10000000 + 0x05000000
+            + 0x00600000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:FLOAT
+    /**
+     * HVAC, target temperature set.
+     *
+     * The configArray is used to indicate the valid values for HVAC in Fahrenheit and Celsius.
+     * Android might use it in the HVAC app UI.
+     * The configArray is set as follows:
+     *      configArray[0] = [the lower bound of the supported temperature in Celsius] * 10.
+     *      configArray[1] = [the upper bound of the supported temperature in Celsius] * 10.
+     *      configArray[2] = [the increment in Celsius] * 10.
+     *      configArray[3] = [the lower bound of the supported temperature in Fahrenheit] * 10.
+     *      configArray[4] = [the upper bound of the supported temperature in Fahrenheit] * 10.
+     *      configArray[5] = [the increment in Fahrenheit] * 10.
+     * For example, if the vehicle supports temperature values as:
+     *      [16.0, 16.5, 17.0 ,..., 28.0] in Celsius
+     *      [60.5, 61.5, 62.5 ,..., 85.5] in Fahrenheit.
+     * The configArray should be configArray = {160, 280, 5, 605, 825, 10}.
+     *
+     * If the vehicle supports HVAC_TEMPERATURE_VALUE_SUGGESTION, the application can use
+     * that property to get the suggested value before setting HVAC_TEMPERATURE_SET. Otherwise,
+     * the application may choose the value in HVAC_TEMPERATURE_SET configArray by itself.
+     *
+     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
+     * @access VehiclePropertyAccess:READ_WRITE
+     * @unit VehicleUnit:CELSIUS
+     */
+    HVAC_TEMPERATURE_SET = 0x0503 + 0x10000000 + 0x05000000
+            + 0x00600000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:FLOAT
+    /**
+     * Fan-based defrost for designated window.
+     *
+     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
+     * @access VehiclePropertyAccess:READ_WRITE
+     */
+    HVAC_DEFROSTER = 0x0504 + 0x10000000 + 0x03000000
+            + 0x00200000, // VehiclePropertyGroup:SYSTEM,VehicleArea:WINDOW,VehiclePropertyType:BOOLEAN
+    /**
+     * On/off AC for designated areaId
+     *
+     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
+     * @access VehiclePropertyAccess:READ_WRITE
+     * @config_flags Supported areaIds
+     */
+    HVAC_AC_ON = 0x0505 + 0x10000000 + 0x05000000
+            + 0x00200000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:BOOLEAN
+    /**
+     * On/off max AC
+     *
+     * When MAX AC is on, the ECU may adjust the vent position, fan speed,
+     * temperature, etc as necessary to cool the vehicle as quickly as possible.
+     * Any parameters modified as a side effect of turning on/off the MAX AC
+     * parameter shall generate onPropertyEvent() callbacks to the VHAL.
+     *
+     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
+     * @access VehiclePropertyAccess:READ_WRITE
+     */
+    HVAC_MAX_AC_ON = 0x0506 + 0x10000000 + 0x05000000
+            + 0x00200000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:BOOLEAN
+    /**
+     * On/off max defrost
+     *
+     * When MAX DEFROST is on, the ECU may adjust the vent position, fan speed,
+     * temperature, etc as necessary to defrost the windows as quickly as
+     * possible.  Any parameters modified as a side effect of turning on/off
+     * the MAX DEFROST parameter shall generate onPropertyEvent() callbacks to
+     * the VHAL.
+     * The AreaIDs for HVAC_MAX_DEFROST_ON indicate MAX DEFROST can be controlled
+     * in the area.
+     * For example:
+     * areaConfig.areaId = {ROW_1_LEFT | ROW_1_RIGHT} indicates HVAC_MAX_DEFROST_ON
+     * only can be controlled for the front rows.
+     *
+     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
+     * @access VehiclePropertyAccess:READ_WRITE
+     */
+    HVAC_MAX_DEFROST_ON = 0x0507 + 0x10000000 + 0x05000000
+            + 0x00200000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:BOOLEAN
+    /**
+     * Recirculation on/off
+     *
+     * Controls the supply of exterior air to the cabin.  Recirc “on” means the
+     * majority of the airflow into the cabin is originating in the cabin.
+     * Recirc “off” means the majority of the airflow into the cabin is coming
+     * from outside the car.
+     *
+     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
+     * @access VehiclePropertyAccess:READ_WRITE
+     */
+    HVAC_RECIRC_ON = 0x0508 + 0x10000000 + 0x05000000
+            + 0x00200000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:BOOLEAN
+    /**
+     * Enable temperature coupling between areas.
+     *
+     * The AreaIDs for HVAC_DUAL_ON property shall contain a combination of
+     * HVAC_TEMPERATURE_SET AreaIDs that can be coupled together. If
+     * HVAC_TEMPERATURE_SET is mapped to AreaIDs [a_1, a_2, ..., a_n], and if
+     * HVAC_DUAL_ON can be enabled to couple a_i and a_j, then HVAC_DUAL_ON
+     * property must be mapped to [a_i | a_j]. Further, if a_k and a_l can also
+     * be coupled together separately then HVAC_DUAL_ON must be mapped to
+     * [a_i | a_j, a_k | a_l].
+     *
+     * Example: A car has two front seats (ROW_1_LEFT, ROW_1_RIGHT) and three
+     *  back seats (ROW_2_LEFT, ROW_2_CENTER, ROW_2_RIGHT). There are two
+     *  temperature control units -- driver side and passenger side -- which can
+     *  be optionally synchronized. This may be expressed in the AreaIDs this way:
+     *  - HVAC_TEMPERATURE_SET->[ROW_1_LEFT | ROW_2_LEFT, ROW_1_RIGHT | ROW_2_CENTER | ROW_2_RIGHT]
+     *  - HVAC_DUAL_ON->[ROW_1_LEFT | ROW_2_LEFT | ROW_1_RIGHT | ROW_2_CENTER | ROW_2_RIGHT]
+     *
+     * When the property is enabled, the ECU must synchronize the temperature
+     * for the affected areas. Any parameters modified as a side effect
+     * of turning on/off the DUAL_ON parameter shall generate
+     * onPropertyEvent() callbacks to the VHAL. In addition, if setting
+     * a temperature (i.e. driver's temperature) changes another temperature
+     * (i.e. front passenger's temperature), then the appropriate
+     * onPropertyEvent() callbacks must be generated.  If a user changes a
+     * temperature that breaks the coupling (e.g. setting the passenger
+     * temperature independently) then the VHAL must send the appropriate
+     * onPropertyEvent() callbacks (i.e. HVAC_DUAL_ON = false,
+     * HVAC_TEMPERATURE_SET[AreaID] = xxx, etc).
+     *
+     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
+     * @access VehiclePropertyAccess:READ_WRITE
+     */
+    HVAC_DUAL_ON = 0x0509 + 0x10000000 + 0x05000000
+            + 0x00200000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:BOOLEAN
+    /**
+     * On/off automatic mode
+     *
+     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
+     * @access VehiclePropertyAccess:READ_WRITE
+     */
+    HVAC_AUTO_ON = 0x050A + 0x10000000 + 0x05000000
+            + 0x00200000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:BOOLEAN
+    /**
+     * Seat heating/cooling
+     *
+     * Negative values indicate cooling.
+     * 0 indicates off.
+     * Positive values indicate heating.
+     *
+     * Some vehicles may have multiple levels of heating and cooling. The
+     * min/max range defines the allowable range and number of steps in each
+     * direction.
+     *
+     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
+     * @access VehiclePropertyAccess:READ_WRITE
+     */
+    HVAC_SEAT_TEMPERATURE = 0x050B + 0x10000000 + 0x05000000
+            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
+    /**
+     * Side Mirror Heat
+     *
+     * Increasing values denote higher heating levels for side mirrors.
+     * The Max value in the config data represents the highest heating level.
+     * The Min value in the config data MUST be zero and indicates no heating.
+     *
+     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
+     * @access VehiclePropertyAccess:READ_WRITE
+     */
+    HVAC_SIDE_MIRROR_HEAT = 0x050C + 0x10000000 + 0x04000000
+            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:MIRROR,VehiclePropertyType:INT32
+    /**
+     * Steering Wheel Heating/Cooling
+     *
+     * Sets the amount of heating/cooling for the steering wheel
+     * config data Min and Max MUST be set appropriately.
+     * Positive value indicates heating.
+     * Negative value indicates cooling.
+     * 0 indicates temperature control is off.
+     *
+     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
+     * @access VehiclePropertyAccess:READ_WRITE
+     */
+    HVAC_STEERING_WHEEL_HEAT = 0x050D + 0x10000000 + 0x01000000
+            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
+    /**
+     * Temperature units for display
+     *
+     * Indicates whether the vehicle is displaying temperature to the user as
+     * Celsius or Fahrenheit.
+     * VehiclePropConfig.configArray is used to indicate the supported temperature display units.
+     * For example: configArray[0] = CELSIUS
+     *              configArray[1] = FAHRENHEIT
+     *
+     * This parameter MAY be used for displaying any HVAC temperature in the system.
+     * Values must be one of VehicleUnit::CELSIUS or VehicleUnit::FAHRENHEIT
+     * Note that internally, all temperatures are represented in floating point Celsius.
+     *
+     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
+     * @access VehiclePropertyAccess:READ_WRITE
+     * @data_enum VehicleUnit
+     */
+    HVAC_TEMPERATURE_DISPLAY_UNITS = 0x050E + 0x10000000 + 0x01000000
+            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
+    /**
+     * Actual fan speed
+     *
+     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
+     * @access VehiclePropertyAccess:READ
+     */
+    HVAC_ACTUAL_FAN_SPEED_RPM = 0x050F + 0x10000000 + 0x05000000
+            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
+    /**
+     * Represents global power state for HVAC. Setting this property to false
+     * MAY mark some properties that control individual HVAC features/subsystems
+     * to UNAVAILABLE state. Setting this property to true MAY mark some
+     * properties that control individual HVAC features/subsystems to AVAILABLE
+     * state (unless any/all of them are UNAVAILABLE on their own individual
+     * merits).
+     *
+     * [Definition] HvacPower_DependentProperties: Properties that need HVAC to be
+     *   powered on in order to enable their functionality. For example, in some cars,
+     *   in order to turn on the AC, HVAC must be powered on first.
+     *
+     * HvacPower_DependentProperties list must be set in the
+     * VehiclePropConfig.configArray. HvacPower_DependentProperties must only contain
+     * properties that are associated with VehicleArea:SEAT. Properties that are not
+     * associated with VehicleArea:SEAT, for example, HVAC_DEFROSTER, must never
+     * depend on HVAC_POWER_ON property and must never be part of
+     * HvacPower_DependentProperties list.
+     *
+     * AreaID mapping for HVAC_POWER_ON property must contain all AreaIDs that
+     * HvacPower_DependentProperties are mapped to.
+     *
+     * Example 1: A car has two front seats (ROW_1_LEFT, ROW_1_RIGHT) and three back
+     *  seats (ROW_2_LEFT, ROW_2_CENTER, ROW_2_RIGHT). If the HVAC features (AC,
+     *  Temperature etc.) throughout the car are dependent on a single HVAC power
+     *  controller then HVAC_POWER_ON must be mapped to
+     *  [ROW_1_LEFT | ROW_1_RIGHT | ROW_2_LEFT | ROW_2_CENTER | ROW_2_RIGHT].
+     *
+     * Example 2: A car has two seats in the front row (ROW_1_LEFT, ROW_1_RIGHT) and
+     *   three seats in the second (ROW_2_LEFT, ROW_2_CENTER, ROW_2_RIGHT) and third
+     *   rows (ROW_3_LEFT, ROW_3_CENTER, ROW_3_RIGHT). If the car has temperature
+     *   controllers in the front row which can operate entirely independently of
+     *   temperature controllers in the back of the vehicle, then HVAC_POWER_ON
+     *   must be mapped to a two element array:
+     *   - ROW_1_LEFT | ROW_1_RIGHT
+     *   - ROW_2_LEFT | ROW_2_CENTER | ROW_2_RIGHT | ROW_3_LEFT | ROW_3_CENTER | ROW_3_RIGHT
+     *
+     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
+     * @access VehiclePropertyAccess:READ_WRITE
+     */
+    HVAC_POWER_ON = 0x0510 + 0x10000000 + 0x05000000
+            + 0x00200000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:BOOLEAN
+    /**
+     * Fan Positions Available
+     *
+     * This is a bit mask of fan positions available for the zone.  Each
+     * available fan direction is denoted by a separate entry in the vector.  A
+     * fan direction may have multiple bits from vehicle_hvac_fan_direction set.
+     * For instance, a typical car may have the following fan positions:
+     *   - FAN_DIRECTION_FACE (0x1)
+     *   - FAN_DIRECTION_FLOOR (0x2)
+     *   - FAN_DIRECTION_FACE | FAN_DIRECTION_FLOOR (0x3)
+     *   - FAN_DIRECTION_DEFROST (0x4)
+     *   - FAN_DIRECTION_FLOOR | FAN_DIRECTION_DEFROST (0x6)
+     *
+     * @change_mode VehiclePropertyChangeMode:STATIC
+     * @access VehiclePropertyAccess:READ
+     * @data_enum VehicleHvacFanDirection
+     */
+    HVAC_FAN_DIRECTION_AVAILABLE = 0x0511 + 0x10000000 + 0x05000000
+            + 0x00410000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32_VEC
+    /**
+     * Automatic recirculation on/off
+     *
+     * When automatic recirculation is ON, the HVAC system may automatically
+     * switch to recirculation mode if the vehicle detects poor incoming air
+     * quality.
+     *
+     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
+     * @access VehiclePropertyAccess:READ_WRITE
+     */
+    HVAC_AUTO_RECIRC_ON = 0x0512 + 0x10000000 + 0x05000000
+            + 0x00200000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:BOOLEAN
+    /**
+     * Seat ventilation
+     *
+     * 0 indicates off.
+     * Positive values indicates ventilation level.
+     *
+     * Used by HVAC apps and Assistant to enable, change, or read state of seat
+     * ventilation.  This is different than seating cooling. It can be on at the
+     * same time as cooling, or not.
+     *
+     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
+     * @access VehiclePropertyAccess:READ_WRITE
+     */
+    HVAC_SEAT_VENTILATION = 0x0513 + 0x10000000 + 0x05000000
+            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
+    /**
+     * Electric defrosters' status
+     *
+     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
+     * @access VehiclePropertyAccess:READ_WRITE
+     */
+    HVAC_ELECTRIC_DEFROSTER_ON = 0x0514 + 0x10000000 + 0x03000000
+            + 0x00200000, // VehiclePropertyGroup:SYSTEM,VehicleArea:WINDOW,VehiclePropertyType:BOOLEAN
+    /**
+     * Suggested values for setting HVAC temperature.
+     *
+     * Implement the property to help applications understand the closest supported temperature
+     * value in Celsius or Fahrenheit.
+     *
+     *      floatValues[0] = the requested value that an application wants to set a temperature to.
+     *      floatValues[1] = the unit for floatValues[0]. It should be one of
+     *                       {VehicleUnit:CELSIUS, VehicleUnit:FAHRENHEIT}.
+     *      floatValues[2] = the value OEMs suggested in CELSIUS. This value is not included
+     *                       in the request.
+     *      floatValues[3] = the value OEMs suggested in FAHRENHEIT. This value is not included
+     *                       in the request.
+     *
+     * An application calls set(VehiclePropValue propValue) with the requested value and unit for
+     * the value. OEMs need to return the suggested values in floatValues[2] and floatValues[3] by
+     * onPropertyEvent() callbacks.
+     *
+     * For example, when a user uses the voice assistant to set HVAC temperature to 66.2 in
+     * Fahrenheit.
+     * First, an application will set this property with the value
+     * [66.2, (float)VehicleUnit:FAHRENHEIT,0,0].
+     * If OEMs suggest to set 19.0 in Celsius or 66.5 in Fahrenheit for user's request, then VHAL
+     * must generate a callback with property value
+     * [66.2, (float)VehicleUnit:FAHRENHEIT, 19.0, 66.5]. After the voice assistant gets the
+     * callback, it will inform the user and set HVAC temperature to the suggested value.
+     *
+     * Another example, an application receives 21 Celsius as the current temperature value by
+     * querying HVC_TEMPERATURE_SET. But the application wants to know what value is displayed on
+     * the car's UI in Fahrenheit.
+     * For this, the application sets the property to [21, (float)VehicleUnit:CELSIUS, 0, 0]. If
+     * the suggested value by the OEM for 21 Celsius is 70 Fahrenheit, then VHAL must generate a
+     * callback with property value [21, (float)VehicleUnit:CELSIUS, 21.0, 70.0].
+     * In this case, the application can know that the value is 70.0 Fahrenheit in the car’s UI.
+     *
+     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
+     * @access VehiclePropertyAccess:READ_WRITE
+     */
+    HVAC_TEMPERATURE_VALUE_SUGGESTION = 0x0515 + 0x10000000 + 0x01000000
+            + 0x00610000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:FLOAT_VEC
+    /**
+     * Distance units for display
+     *
+     * Indicates which units the car is using to display distances to the user. Eg. Mile, Meter
+     * Kilometer.
+     *
+     * Distance units are defined in VehicleUnit.
+     * VehiclePropConfig.configArray is used to indicate the supported distance display units.
+     * For example: configArray[0] = METER
+     *              configArray[1] = KILOMETER
+     *              configArray[2] = MILE
+     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
+     * @access VehiclePropertyAccess:READ_WRITE
+     * @data_enum VehicleUnit
+     */
+    DISTANCE_DISPLAY_UNITS = 0x0600 + 0x10000000 + 0x01000000
+            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
+    /**
+     * Fuel volume units for display
+     *
+     * Indicates which units the car is using to display fuel volume to the user. Eg. Liter or
+     * Gallon.
+     *
+     * VehiclePropConfig.configArray is used to indicate the supported fuel volume display units.
+     * Volume units are defined in VehicleUnit.
+     * For example: configArray[0] = LITER
+     *              configArray[1] = GALLON
+     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
+     * @access VehiclePropertyAccess:READ_WRITE
+     * @data_enum VehicleUnit
+     */
+    FUEL_VOLUME_DISPLAY_UNITS = 0x0601 + 0x10000000 + 0x01000000
+            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
+    /**
+     * Tire pressure units for display
+     *
+     * Indicates which units the car is using to display tire pressure to the user. Eg. PSI, Bar or
+     * Kilopascal.
+     *
+     * VehiclePropConfig.configArray is used to indicate the supported pressure display units.
+     * Pressure units are defined in VehicleUnit.
+     * For example: configArray[0] = KILOPASCAL
+     *              configArray[1] = PSI
+     *              configArray[2] = BAR
+     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
+     * @access VehiclePropertyAccess:READ_WRITE
+     * @data_enum VehicleUnit
+     */
+    TIRE_PRESSURE_DISPLAY_UNITS = 0x0602 + 0x10000000 + 0x01000000
+            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
+    /**
+     * EV battery units for display
+     *
+     * Indicates which units the car is using to display EV battery information to the user. Eg.
+     * watt-hours(Wh), kilowatt-hours(kWh) or ampere-hours(Ah).
+     *
+     * VehiclePropConfig.configArray is used to indicate the supported electrical energy units.
+     * Electrical energy units are defined in VehicleUnit.
+     * For example: configArray[0] = WATT_HOUR
+     *              configArray[1] = AMPERE_HOURS
+     *              configArray[2] = KILOWATT_HOUR
+     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
+     * @access VehiclePropertyAccess:READ_WRITE
+     * @data_enum VehicleUnit
+     */
+    EV_BATTERY_DISPLAY_UNITS = 0x0603 + 0x10000000 + 0x01000000
+            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
+    /**
+     * Fuel consumption units for display
+     *
+     * Indicates type of units the car is using to display fuel consumption information to user
+     * True indicates units are distance over volume such as MPG.
+     * False indicates units are volume over distance such as L/100KM.
+     *
+     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
+     * @access VehiclePropertyAccess:READ_WRITE
+     */
+    FUEL_CONSUMPTION_UNITS_DISTANCE_OVER_VOLUME = 0x0604 + 0x10000000 + 0x01000000
+            + 0x00200000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:BOOLEAN
+    /**
+     * Speed units for display
+     *
+     * Indicates type of units the car is using to display speed to user. Eg. m/s, km/h, or mph.
+     *
+     * VehiclePropConfig.configArray is used to indicate the supported speed display units.
+     * Pressure units are defined in VehicleUnit.
+     * For example: configArray[0] = METER_PER_SEC
+     *              configArray[1] = MILES_PER_HOUR
+     *              configArray[2] = KILOMETERS_PER_HOUR
+     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
+     * @access VehiclePropertyAccess:READ_WRITE
+     */
+    VEHICLE_SPEED_DISPLAY_UNITS = 0x0605 + 0x10000000 + 0x01000000
+            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
+    /**
+     * Current date and time, encoded as Unix time (in milliseconds).
+     * This value denotes the number of milliseconds seconds that have
+     * elapsed since 1/1/1970 UTC.
+     *
+     * Reading this value will give you the system’s time. This can be
+     * useful to synchronize other vehicle systems (dash clock etc).
+     *
+     * Writing this value will update the ‘ExternalTimeSuggestion’
+     * value (if enabled). This value may be consumed by the “Time
+     * Detector Service”, if other sources do not have a higher
+     * priority. For information on how to adjust time source
+     * priorities see Time Detector Service documentation.
+     *
+     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
+     * @access VehiclePropertyAccess:READ_WRITE
+     * @unit VehicleUnit:MILLI_SECS
+     */
+    EPOCH_TIME = 0x0606 + 0x10000000 + 0x01000000
+            + 0x00500000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT64
+    /**
+     * External encryption binding seed.
+     *
+     * This value is mixed with the local key storage encryption key.
+     * This property holds 16 bytes, and is expected to be persisted on an ECU separate from
+     * the IVI. The property is initially set by AAOS, who generates it using a CSRNG.
+     * AAOS will then read the property on subsequent boots. The binding seed is expected to be
+     * reliably persisted. Any loss of the seed results in a factory reset of the IVI.
+     *
+     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
+     * @access VehiclePropertyAccess:READ_WRITE
+     */
+    STORAGE_ENCRYPTION_BINDING_SEED = 0x0607 + 0x10000000 + 0x01000000
+            + 0x00700000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:BYTES
+    /**
+     * Outside temperature
+     *
+     * @change_mode VehiclePropertyChangeMode:CONTINUOUS
+     * @access VehiclePropertyAccess:READ
+     * @unit VehicleUnit:CELSIUS
+     */
+    ENV_OUTSIDE_TEMPERATURE = 0x0703 + 0x10000000 + 0x01000000
+            + 0x00600000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:FLOAT
+    /**
+     * Property to control power state of application processor
+     *
+     * It is assumed that AP's power state is controlled by a separate power
+     * controller.
+     *
+     * For configuration information, VehiclePropConfig.configArray can have bit flag combining
+     * values in VehicleApPowerStateConfigFlag.
+     *
+     *   int32Values[0] : VehicleApPowerStateReq enum value
+     *   int32Values[1] : additional parameter relevant for each state,
+     *                    0 if not used.
+     *
+     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
+     * @access VehiclePropertyAccess:READ
+     */
+    AP_POWER_STATE_REQ = 0x0A00 + 0x10000000 + 0x01000000
+            + 0x00410000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32_VEC
+    /**
+     * Property to report power state of application processor
+     *
+     * It is assumed that AP's power state is controller by separate power
+     * controller.
+     *
+     *   int32Values[0] : VehicleApPowerStateReport enum value
+     *   int32Values[1] : Time in ms to wake up, if necessary.  Otherwise 0.
+
+     *
+     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
+     * @access VehiclePropertyAccess:READ_WRITE
+     */
+    AP_POWER_STATE_REPORT = 0x0A01 + 0x10000000 + 0x01000000
+            + 0x00410000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32_VEC
+    /**
+     * Property to report bootup reason for the current power on. This is a
+     * static property that will not change for the whole duration until power
+     * off. For example, even if user presses power on button after automatic
+     * power on with door unlock, bootup reason must stay with
+     * VehicleApPowerBootupReason#USER_UNLOCK.
+     *
+     * int32Values[0] must be VehicleApPowerBootupReason.
+     *
+     * @change_mode VehiclePropertyChangeMode:STATIC
+     * @access VehiclePropertyAccess:READ
+     */
+    AP_POWER_BOOTUP_REASON = 0x0A02 + 0x10000000 + 0x01000000
+            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
+    /**
+     * Property to represent brightness of the display. Some cars have single
+     * control for the brightness of all displays and this property is to share
+     * change in that control.
+     *
+     * If this is writable, android side can set this value when user changes
+     * display brightness from Settings. If this is read only, user may still
+     * change display brightness from Settings, but that must not be reflected
+     * to other displays.
+     *
+     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
+     * @access VehiclePropertyAccess:READ_WRITE
+     */
+    DISPLAY_BRIGHTNESS = 0x0A03 + 0x10000000 + 0x01000000
+            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
+    /**
+     * Property to feed H/W input events to android
+     *
+     * int32Values[0] : action defined by VehicleHwKeyInputAction
+     * int32Values[1] : key code, must use standard android key code
+     * int32Values[2] : target display defined in VehicleDisplay. Events not
+     *                  tied to specific display must be sent to
+     *                  VehicleDisplay#MAIN.
+     * int32Values[3] : [optional] Number of ticks. The value must be equal or
+     *                  greater than 1. When omitted, Android will default to 1.
+     *
+     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
+     * @access VehiclePropertyAccess:READ
+     * @config_flags
+     */
+    HW_KEY_INPUT = 0x0A10 + 0x10000000 + 0x01000000
+            + 0x00410000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32_VEC
+    /**
+     * Property to feed H/W rotary events to android
+     *
+     * int32Values[0] : RotaryInputType identifying which rotary knob rotated
+     * int32Values[1] : number of detents (clicks), positive for clockwise,
+     *                  negative for counterclockwise
+     * int32Values[2] : target display defined in VehicleDisplay. Events not
+     *                  tied to specific display must be sent to
+     *                  VehicleDisplay#MAIN.
+     * int32values[3 .. 3 + abs(number of detents) - 2]:
+     *                  nanosecond deltas between pairs of consecutive detents,
+     *                  if the number of detents is > 1 or < -1
+     *
+     * VehiclePropValue.timestamp: when the rotation occurred. If the number of
+     *                             detents is > 1 or < -1, this is when the
+     *                             first detent of rotation occurred.
+     *
+     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
+     * @data_enum RotaryInputType
+     * @access VehiclePropertyAccess:READ
+     */
+    HW_ROTARY_INPUT = 0x0A20 + 0x10000000 + 0x01000000
+            + 0x00410000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32_VEC
+    /**
+     * Defines a custom OEM partner input event.
+     *
+     * This input event must be used by OEM partners who wish to propagate events not supported
+     * by Android. It is composed by an array of int32 values only.
+     *
+     * The Android properties are:
+     *
+     * int32Values[0] : Input code identifying the function representing this event. Valid event
+     *                  types are defined by CustomInputType.CUSTOM_EVENT_F1 up to
+     *                  CustomInputType.CUSTOM_EVENT_F10. They represent the custom event to be
+     *                  defined by OEM partners.
+     * int32Values[1] : target display type defined in VehicleDisplay. Events not tied to specific
+     *                  display must be sent to VehicleDisplay#MAIN.
+     * int32Values[2] : repeat counter, if 0 then event is not repeated. Values 1 or above means
+     *                  how many times this event repeated.
+     *
+     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
+     * @data_enum CustomInputType
+     * @access VehiclePropertyAccess:READ
+     */
+    HW_CUSTOM_INPUT = 0X0A30 + 0x10000000 + 0x01000000
+            + 0x00410000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32_VEC
+    /***************************************************************************
+     * Most Car Cabin properties have both a POSition and MOVE parameter.  These
+     * are used to control the various movements for seats, doors, and windows
+     * in a vehicle.
+     *
+     * A POS parameter allows the user to set the absolution position.  For
+     * instance, for a door, 0 indicates fully closed and max value indicates
+     * fully open.  Thus, a value halfway between min and max must indicate
+     * the door is halfway open.
+     *
+     * A MOVE parameter moves the device in a particular direction.  The sign
+     * indicates direction, and the magnitude indicates speed (if multiple
+     * speeds are available).  For a door, a move of -1 will close the door, and
+     * a move of +1 will open it.  Once a door reaches the limit of open/close,
+     * the door should automatically stop moving.  The user must NOT need to
+     * send a MOVE(0) command to stop the door at the end of its range.
+     **************************************************************************/
+
+    /**
+     * Door position
+     *
+     * This is an integer in case a door may be set to a particular position.
+     * Max value indicates fully open, min value (0) indicates fully closed.
+     *
+     * Some vehicles (minivans) can open the door electronically.  Hence, the
+     * ability to write this property.
+     *
+     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
+     * @access VehiclePropertyAccess:READ_WRITE
+     */
+    DOOR_POS = 0x0B00 + 0x10000000 + 0x06000000
+            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:DOOR,VehiclePropertyType:INT32
+    /**
+     * Door move
+     *
+     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
+     * @access VehiclePropertyAccess:READ_WRITE
+     */
+    DOOR_MOVE = 0x0B01 + 0x10000000 + 0x06000000
+            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:DOOR,VehiclePropertyType:INT32
+    /**
+     * Door lock
+     *
+     * 'true' indicates door is locked
+     *
+     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
+     * @access VehiclePropertyAccess:READ_WRITE
+     */
+    DOOR_LOCK = 0x0B02 + 0x10000000 + 0x06000000
+            + 0x00200000, // VehiclePropertyGroup:SYSTEM,VehicleArea:DOOR,VehiclePropertyType:BOOLEAN
+    /**
+     * Mirror Z Position
+     *
+     * Positive value indicates tilt upwards, negative value is downwards
+     *
+     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
+     * @access VehiclePropertyAccess:READ_WRITE
+     */
+    MIRROR_Z_POS = 0x0B40 + 0x10000000 + 0x04000000
+            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:MIRROR,VehiclePropertyType:INT32
+    /**
+     * Mirror Z Move
+     *
+     * Positive value indicates tilt upwards, negative value is downwards
+     *
+     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
+     * @access VehiclePropertyAccess:READ_WRITE
+     */
+    MIRROR_Z_MOVE = 0x0B41 + 0x10000000 + 0x04000000
+            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:MIRROR,VehiclePropertyType:INT32
+    /**
+     * Mirror Y Position
+     *
+     * Positive value indicate tilt right, negative value is left
+     *
+     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
+     * @access VehiclePropertyAccess:READ_WRITE
+     */
+    MIRROR_Y_POS = 0x0B42 + 0x10000000 + 0x04000000
+            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:MIRROR,VehiclePropertyType:INT32
+    /**
+     * Mirror Y Move
+     *
+     * Positive value indicate tilt right, negative value is left
+     *
+     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
+     * @access VehiclePropertyAccess:READ_WRITE
+     */
+    MIRROR_Y_MOVE = 0x0B43 + 0x10000000 + 0x04000000
+            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:MIRROR,VehiclePropertyType:INT32
+    /**
+     * Mirror Lock
+     *
+     * True indicates mirror positions are locked and not changeable
+     *
+     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
+     * @access VehiclePropertyAccess:READ_WRITE
+     */
+    MIRROR_LOCK = 0x0B44 + 0x10000000 + 0x01000000
+            + 0x00200000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:BOOLEAN
+    /**
+     * Mirror Fold
+     *
+     * True indicates mirrors are folded
+     *
+     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
+     * @access VehiclePropertyAccess:READ_WRITE
+     */
+    MIRROR_FOLD = 0x0B45 + 0x10000000 + 0x01000000
+            + 0x00200000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:BOOLEAN
+    /**
+     * Seat memory select
+     *
+     * This parameter selects the memory preset to use to select the seat
+     * position. The minValue is always 0, and the maxValue determines the
+     * number of seat positions available.
+     *
+     * For instance, if the driver's seat has 3 memory presets, the maxValue
+     * will be 3. When the user wants to select a preset, the desired preset
+     * number (1, 2, or 3) is set.
+     *
+     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
+     * @access VehiclePropertyAccess:WRITE
+     */
+    SEAT_MEMORY_SELECT = 0x0B80 + 0x10000000 + 0x05000000
+            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
+    /**
+     * Seat memory set
+     *
+     * This setting allows the user to save the current seat position settings
+     * into the selected preset slot.  The maxValue for each seat position
+     * must match the maxValue for SEAT_MEMORY_SELECT.
+     *
+     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
+     * @access VehiclePropertyAccess:WRITE
+     */
+    SEAT_MEMORY_SET = 0x0B81 + 0x10000000 + 0x05000000
+            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
+    /**
+     * Seatbelt buckled
+     *
+     * True indicates belt is buckled.
+     *
+     * Write access indicates automatic seat buckling capabilities.  There are
+     * no known cars at this time, but you never know...
+     *
+     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
+     * @access VehiclePropertyAccess:READ_WRITE
+     */
+    SEAT_BELT_BUCKLED = 0x0B82 + 0x10000000 + 0x05000000
+            + 0x00200000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:BOOLEAN
+    /**
+     * Seatbelt height position
+     *
+     * Adjusts the shoulder belt anchor point.
+     * Max value indicates highest position
+     * Min value indicates lowest position
+     *
+     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
+     * @access VehiclePropertyAccess:READ_WRITE
+     */
+    SEAT_BELT_HEIGHT_POS = 0x0B83 + 0x10000000 + 0x05000000
+            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
+    /**
+     * Seatbelt height move
+     *
+     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
+     * @access VehiclePropertyAccess:READ_WRITE
+     */
+    SEAT_BELT_HEIGHT_MOVE = 0x0B84 + 0x10000000 + 0x05000000
+            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
+    /**
+     * Seat fore/aft position
+     *
+     * Sets the seat position forward (closer to steering wheel) and backwards.
+     * Max value indicates closest to wheel, min value indicates most rearward
+     * position.
+     *
+     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
+     * @access VehiclePropertyAccess:READ_WRITE
+     */
+    SEAT_FORE_AFT_POS = 0x0B85 + 0x10000000 + 0x05000000
+            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
+    /**
+     * Seat fore/aft move
+     *
+     * Moves the seat position forward and aft.
+     *
+     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
+     * @access VehiclePropertyAccess:READ_WRITE
+     */
+    SEAT_FORE_AFT_MOVE = 0x0B86 + 0x10000000 + 0x05000000
+            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
+    /**
+     * Seat backrest angle 1 position
+     *
+     * Backrest angle 1 is the actuator closest to the bottom of the seat.
+     * Max value indicates angling forward towards the steering wheel.
+     * Min value indicates full recline.
+     *
+     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
+     * @access VehiclePropertyAccess:READ_WRITE
+     */
+    SEAT_BACKREST_ANGLE_1_POS = 0x0B87 + 0x10000000 + 0x05000000
+            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
+    /**
+     * Seat backrest angle 1 move
+     *
+     * Moves the backrest forward or recline.
+     *
+     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
+     * @access VehiclePropertyAccess:READ_WRITE
+     */
+    SEAT_BACKREST_ANGLE_1_MOVE = 0x0B88 + 0x10000000 + 0x05000000
+            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
+    /**
+     * Seat backrest angle 2 position
+     *
+     * Backrest angle 2 is the next actuator up from the bottom of the seat.
+     * Max value indicates angling forward towards the steering wheel.
+     * Min value indicates full recline.
+     *
+     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
+     * @access VehiclePropertyAccess:READ_WRITE
+     */
+    SEAT_BACKREST_ANGLE_2_POS = 0x0B89 + 0x10000000 + 0x05000000
+            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
+    /**
+     * Seat backrest angle 2 move
+     *
+     * Moves the backrest forward or recline.
+     *
+     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
+     * @access VehiclePropertyAccess:READ_WRITE
+     */
+    SEAT_BACKREST_ANGLE_2_MOVE = 0x0B8A + 0x10000000 + 0x05000000
+            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
+    /**
+     * Seat height position
+     *
+     * Sets the seat height.
+     * Max value indicates highest position.
+     * Min value indicates lowest position.
+     *
+     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
+     * @access VehiclePropertyAccess:READ_WRITE
+     */
+    SEAT_HEIGHT_POS = 0x0B8B + 0x10000000 + 0x05000000
+            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
+    /**
+     * Seat height move
+     *
+     * Moves the seat height.
+     *
+     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
+     * @access VehiclePropertyAccess:READ_WRITE
+     */
+    SEAT_HEIGHT_MOVE = 0x0B8C + 0x10000000 + 0x05000000
+            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
+    /**
+     * Seat depth position
+     *
+     * Sets the seat depth, distance from back rest to front edge of seat.
+     * Max value indicates longest depth position.
+     * Min value indicates shortest position.
+     *
+     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
+     * @access VehiclePropertyAccess:READ_WRITE
+     */
+    SEAT_DEPTH_POS = 0x0B8D + 0x10000000 + 0x05000000
+            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
+    /**
+     * Seat depth move
+     *
+     * Adjusts the seat depth.
+     *
+     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
+     * @access VehiclePropertyAccess:READ_WRITE
+     */
+    SEAT_DEPTH_MOVE = 0x0B8E + 0x10000000 + 0x05000000
+            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
+    /**
+     * Seat tilt position
+     *
+     * Sets the seat tilt.
+     * Max value indicates front edge of seat higher than back edge.
+     * Min value indicates front edge of seat lower than back edge.
+     *
+     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
+     * @access VehiclePropertyAccess:READ_WRITE
+     */
+    SEAT_TILT_POS = 0x0B8F + 0x10000000 + 0x05000000
+            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
+    /**
+     * Seat tilt move
+     *
+     * Tilts the seat.
+     *
+     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
+     * @access VehiclePropertyAccess:READ_WRITE
+     */
+    SEAT_TILT_MOVE = 0x0B90 + 0x10000000 + 0x05000000
+            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
+    /**
+     * Lumber fore/aft position
+     *
+     * Pushes the lumbar support forward and backwards
+     * Max value indicates most forward position.
+     * Min value indicates most rearward position.
+     *
+     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
+     * @access VehiclePropertyAccess:READ_WRITE
+     */
+    SEAT_LUMBAR_FORE_AFT_POS = 0x0B91 + 0x10000000 + 0x05000000
+            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
+    /**
+     * Lumbar fore/aft move
+     *
+     * Adjusts the lumbar support.
+     *
+     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
+     * @access VehiclePropertyAccess:READ_WRITE
+     */
+    SEAT_LUMBAR_FORE_AFT_MOVE = 0x0B92 + 0x10000000 + 0x05000000
+            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
+    /**
+     * Lumbar side support position
+     *
+     * Sets the amount of lateral lumbar support.
+     * Max value indicates widest lumbar setting (i.e. least support)
+     * Min value indicates thinnest lumbar setting.
+     *
+     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
+     * @access VehiclePropertyAccess:READ_WRITE
+     */
+    SEAT_LUMBAR_SIDE_SUPPORT_POS = 0x0B93 + 0x10000000 + 0x05000000
+            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
+    /**
+     * Lumbar side support move
+     *
+     * Adjusts the amount of lateral lumbar support.
+     *
+     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
+     * @access VehiclePropertyAccess:READ_WRITE
+     */
+    SEAT_LUMBAR_SIDE_SUPPORT_MOVE = 0x0B94 + 0x10000000 + 0x05000000
+            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
+    /**
+     * Headrest height position
+     *
+     * Sets the headrest height.
+     * Max value indicates tallest setting.
+     * Min value indicates shortest setting.
+     *
+     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
+     * @access VehiclePropertyAccess:READ_WRITE
+     */
+    SEAT_HEADREST_HEIGHT_POS = 0x0B95 + 0x10000000 + 0x01000000
+            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
+    /**
+     * Headrest height move
+     *
+     * Moves the headrest up and down.
+     *
+     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
+     * @access VehiclePropertyAccess:READ_WRITE
+     */
+    SEAT_HEADREST_HEIGHT_MOVE = 0x0B96 + 0x10000000 + 0x05000000
+            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
+    /**
+     * Headrest angle position
+     *
+     * Sets the angle of the headrest.
+     * Max value indicates most upright angle.
+     * Min value indicates shallowest headrest angle.
+     *
+     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
+     * @access VehiclePropertyAccess:READ_WRITE
+     */
+    SEAT_HEADREST_ANGLE_POS = 0x0B97 + 0x10000000 + 0x05000000
+            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
+    /**
+     * Headrest angle move
+     *
+     * Adjusts the angle of the headrest
+     *
+     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
+     * @access VehiclePropertyAccess:READ_WRITE
+     */
+    SEAT_HEADREST_ANGLE_MOVE = 0x0B98 + 0x10000000 + 0x05000000
+            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
+    /**
+     * Headrest fore/aft position
+     *
+     * Adjusts the headrest forwards and backwards.
+     * Max value indicates position closest to front of car.
+     * Min value indicates position closest to rear of car.
+     *
+     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
+     * @access VehiclePropertyAccess:READ_WRITE
+     */
+    SEAT_HEADREST_FORE_AFT_POS = 0x0B99 + 0x10000000 + 0x05000000
+            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
+    /**
+     * Headrest fore/aft move
+     *
+     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
+     * @access VehiclePropertyAccess:READ_WRITE
+     */
+    SEAT_HEADREST_FORE_AFT_MOVE = 0x0B9A + 0x10000000 + 0x05000000
+            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
+    /**
+     * Seat Occupancy
+     *
+     * Indicates whether a particular seat is occupied or not, to the best of the car's ability
+     * to determine. Valid values are from the VehicleSeatOccupancyState enum.
+     *
+     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
+     * @access VehiclePropertyAccess:READ
+     * @data_enum VehicleSeatOccupancyState
+     */
+    SEAT_OCCUPANCY = 0x0BB0 + 0x10000000 + 0x05000000
+            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
+    /**
+     * Window Position
+     *
+     * Min = window up / closed
+     * Max = window down / open
+     *
+     * For a window that may open out of plane (i.e. vent mode of sunroof) this
+     * parameter will work with negative values as follows:
+     *  Max = sunroof completely open
+     *  0 = sunroof closed.
+     *  Min = sunroof vent completely open
+     *
+     *  Note that in this mode, 0 indicates the window is closed.
+     *
+     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
+     * @access VehiclePropertyAccess:READ_WRITE
+     */
+    WINDOW_POS = 0x0BC0 + 0x10000000 + 0x03000000
+            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:WINDOW,VehiclePropertyType:INT32
+    /**
+     * Window Move
+     *
+     * Max = Open the window as fast as possible
+     * Min = Close the window as fast as possible
+     * Magnitude denotes relative speed.  I.e. +2 is faster than +1 in closing
+     * the window.
+     *
+     * For a window that may open out of plane (i.e. vent mode of sunroof) this
+     * parameter will work as follows:
+     *
+     * If sunroof is open:
+     *   Max = open the sunroof further, automatically stop when fully open.
+     *   Min = close the sunroof, automatically stop when sunroof is closed.
+     *
+     * If vent is open:
+     *   Max = close the vent, automatically stop when vent is closed.
+     *   Min = open the vent further, automatically stop when vent is fully open.
+     *
+     * If sunroof is in the closed position:
+     *   Max = open the sunroof, automatically stop when sunroof is fully open.
+     *   Min = open the vent, automatically stop when vent is fully open.
+     *
+     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
+     * @access VehiclePropertyAccess:READ_WRITE
+     */
+    WINDOW_MOVE = 0x0BC1 + 0x10000000 + 0x03000000
+            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:WINDOW,VehiclePropertyType:INT32
+    /**
+     * Window Lock
+     *
+     * True indicates windows are locked and can't be moved.
+     *
+     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
+     * @access VehiclePropertyAccess:READ_WRITE
+     */
+    WINDOW_LOCK = 0x0BC4 + 0x10000000 + 0x03000000
+            + 0x00200000, // VehiclePropertyGroup:SYSTEM,VehicleArea:WINDOW,VehiclePropertyType:BOOLEAN
+    /**
+     * Vehicle Maps Service (VMS) message
+     *
+     * This property uses MIXED data to communicate vms messages.
+     *
+     * Its contents are to be interpreted as follows:
+     * the indices defined in VmsMessageIntegerValuesIndex are to be used to
+     * read from int32Values;
+     * bytes is a serialized VMS message as defined in the vms protocol
+     * which is opaque to the framework;
+     *
+     * IVehicle#get must always return StatusCode::NOT_AVAILABLE.
+     *
+     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
+     * @access VehiclePropertyAccess:READ_WRITE
+     */
+    VEHICLE_MAP_SERVICE = 0x0C00 + 0x10000000 + 0x01000000
+            + 0x00e00000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:MIXED
+    /**
+     * OBD2 Live Sensor Data
+     *
+     * Reports a snapshot of the current (live) values of the OBD2 sensors available.
+     *
+     * The configArray is set as follows:
+     *   configArray[0] = number of vendor-specific integer-valued sensors
+     *   configArray[1] = number of vendor-specific float-valued sensors
+     *
+     * The values of this property are to be interpreted as in the following example.
+     * Considering a configArray = {2,3}
+     * int32Values must be a vector containing Obd2IntegerSensorIndex.LAST_SYSTEM_INDEX + 2
+     * elements (that is, 33 elements);
+     * floatValues must be a vector containing Obd2FloatSensorIndex.LAST_SYSTEM_INDEX + 3
+     * elements (that is, 73 elements);
+     *
+     * It is possible for each frame to contain a different subset of sensor values, both system
+     * provided sensors, and vendor-specific ones. In order to support that, the bytes element
+     * of the property value is used as a bitmask,.
+     *
+     * bytes must have a sufficient number of bytes to represent the total number of possible
+     * sensors (in this case, 14 bytes to represent 106 possible values); it is to be read as
+     * a contiguous bitmask such that each bit indicates the presence or absence of a sensor
+     * from the frame, starting with as many bits as the size of int32Values, immediately
+     * followed by as many bits as the size of floatValues.
+     *
+     * For example, should bytes[0] = 0x4C (0b01001100) it would mean that:
+     *   int32Values[0 and 1] are not valid sensor values
+     *   int32Values[2 and 3] are valid sensor values
+     *   int32Values[4 and 5] are not valid sensor values
+     *   int32Values[6] is a valid sensor value
+     *   int32Values[7] is not a valid sensor value
+     * Should bytes[5] = 0x61 (0b01100001) it would mean that:
+     *   int32Values[32] is a valid sensor value
+     *   floatValues[0 thru 3] are not valid sensor values
+     *   floatValues[4 and 5] are valid sensor values
+     *   floatValues[6] is not a valid sensor value
+     *
+     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
+     * @access VehiclePropertyAccess:READ
+     */
+    OBD2_LIVE_FRAME = 0x0D00 + 0x10000000 + 0x01000000
+            + 0x00e00000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:MIXED
+    /**
+     * OBD2 Freeze Frame Sensor Data
+     *
+     * Reports a snapshot of the value of the OBD2 sensors available at the time that a fault
+     * occurred and was detected.
+     *
+     * A configArray must be provided with the same meaning as defined for OBD2_LIVE_FRAME.
+     *
+     * The values of this property are to be interpreted in a similar fashion as those for
+     * OBD2_LIVE_FRAME, with the exception that the stringValue field may contain a non-empty
+     * diagnostic troubleshooting code (DTC).
+     *
+     * A IVehicle#get request of this property must provide a value for int64Values[0].
+     * This will be interpreted as the timestamp of the freeze frame to retrieve. A list of
+     * timestamps can be obtained by a IVehicle#get of OBD2_FREEZE_FRAME_INFO.
+     *
+     * Should no freeze frame be available at the given timestamp, a response of NOT_AVAILABLE
+     * must be returned by the implementation. Because vehicles may have limited storage for
+     * freeze frames, it is possible for a frame request to respond with NOT_AVAILABLE even if
+     * the associated timestamp has been recently obtained via OBD2_FREEZE_FRAME_INFO.
+     *
+     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
+     * @access VehiclePropertyAccess:READ
+     */
+    OBD2_FREEZE_FRAME = 0x0D01 + 0x10000000 + 0x01000000
+            + 0x00e00000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:MIXED
+    /**
+     * OBD2 Freeze Frame Information
+     *
+     * This property describes the current freeze frames stored in vehicle
+     * memory and available for retrieval via OBD2_FREEZE_FRAME.
+     *
+     * The values are to be interpreted as follows:
+     * each element of int64Values must be the timestamp at which a a fault code
+     * has been detected and the corresponding freeze frame stored, and each
+     * such element can be used as the key to OBD2_FREEZE_FRAME to retrieve
+     * the corresponding freeze frame.
+     *
+     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
+     * @access VehiclePropertyAccess:READ
+     */
+    OBD2_FREEZE_FRAME_INFO = 0x0D02 + 0x10000000 + 0x01000000
+            + 0x00e00000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:MIXED
+    /**
+     * OBD2 Freeze Frame Clear
+     *
+     * This property allows deletion of any of the freeze frames stored in
+     * vehicle memory, as described by OBD2_FREEZE_FRAME_INFO.
+     *
+     * The configArray is set as follows:
+     *  configArray[0] = 1 if the implementation is able to clear individual freeze frames
+     *                   by timestamp, 0 otherwise
+     *
+     * IVehicle#set of this property is to be interpreted as follows:
+     *   if int64Values contains no elements, then all frames stored must be cleared;
+     *   if int64Values contains one or more elements, then frames at the timestamps
+     *   stored in int64Values must be cleared, and the others not cleared. Should the
+     *   vehicle not support selective clearing of freeze frames, this latter mode must
+     *   return NOT_AVAILABLE.
+     *
+     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
+     * @access VehiclePropertyAccess:WRITE
+     */
+    OBD2_FREEZE_FRAME_CLEAR = 0x0D03 + 0x10000000 + 0x01000000
+            + 0x00e00000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:MIXED
+    /**
+     * Headlights State
+     *
+     * Return the current state of headlights.
+     *
+     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
+     * @access VehiclePropertyAccess:READ
+     * @data_enum VehicleLightState
+     */
+    HEADLIGHTS_STATE = 0x0E00 + 0x10000000 + 0x01000000
+            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
+    /**
+     * High beam lights state
+     *
+     * Return the current state of high beam lights.
+     *
+     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
+     * @access VehiclePropertyAccess:READ
+     * @data_enum VehicleLightState
+     */
+    HIGH_BEAM_LIGHTS_STATE = 0x0E01 + 0x10000000 + 0x01000000
+            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
+    /**
+     * Fog light state
+     *
+     * Return the current state of fog lights.
+     *
+     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
+     * @access VehiclePropertyAccess:READ
+     * @data_enum VehicleLightState
+     */
+    FOG_LIGHTS_STATE = 0x0E02 + 0x10000000 + 0x01000000
+            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
+    /**
+     * Hazard light status
+     *
+     * Return the current status of hazard lights.
+     *
+     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
+     * @access VehiclePropertyAccess:READ
+     * @data_enum VehicleLightState
+     */
+    HAZARD_LIGHTS_STATE = 0x0E03 + 0x10000000 + 0x01000000
+            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
+    /**
+     * Headlight switch
+     *
+     * The setting that the user wants.
+     *
+     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
+     * @access VehiclePropertyAccess:READ_WRITE
+     * @data_enum VehicleLightSwitch
+     */
+    HEADLIGHTS_SWITCH = 0x0E10 + 0x10000000 + 0x01000000
+            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
+    /**
+     * High beam light switch
+     *
+     * The setting that the user wants.
+     *
+     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
+     * @access VehiclePropertyAccess:READ_WRITE
+     * @data_enum VehicleLightSwitch
+     */
+    HIGH_BEAM_LIGHTS_SWITCH = 0x0E11 + 0x10000000 + 0x01000000
+            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
+    /**
+     * Fog light switch
+     *
+     * The setting that the user wants.
+     *
+     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
+     * @access VehiclePropertyAccess:READ_WRITE
+     * @data_enum VehicleLightSwitch
+     */
+    FOG_LIGHTS_SWITCH = 0x0E12 + 0x10000000 + 0x01000000
+            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
+    /**
+     * Hazard light switch
+     *
+     * The setting that the user wants.
+     *
+     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
+     * @access VehiclePropertyAccess:READ_WRITE
+     * @data_enum VehicleLightSwitch
+     */
+    HAZARD_LIGHTS_SWITCH = 0x0E13 + 0x10000000 + 0x01000000
+            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
+    /**
+     * Cabin lights
+     *
+     * Return current status of cabin lights.
+     *
+     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
+     * @access VehiclePropertyAccess:READ
+     * @data_enum VehicleLightState
+     */
+    CABIN_LIGHTS_STATE = 0x0F01 + 0x10000000 + 0x01000000
+            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
+    /**
+     * Cabin lights switch
+     *
+     * The position of the physical switch which controls the cabin lights.
+     * This might be different than the CABIN_LIGHTS_STATE if the lights are on because a door
+     * is open or because of a voice command.
+     * For example, while the switch is in the "off" or "automatic" position.
+     *
+     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
+     * @access VehiclePropertyAccess:READ_WRITE
+     * @data_enum VehicleLightSwitch
+     */
+    CABIN_LIGHTS_SWITCH = 0x0F02 + 0x10000000 + 0x01000000
+            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
+    /**
+     * Reading lights
+     *
+     * Return current status of reading lights.
+     *
+     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
+     * @access VehiclePropertyAccess:READ
+     * @data_enum VehicleLightState
+     */
+    READING_LIGHTS_STATE = 0x0F03 + 0x10000000 + 0x05000000
+            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
+    /**
+     * Reading lights switch
+     *
+     * The position of the physical switch which controls the reading lights.
+     * This might be different than the READING_LIGHTS_STATE if the lights are on because a door
+     * is open or because of a voice command.
+     * For example, while the switch is in the "off" or "automatic" position.
+     *
+     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
+     * @access VehiclePropertyAccess:READ_WRITE
+     * @data_enum VehicleLightSwitch
+     */
+    READING_LIGHTS_SWITCH = 0x0F04 + 0x10000000 + 0x05000000
+            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
+    /**
+     * Support customize permissions for vendor properties
+     *
+     * Implement this property if vehicle hal support customize vendor permissions feature.
+     * VehiclePropConfig.configArray is used to indicate vendor properties and permissions
+     * which selected for this vendor property. The permission must be one of enum in
+     * VehicleVendorPermission.
+     * The configArray is set as follows:
+     *      configArray[n] = propId : property ID for the vendor property
+     *      configArray[n+1] = one of enums in VehicleVendorPermission. It indicates the permission
+     *      for reading value of the property.
+     *      configArray[n+2] = one of enums in VehicleVendorPermission. It indicates the permission
+     *      for writing value of the property.
+     *
+     * For example:
+     * configArray = {
+     *      vendor_prop_1, PERMISSION_VENDOR_SEAT_READ, PERMISSION_VENDOR_SEAT_WRITE,
+     *      vendor_prop_2, PERMISSION_VENDOR_INFO, PERMISSION_NOT_ACCESSIBLE,
+     * }
+     * If vendor properties are not in this array, they will have the default vendor permission.
+     * If vendor chose PERMISSION_NOT_ACCESSIBLE, android will not have access to the property. In
+     * the example, Android can not write value for vendor_prop_2.
+     *
+     * @change_mode VehiclePropertyChangeMode:STATIC
+     * @access VehiclePropertyAccess:READ
+     */
+    SUPPORT_CUSTOMIZE_VENDOR_PERMISSION = 0x0F05 + 0x10000000 + 0x01000000
+            + 0x00200000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:BOOLEAN
+    /**
+     * Allow disabling optional featurs from vhal.
+     *
+     * This property reports optional features that should be disabled.
+     * All allowed optional features for the system is declared in Car service overlay,
+     * config_allowed_optional_car_features.
+     * This property allows disabling features defined in the overlay. Without this property,
+     * all the features declared in the overlay will be enabled.
+     *
+     * Value read should include all features disabled with ',' separation.
+     * ex) "com.android.car.user.CarUserNoticeService,storage_monitoring"
+     * @change_mode VehiclePropertyChangeMode:STATIC
+     * @access VehiclePropertyAccess:READ
+     */
+    DISABLED_OPTIONAL_FEATURES = 0x0F06 + 0x10000000 + 0x01000000
+            + 0x00100000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:STRING
+    /**
+     * Defines the initial Android user to be used during initialization.
+     *
+     * This property is called by the Android system when it initializes and it lets the HAL
+     * define which Android user should be started.
+     *
+     * This request is made by setting a VehiclePropValue (defined by InitialUserInfoRequest),
+     * and the HAL must respond with a property change event (defined by InitialUserInfoResponse).
+     * If the HAL doesn't respond after some time (defined by the Android system), the Android
+     * system will proceed as if HAL returned a response of action
+     * InitialUserInfoResponseAction:DEFAULT.
+     *
+     * For example, on first boot, the request could be:
+     *
+     * int32[0]: 42  // request id (arbitrary number set by Android system)
+     * int32[1]: 1   // InitialUserInfoRequestType::FIRST_BOOT
+     * int32[2]: 0   // id of current user (usersInfo.currentUser.userId)
+     * int32[3]: 1   // flag of current user (usersInfo.currentUser.flags = SYSTEM)
+     * int32[4]: 1   // number of existing users (usersInfo.numberUsers);
+     * int32[5]: 0   // user #0  (usersInfo.existingUsers[0].userId)
+     * int32[6]: 1   // flags of user #0  (usersInfo.existingUsers[0].flags)
+     *
+     * And if the HAL want to respond with the creation of an admin user called "Owner", the
+     * response would be:
+     *
+     * int32[0]: 42      // must match the request id from the request
+     * int32[1]:  2      // action = InitialUserInfoResponseAction::CREATE
+     * int32[2]: -10000  // userToSwitchOrCreate.userId (not used as user will be created)
+     * int32[3]:  8      // userToSwitchOrCreate.flags = ADMIN
+     * string: "||Owner" // userLocales + separator + userNameToCreate
+     *
+     * Notice the string value represents multiple values, separated by ||. The first value is the
+     * (optional) system locales for the user to be created (in this case, it's empty, meaning it
+     * will use Android's default value), while the second value is the (also optional) name of the
+     * to user to be created (when the type of response is InitialUserInfoResponseAction:CREATE).
+     * For example, to create the same "Owner" user with "en-US" and "pt-BR" locales, the string
+     * value of the response would be "en-US,pt-BR||Owner". As such, neither the locale nor the
+     * name can have || on it, although a single | is fine.
+     *
+     * NOTE: if the HAL doesn't support user management, then it should not define this property,
+     * which in turn would disable the other user-related properties (for example, the Android
+     * system would never issue them and user-related requests from the HAL layer would be ignored
+     * by the Android System). But if it supports user management, then it must support all core
+     * user-related properties (INITIAL_USER_INFO, SWITCH_USER, CREATE_USER, and REMOVE_USER).
+     *
+     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
+     * @access VehiclePropertyAccess:READ_WRITE
+     */
+    INITIAL_USER_INFO = 0x0F07 + 0x10000000 + 0x01000000
+            + 0x00e00000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:MIXED
+    /**
+     * Defines a request to switch the foreground Android user.
+     *
+     * This property is used primarily by the Android System to inform the HAL that the
+     * current foreground Android user is switching, but it could also be used by the HAL to request
+     * the Android system to switch users - the
+     *
+     * When the request is made by Android, it sets a VehiclePropValue and the HAL must responde
+     * with a property change event; when the HAL is making the request, it must also do it through
+     * a property change event (the main difference is that the request id will be positive in the
+     * former case, and negative in the latter; the SwitchUserMessageType will also be different).
+     *
+     * The format of both request is defined by SwitchUserRequest and the format of the response
+     * (when needed) is defined by SwitchUserResponse. How the HAL (or Android System) should
+     * proceed depends on the message type (which is defined by the SwitchUserMessageType
+     * parameter), as defined below.
+     *
+     * 1.LEGACY_ANDROID_SWITCH
+     * -----------------------
+     *
+     * Called by the Android System to indicate the Android user is about to change, when the change
+     * request was made in a way that is not integrated with the HAL (for example, through
+     * adb shell am switch-user).
+     *
+     * The HAL can switch its internal user once it receives this request, but it doesn't need to
+     * reply back to the Android System. If its internal user cannot be changed for some reason,
+     * then it must wait for the SWITCH_USER(type=ANDROID_POST_SWITCH) call to recover
+     * (for example, it could issue a SWITCH_USER(type=VEHICLE_REQUEST) to switch back to
+     * the previous user), but ideally it should never fail (as switching back could result in a
+     * confusing experience for the end user).
+     *
+     * For example, if the system have users (0, 10, 11) and it's switching from 0 to 11 (where none
+     * of them have any special flag), the request would be:
+     *
+     * int32[0]:  42  // request id
+     * int32[1]:  1   // SwitchUserMessageType::LEGACY_ANDROID_SWITCH
+     * int32[2]:  11  // target user id
+     * int32[3]:  0   // target user flags (none)
+     * int32[4]:  10  // current user
+     * int32[5]:  0   // current user flags (none)
+     * int32[6]:  3   // number of users
+     * int32[7]:  0   // user #0 (Android user id 0)
+     * int32[8]:  0   // flags of user #0 (none)
+     * int32[9]:  10  // user #1 (Android user id 10)
+     * int32[10]: 0   // flags of user #1 (none)
+     * int32[11]: 11  // user #2 (Android user id 11)
+     * int32[12]: 0   // flags of user #2 (none)
+     *
+     * 2.ANDROID_SWITCH
+     * ----------------
+     * Called by the Android System to indicate the Android user is about to change, but Android
+     * will wait for the HAL's response (up to some time) before proceeding.
+     *
+     * The HAL must switch its internal user once it receives this request, then respond back to
+     * Android with a SWITCH_USER(type=VEHICLE_RESPONSE) indicating whether its internal
+     * user was switched or not (through the SwitchUserStatus enum).
+     *
+     * For example, if Android has users (0, 10, 11) and it's switching from 10 to 11 (where
+     * none of them have any special flag), the request would be:
+     *
+     * int32[0]:  42  // request id
+     * int32[1]:  2   // SwitchUserMessageType::ANDROID_SWITCH
+     * int32[2]:  11  // target user id
+     * int32[3]:  0   // target user flags (none)
+     * int32[4]:  10  // current user
+     * int32[5]:  0   // current user flags (none)
+     * int32[6]:  3   // number of users
+     * int32[7]:  0   // 1st user (user 0)
+     * int32[8]:  1   // 1st user flags (SYSTEM)
+     * int32[9]:  10  // 2nd user (user 10)
+     * int32[10]: 0   // 2nd user flags (none)
+     * int32[11]: 11  // 3rd user (user 11)
+     * int32[12]: 0   // 3rd user flags (none)
+     *
+     * If the request succeeded, the HAL must update the property with:
+     *
+     * int32[0]: 42  // request id
+     * int32[1]: 3   // messageType = SwitchUserMessageType::VEHICLE_RESPONSE
+     * int32[2]: 1   // status = SwitchUserStatus::SUCCESS
+     *
+     * But if it failed, the response would be something like:
+     *
+     * int32[0]: 42   // request id
+     * int32[1]: 3    // messageType = SwitchUserMessageType::VEHICLE_RESPONSE
+     * int32[2]: 2    // status = SwitchUserStatus::FAILURE
+     * string: "108-D'OH!" // OEM-specific error message
+     *
+     * 3.VEHICLE_RESPONSE
+     * ------------------
+     * Called by the HAL to indicate whether a request of type ANDROID_SWITCH should proceed or
+     * abort - see the ANDROID_SWITCH section above for more info.
+     *
+     * 4.VEHICLE_REQUEST
+     * ------------------
+     * Called by the HAL to request that the current foreground Android user is switched.
+     *
+     * This is useful in situations where Android started as one user, but the vehicle identified
+     * the driver as another user. For example, user A unlocked the car using the key fob of user B;
+     * the INITIAL_USER_INFO request returned user B, but then a face recognition subsubsystem
+     * identified the user as A.
+     *
+     * The HAL makes this request by a property change event (passing a negative request id), and
+     * the Android system will response by issue an ANDROID_POST_SWITCH call which the same
+     * request id.
+     *
+     * For example, if the current foreground Android user is 10 and the HAL asked it to switch to
+     * 11, the request would be:
+     *
+     * int32[0]: -108  // request id
+     * int32[1]: 4     // messageType = SwitchUserMessageType::VEHICLE_REQUEST
+     * int32[2]: 11    // Android user id
+     *
+     * If the request succeeded and Android has 3 users (0, 10, 11), the response would be:
+     *
+     * int32[0]: -108 // request id
+     * int32[1]:  5   // messageType = SwitchUserMessageType::ANDROID_POST_SWITCH
+     * int32[2]:  11  // target user id
+     * int32[3]:  0   // target user id flags (none)
+     * int32[4]:  11  // current user
+     * int32[5]:  0   // current user flags (none)
+     * int32[6]:  3   // number of users
+     * int32[7]:  0   // 1st user (user 0)
+     * int32[8]:  0   // 1st user flags (none)
+     * int32[9]:  10  // 2nd user (user 10)
+     * int32[10]: 4   // 2nd user flags (none)
+     * int32[11]: 11  // 3rd user (user 11)
+     * int32[12]: 3   // 3rd user flags (none)
+     *
+     * Notice that both the current and target user ids are the same - if the request failed, then
+     * they would be different (i.e, target user would be 11, but current user would still be 10).
+     *
+     * 5.ANDROID_POST_SWITCH
+     * ---------------------
+     * Called by the Android System after a request to switch a user was made.
+     *
+     * This property is called after switch requests of any type (i.e., LEGACY_ANDROID_SWITCH,
+     * ANDROID_SWITCH, or VEHICLE_REQUEST) and can be used to determine if the request succeeded or
+     * failed:
+     *
+     * 1. When it succeeded, it's called when the Android user is in the unlocked state and the
+     *    value of the current and target users ids in the response are the same. This would be
+     *    equivalent to receiving an Intent.ACTION_USER_UNLOCKED in an Android app.
+     * 2. When it failed it's called right away and the value of the current and target users ids
+     *    in the response are different (as the current user didn't change to the target).
+     * 3. If a new switch request is made before the HAL responded to the previous one or before
+     *    the user was unlocked, then the ANDROID_POST_SWITCH request is not made. For example,
+     *    the driver could accidentally switch to the wrong user which has lock credentials, then
+     *    switch to the right one before entering the credentials.
+     *
+     * The HAL can update its internal state once it receives this request, but it doesn't need to
+     * reply back to the Android System.
+     *
+     * Request: the first N values as defined by INITIAL_USER_INFO (where the request-specific
+     * value at index 1 is SwitchUserMessageType::ANDROID_POST_SWITCH), then 2 more values for the
+     * target user id (i.e., the Android user id that was requested to be switched to) and its flags
+     * (as defined by  UserFlags).
+     *
+     * Response: none.
+     *
+     * Example: see VEHICLE_REQUEST section above.
+     *
+     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
+     * @access VehiclePropertyAccess:READ_WRITE
+     */
+    SWITCH_USER = 0x0F08 + 0x10000000 + 0x01000000
+            + 0x00e00000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:MIXED
+    /**
+     * Called by the Android System after an Android user was created.
+     *
+     * The HAL can use this property to create its equivalent user.
+     *
+     * This is an async request: Android makes the request by setting a VehiclePropValue, and HAL
+     * must respond with a property change indicating whether the request succeeded or failed. If
+     * it failed, the Android system will remove the user.
+     *
+     * The format of the request is defined by CreateUserRequest and the format of the response by
+     * CreateUserResponse.
+     *
+     * For example, if system had 2 users (0 and 10) and a 3rd one (which is an ephemeral guest) was
+     * created, the request would be:
+     *
+     * int32[0]: 42  // request id
+     * int32[1]: 11  // Android id of the created user
+     * int32[2]: 6   // Android flags (ephemeral guest) of the created user
+     * int32[3]: 10  // current user
+     * int32[4]: 0   // current user flags (none)
+     * int32[5]: 3   // number of users
+     * int32[6]: 0   // 1st user (user 0)
+     * int32[7]: 0   // 1st user flags (none)
+     * int32[8]: 10  // 2nd user (user 10)
+     * int32[9]: 0   // 2nd user flags (none)
+     * int32[19]: 11 // 3rd user (user 11)
+     * int32[11]: 6  // 3rd user flags (ephemeral guest)
+     * string: "ElGuesto" // name of the new user
+     *
+     * Then if the request succeeded, the HAL would return:
+     *
+     * int32[0]: 42  // request id
+     * int32[1]: 1   // CreateUserStatus::SUCCESS
+     *
+     * But if it failed:
+     *
+     * int32[0]: 42  // request id
+     * int32[1]: 2   // CreateUserStatus::FAILURE
+     * string: "D'OH!" // The meaning is a blackbox - it's passed to the caller (like Settings UI),
+     *                 // which in turn can take the proper action.
+     *
+     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
+     * @access VehiclePropertyAccess:READ_WRITE
+     */
+    CREATE_USER = 0x0F09 + 0x10000000 + 0x01000000
+            + 0x00e00000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:MIXED
+    /**
+     * Called by the Android System after an Android user was removed.
+     *
+     * The HAL can use this property to remove its equivalent user.
+     *
+     * This is write-only call - the Android System is not expecting a reply from the HAL. Hence,
+     * this request should not fail - if the equivalent HAL user cannot be removed, then HAL should
+     * mark it as inactive or recover in some other way.
+     *
+     * The request is made by setting the VehiclePropValue with the contents defined by
+     * RemoveUserRequest.
+     *
+     * For example, if system had 3 users (0, 10, and 11) and user 11 was removed, the request
+     * would be:
+     *
+     * int32[0]: 42  // request id
+     * int32[1]: 11  // (Android user id of the removed user)
+     * int32[2]: 0   // (Android user flags of the removed user)
+     * int32[3]: 10  // current user
+     * int32[4]: 0   // current user flags (none)
+     * int32[5]: 2   // number of users
+     * int32[6]: 0   // 1st user (user 0)
+     * int32[7]: 0   // 1st user flags (none)
+     * int32[8]: 10  // 2nd user (user 10)
+     * int32[9]: 0   // 2nd user flags (none)
+     *
+     * @change_mode VehiclePropertyChangeMode:STATIC
+     * @access VehiclePropertyAccess:WRITE
+     */
+    REMOVE_USER = 0x0F0A + 0x10000000 + 0x01000000
+            + 0x00e00000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:MIXED
+    /**
+     * Property used to associate (or query the association) the current user with vehicle-specific
+     * identification mechanisms (such as key FOB).
+     *
+     * This is an optional user management property - the OEM could still support user management
+     * without defining it. In fact, this property could be used without supporting the core
+     * user-related functions described on INITIAL_USER_INFO.
+     *
+     * To query the association, the Android system gets the property, passing a VehiclePropValue
+     * containing the types of associations are being queried, as defined by
+     * UserIdentificationGetRequest. The HAL must return right away, returning a VehiclePropValue
+     * with a UserIdentificationResponse. Notice that user identification should have already
+     * happened while system is booting up and the VHAL implementation should only return the
+     * already identified association (like the key FOB used to unlock the car), instead of starting
+     * a new association from the get call.
+     *
+     * To associate types, the Android system sets the property, passing a VehiclePropValue
+     * containing the types and values of associations being set, as defined by the
+     * UserIdentificationSetRequest. The HAL will then use a property change event (whose
+     * VehiclePropValue is defined by UserIdentificationResponse) indicating the current status of
+     * the types after the request.
+     *
+     * For example, to query if the current user (10) is associated with the FOB that unlocked the
+     * car and a custom mechanism provided by the OEM, the request would be:
+     *
+     * int32[0]: 42  // request id
+     * int32[1]: 10  (Android user id)
+     * int32[2]: 0   (Android user flags)
+     * int32[3]: 2   (number of types queried)
+     * int32[4]: 1   (1st type queried, UserIdentificationAssociationType::KEY_FOB)
+     * int32[5]: 101 (2nd type queried, UserIdentificationAssociationType::CUSTOM_1)
+     *
+     * If the user is associated with the FOB but not with the custom mechanism, the response would
+     * be:
+     *
+     * int32[0]: 42  // request id
+     * int32[1]: 2   (number of associations in the response)
+     * int32[2]: 1   (1st type: UserIdentificationAssociationType::KEY_FOB)
+     * int32[3]: 2   (1st value: UserIdentificationAssociationValue::ASSOCIATED_CURRENT_USER)
+     * int32[4]: 101 (2st type: UserIdentificationAssociationType::CUSTOM_1)
+     * int32[5]: 4   (2nd value: UserIdentificationAssociationValue::NOT_ASSOCIATED_ANY_USER)
+     *
+     * Then to associate the user with the custom mechanism, a set request would be made:
+     *
+     * int32[0]: 43  // request id
+     * int32[1]: 10  (Android user id)
+     * int32[2]: 0   (Android user flags)
+     * int32[3]: 1   (number of associations being set)
+     * int32[4]: 101 (1st type: UserIdentificationAssociationType::CUSTOM_1)
+     * int32[5]: 1   (1st value: UserIdentificationAssociationSetValue::ASSOCIATE_CURRENT_USER)
+     *
+     * If the request succeeded, the response would be simply:
+     *
+     * int32[0]: 43  // request id
+     * int32[1]: 1   (number of associations in the response)
+     * int32[2]: 101 (1st type: UserIdentificationAssociationType::CUSTOM_1)
+     * int32[3]: 1   (1st value: UserIdentificationAssociationValue::ASSOCIATED_CURRENT_USER)
+     *
+     * Notice that the set request adds associations, but doesn't remove the existing ones. In the
+     * example above, the end state would be 2 associations (FOB and CUSTOM_1). If we wanted to
+     * associate the user with just CUSTOM_1 but not FOB, then the request should have been:
+     *
+     * int32[0]: 43  // request id
+     * int32[1]: 10  (Android user id)
+     * int32[2]: 2   (number of types set)
+     * int32[3]: 1   (1st type: UserIdentificationAssociationType::KEY_FOB)
+     * int32[4]: 2   (1st value: UserIdentificationAssociationValue::DISASSOCIATE_CURRENT_USER)
+     * int32[5]: 101 (2nd type: UserIdentificationAssociationType::CUSTOM_1)
+     * int32[6]: 1   (2nd value: UserIdentificationAssociationValue::ASSOCIATE_CURRENT_USER)
+     *
+     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
+     * @access VehiclePropertyAccess:READ_WRITE
+     */
+    USER_IDENTIFICATION_ASSOCIATION = 0x0F0B + 0x10000000 + 0x01000000
+            + 0x00e00000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:MIXED
+    /**
+     * Enable/request an EVS service.
+     *
+     * The property provides a generalized way to trigger EVS services.  VHAL
+     * should use this property to request Android to start or stop EVS service.
+     *
+     *  int32Values[0] = a type of the EVS service. The value must be one of enums in
+     *                   EvsServiceType.
+     *  int32Values[1] = the state of the EVS service. The value must be one of enums in
+     *                   EvsServiceState.
+     *
+     * For example, to enable rear view EVS service, android side can set the property value as
+     * [EvsServiceType::REAR_VIEW, EvsServiceState::ON].
+     *
+     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
+     * @access VehiclePropertyAccess:READ
+     */
+    EVS_SERVICE_REQUEST = 0x0F10 + 0x10000000 + 0x01000000
+            + 0x00410000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32_VEC
+    /**
+     * Defines a request to apply power policy.
+     *
+     * VHAL sets this property to change car power policy. Car power policy service subscribes to
+     * this property and actually changes the power policy.
+     * The request is made by setting the VehiclePropValue with the ID of a power policy which is
+     * defined at /vendor/etc/power_policy.xml. If the given ID is not defined, car power policy
+     * service ignores the request and the current power policy is maintained.
+     *
+     *   string: "sample_policy_id" // power policy ID
+     *
+     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
+     * @access VehiclePropertyAccess:READ
+     */
+    POWER_POLICY_REQ = 0x0F21 + 0x10000000 + 0x01000000
+            + 0x00100000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:STRING
+    /**
+     * Defines a request to set the power polic group used to decide a default power policy per
+     * power status transition.
+     *
+     * VHAL sets this property with the ID of a power policy group in order to set the default power
+     * policy applied at power status transition. Power policy groups are defined at
+     * /vendor/etc/power_policy.xml. If the given ID is not defined, car power policy service
+     * ignores the request.
+     * Car power policy service subscribes to this property and sets the power policy group.
+     * The actual application of power policy takes place when the system power status changes and
+     * there is a valid mapped power policy for the new power status.
+     *
+     *   string: "sample_policy_group_id" // power policy group ID
+     *
+     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
+     * @access VehiclePropertyAccess:READ
+     */
+    POWER_POLICY_GROUP_REQ = 0x0F22 + 0x10000000 + 0x01000000
+            + 0x00100000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:STRING
+    /**
+     * Notifies the current power policy to VHAL layer.
+     *
+     * Car power policy service sets this property when the current power policy is changed.
+     *
+     *   string: "sample_policy_id" // power policy ID
+     *
+     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
+     * @access VehiclePropertyAccess:READ_WRITE
+     */
+    CURRENT_POWER_POLICY = 0x0F23 + 0x10000000 + 0x01000000
+            + 0x00100000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:STRING
+    /**
+     * Defines an event that car watchdog updates to tell it's alive.
+     *
+     * Car watchdog sets this property to system uptime in milliseconds at every 3 second.
+     * During the boot, the update may take longer time.
+     *
+     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
+     * @access VehiclePropertyAccess:WRITE
+     */
+    WATCHDOG_ALIVE = 0xF31 + 0x10000000 + 0x01000000
+            + 0x00500000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT64
+    /**
+     * Defines a process terminated by car watchdog and the reason of termination.
+     *
+     *   int32Values[0]: 1         // ProcessTerminationReason showing why a process is terminated.
+     *   string: "/system/bin/log" // Process execution command.
+     *
+     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
+     * @access VehiclePropertyAccess:WRITE
+     */
+    WATCHDOG_TERMINATED_PROCESS = 0x0F32 + 0x10000000 + 0x01000000
+            + 0x00e00000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:MIXED
+    /**
+     * Defines an event that VHAL signals to car watchdog as a heartbeat.
+     *
+     * If VHAL supports this property, VHAL should write system uptime to this property at every 3
+     * second. Car watchdog subscribes to this property and checks if the property is updated at
+     * every 3 second. With the buffer time of 3 second, car watchdog waits for a heart beat to be
+     * signaled up to 6 seconds from the last heart beat. If it isn’t, car watchdog considers
+     * VHAL unhealthy and terminates it.
+     * If this property is not supported by VHAL, car watchdog doesn't check VHAL health status.
+     *
+     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
+     * @access VehiclePropertyAccess:READ
+     */
+    VHAL_HEARTBEAT = 0x0F33 + 0x10000000 + 0x01000000
+            + 0x00500000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT64
+    /**
+     * Starts the ClusterUI in cluster display.
+     *
+     * int32: the type of ClusterUI to show
+     *    0 indicates ClusterHome, that is a home screen of cluster display, and provides
+     *        the default UI and a kind of launcher functionality for cluster display.
+     *    the other values are followed by OEM's definition.
+     *
+     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
+     * @access VehiclePropertyAccess:READ
+     */
+    CLUSTER_SWITCH_UI = 0x0F34 + 0x10000000 + 0x01000000
+            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
+    /**
+     * Changes the state of the cluster display.
+     *
+     * Bounds: the area to render the cluster Activity.
+     * Inset: the area which Activity should avoid from placing any important
+     *     information.
+     *
+     * int32[0]: on/off: 0 - off, 1 - on, -1 - don't care
+     * int32[1]: Bounds - left: positive number - left position in pixels
+                                -1 - don't care (should set all Bounds fields)
+     * int32[2]: Bounds - top:    same format with 'left'
+     * int32[3]: Bounds - right:  same format with 'left'
+     * int32[4]: Bounds - bottom: same format with 'left'
+     * int32[5]: Inset - left: positive number - actual left inset value in pixels
+                               -1 - don't care (should set "don't care" all Inset fields)
+     * int32[6]: Inset - top:    same format with 'left'
+     * int32[7]: Inset - right:  same format with 'left'
+     * int32[8]: Inset - bottom: same format with 'left'
+     *
+     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
+     * @access VehiclePropertyAccess:READ
+     */
+    CLUSTER_DISPLAY_STATE = 0x0F35 + 0x10000000 + 0x01000000
+            + 0x00410000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32_VEC
+    /**
+     * Reports the current display state and ClusterUI state.
+     *
+     * ClusterHome will send this message when it handles CLUSTER_SWITCH_UI, CLUSTER_DISPLAY_STATE.
+     *
+     * In addition, ClusterHome should send this message when it starts for the first time.
+     * When ClusterOS receives this message and if the internal expectation is different with the
+     * received message, then it should send CLUSTER_SWITCH_UI, CLUSTER_DISPLAY_STATE again to
+     * match the state.
+     *
+     * int32[0]: on/off: 0 - off, 1 - on
+     * int32[1]: Bounds - left
+     * int32[2]: Bounds - top
+     * int32[3]: Bounds - right
+     * int32[4]: Bounds - bottom
+     * int32[5]: Inset - left
+     * int32[6]: Inset - top
+     * int32[7]: Inset - right
+     * int32[8]: Inset - bottom
+     * int32[9]: the type of ClusterUI in the fullscreen or main screen.
+     *    0 indicates ClusterHome.
+     *    the other values are followed by OEM's definition.
+     * int32[10]: the type of ClusterUI in sub screen if the currently two UIs are shown.
+     *    -1 indicates the area isn't used any more.
+     * bytes: the array to represent the availability of ClusterUI.
+     *     0 indicates non-available and 1 indicates available.
+     *     For example, let's assume a car supports 3 OEM defined ClusterUI like HOME, MAPS, CALL,
+     *     and it only supports CALL UI only when the cellular network is available. Then, if the
+     *     nework is avaibale, it'll send [1 1 1], and if it's out of network, it'll send [1 1 0].
+     *
+     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
+     * @access VehiclePropertyAccess:WRITE
+     */
+    CLUSTER_REPORT_STATE = 0x0F36 + 0x10000000 + 0x01000000
+            + 0x00e00000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:MIXED
+    /**
+     * Requests to change the cluster display state to show some ClusterUI.
+     *
+     * When the current display state is off and ClusterHome sends this message to ClusterOS to
+     * request to turn the display on to show some specific ClusterUI.
+     * ClusterOS should response this with CLUSTER_DISPLAY_STATE.
+     *
+     * int32: the type of ClusterUI to show
+     *
+     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
+     * @access VehiclePropertyAccess:WRITE
+     */
+    CLUSTER_REQUEST_DISPLAY = 0x0F37 + 0x10000000 + 0x01000000
+            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
+    /**
+     * Informs the current navigation state.
+     *
+     * bytes: the serialized message of NavigationStateProto.
+     *
+     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
+     * @access VehiclePropertyAccess:WRITE
+     */
+    CLUSTER_NAVIGATION_STATE = 0x0F38 + 0x10000000 + 0x01000000
+            + 0x00700000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:BYTES
+    /**
+     * Electronic Toll Collection card type.
+     *
+     * This property indicates the type of ETC card in this vehicle.
+     * If the head unit is aware of an ETC card attached to the vehicle, this property should
+     * return the type of card attached; otherwise, this property should be UNAVAILABLE.
+     *
+     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
+     * @access VehiclePropertyAccess:READ
+     * @data_enum ElectronicTollCollectionCardType
+     */
+    ELECTRONIC_TOLL_COLLECTION_CARD_TYPE = 0x0F39 + 0x10000000 + 0x01000000
+            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
+    /**
+     * Electronic Toll Collection card status.
+     *
+     * This property indicates the status of ETC card in this vehicle.
+     * If the head unit is aware of an ETC card attached to the vehicle,
+     * ELECTRONIC_TOLL_COLLECTION_CARD_TYPE gives that status of the card; otherwise,
+     * this property should be UNAVAILABLE.
+     *
+     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
+     * @access VehiclePropertyAccess:READ
+     * @data_enum ElectronicTollCollectionCardStatus
+     */
+    ELECTRONIC_TOLL_COLLECTION_CARD_STATUS = 0x0F3A + 0x10000000 + 0x01000000
+            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
+}
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehiclePropertyAccess.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehiclePropertyAccess.aidl
new file mode 100644
index 0000000..055f96f
--- /dev/null
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehiclePropertyAccess.aidl
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+package android.hardware.automotive.vehicle;
+
+/**
+ * Property config defines the capabilities of it. User of the API
+ * must first get the property config to understand the output from get()
+ * commands and also to ensure that set() or events commands are in sync with
+ * the expected output.
+ */
+// @VintfStability
+@Backing(type="int")
+enum VehiclePropertyAccess {
+    NONE = 0x00,
+
+    READ = 0x01,
+    WRITE = 0x02,
+    READ_WRITE = 0x03,
+}
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehiclePropertyChangeMode.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehiclePropertyChangeMode.aidl
new file mode 100644
index 0000000..2628730
--- /dev/null
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehiclePropertyChangeMode.aidl
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+package android.hardware.automotive.vehicle;
+
+/**
+ * This describes how value of property can change.
+ */
+// @VintfStability
+@Backing(type="int")
+enum VehiclePropertyChangeMode {
+    /**
+     * Property of this type must never be changed. Subscription is not supported
+     * for these properties.
+     */
+    STATIC = 0x00,
+
+    /**
+     * Properties of this type must report when there is a change.
+     * IVehicle#get call must return the current value.
+     * Set operation for this property is assumed to be asynchronous. When the
+     * property is read (using IVehicle#get) after IVehicle#set, it may still
+     * return old value until underlying H/W backing this property has actually
+     * changed the state. Once state is changed, the property must dispatch
+     * changed value as event.
+     */
+    ON_CHANGE = 0x01,
+
+    /**
+     * Properties of this type change continuously and require a fixed rate of
+     * sampling to retrieve the data.  Implementers may choose to send extra
+     * notifications on significant value changes.
+     */
+    CONTINUOUS = 0x02,
+}
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehiclePropertyGroup.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehiclePropertyGroup.aidl
new file mode 100644
index 0000000..529a46d
--- /dev/null
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehiclePropertyGroup.aidl
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+package android.hardware.automotive.vehicle;
+
+// @VintfStability
+@Backing(type="int")
+enum VehiclePropertyGroup {
+    /**
+     * Properties declared in AOSP must use this flag.
+     */
+    SYSTEM = 0x10000000,
+
+    /**
+     * Properties declared by vendors must use this flag.
+     */
+    VENDOR = 0x20000000,
+
+    MASK = 0xf0000000,
+}
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehiclePropertyStatus.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehiclePropertyStatus.aidl
new file mode 100644
index 0000000..6dea0d1
--- /dev/null
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehiclePropertyStatus.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+package android.hardware.automotive.vehicle;
+
+/**
+ * Property status is a dynamic value that may change based on the vehicle state.
+ */
+// @VintfStability
+@Backing(type="int")
+enum VehiclePropertyStatus {
+    /** Property is available and behaving normally */
+    AVAILABLE = 0x00,
+    /**
+     * A property in this state is not available for reading and writing.  This
+     * is a transient state that depends on the availability of the underlying
+     * implementation (e.g. hardware or driver). It MUST NOT be used to
+     * represent features that this vehicle is always incapable of.  A get() of
+     * a property in this state MAY return an undefined value, but MUST
+     * correctly describe its status as UNAVAILABLE A set() of a property in
+     * this state MAY return NOT_AVAILABLE. The HAL implementation MUST ignore
+     * the value of the status field when writing a property value coming from
+     * Android.
+     */
+    UNAVAILABLE = 0x01,
+    /** There is an error with this property. */
+    ERROR = 0x02,
+}
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehiclePropertyType.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehiclePropertyType.aidl
new file mode 100644
index 0000000..4591e92
--- /dev/null
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehiclePropertyType.aidl
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+package android.hardware.automotive.vehicle;
+
+/**
+ * Enumerates supported data type for VehicleProperty.
+ *
+ * Used to create property ID in VehicleProperty enum.
+ */
+// @VintfStability
+@Backing(type="int")
+enum VehiclePropertyType {
+    STRING = 0x00100000,
+    BOOLEAN = 0x00200000,
+    INT32 = 0x00400000,
+    INT32_VEC = 0x00410000,
+    INT64 = 0x00500000,
+    INT64_VEC = 0x00510000,
+    FLOAT = 0x00600000,
+    FLOAT_VEC = 0x00610000,
+    BYTES = 0x00700000,
+
+    /**
+     * Any combination of scalar or vector types. The exact format must be
+     * provided in the description of the property.
+     *
+     * For vendor MIXED type properties, configArray needs to be formatted in this
+     * structure.
+     * configArray[0], 1 indicates the property has a String value
+     * configArray[1], 1 indicates the property has a Boolean value .
+     * configArray[2], 1 indicates the property has an Integer value.
+     * configArray[3], the number indicates the size of Integer[] in the property.
+     * configArray[4], 1 indicates the property has a Long value.
+     * configArray[5], the number indicates the size of Long[] in the property.
+     * configArray[6], 1 indicates the property has a Float value.
+     * configArray[7], the number indicates the size of Float[] in the property.
+     * configArray[8], the number indicates the size of byte[] in the property.
+     * For example:
+     * {@code configArray = {1, 1, 1, 3, 0, 0, 0, 0, 0}} indicates the property has
+     * a String value, a Boolean value, an Integer value and an array with 3 integers.
+     */
+    MIXED = 0x00e00000,
+
+    MASK = 0x00ff0000,
+}
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleSeatOccupancyState.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleSeatOccupancyState.aidl
new file mode 100644
index 0000000..a17c9f0
--- /dev/null
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleSeatOccupancyState.aidl
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+package android.hardware.automotive.vehicle;
+
+/**
+ * Used by seat occupancy to enumerate the current occupancy state of the seat.
+ */
+// @VintfStability
+@Backing(type="int")
+enum VehicleSeatOccupancyState {
+    UNKNOWN = 0,
+    VACANT = 1,
+    OCCUPIED = 2,
+}
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleTurnSignal.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleTurnSignal.aidl
new file mode 100644
index 0000000..cec86db
--- /dev/null
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleTurnSignal.aidl
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+package android.hardware.automotive.vehicle;
+
+// @VintfStability
+@Backing(type="int")
+enum VehicleTurnSignal {
+    NONE = 0x00,
+    RIGHT = 0x01,
+    LEFT = 0x02,
+}
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleUnit.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleUnit.aidl
new file mode 100644
index 0000000..3fc69de
--- /dev/null
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleUnit.aidl
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+package android.hardware.automotive.vehicle;
+
+/**
+ * Units used for int or float type with no attached enum types.
+ */
+// @VintfStability
+@Backing(type="int")
+enum VehicleUnit {
+    SHOULD_NOT_USE = 0x000,
+    METER_PER_SEC = 0x01,
+    RPM = 0x02,
+    HERTZ = 0x03,
+    PERCENTILE = 0x10,
+    MILLIMETER = 0x20,
+    METER = 0x21,
+    KILOMETER = 0x23,
+    MILE = 0x24,
+    CELSIUS = 0x30,
+    FAHRENHEIT = 0x31,
+    KELVIN = 0x32,
+    MILLILITER = 0x40,
+    LITER = 0x41,
+    /**
+     * deprecated. Use US_GALLON instead.
+     */
+    GALLON = 0x42,
+    US_GALLON = 0x42,
+    IMPERIAL_GALLON = 0x43,
+    NANO_SECS = 0x50,
+    SECS = 0x53,
+    YEAR = 0x59,
+    WATT_HOUR = 0x60,
+    MILLIAMPERE = 0x61,
+    MILLIVOLT = 0x62,
+    MILLIWATTS = 0x63,
+    AMPERE_HOURS = 0x64,
+    KILOWATT_HOUR = 0x65,
+    KILOPASCAL = 0x70,
+    PSI = 0x71,
+    BAR = 0x72,
+    DEGREES = 0x80,
+    MILES_PER_HOUR = 0x90,
+    KILOMETERS_PER_HOUR = 0x91,
+}
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleVendorPermission.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleVendorPermission.aidl
new file mode 100644
index 0000000..46a66e1
--- /dev/null
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleVendorPermission.aidl
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+package android.hardware.automotive.vehicle;
+
+/**
+ * Used by SUPPORT_CUSTOMIZE_VENDOR_PERMISSION to indicate the permission of vendor properties.
+ */
+// @VintfStability
+@Backing(type="int")
+enum VehicleVendorPermission {
+    PERMISSION_DEFAULT = 0x00000000,
+    PERMISSION_SET_VENDOR_CATEGORY_WINDOW = 0X00000001,
+    PERMISSION_GET_VENDOR_CATEGORY_WINDOW = 0x00000002,
+    PERMISSION_SET_VENDOR_CATEGORY_DOOR = 0x00000003,
+    PERMISSION_GET_VENDOR_CATEGORY_DOOR = 0x00000004,
+    PERMISSION_SET_VENDOR_CATEGORY_SEAT = 0x00000005,
+    PERMISSION_GET_VENDOR_CATEGORY_SEAT = 0x00000006,
+    PERMISSION_SET_VENDOR_CATEGORY_MIRROR = 0x00000007,
+    PERMISSION_GET_VENDOR_CATEGORY_MIRROR = 0x00000008,
+    PERMISSION_SET_VENDOR_CATEGORY_INFO = 0x00000009,
+    PERMISSION_GET_VENDOR_CATEGORY_INFO = 0x0000000A,
+    PERMISSION_SET_VENDOR_CATEGORY_ENGINE = 0x0000000B,
+    PERMISSION_GET_VENDOR_CATEGORY_ENGINE = 0x0000000C,
+    PERMISSION_SET_VENDOR_CATEGORY_HVAC = 0x0000000D,
+    PERMISSION_GET_VENDOR_CATEGORY_HVAC = 0x0000000E,
+    PERMISSION_SET_VENDOR_CATEGORY_LIGHT = 0x0000000F,
+    PERMISSION_GET_VENDOR_CATEGORY_LIGHT = 0x00000010,
+    PERMISSION_SET_VENDOR_CATEGORY_1 = 0x00010000,
+    PERMISSION_GET_VENDOR_CATEGORY_1 = 0x00011000,
+    PERMISSION_SET_VENDOR_CATEGORY_2 = 0x00020000,
+    PERMISSION_GET_VENDOR_CATEGORY_2 = 0x00021000,
+    PERMISSION_SET_VENDOR_CATEGORY_3 = 0x00030000,
+    PERMISSION_GET_VENDOR_CATEGORY_3 = 0x00031000,
+    PERMISSION_SET_VENDOR_CATEGORY_4 = 0x00040000,
+    PERMISSION_GET_VENDOR_CATEGORY_4 = 0x00041000,
+    PERMISSION_SET_VENDOR_CATEGORY_5 = 0x00050000,
+    PERMISSION_GET_VENDOR_CATEGORY_5 = 0x00051000,
+    PERMISSION_SET_VENDOR_CATEGORY_6 = 0x00060000,
+    PERMISSION_GET_VENDOR_CATEGORY_6 = 0x00061000,
+    PERMISSION_SET_VENDOR_CATEGORY_7 = 0x00070000,
+    PERMISSION_GET_VENDOR_CATEGORY_7 = 0x00071000,
+    PERMISSION_SET_VENDOR_CATEGORY_8 = 0x00080000,
+    PERMISSION_GET_VENDOR_CATEGORY_8 = 0x00081000,
+    PERMISSION_SET_VENDOR_CATEGORY_9 = 0x00090000,
+    PERMISSION_GET_VENDOR_CATEGORY_9 = 0x00091000,
+    PERMISSION_SET_VENDOR_CATEGORY_10 = 0x000A0000,
+    PERMISSION_GET_VENDOR_CATEGORY_10 = 0x000A1000,
+    PERMISSION_NOT_ACCESSIBLE = 0xF0000000,
+}
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VmsAvailabilityStateIntegerValuesIndex.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VmsAvailabilityStateIntegerValuesIndex.aidl
new file mode 100644
index 0000000..74e944d
--- /dev/null
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VmsAvailabilityStateIntegerValuesIndex.aidl
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+package android.hardware.automotive.vehicle;
+
+import android.hardware.automotive.vehicle.VmsBaseMessageIntegerValuesIndex;
+
+/**
+ * An availability state is sent to the subscribers in response to a change in the available
+ * layers as part of a VmsMessageType.AVAILABILITY_CHANGE message, or in response to a
+ * VmsMessageType.AVAILABILITY_REQUEST message as part of a VmsMessageType.AVAILABILITY_RESPONSE.
+ * The VMS service issues monotonically increasing sequence numbers, and in case a subscriber
+ * receives a smaller sequence number, it should ignore the message. An available associated layer
+ * is a layer with a list of publisher IDs:
+ * - Layer type
+ * - Layer subtype
+ * - Layer version
+ * - Number of publisher IDs (N)
+ * - N x publisher ID
+ */
+// @VintfStability
+@Backing(type="int")
+enum VmsAvailabilityStateIntegerValuesIndex {
+    /*
+     * The message type as enumerated by VmsMessageType enum.
+     */
+    MESSAGE_TYPE = 0,
+    SEQUENCE_NUMBER = 1,
+    NUMBER_OF_ASSOCIATED_LAYERS = 2,
+    LAYERS_START = 3,
+}
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VmsBaseMessageIntegerValuesIndex.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VmsBaseMessageIntegerValuesIndex.aidl
new file mode 100644
index 0000000..a3a2e18
--- /dev/null
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VmsBaseMessageIntegerValuesIndex.aidl
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+package android.hardware.automotive.vehicle;
+
+/**
+ * Every VMS message starts with the type of the message from the VmsMessageType enum.
+ * Messages with no parameters such as VmsMessageType.AVAILABILITY_REQUEST,
+ * VmsMessageType.SUBSCRIPTIONS_REQUEST and VmsMessageType.DATA are also based on this enum.
+ */
+// @VintfStability
+@Backing(type="int")
+enum VmsBaseMessageIntegerValuesIndex {
+    /*
+     * The message type as enumerated by VmsMessageType enum.
+     */
+    MESSAGE_TYPE = 0,
+}
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VmsMessageType.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VmsMessageType.aidl
new file mode 100644
index 0000000..bdffde7
--- /dev/null
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VmsMessageType.aidl
@@ -0,0 +1,141 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+package android.hardware.automotive.vehicle;
+
+/**
+ * This enum lists the types of supported VMS messages. It is used as the first
+ * integer in the vehicle property integers array and determines how the rest of
+ * the message is decoded.
+ */
+// @VintfStability
+@Backing(type="int")
+enum VmsMessageType {
+    /**
+     * A request from the subscribers to the VMS service to subscribe to a layer.
+     *
+     * This message type uses enum VmsMessageWithLayerIntegerValuesIndex.
+     */
+    SUBSCRIBE = 1,
+    /**
+     * A request from the subscribers to the VMS service to subscribe to a layer from a specific
+     * publisher.
+     *
+     * This message type uses enum VmsMessageWithLayerAndPublisherIdIntegerValuesIndex.
+     */
+    SUBSCRIBE_TO_PUBLISHER = 2,
+    /**
+     * A request from the subscribers to the VMS service to unsubscribes from a layer.
+     *
+     * This message type uses enum VmsMessageWithLayerIntegerValuesIndex.
+     */
+    UNSUBSCRIBE = 3,
+    /**
+     * A request from the subscribers to the VMS service to unsubscribes from a layer from a
+     * specific publisher.
+     *
+     * This message type uses enum VmsMessageWithLayerAndPublisherIdIntegerValuesIndex.
+     */
+    UNSUBSCRIBE_TO_PUBLISHER = 4,
+    /**
+     * Information from the publishers to the VMS service about the layers which the client can
+     * publish.
+     *
+     * This message type uses enum VmsOfferingMessageIntegerValuesIndex.
+     */
+    OFFERING = 5,
+    /**
+     * A request from the subscribers to the VMS service to get the available layers.
+     *
+     * This message type uses enum VmsBaseMessageIntegerValuesIndex.
+     */
+    AVAILABILITY_REQUEST = 6,
+    /**
+     * A request from the publishers to the VMS service to get the layers with subscribers.
+     *
+     * This message type uses enum VmsBaseMessageIntegerValuesIndex.
+     */
+    SUBSCRIPTIONS_REQUEST = 7,
+    /**
+     * A response from the VMS service to the subscribers to a VmsMessageType.AVAILABILITY_REQUEST
+     *
+     * This message type uses enum VmsAvailabilityStateIntegerValuesIndex.
+     */
+    AVAILABILITY_RESPONSE = 8,
+    /**
+     * A notification from the VMS service to the subscribers on a change in the available layers.
+     *
+     * This message type uses enum VmsAvailabilityStateIntegerValuesIndex.
+     */
+    AVAILABILITY_CHANGE = 9,
+    /**
+     * A response from the VMS service to the publishers to a VmsMessageType.SUBSCRIPTIONS_REQUEST
+     *
+     * This message type uses enum VmsSubscriptionsStateIntegerValuesIndex.
+     */
+    SUBSCRIPTIONS_RESPONSE = 10,
+    /**
+     * A notification from the VMS service to the publishers on a change in the layers with
+     * subscribers.
+     *
+     * This message type uses enum VmsSubscriptionsStateIntegerValuesIndex.
+     */
+    SUBSCRIPTIONS_CHANGE = 11,
+    /**
+     * A message from the VMS service to the subscribers or from the publishers to the VMS service
+     * with a serialized VMS data packet as defined in the VMS protocol.
+     *
+     * This message type uses enum VmsMessageWithLayerAndPublisherIdIntegerValuesIndex.
+     */
+    DATA = 12,
+    /**
+     * A request from the publishers to the VMS service to get a Publisher ID for a serialized VMS
+     * provider description packet as defined in the VMS protocol.
+     *
+     * This message type uses enum VmsBaseMessageIntegerValuesIndex.
+     */
+    PUBLISHER_ID_REQUEST = 13,
+    /**
+     * A response from the VMS service to the publisher that contains a provider description packet
+     * and the publisher ID assigned to it.
+     *
+     * This message type uses enum VmsPublisherInformationIntegerValuesIndex.
+     */
+    PUBLISHER_ID_RESPONSE = 14,
+    /**
+     * A request from the subscribers to the VMS service to get information for a Publisher ID.
+     *
+     * This message type uses enum VmsPublisherInformationIntegerValuesIndex.
+     */
+    PUBLISHER_INFORMATION_REQUEST = 15,
+    /**
+     * A response from the VMS service to the subscribers that contains a provider description
+     * packet and the publisher ID assigned to it.
+     *
+     * This message type uses enum VmsPublisherInformationIntegerValuesIndex.
+     */
+    PUBLISHER_INFORMATION_RESPONSE = 16,
+    /**
+     * A notification indicating that the sender has been reset.
+     *
+     * The receiving party must reset its internal state and respond to the
+     * sender with a START_SESSION message as acknowledgement.
+     *
+     * This message type uses enum VmsStartSessionMessageIntegerValuesIndex.
+     */
+    START_SESSION = 17,
+    // LAST_VMS_MESSAGE_TYPE = START_SESSION,
+}
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VmsMessageWithLayerAndPublisherIdIntegerValuesIndex.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VmsMessageWithLayerAndPublisherIdIntegerValuesIndex.aidl
new file mode 100644
index 0000000..594ddbc
--- /dev/null
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VmsMessageWithLayerAndPublisherIdIntegerValuesIndex.aidl
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+package android.hardware.automotive.vehicle;
+
+import android.hardware.automotive.vehicle.VmsMessageWithLayerIntegerValuesIndex;
+
+/*
+ * A VMS message with a layer and publisher ID is sent as part of a
+ * VmsMessageType.SUBSCRIBE_TO_PUBLISHER, VmsMessageType.UNSUBSCRIBE_TO_PUBLISHER messages and
+ * VmsMessageType.DATA .
+ */
+// @VintfStability
+@Backing(type="int")
+enum VmsMessageWithLayerAndPublisherIdIntegerValuesIndex {
+    /*
+     * The message type as enumerated by VmsMessageType enum.
+     */
+    MESSAGE_TYPE = 0,
+    LAYER_TYPE = 1,
+    LAYER_SUBTYPE = 2,
+    LAYER_VERSION = 3,
+    PUBLISHER_ID = 4,
+}
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VmsMessageWithLayerIntegerValuesIndex.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VmsMessageWithLayerIntegerValuesIndex.aidl
new file mode 100644
index 0000000..e3a6126
--- /dev/null
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VmsMessageWithLayerIntegerValuesIndex.aidl
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+package android.hardware.automotive.vehicle;
+
+import android.hardware.automotive.vehicle.VmsBaseMessageIntegerValuesIndex;
+
+/*
+ * A VMS message with a layer is sent as part of a VmsMessageType.SUBSCRIBE or
+ * VmsMessageType.UNSUBSCRIBE messages.
+ *
+ * The layer type is defined in the VMS protocol, and the subtype and version are
+ * controlled by the implementer of the publisher.
+ */
+// @VintfStability
+@Backing(type="int")
+enum VmsMessageWithLayerIntegerValuesIndex {
+    /*
+     * The message type as enumerated by VmsMessageType enum.
+     */
+    MESSAGE_TYPE = 0,
+    LAYER_TYPE = 1,
+    LAYER_SUBTYPE = 2,
+    LAYER_VERSION = 3,
+}
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VmsOfferingMessageIntegerValuesIndex.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VmsOfferingMessageIntegerValuesIndex.aidl
new file mode 100644
index 0000000..9dc7a58
--- /dev/null
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VmsOfferingMessageIntegerValuesIndex.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+package android.hardware.automotive.vehicle;
+
+import android.hardware.automotive.vehicle.VmsBaseMessageIntegerValuesIndex;
+
+/*
+ * An offering can be sent by publishers as part of VmsMessageType.OFFERING in order to
+ * advertise which layers they can publish and under which constraints: e.g., I can publish Layer X
+ * if someone else will publish Layer Y.
+ * The offering contains the publisher ID which was assigned to the publisher by the VMS service.
+ * A single offering is represented as:
+ * - Layer type
+ * - Layer subtype
+ * - Layer version
+ * - Number of dependencies (N)
+ * - N x (Layer type, Layer subtype, Layer version)
+ */
+// @VintfStability
+@Backing(type="int")
+enum VmsOfferingMessageIntegerValuesIndex {
+    /*
+     * The message type as enumerated by VmsMessageType enum.
+     */
+    MESSAGE_TYPE = 0,
+    PUBLISHER_ID = 1,
+    NUMBER_OF_OFFERS = 2,
+    OFFERING_START = 3,
+}
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VmsPublisherInformationIntegerValuesIndex.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VmsPublisherInformationIntegerValuesIndex.aidl
new file mode 100644
index 0000000..32049cc
--- /dev/null
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VmsPublisherInformationIntegerValuesIndex.aidl
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+package android.hardware.automotive.vehicle;
+
+import android.hardware.automotive.vehicle.VmsBaseMessageIntegerValuesIndex;
+
+/*
+ * Publishers send the VMS service their information and assigned in response a publisher ID.
+ * Subscribers can request the publisher information for a publisher ID they received in other
+ * messages.
+ */
+// @VintfStability
+@Backing(type="int")
+enum VmsPublisherInformationIntegerValuesIndex {
+    /*
+     * The message type as enumerated by VmsMessageType enum.
+     */
+    MESSAGE_TYPE = 0,
+    PUBLISHER_ID = 1,
+}
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VmsStartSessionMessageIntegerValuesIndex.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VmsStartSessionMessageIntegerValuesIndex.aidl
new file mode 100644
index 0000000..95f2d6d
--- /dev/null
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VmsStartSessionMessageIntegerValuesIndex.aidl
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+package android.hardware.automotive.vehicle;
+
+import android.hardware.automotive.vehicle.VmsBaseMessageIntegerValuesIndex;
+
+/*
+ * Handshake data sent as part of a VmsMessageType.START_SESSION message.
+ *
+ * A new session is initiated by sending a START_SESSION message with the
+ * sender's identifier populated and the receiver's identifier set to -1.
+ *
+ * Identifier values are independently generated, but must be non-negative, and
+ * increase monotonically between reboots.
+ *
+ * Upon receiving a START_SESSION with a mis-matching identifier, the receiver
+ * must clear any cached VMS offering or subscription state and acknowledge the
+ * new session by responding with a START_SESSION message that populates both
+ * identifier fields.
+ *
+ * Any VMS messages received between initiation and completion of the handshake
+ * must be discarded.
+ */
+// @VintfStability
+@Backing(type="int")
+enum VmsStartSessionMessageIntegerValuesIndex {
+    /*
+     * The message type as enumerated by VmsMessageType enum.
+     */
+    MESSAGE_TYPE = 0,
+    /*
+     * Identifier field for the Android system service.
+     */
+    SERVICE_ID = 1,
+    /*
+     * Identifier field for the HAL client process.
+     */
+    CLIENT_ID = 2,
+}
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VmsSubscriptionsStateIntegerValuesIndex.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VmsSubscriptionsStateIntegerValuesIndex.aidl
new file mode 100644
index 0000000..87d59e5
--- /dev/null
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VmsSubscriptionsStateIntegerValuesIndex.aidl
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+package android.hardware.automotive.vehicle;
+
+import android.hardware.automotive.vehicle.VmsBaseMessageIntegerValuesIndex;
+
+/**
+ * A subscriptions state is sent to the publishers in response to a change in the subscriptions
+ * as part of a VmsMessageType.SUBSCRIPTIONS_CHANGE, or in response to a
+ * VmsMessageType.SUBSCRIPTIONS_REQUEST message as part of VmsMessageType.SUBSCRIPTIONS_RESPONSE.
+ * The VMS service issues monotonically increasing sequence numbers, and in case a subscriber
+ * receives a smaller sequence number it should ignore the message. The subscriptions are sent as a
+ * list of layers followed by a list of associated layers: {Sequence number, N, M, N x layer, M x
+ * associated layer} A subscribed layer is represented as three integers:
+ * - Layer type
+ * - Layer subtype
+ * - Layer version
+ * A subscribed associated layer is a layer with a list of publisher IDs. It is represented as:
+ * - Layer type
+ * - Layer subtype
+ * - Layer version
+ * - Number of publisher IDs (N)
+ * - N x publisher ID
+ */
+// @VintfStability
+@Backing(type="int")
+enum VmsSubscriptionsStateIntegerValuesIndex {
+    /*
+     * The message type as enumerated by VmsMessageType enum.
+     */
+    MESSAGE_TYPE = 0,
+    SEQUENCE_NUMBER = 1,
+    NUMBER_OF_LAYERS = 2,
+    NUMBER_OF_ASSOCIATED_LAYERS = 3,
+    SUBSCRIPTIONS_START = 4,
+}
diff --git a/automotive/vehicle/tools/translate_vehicle_props.py b/automotive/vehicle/tools/translate_vehicle_props.py
new file mode 100644
index 0000000..59eb17d
--- /dev/null
+++ b/automotive/vehicle/tools/translate_vehicle_props.py
@@ -0,0 +1,151 @@
+#!/usr/bin/python
+
+# Copyright (C) 2021 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.
+#
+"""Tools to translate VehicleProperty from types.hal into AIDL format.
+   To store it to a file:
+   $ python translate_vehicle_props.py types.hal > VehicleProperty.aidl
+"""
+import re
+import sys
+
+ENUM_TYPE_TO_PARSE = [ "VehiclePropertyType", "VehiclePropertyGroup", "VehicleArea" ]
+VEHICLE_PROP_ENUM = "VehicleProperty"
+
+RE_COMMENT_BEGIN = re.compile("\s*\/\*\*")
+RE_COMMENT_END = re.compile("\s*\*\/")
+RE_COMMENT_SINGLE_LINE = re.compile("\s*\/\*\*.*\*\/")
+
+RE_ENUM_START = re.compile("\s*enum\s*(\w+)\s?.*\{")
+RE_ENUM_END = re.compile("\s*\}\;")
+
+RE_ENUM_ELEMENT = re.compile("\s*(\w+)\s*\=\s*(\w+),")
+
+RE_VEHICLE_PROP_ELEMENT = re.compile("\s*(\w+)\s*\=\s*\(?\s*(\w+)\s*\|?\s*(\w+\:\w+)?\s*\|?\s*(\w+:\w+)?\s*\|?\s*(\w+:\w+)?\s*\)?,")
+
+DBG_COMMENT = False
+DBG_ENUM = False
+
+class HIDLParser:
+    def __init__(self):
+        self.inEnum = False
+        self.currentEnumName = None
+        self.inVehicleProperty = False
+        self.inComment = False
+        self.recentComments = []
+        self.currentType = None
+        self.enumMap = {}
+        self.outputMsg = []
+        self.multilineFormat = []
+        self.outputMsg.append("package android.hardware.automotive.vehicle\n\n")
+
+    def addRecentCommentToMsg(self):
+        self.outputMsg.extend(self.recentComments)
+        self.recentComments = []
+
+    def addToMsg(self, msg):
+        self.outputMsg.append(msg)
+
+    def printOutputMsg(self):
+        msg = "".join(self.outputMsg)
+        print(msg)
+
+    def parseLine(self, line):
+        if self.inComment:
+            self.recentComments.append(line)
+            if RE_COMMENT_END.match(line):
+                self.inComment = False
+                if DBG_COMMENT:
+                    print("Comment end:{}".format(self.recentComments))
+            return
+        elif RE_COMMENT_BEGIN.match(line):
+            self.recentComments = []
+            self.recentComments.append(line)
+            if RE_COMMENT_SINGLE_LINE.match(line):
+                if DBG_COMMENT:
+                    print("Single line Comment:{}".format(self.recentComments))
+                return
+            self.inComment = True
+            if DBG_COMMENT:
+                print("Comment start")
+            return
+
+        if self.inEnum:
+            if RE_ENUM_END.match(line):
+                self.inEnum = False
+                if DBG_ENUM:
+                    print("End enum {}".format(self.currentEnumName))
+            else:
+                matchElement = RE_ENUM_ELEMENT.match(line);
+                if matchElement:
+                    elementName = matchElement.group(1)
+                    elementValue = matchElement.group(2)
+                    self.enumMap[self.currentEnumName + ':' + elementName] = elementValue
+        elif self.inVehicleProperty:
+            if RE_ENUM_END.match(line):
+                self.inVehicleProperty = False
+                self.addToMsg("}\n")
+            else:
+                text = line.strip()
+                if len(text) == 0:
+                    self.multilineFormat = []
+                else:
+                    self.multilineFormat.append(text)
+                    textToMatch = "".join(self.multilineFormat)
+                    match = RE_VEHICLE_PROP_ELEMENT.match(textToMatch)
+                    if match:
+                        self.multilineFormat = []
+                        name = match.group(1)
+                        val = match.group(2)
+                        type1 = match.group(3)
+                        self.addRecentCommentToMsg()
+                        if type1 == None: # one line case
+                            self.addToMsg("    {} = {},\n".format(name, val))
+                        else:
+                            type2 = match.group(4)
+                            type3 = match.group(5)
+                            self.addToMsg("    {} = {} + {} + {} + {}, // {},{},{}\n".\
+                            format(name, val, self.enumMap[type1], self.enumMap[type3],\
+                                self.enumMap[type2], type1, type3, type2))
+        else:
+            matchEnum = RE_ENUM_START.match(line)
+            if matchEnum:
+                enumName = matchEnum.group(1)
+                if enumName in ENUM_TYPE_TO_PARSE:
+                    self.currentEnumName = enumName
+                    self.inEnum = True
+                    if DBG_ENUM:
+                        print("enum {}".format(enumName))
+                elif enumName == VEHICLE_PROP_ENUM:
+                    self.inVehicleProperty = True
+                    self.addRecentCommentToMsg()
+                    self.addToMsg("@Backing(type=\"int\")\nenum VehicleProperty {\n")
+                    if DBG_ENUM:
+                        print("VehicleProperty starts, all enum values {}".format(self.enumMap))
+
+
+def main():
+    if len(sys.argv) != 2:
+        print("Usage: {} types_hal_file".format(sys.argv[0]))
+        sys.exit(1)
+    file_name = sys.argv[1]
+    with open(file_name, 'r') as f:
+        parser = HIDLParser()
+        for line in f.readlines():
+            parser.parseLine(line)
+        parser.printOutputMsg()
+
+if __name__ == "__main__":
+    main()
diff --git a/compatibility_matrices/compatibility_matrix.current.xml b/compatibility_matrices/compatibility_matrix.current.xml
index 8b6e841..d4b49af 100644
--- a/compatibility_matrices/compatibility_matrix.current.xml
+++ b/compatibility_matrices/compatibility_matrix.current.xml
@@ -85,12 +85,19 @@
             <instance>default</instance>
         </interface>
     </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.automotive.vehicle</name>
+        <interface>
+            <name>IVehicle</name>
+            <regex-instance>.*</regex-instance>
+        </interface>
+    </hal>
     <hal format="hidl" optional="true">
         <name>android.hardware.automotive.vehicle</name>
         <version>2.0</version>
         <interface>
             <name>IVehicle</name>
-            <instance>default</instance>
+            <regex-instance>.*</regex-instance>
         </interface>
     </hal>
     <hal format="hidl" optional="true">
@@ -522,12 +529,20 @@
     </hal>
     <hal format="hidl" optional="true">
         <name>android.hardware.soundtrigger</name>
-        <version>2.3</version>
+        <version>2.3-4</version>
         <interface>
             <name>ISoundTriggerHw</name>
             <instance>default</instance>
         </interface>
     </hal>
+    <hal format="aidl" optional="true">
+         <name>android.hardware.soundtrigger3</name>
+         <version>1</version>
+         <interface>
+             <name>ISoundTriggerHw</name>
+             <instance>default</instance>
+         </interface>
+    </hal>
     <hal format="hidl" optional="true">
         <name>android.hardware.tetheroffload.config</name>
         <version>1.0</version>
diff --git a/soundtrigger/2.4/Android.bp b/soundtrigger/2.4/Android.bp
new file mode 100644
index 0000000..44befc3
--- /dev/null
+++ b/soundtrigger/2.4/Android.bp
@@ -0,0 +1,30 @@
+// This file is autogenerated by hidl-gen -Landroidbp.
+
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "hardware_interfaces_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["hardware_interfaces_license"],
+}
+
+hidl_interface {
+    name: "android.hardware.soundtrigger@2.4",
+    root: "android.hardware",
+    srcs: [
+        "ISoundTriggerHw.hal",
+        "ISoundTriggerHwCallback.hal",
+        "ISoundTriggerHwGlobalCallback.hal",
+    ],
+    interfaces: [
+        "android.hardware.audio.common@2.0",
+        "android.hardware.soundtrigger@2.0",
+        "android.hardware.soundtrigger@2.1",
+        "android.hardware.soundtrigger@2.2",
+        "android.hardware.soundtrigger@2.3",
+        "android.hidl.base@1.0",
+        "android.hidl.safe_union@1.0",
+    ],
+    gen_java: true,
+}
diff --git a/soundtrigger/2.4/ISoundTriggerHw.hal b/soundtrigger/2.4/ISoundTriggerHw.hal
new file mode 100644
index 0000000..fd39303
--- /dev/null
+++ b/soundtrigger/2.4/ISoundTriggerHw.hal
@@ -0,0 +1,190 @@
+/*
+ * Copyright 2021 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.
+ */
+
+package android.hardware.soundtrigger@2.4;
+
+import @2.0::SoundModelHandle;
+import @2.1::ISoundTriggerHw.SoundModel;
+import @2.1::ISoundTriggerHw.PhraseSoundModel;
+import @2.3::ISoundTriggerHw;
+import @2.3::RecognitionConfig;
+import ISoundTriggerHwCallback;
+import ISoundTriggerHwGlobalCallback;
+
+/**
+ * SoundTrigger HAL interface. Used for hardware recognition of hotwords
+ * and other sounds.
+ *
+ * Important notes about the threading model:
+ * ==========================================
+ * Both this interface and the corresponding callback interface use a synchronized calling
+ * convention. This model comes with some advantages, but also with some risks of deadlocks if the
+ * implementation does not handle this correctly. Please consider the following:
+ * - After stopRecognition() returns no more recognition events for that model may be sent. This
+ *   implies that any queues holding such events must be flushed before the call returns and that
+ *   may imply that callback from the HAL to the client are done while stopRecognition() is blocked.
+ *   This is OK, and supported by the framework.
+ * - Similarly, the same relationship applies between unloadModel() and subsequent callbacks to
+ *   modelUnloaded().
+ * - Other than these two cases, calls into the HAL *MAY NOT* block on callbacks from the HAL, or
+ *   else deadlock conditions may result, which may be handled by rebooting of the HAL process and
+ *   cause service outages.
+ *
+ * Similarly, it is expected that a single call to startRecognition() generates at most one event
+ * (the model automatically becomes stopped when the event occurs, until explicitly started again)
+ * and that after a modelUnloaded() event no more events would be sent regarding the model.
+ * Note that a getModelState() call may generate a recognition event, but this event DOES NOT modify
+ * the model state - the model remains started.
+ *
+ * The HAL is expected to correctly handle a stopRecognition() call even after it sent an event
+ * indicating that recognition is stopped and an unloadModel() call even after it sent an event
+ * indicating that it has been unloaded. This is required in order to prevent race conditions
+ * between these calls. This also implies that model handles should generally not be reused until
+ * explicitly unloaded. To avoid the rare possibility of running out of handles, the framework will
+ * call unloadModel() on models that have been preemptively unloaded by the HAL.
+ *
+ * Due to the asynchronous nature of recognition events and preemptive model unloading, the HAL must
+ * correctly handle requests that would have been valid before an event has been delivered, but
+ * became moot as result of the event. Namely:
+ * - stopRecognition() may be called on a model that has already delivered an event and became
+ *   inactive as a result. The HAL must return a successful return code in this case.
+ * - Furthermore, if a model is preemptively unloaded after it triggers (typically, this would
+ *   happen when it is first aborted and immediately preemptively unloaded), stopRecognition() may
+ *   be called on it. The HAL must return a successful return code in this case.
+ * - startRecognition() may be called on a model that has been preemptively unloaded. In this case,
+ *   the HAL must return -EBUSY to indicate that the operation is temporarily unsuccessful.
+ * - unloadSoundModel() may be called on a model that has been preemptively unloaded. The HAL must
+ *   return a successful return code in this case.
+ *
+ * Important notes about resource constraints and concurrency
+ * =========================================================
+ * Up until this version, the framework would enforce concurrency constraints expressed by the
+ * Properties presented by the soundtrigger instance. These include constraints on the maximum
+ * amount of models that can be loaded at the same time and on running recognition while capturing
+ * from the microphone.
+ * This version changes the approach for how these constraints are modeled, both offering the HAL
+ * implementation more flexibility and simplifying the framework's job in enforcing these
+ * limitations. Note that there is no change for how the framework behaves with earlier versions,
+ * everything described below only applies to this version and onward.
+ * The way this is achieved is as following:
+ * - The framework will no longer enforce constraints on concurrent loading of models, as expressed
+ *   in the Properties.maxSoundModels field (this property is merely a hint at this point and may be
+ *   deprecated in the future.
+ * - The framework will no longer enforce constraints on concurrency of audio recording and
+ *   soundtrigger operation, as expressed in the Properties.concurrentCapture field (this property
+ *   is merely a hint at this point and may be deprecated in the future).
+ * - The framework will no longer enforce constraints on concurrent loading of models, as expressed
+ *   in the Properties (these properties are merely hints at this point and may be deprecated in the
+ *   future.
+ * - The HAL implementation is free to reject starting of any model at any time by having the
+ *   respective start*() method return -EBUSY.
+ * - The HAL implementation is free to reject loading of any model at any time by having the
+ *   respective load*() method return -EBUSY.
+ * - The HAL implementation is free to preemptively stop a previously started model at its own
+ *   discretion (for example, if a higher priority use-case which cannot coexist with detection
+ *   has been requested). The HAL must notify the framework of the preemption by sending a
+ *   recognition event with an `ABORT` status. The implementation must NOT attempt to restart the
+ *   recognition automatically when conditions change.
+ * - The HAL implementation is free to preemptively unload a previously loaded model at its own
+ *   discretion (for example, if a higher-priority model is being loaded and the two cannot
+ *   coexist). When doing so, it must first abort the detection if active (as per above) and then
+ *   notify the framework of the unload using the newly added modelUnloaded callback.
+ * - When conditions change, such that a model that couldn't previously load or start or that had
+ *   previously been preemptively stopped or unloaded, the HAL must notify the framework via the
+ *   newly added tryAgain() callback. This callback is not a guarantee that any operation would now
+ *   succeed, but merely a hint that retrying something that had previously failed, now MAY succeed.
+ *   Until this callback arrives, the framework may assume that any operation that had previously
+ *   failed or aborted would still fail if retried, so the implementation should not forget to
+ *   deliver it. There are no guarantees regarding how the framework may respond to this event and
+ *   the order in which it may choose to reload/restart its models. Typically, as result of this
+ *   event the framework will make a single attempt per model to bring this model to its desired
+ *   state (loaded, started).
+ */
+interface ISoundTriggerHw extends @2.3::ISoundTriggerHw {
+    /**
+     * This will get called at most once per every attachment to the service.
+     *
+     * All events not tied to a specific model should go through this callback.
+     */
+    registerGlobalCallback(ISoundTriggerHwGlobalCallback callback);
+
+    /**
+     * Load a sound model. Once loaded, recognition of this model can be
+     * started and stopped.
+     * The implementation returns a unique handle used by other functions
+     * (unloadSoundModel(), startRecognition*(), etc...
+     *
+     * Must have the exact same semantics as loadSoundModel from ISoundTriggerHw@2.3 except that the
+     * return values have changed and that there is no cookie provided (the implementation may pass
+     * any value to the callback, as it is ignored).
+     *
+     * @param soundModel A SoundModel structure describing the sound model
+     *     to load.
+     * @param callback The callback interface on which the soundModelCallback*()
+     *     method must be called upon completion and modelUnloaded() upon preempted unload.
+     * @return retval Operation completion status: 0 in case of success,
+     *     -EBUSY in case the operation is temporarily unavailable (but possible in general).
+     * @return modelHandle A unique handle assigned by the HAL for use by the
+     *     framework when controlling activity for this sound model.
+     */
+    loadSoundModel_2_4(SoundModel soundModel, ISoundTriggerHwCallback callback)
+            generates (int32_t retval, SoundModelHandle modelHandle);
+
+    /**
+     * Load a key phrase sound model. Once loaded, recognition of this model can
+     * be started and stopped. Only one active recognition per model at a time.
+     * The SoundTrigger service must handle concurrent recognition requests by
+     * different users/applications on the same model.
+     * The implementation returns a unique handle used by other functions
+     * (unloadSoundModel(), startRecognition*(), etc...
+     *
+     * Must have the exact same semantics as loadPhraseSoundModel from ISoundTriggerHw@2.3 except
+     * that the return values have changed and that there is no cookie provided (the implementation
+     * may pass any value to the callback, as it is ignored).
+     *
+     * @param soundModel A PhraseSoundModel structure describing the sound model
+     *     to load.
+     * @param callback The callback interface on which the soundModelCallback*()
+     *     method must be called upon completion and modelUnloaded() upon preempted unload.
+     * @return retval Operation completion status: 0 in case of success,
+     *     -EBUSY in case the operation is temporarily unavailable (but possible in general).
+     * @return modelHandle A unique handle assigned by the HAL for use by the
+     *     framework when controlling activity for this sound model.
+     */
+    loadPhraseSoundModel_2_4(PhraseSoundModel soundModel, ISoundTriggerHwCallback callback)
+            generates (int32_t retval, SoundModelHandle modelHandle);
+
+    /**
+     * Start recognition on a given model. Only one recognition active
+     * at a time per model. Once recognition succeeds or fails, the callback
+     * associated with the model handle is called.
+     *
+     * Must have the exact same semantics as startRecognition from ISoundTriggerHw@2.3 except that
+     * there are different expectations of the return value and that there is no cookie provided
+     * (the implementation may pass any value to the callback, as it is ignored).
+     *
+     * @param modelHandle the handle of the sound model to use for recognition
+     * @param config A RecognitionConfig structure containing attributes of the
+     *     recognition to perform
+     * @param callback The callback interface on which the recognitionCallback()
+     *     method must be called upon recognition.
+     * @return retval Operation completion status: 0 in case of success,
+     *     -EBUSY in case the operation is temporarily unavailable (but possible in general), or in
+     *            case model has been preemtively unloaded.
+     */
+    startRecognition_2_4(SoundModelHandle modelHandle, RecognitionConfig config)
+            generates (int32_t retval);
+};
diff --git a/soundtrigger/2.4/ISoundTriggerHwCallback.hal b/soundtrigger/2.4/ISoundTriggerHwCallback.hal
new file mode 100644
index 0000000..594deb0
--- /dev/null
+++ b/soundtrigger/2.4/ISoundTriggerHwCallback.hal
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2021 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.
+ */
+
+package android.hardware.soundtrigger@2.4;
+
+import @2.0::SoundModelHandle;
+import @2.1::ISoundTriggerHwCallback;
+
+/**
+ * SoundTrigger HAL per-model Callback interface.
+ */
+interface ISoundTriggerHwCallback extends @2.1::ISoundTriggerHwCallback {
+    /**
+     * Callback method called by the HAL when a model has been unloaded at the HAL implementation's
+     * discretion. Only a stopped model may be unloaded.
+     * This event is NOT sent as part of an unload sequence initiated by the client.
+     *
+     * @param model The model handle.
+     */
+    modelUnloaded(SoundModelHandle model);
+};
diff --git a/soundtrigger/2.4/ISoundTriggerHwGlobalCallback.hal b/soundtrigger/2.4/ISoundTriggerHwGlobalCallback.hal
new file mode 100644
index 0000000..2f1a977
--- /dev/null
+++ b/soundtrigger/2.4/ISoundTriggerHwGlobalCallback.hal
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2021 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.
+ */
+
+package android.hardware.soundtrigger@2.4;
+
+/**
+ * SoundTrigger HAL callback interface for events not associated with a particular model.
+ */
+interface ISoundTriggerHwGlobalCallback {
+    /**
+     * Callback method called by the HAL whenever internal conditions have been made available, such
+     * that a call that would previously have failed with an -EBUSY status may now succeed.
+     * There is no guarantee that any call would succeed following this event. It is merely a hint
+     * to the client that it may retry.
+     * Conversely, any call that have failed previously with -EBUSY is guaranteed to fail again if
+     * retried, until this callback is delivered.
+     */
+    onResourcesAvailable();
+};
diff --git a/soundtrigger/2.4/cli/Android.bp b/soundtrigger/2.4/cli/Android.bp
new file mode 100644
index 0000000..8d0979b
--- /dev/null
+++ b/soundtrigger/2.4/cli/Android.bp
@@ -0,0 +1,17 @@
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "hardware_interfaces_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["hardware_interfaces_license"],
+}
+
+java_binary {
+    name: "sthal_cli_2.4",
+    wrapper: "sthal_cli_2.4",
+    srcs: ["java/**/*.java"],
+    static_libs: [
+        "android.hardware.soundtrigger-V2.4-java",
+    ],
+}
diff --git a/soundtrigger/2.4/cli/OWNERS b/soundtrigger/2.4/cli/OWNERS
new file mode 100644
index 0000000..e21b66e
--- /dev/null
+++ b/soundtrigger/2.4/cli/OWNERS
@@ -0,0 +1 @@
+include /media/java/android/media/soundtrigger_middleware/OWNERS
diff --git a/soundtrigger/2.4/cli/java/android/hardware/soundtrigger/V2_4/cli/SthalCli.java b/soundtrigger/2.4/cli/java/android/hardware/soundtrigger/V2_4/cli/SthalCli.java
new file mode 100644
index 0000000..4931105
--- /dev/null
+++ b/soundtrigger/2.4/cli/java/android/hardware/soundtrigger/V2_4/cli/SthalCli.java
@@ -0,0 +1,401 @@
+/*
+ * Copyright 2021 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.
+ */
+package android.hardware.soundtrigger.V2_4.cli;
+
+import android.hardware.soundtrigger.V2_0.PhraseRecognitionExtra;
+import android.hardware.soundtrigger.V2_0.RecognitionMode;
+import android.hardware.soundtrigger.V2_0.SoundModelType;
+import android.hardware.soundtrigger.V2_3.OptionalModelParameterRange;
+import android.hardware.soundtrigger.V2_4.ISoundTriggerHw;
+import android.hardware.soundtrigger.V2_4.ISoundTriggerHwCallback;
+import android.hardware.soundtrigger.V2_4.ISoundTriggerHwGlobalCallback;
+import android.os.HidlMemoryUtil;
+import android.os.HwBinder;
+import android.os.RemoteException;
+import android.os.SystemProperties;
+
+import java.util.Scanner;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+
+/**
+ * This is a quick-and-dirty sound trigger HAL console mock.
+ *
+ * It would only work on userdebug builds.
+ *
+ * When this app is started, it will initially:
+ * - Register a ISoundTriggerHw HAL with an instance name "mock".
+ * - Set a sysprop that tells SoundTriggerMiddlewareService to try to connect to the mock instance
+ * rather than the default one.
+ * - Reboot the real (default) HAL.
+ *
+ * In response to that, SoundTriggerMiddlewareService is going to connect to the mock HAL and resume
+ * normal operation.
+ *
+ * Our mock HAL will print to stdout every call it receives as well as expose a basic set of
+ * operations for sending event callbacks to the client. This allows us to simulate the frameworks
+ * behavior in response to different HAL behaviors.
+ */
+public class SthalCli {
+    private static SoundTriggerImpl mService;
+    private static final Scanner scanner = new Scanner(System.in);
+
+    public static void main(String[] args) {
+        try {
+            System.out.println("Registering mock STHAL");
+            HwBinder.setTrebleTestingOverride(true);
+            mService = new SoundTriggerImpl();
+            mService.registerAsService("mock");
+
+            System.out.println("Rebooting STHAL");
+            SystemProperties.set("debug.soundtrigger_middleware.use_mock_hal", "2");
+            SystemProperties.set("sys.audio.restart.hal", "1");
+
+            while (processCommand()) ;
+        } catch (Exception e) {
+            e.printStackTrace();
+        } finally {
+            cleanup();
+        }
+    }
+
+    private static void cleanup() {
+        System.out.println("Cleaning up.");
+        SystemProperties.set("debug.soundtrigger_middleware.use_mock_hal", null);
+        HwBinder.setTrebleTestingOverride(false);
+    }
+
+    private static boolean processCommand() {
+        String line = scanner.nextLine();
+        String[] tokens = line.split("\\s+");
+        if (tokens.length < 1) {
+            return false;
+        }
+        switch (tokens[0]) {
+            case "q":
+                return false;
+
+            case "a":
+                mService.sendOnResourcesAvailable();
+                return true;
+
+            case "u":
+                mService.sendModelUnloaded(Integer.parseInt(tokens[1]));
+                return true;
+
+            case "r":
+                mService.sendRecognitionEvent(Integer.parseInt(tokens[1]),
+                        Integer.parseInt(tokens[2]));
+                return true;
+
+            case "p":
+                mService.sendPhraseRecognitionEvent(Integer.parseInt(tokens[1]),
+                        Integer.parseInt(tokens[2]));
+                return true;
+
+            case "d":
+                mService.dumpModels();
+                return true;
+
+            case "h":
+                System.out.print("Available commands:\n" + "h - help\n" + "q - quit\n"
+                        + "a - send onResourcesAvailable event\n"
+                        + "u <model> - send modelUnloaded event\n"
+                        + "r <model> <status> - send recognitionEvent\n"
+                        + "p <model> <status> - send phraseRecognitionEvent\n"
+                        + "d - dump models\n");
+
+            default:
+                return true;
+        }
+    }
+
+    private static class SoundTriggerImpl extends ISoundTriggerHw.Stub {
+        static class Model {
+            final ISoundTriggerHwCallback callback;
+            final SoundModel model;
+            final PhraseSoundModel phraseModel;
+            public android.hardware.soundtrigger.V2_3.RecognitionConfig config = null;
+
+            Model(ISoundTriggerHwCallback callback, SoundModel model) {
+                this.callback = callback;
+                this.model = model;
+                this.phraseModel = null;
+            }
+
+            Model(ISoundTriggerHwCallback callback, PhraseSoundModel model) {
+                this.callback = callback;
+                this.model = null;
+                this.phraseModel = model;
+            }
+        }
+
+        private ISoundTriggerHwGlobalCallback mGlobalCallback;
+        private final ConcurrentMap<Integer, Model> mLoadedModels = new ConcurrentHashMap<>();
+        private int mHandleCounter = 1;
+
+        public void dumpModels() {
+            mLoadedModels.forEach((handle, model) -> {
+                System.out.println("+++ Model " + handle);
+                System.out.println("    config = " + model.config);
+                android.hardware.soundtrigger.V2_3.RecognitionConfig recognitionConfig =
+                        model.config;
+                if (recognitionConfig != null) {
+                    System.out.println("    ACTIVE recognitionConfig = " + recognitionConfig);
+                } else {
+                    System.out.println("    INACTIVE");
+                }
+            });
+        }
+
+        public void sendOnResourcesAvailable() {
+            if (mGlobalCallback != null) {
+                try {
+                    mGlobalCallback.onResourcesAvailable();
+                } catch (RemoteException e) {
+                    e.printStackTrace();
+                }
+            }
+        }
+
+        public void sendRecognitionEvent(int modelHandle, int status) {
+            Model model = mLoadedModels.get(modelHandle);
+            if (model != null && model.config != null) {
+                android.hardware.soundtrigger.V2_1.ISoundTriggerHwCallback.RecognitionEvent event =
+                        new android.hardware.soundtrigger.V2_1.ISoundTriggerHwCallback.RecognitionEvent();
+                event.header.model = modelHandle;
+                event.header.type = SoundModelType.GENERIC;
+                event.header.status = status;
+                event.header.captureSession = model.config.base.header.captureHandle;
+                event.header.captureAvailable = true;
+                event.header.audioConfig.channelMask = 16;
+                event.header.audioConfig.format = 1;
+                event.header.audioConfig.sampleRateHz = 16000;
+                event.data = HidlMemoryUtil.byteArrayToHidlMemory(new byte[0]);
+                try {
+                    model.callback.recognitionCallback_2_1(event, 0);
+                } catch (RemoteException e) {
+                    e.printStackTrace();
+                }
+                model.config = null;
+            }
+        }
+
+        public void sendPhraseRecognitionEvent(int modelHandle, int status) {
+            Model model = mLoadedModels.get(modelHandle);
+            if (model != null && model.config != null) {
+                android.hardware.soundtrigger.V2_1.ISoundTriggerHwCallback.PhraseRecognitionEvent
+                        event =
+                        new android.hardware.soundtrigger.V2_1.ISoundTriggerHwCallback.PhraseRecognitionEvent();
+                event.common.header.model = modelHandle;
+                event.common.header.type = SoundModelType.KEYPHRASE;
+                event.common.header.status = status;
+                event.common.header.captureSession = model.config.base.header.captureHandle;
+                event.common.header.captureAvailable = true;
+                event.common.header.audioConfig.channelMask = 16;
+                event.common.header.audioConfig.format = 1;
+                event.common.header.audioConfig.sampleRateHz = 16000;
+                event.common.data = HidlMemoryUtil.byteArrayToHidlMemory(new byte[0]);
+                if (!model.phraseModel.phrases.isEmpty()) {
+                    PhraseRecognitionExtra extra = new PhraseRecognitionExtra();
+                    extra.id = model.phraseModel.phrases.get(0).id;
+                    extra.confidenceLevel = 100;
+                    extra.recognitionModes = model.phraseModel.phrases.get(0).recognitionModes;
+                    event.phraseExtras.add(extra);
+                }
+                try {
+                    model.callback.phraseRecognitionCallback_2_1(event, 0);
+                } catch (RemoteException e) {
+                    e.printStackTrace();
+                }
+                model.config = null;
+            }
+        }
+
+        public void sendModelUnloaded(int modelHandle) {
+            Model model = mLoadedModels.remove(modelHandle);
+            if (model != null) {
+                try {
+                    model.callback.modelUnloaded(modelHandle);
+                } catch (RemoteException e) {
+                    e.printStackTrace();
+                }
+            }
+        }
+
+        @Override
+        public void registerGlobalCallback(ISoundTriggerHwGlobalCallback callback) {
+            System.out.println("registerGlobalCallback()");
+            mGlobalCallback = callback;
+        }
+
+        @Override
+        public void loadSoundModel_2_4(SoundModel soundModel, ISoundTriggerHwCallback callback,
+                loadSoundModel_2_4Callback _hidl_cb) {
+            int handle = mHandleCounter++;
+            System.out.printf("loadSoundModel_2_4(soundModel=%s) -> %d%n", soundModel, handle);
+            mLoadedModels.put(handle, new Model(callback, soundModel));
+            _hidl_cb.onValues(0, handle);
+        }
+
+        @Override
+        public void loadPhraseSoundModel_2_4(PhraseSoundModel soundModel,
+                ISoundTriggerHwCallback callback, loadPhraseSoundModel_2_4Callback _hidl_cb) {
+            int handle = mHandleCounter++;
+            System.out.printf("loadPhraseSoundModel_2_4(soundModel=%s) -> %d%n", soundModel,
+                    handle);
+            mLoadedModels.put(handle, new Model(callback, soundModel));
+            _hidl_cb.onValues(0, handle);
+        }
+
+        @Override
+        public int startRecognition_2_4(int modelHandle,
+                android.hardware.soundtrigger.V2_3.RecognitionConfig config) {
+            System.out.printf("startRecognition_2_4(modelHandle=%d)%n", modelHandle);
+            Model model = mLoadedModels.get(modelHandle);
+            if (model != null) {
+                model.config = config;
+            }
+            return 0;
+        }
+
+        @Override
+        public void getProperties_2_3(getProperties_2_3Callback _hidl_cb) {
+            System.out.println("getProperties_2_3()");
+            android.hardware.soundtrigger.V2_3.Properties properties =
+                    new android.hardware.soundtrigger.V2_3.Properties();
+            properties.base.implementor = "Android";
+            properties.base.description = "Mock STHAL";
+            properties.base.maxSoundModels = 2;
+            properties.base.maxKeyPhrases = 1;
+            properties.base.recognitionModes =
+                    RecognitionMode.VOICE_TRIGGER | RecognitionMode.GENERIC_TRIGGER;
+            _hidl_cb.onValues(0, properties);
+        }
+
+        @Override
+        public void queryParameter(int modelHandle, int modelParam,
+                queryParameterCallback _hidl_cb) {
+            _hidl_cb.onValues(0, new OptionalModelParameterRange());
+        }
+
+        @Override
+        public int getModelState(int modelHandle) {
+            System.out.printf("getModelState(modelHandle=%d)%n", modelHandle);
+            return 0;
+        }
+
+        @Override
+        public int unloadSoundModel(int modelHandle) {
+            System.out.printf("unloadSoundModel(modelHandle=%d)%n", modelHandle);
+            return 0;
+        }
+
+        @Override
+        public int stopRecognition(int modelHandle) {
+            System.out.printf("stopRecognition(modelHandle=%d)%n", modelHandle);
+            Model model = mLoadedModels.get(modelHandle);
+            if (model != null) {
+                model.config = null;
+            }
+            return 0;
+        }
+
+        @Override
+        public void debug(android.os.NativeHandle fd, java.util.ArrayList<String> options) {
+            if (!options.isEmpty()) {
+                switch (options.get(0)) {
+                    case "reboot":
+                        System.out.println("Received a reboot request. Exiting.");
+                        cleanup();
+                        System.exit(1);
+                }
+            }
+        }
+
+        ////////////////////////////////////////////////////////////////////////////////////////////
+        // Everything below is not implemented and not expected to be called.
+
+        @Override
+        public int startRecognition_2_3(int modelHandle,
+                android.hardware.soundtrigger.V2_3.RecognitionConfig config) {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public int setParameter(int modelHandle, int modelParam, int value) {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public void getParameter(int modelHandle, int modelParam, getParameterCallback _hidl_cb) {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public void loadSoundModel_2_1(SoundModel soundModel,
+                android.hardware.soundtrigger.V2_1.ISoundTriggerHwCallback callback, int cookie,
+                loadSoundModel_2_1Callback _hidl_cb) {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public void loadPhraseSoundModel_2_1(PhraseSoundModel soundModel,
+                android.hardware.soundtrigger.V2_1.ISoundTriggerHwCallback callback, int cookie,
+                loadPhraseSoundModel_2_1Callback _hidl_cb) {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public int startRecognition_2_1(int modelHandle, RecognitionConfig config,
+                android.hardware.soundtrigger.V2_1.ISoundTriggerHwCallback callback, int cookie) {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public void getProperties(getPropertiesCallback _hidl_cb) {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public void loadSoundModel(
+                android.hardware.soundtrigger.V2_0.ISoundTriggerHw.SoundModel soundModel,
+                android.hardware.soundtrigger.V2_0.ISoundTriggerHwCallback callback, int cookie,
+                loadSoundModelCallback _hidl_cb) {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public void loadPhraseSoundModel(
+                android.hardware.soundtrigger.V2_0.ISoundTriggerHw.PhraseSoundModel soundModel,
+                android.hardware.soundtrigger.V2_0.ISoundTriggerHwCallback callback, int cookie,
+                loadPhraseSoundModelCallback _hidl_cb) {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public int startRecognition(int modelHandle,
+                android.hardware.soundtrigger.V2_0.ISoundTriggerHw.RecognitionConfig config,
+                android.hardware.soundtrigger.V2_0.ISoundTriggerHwCallback callback, int cookie) {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public int stopAllRecognitions() {
+            throw new UnsupportedOperationException();
+        }
+    }
+}
diff --git a/soundtrigger/2.4/cli/sthal_cli_2.4 b/soundtrigger/2.4/cli/sthal_cli_2.4
new file mode 100644
index 0000000..0801464
--- /dev/null
+++ b/soundtrigger/2.4/cli/sthal_cli_2.4
@@ -0,0 +1,7 @@
+#!/system/bin/sh
+# Script to start "sthal_cli_2.4" on the device
+#
+base=/system
+export CLASSPATH=$base/framework/sthal_cli_2.4.jar
+exec app_process $base/bin android.hardware.soundtrigger.V2_4.cli.SthalCli "$@"
+
diff --git a/soundtrigger/2.4/vts/functional/Android.bp b/soundtrigger/2.4/vts/functional/Android.bp
new file mode 100644
index 0000000..4b7ae91
--- /dev/null
+++ b/soundtrigger/2.4/vts/functional/Android.bp
@@ -0,0 +1,41 @@
+//
+// Copyright (C) 2021 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.
+//
+
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "hardware_interfaces_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["hardware_interfaces_license"],
+}
+
+cc_test {
+    name: "VtsHalSoundtriggerV2_4TargetTest",
+    defaults: ["VtsHalTargetTestDefaults"],
+    srcs: ["VtsHalSoundtriggerV2_4TargetTest.cpp"],
+    static_libs: [
+        "android.hardware.soundtrigger@2.0",
+        "android.hardware.soundtrigger@2.1",
+        "android.hardware.soundtrigger@2.2",
+        "android.hardware.soundtrigger@2.3",
+        "android.hardware.soundtrigger@2.4",
+    ],
+    test_suites: [
+        "general-tests",
+        "vts",
+    ],
+}
diff --git a/soundtrigger/2.4/vts/functional/VtsHalSoundtriggerV2_4TargetTest.cpp b/soundtrigger/2.4/vts/functional/VtsHalSoundtriggerV2_4TargetTest.cpp
new file mode 100644
index 0000000..13d7005
--- /dev/null
+++ b/soundtrigger/2.4/vts/functional/VtsHalSoundtriggerV2_4TargetTest.cpp
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+#define LOG_TAG "SoundTriggerHidlHalTest"
+
+#include <android-base/logging.h>
+#include <android/hardware/audio/common/2.0/types.h>
+#include <android/hardware/soundtrigger/2.4/ISoundTriggerHwGlobalCallback.h>
+#include <android/hardware/soundtrigger/2.4/ISoundTriggerHw.h>
+#include <gtest/gtest.h>
+#include <hidl/GtestPrinter.h>
+#include <hidl/ServiceManagement.h>
+
+using ::android::sp;
+using ::android::hardware::Return;
+using ::android::hardware::Status;
+using ::android::hardware::soundtrigger::V2_4::ISoundTriggerHw;
+using ::android::hardware::soundtrigger::V2_4::ISoundTriggerHwGlobalCallback;
+
+/**
+ * Test class holding the instance of the SoundTriggerHW service to test.
+ * The passed parameter is the registered name of the implementing service
+ * supplied by INSTANTIATE_TEST_SUITE_P() call.
+ */
+class SoundTriggerHidlTest : public testing::TestWithParam<std::string> {
+public:
+    void SetUp() override {
+        mSoundtrigger = ISoundTriggerHw::getService(GetParam());
+
+        ASSERT_NE(mSoundtrigger, nullptr);
+        LOG(INFO) << "Test is remote " << mSoundtrigger->isRemote();
+    }
+
+protected:
+    sp<ISoundTriggerHw> mSoundtrigger;
+};
+
+/**
+ * Empty test is in place to ensure service is initialized.
+ * Due to the nature of SoundTrigger HAL providing an interface for
+ * proprietary or vendor specific implementations, limited testing on
+ * individual APIs is possible.
+ */
+TEST_P(SoundTriggerHidlTest, ServiceIsInstantiated) {}
+
+class GlobalCallback : public ISoundTriggerHwGlobalCallback {
+    Return<void> onResourcesAvailable() override {
+        return Status::ok();
+    }
+};
+
+/**
+ * Test ISoundTriggerHw::registerGlobalCallback method
+ *
+ * Verifies that:
+ * - the implementation implements the method
+ * - the method returns no error
+ */
+TEST_P(SoundTriggerHidlTest, RegisterGlobalCallback) {
+    Return<void> hidlReturn;
+    sp<ISoundTriggerHwGlobalCallback> callback = new GlobalCallback();
+    hidlReturn = mSoundtrigger->registerGlobalCallback(callback);
+    EXPECT_TRUE(hidlReturn.isOk());
+}
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(SoundTriggerHidlTest);
+
+INSTANTIATE_TEST_SUITE_P(
+        PerInstance, SoundTriggerHidlTest,
+        testing::ValuesIn(android::hardware::getAllHalInstanceNames(ISoundTriggerHw::descriptor)),
+        android::hardware::PrintInstanceNameToString);
diff --git a/soundtrigger/aidl/Android.bp b/soundtrigger/aidl/Android.bp
new file mode 100644
index 0000000..fcccc27
--- /dev/null
+++ b/soundtrigger/aidl/Android.bp
@@ -0,0 +1,37 @@
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "hardware_interfaces_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["hardware_interfaces_license"],
+}
+
+aidl_interface {
+    name: "android.hardware.soundtrigger3",
+    vendor_available: true,
+    flags: ["-Werror", "-Weverything", ],
+    srcs: [
+        "android/hardware/soundtrigger3/ISoundTriggerHw.aidl",
+        "android/hardware/soundtrigger3/ISoundTriggerHwCallback.aidl",
+        "android/hardware/soundtrigger3/ISoundTriggerHwGlobalCallback.aidl",
+    ],
+    stability: "vintf",
+    imports: [
+        "android.media.soundtrigger.types",
+    ],
+    backend: {
+        cpp: {
+            // prefer NDK backend which can be used anywhere
+            enabled: false,
+        },
+        java: {
+            sdk_version: "module_current",
+        },
+        ndk: {
+            vndk: {
+                enabled: true,
+            },
+        },
+    },
+}
diff --git a/soundtrigger/aidl/aidl_api/android.hardware.soundtrigger3/current/android/hardware/soundtrigger3/ISoundTriggerHw.aidl b/soundtrigger/aidl/aidl_api/android.hardware.soundtrigger3/current/android/hardware/soundtrigger3/ISoundTriggerHw.aidl
new file mode 100644
index 0000000..bbfe7d9
--- /dev/null
+++ b/soundtrigger/aidl/aidl_api/android.hardware.soundtrigger3/current/android/hardware/soundtrigger3/ISoundTriggerHw.aidl
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2021 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 FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.soundtrigger3;
+@VintfStability
+interface ISoundTriggerHw {
+  android.media.soundtrigger.Properties getProperties();
+  void registerGlobalCallback(in android.hardware.soundtrigger3.ISoundTriggerHwGlobalCallback callback);
+  int loadSoundModel(in android.media.soundtrigger.SoundModel soundModel, in android.hardware.soundtrigger3.ISoundTriggerHwCallback callback);
+  int loadPhraseSoundModel(in android.media.soundtrigger.PhraseSoundModel soundModel, in android.hardware.soundtrigger3.ISoundTriggerHwCallback callback);
+  void unloadSoundModel(in int modelHandle);
+  void startRecognition(in int modelHandle, in int deviceHandle, in int ioHandle, in android.media.soundtrigger.RecognitionConfig config);
+  void stopRecognition(in int modelHandle);
+  void forceRecognitionEvent(in int modelHandle);
+  @nullable android.media.soundtrigger.ModelParameterRange queryParameter(in int modelHandle, in android.media.soundtrigger.ModelParameter modelParam);
+  int getParameter(in int modelHandle, in android.media.soundtrigger.ModelParameter modelParam);
+  void setParameter(in int modelHandle, in android.media.soundtrigger.ModelParameter modelParam, in int value);
+}
diff --git a/soundtrigger/aidl/aidl_api/android.hardware.soundtrigger3/current/android/hardware/soundtrigger3/ISoundTriggerHwCallback.aidl b/soundtrigger/aidl/aidl_api/android.hardware.soundtrigger3/current/android/hardware/soundtrigger3/ISoundTriggerHwCallback.aidl
new file mode 100644
index 0000000..152dfed
--- /dev/null
+++ b/soundtrigger/aidl/aidl_api/android.hardware.soundtrigger3/current/android/hardware/soundtrigger3/ISoundTriggerHwCallback.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2021 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 FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.soundtrigger3;
+@VintfStability
+interface ISoundTriggerHwCallback {
+  void modelUnloaded(in int model);
+  void phraseRecognitionCallback(in int model, in android.media.soundtrigger.PhraseRecognitionEvent event);
+  void recognitionCallback(in int model, in android.media.soundtrigger.RecognitionEvent event);
+}
diff --git a/soundtrigger/aidl/aidl_api/android.hardware.soundtrigger3/current/android/hardware/soundtrigger3/ISoundTriggerHwGlobalCallback.aidl b/soundtrigger/aidl/aidl_api/android.hardware.soundtrigger3/current/android/hardware/soundtrigger3/ISoundTriggerHwGlobalCallback.aidl
new file mode 100644
index 0000000..6dfee9f
--- /dev/null
+++ b/soundtrigger/aidl/aidl_api/android.hardware.soundtrigger3/current/android/hardware/soundtrigger3/ISoundTriggerHwGlobalCallback.aidl
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2021 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 FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.soundtrigger3;
+@VintfStability
+interface ISoundTriggerHwGlobalCallback {
+  void onResourcesAvailable();
+}
diff --git a/soundtrigger/aidl/android/hardware/soundtrigger3/ISoundTriggerHw.aidl b/soundtrigger/aidl/android/hardware/soundtrigger3/ISoundTriggerHw.aidl
new file mode 100644
index 0000000..2a3fc64
--- /dev/null
+++ b/soundtrigger/aidl/android/hardware/soundtrigger3/ISoundTriggerHw.aidl
@@ -0,0 +1,269 @@
+/*
+ * Copyright 2021 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.
+ */
+
+package android.hardware.soundtrigger3;
+
+import android.hardware.soundtrigger3.ISoundTriggerHwCallback;
+import android.hardware.soundtrigger3.ISoundTriggerHwGlobalCallback;
+
+import android.media.soundtrigger.PhraseSoundModel;
+import android.media.soundtrigger.Properties;
+import android.media.soundtrigger.RecognitionConfig;
+import android.media.soundtrigger.SoundModel;
+import android.media.soundtrigger.ModelParameter;
+import android.media.soundtrigger.ModelParameterRange;
+import android.media.soundtrigger.Properties;
+import android.media.soundtrigger.RecognitionConfig;
+
+/**
+ * SoundTrigger HAL interface. Used for hardware recognition of hotwords
+ * and other sounds.
+ *
+ * Basic usage:
+ * ============
+ * ISoundTriggerHw supports the ability to have one of more  detection sessions running at a given
+ * time, and listening to acoustic events. The basic flow of setting up such a session is:
+ * - Load a model using loadSoundModel() or loadPhraseSoundModel(). The provided model object would
+ *   indicate the (implementation-specific) detection algorithm (engine) to use, as well as any
+ *   parameters applicable for this agorithm. Upon success, those methods would return a handle
+ *   which will be used to reference this model in subsequent calls.
+ * - Once the model had been successfully loaded, detection can begin by calling startRecognition().
+ * - Recognition will continue running in the background until one of the following events occurs:
+ *   - stopRecognition() has been called on this model.
+ *   - A detection has occurred.
+ *   - Detection was aborted, typically for resource constraints, for example, when a higher-
+ *     priority use-case has been initiated.
+ * - In the latter two cases, a recognition event will be sent via a the callback interface that was
+ *   registered by the client upon loading. In either case, after any of these events occur, the
+ *   detection becomes inactive and no more recognition callbacks are allowed.
+ * - The same model maybe started again at a later time, and this process may repeat as many times
+ *   as needed.
+ * - Finally, an inactive model that is no longer needed may be unloaded via unloadModel().
+ *
+ * Important notes about the threading model:
+ * ==========================================
+ * Both this interface and the corresponding callback interface use a synchronous calling
+ * convention. This model comes with some advantages, but also with some risks of deadlocks if the
+ * implementation does not handle this correctly. Please consider the following:
+ * - After stopRecognition() returns, no more recognition events for that model may be sent. This
+ *   implies that any queues holding such events must be flushed before the call returns and that
+ *   may imply that callback from the HAL to the client are done while stopRecognition() is blocked.
+ *   This is OK, and supported by the framework.
+ * - Similarly, the same relationship applies between unloadModel() and subsequent callbacks to
+ *   modelUnloaded().
+ * - Other than these two cases, calls into the HAL *MAY NOT* block on callbacks from the HAL, or
+ *   else deadlock conditions may result, which may be handled by rebooting of the HAL process and
+ *   cause service outages.
+ *
+ * Due to the asynchronous nature of recognition events and preemptive model unloading, the HAL must
+ * correctly handle requests that would have been valid before an event has been delivered, but
+ * became moot as result of the event. Namely:
+ * - stopRecognition() may be called on a model that has already delivered an event and became
+ *   inactive as a result. The HAL must return a successful return code in this case.
+ * - Furthermore, if a model is preemptively unloaded after it triggers (typically, this would
+ *   happen when it is first aborted and immediately preemptively unloaded), stopRecognition() may
+ *   be called on it. The HAL must return successfully in this case.
+ * - startRecognition() may be called on a model that has been preemptively unloaded. In this case,
+ *   the HAL must signal a ServiceSpecificException(RESOURCE_CONTENTION) to indicate that the
+ *   operation is temporarily unsuccessful.
+ * - unloadSoundModel() may be called on a model that has been preemptively unloaded. The HAL must
+ *   return a successful return code in this case. This also implies that model handles should
+ *   generally not be reused until explicitly unloaded. To avoid the rare possibility of running out
+ *   of handles, the framework may call unloadModel() on models that have been preemptively unloaded
+ *   by the HAL.
+ *
+ * Important notes about resource constraints and concurrency
+ * =========================================================
+ * Up until this version, the framework would enforce concurrency constraints expressed by the
+ * Properties presented by the soundtrigger instance. These include constraints on the maximum
+ * amount of models that can be loaded at the same time and on running recognition while capturing
+ * from the microphone.
+ * This version changes the approach for how these constraints are modeled, both offering the HAL
+ * implementation more flexibility and simplifying the framework's job in enforcing these
+ * limitations. Note that there is no change for how the framework behaves with earlier versions,
+ * everything described below only applies to this version and onward.
+ * The way this is achieved is as following:
+ * - The framework will no longer enforce constraints on concurrent loading of models, as expressed
+ *   in the Properties.maxSoundModels field (this property is merely a hint at this point and may be
+ *   deprecated in the future), or any other implicit constraints.
+ * - The framework will no longer enforce constraints on concurrency of audio recording and
+ *   soundtrigger operation, as expressed in the Properties.concurrentCapture field (this property
+ *   is merely a hint at this point and may be deprecated in the future).
+ * - The HAL implementation is free to reject loading of any model at any time by having the
+ *   respective load*() method signal a ServiceSpecificException(RESOURCE_CONTENTION).
+ * - The HAL implementation is free to reject starting of any model at any time by having the
+ *   respective start*() method signal a ServiceSpecificException(RESOURCE_CONTENTION).
+ * - The HAL implementation is free to preemptively stop a previously started model at its own
+ *   discretion (for example, if a higher priority use-case which cannot coexist with detection
+ *   has been requested). The HAL must notify the framework of the preemption by sending a
+ *   recognition event with an `ABORTED` status. The implementation must NOT attempt to restart the
+ *   recognition automatically when conditions change.
+ * - The HAL implementation is free to preemptively unload a previously loaded model at its own
+ *   discretion (for example, if a higher-priority model is being loaded and the two cannot
+ *   coexist). When doing so, it must first abort the detection if active (as per above) and then
+ *   notify the framework of the unload using the modelUnloaded() callback.
+ * - When conditions change, such that a model that couldn't previously load or start or that had
+ *   previously been preemptively stopped or unloaded, the HAL must notify the framework via the
+ *   newly added onResourcesAvailable() callback. This callback is not a guarantee that any
+ *   operation would now succeed, but merely a hint that retrying something that had previously
+ *   failed, now MAY succeed. Until this callback is invoked, the client may assume that any
+ *   operation that had previously failed or aborted would still fail if retried, so the
+ *   implementation should not forget to deliver it.
+ *   There are no guarantees regarding how the framework may respond to this event and the order in
+ *   which it may choose to reload/restart its models. Typically, as result of this event the
+ *   framework will make a single attempt per model to bring this model to its desired state
+ *   (loaded, started).
+ */
+@VintfStability
+interface ISoundTriggerHw {
+    /**
+     * Retrieve implementation properties.
+     *
+     * @return A Properties structure containing implementation description and capabilities.
+     */
+    Properties getProperties();
+
+    /**
+     * This will get called at most once per every attachment to the service.
+     *
+     * All events not tied to a specific model should go through this callback.
+     *
+     * @param callback An interface to receive global event callbacks.
+     */
+    void registerGlobalCallback(in ISoundTriggerHwGlobalCallback callback);
+
+    /**
+     * Load a sound model. Once loaded, recognition of this model can be started and stopped.
+     *
+     * @param soundModel A SoundModel structure describing the sound model to load.
+     * @param callback The callback interface on which the recognitionCallback()
+     *     method will be called upon completion and modelUnloaded() upon preemptive unload.
+     * @return A unique handle assigned by the HAL for use by the client when controlling
+     *     activity for this sound model.
+     * @throws ServiceSpecificException(RESOURCE_CONTENTION) if the model cannot be loaded due
+     *     to resource constraints. This is typically a temporary condition and the client may
+     *     retry after the onResourcesAvailable() global callback is invoked.
+     */
+    int loadSoundModel(in SoundModel soundModel, in ISoundTriggerHwCallback callback);
+
+    /**
+     * Load a key phrase sound model. Once loaded, recognition of this model can be started and
+     * stopped.
+     *
+     * @param soundModel A PhraseSoundModel structure describing the sound model to load.
+     * @param callback The callback interface on which the phraseRecognitionCallback() method will
+     *     be called upon completion and modelUnloaded() upon preempted unload.
+     * @return A unique handle assigned by the HAL for use by the framework when controlling
+     *     activity for this sound model.
+     * @throws ServiceSpecificException(RESOURCE_CONTENTION) if the model cannot be loaded due
+     *     to resource constraints. This is typically a temporary condition and the client may
+     *     retry after the onResourcesAvailable() global callback is invoked.
+     */
+    int loadPhraseSoundModel(in PhraseSoundModel soundModel, in ISoundTriggerHwCallback callback);
+
+    /**
+     * Unload a sound model. A sound model may be unloaded to free up resources and make room for a
+     * new one to overcome implementation limitations.
+     * This call is idempotent, to avoid any race conditions.
+     *
+     * @param modelHandle the handle of the sound model to unload.
+     */
+    void unloadSoundModel(in int modelHandle);
+
+    /**
+     * Start recognition on a given model.
+     * This must be called on a model that is in the stopped state.
+     * The state of this model becomes active and will remain so until explicitly stopped, or a
+     * recognition event had been delivered to the client.
+     *
+     * @param modelHandle the handle of the sound model to use for recognition
+     * @param deviceHandle The handle of the audio device to be used for recognition, as declared by
+     *     the audio subsystem.
+     * @param ioHandle A handle assigned by the framework, which will later be used to retrieve
+     *     an audio stream associated with this recognition session.
+     * @param config A RecognitionConfig structure containing attributes of the recognition to
+     *     perform.
+      * @throws ServiceSpecificException(RESOURCE_CONTENTION) if the model cannot be started due
+     *     to resource constraints. This is typically a temporary condition and the client may
+     *     retry after the onResourcesAvailable() global callback is invoked.
+    */
+    void startRecognition(in int modelHandle, in int deviceHandle,
+                          in int ioHandle, in RecognitionConfig config);
+
+    /**
+     * Stop recognition on a given model.
+     * This call is idempotent, to avoid any race conditions.
+     *
+     * @param modelHandle The handle of the sound model to use for recognition
+     */
+    void stopRecognition(in int modelHandle);
+
+    /**
+     * Request a recognition event to be generated.
+     * The model must be in the started state and will remain started after the event is sent.
+     * The model state is returned asynchronously as a RecognitionEvent via the callback that was
+     * registered upon loading. That event must have a RecognitionStatus.FORCED status.
+     *
+     * @param modelHandle The handle of the sound model whose state is being
+     *     queried.
+     */
+    void forceRecognitionEvent(in int modelHandle);
+
+    /**
+     * Get supported parameter attributes with respect to the provided model handle.
+     * Model parameters are used to query/control model-specific detection behavior during a
+     * detection session.
+     * Along with determining the valid range, this API is also used to determine if a given
+     * parameter ID is supported at all by the modelHandle for use with getParameter() and
+     * setParameter() APIs.
+     *
+     * @param modelHandle The sound model handle indicating which model to query.
+     * @param modelParam Parameter to set which will be validated against the ModelParameter type.
+     * @return This structure indicates supported attributes of the parameter for the given model
+     *      handle. If the parameter is not supported, null is returned.
+     */
+    @nullable ModelParameterRange queryParameter(in int modelHandle, in ModelParameter modelParam);
+
+    /**
+     * Get a model specific parameter.
+     * If the value has not been set, a default value is returned. See ModelParameter for parameter
+     * default values.
+     * The caller must check if the handle supports the parameter via the queryParameter API prior
+     * to calling this method.
+     *
+     * @param modelHandle The sound model associated with given modelParam
+     * @param modelParam Parameter to set which will be validated against the ModelParameter type.
+     *     Not putting ModelParameter type directly in the definition and validating internally
+     *     allows for forward compatibility.
+     * @return Value set to the requested parameter.
+     */
+    int getParameter(in int modelHandle, in ModelParameter modelParam);
+
+    /**
+     * Set a model specific parameter with the given value.
+     * This parameter will keep its value for the duration the model is loaded regardless of
+     * starting and stopping recognition. Once the model is unloaded, the value will be lost.
+     * The caller must check if the handle supports the parameter via the queryParameter API prior
+     * to calling this method.
+     *
+     * @param modelHandle The sound model handle indicating which model to modify parameters
+     * @param modelParam Parameter to set which will be validated against the ModelParameter type.
+     *     Not putting ModelParameter type directly in the definition and validating internally
+     *     allows for forward compatibility.
+     * @param value The value to set for the given model parameter.
+     */
+    void setParameter(in int modelHandle, in ModelParameter modelParam, in int value);
+}
diff --git a/soundtrigger/aidl/android/hardware/soundtrigger3/ISoundTriggerHwCallback.aidl b/soundtrigger/aidl/android/hardware/soundtrigger3/ISoundTriggerHwCallback.aidl
new file mode 100644
index 0000000..049ca65
--- /dev/null
+++ b/soundtrigger/aidl/android/hardware/soundtrigger3/ISoundTriggerHwCallback.aidl
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2021 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.
+ */
+
+package android.hardware.soundtrigger3;
+
+import android.media.soundtrigger.PhraseRecognitionEvent;
+import android.media.soundtrigger.RecognitionEvent;
+
+/**
+ * SoundTrigger HAL per-model Callback interface.
+ */
+@VintfStability
+interface ISoundTriggerHwCallback {
+    /**
+     * Callback method called by the HAL when a model has been unloaded at the HAL implementation's
+     * discretion.
+     * This event may only be delivered when the model state is 'stopped'.
+     * This event is NOT sent as part of an unload sequence initiated by the client.
+     *
+     * @param model The model handle.
+     */
+    void modelUnloaded(in int model);
+
+    /**
+     * Callback method called by the HAL when the sound recognition triggers for a key phrase sound
+     * model.
+     * This event may only be delivered when the model state is 'started'.
+     * Unless the status of the event is RecognitionStatus.FORCED, this event indicates that the
+     * state of this model has become 'stopped'.
+     *
+     * @param event A RecognitionEvent structure containing detailed results of the recognition
+     *     triggered
+     */
+    void phraseRecognitionCallback(in int model, in PhraseRecognitionEvent event);
+
+    /**
+     * Callback method called by the HAL when the sound recognition triggers.
+     * This event may only be delivered when the model state is 'started'.
+     * Unless the status of the event is RecognitionStatus.FORCED, this event indicates that the
+     * state of this model has become 'stopped'.
+     *
+     * @param event A RecognitionEvent structure containing detailed results of the recognition
+     *     triggered
+     */
+    void recognitionCallback(in int model, in RecognitionEvent event);
+}
diff --git a/soundtrigger/aidl/android/hardware/soundtrigger3/ISoundTriggerHwGlobalCallback.aidl b/soundtrigger/aidl/android/hardware/soundtrigger3/ISoundTriggerHwGlobalCallback.aidl
new file mode 100644
index 0000000..d6d8630
--- /dev/null
+++ b/soundtrigger/aidl/android/hardware/soundtrigger3/ISoundTriggerHwGlobalCallback.aidl
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2021 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.
+ */
+
+package android.hardware.soundtrigger3;
+
+/**
+ * SoundTrigger HAL callback interface for events not associated with a particular model.
+ */
+@VintfStability
+interface ISoundTriggerHwGlobalCallback {
+    /**
+     * Callback method called by the HAL whenever internal conditions have been made available, such
+     * that a call that would previously have failed with an -EBUSY status may now succeed.
+     * There is no guarantee that any call would succeed following this event. It is merely a hint
+     * to the client that it may retry.
+     * Conversely, any call that have failed previously with a
+     * ServiceSpecificException(RESOURCE_CONTENTION) is guaranteed to fail again if retried, until
+     * this callback is delivered.
+     */
+    void onResourcesAvailable();
+}
diff --git a/soundtrigger/aidl/cli/Android.bp b/soundtrigger/aidl/cli/Android.bp
new file mode 100644
index 0000000..e8999ff
--- /dev/null
+++ b/soundtrigger/aidl/cli/Android.bp
@@ -0,0 +1,17 @@
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "hardware_interfaces_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["hardware_interfaces_license"],
+}
+
+java_binary {
+    name: "sthal_cli_3",
+    wrapper: "sthal_cli_3",
+    srcs: ["java/**/*.java"],
+    static_libs: [
+        "android.hardware.soundtrigger3-V1-java",
+    ],
+}
diff --git a/soundtrigger/aidl/cli/OWNERS b/soundtrigger/aidl/cli/OWNERS
new file mode 100644
index 0000000..e21b66e
--- /dev/null
+++ b/soundtrigger/aidl/cli/OWNERS
@@ -0,0 +1 @@
+include /media/java/android/media/soundtrigger_middleware/OWNERS
diff --git a/soundtrigger/aidl/cli/java/android/hardware/soundtrigger3/cli/SthalCli.java b/soundtrigger/aidl/cli/java/android/hardware/soundtrigger3/cli/SthalCli.java
new file mode 100644
index 0000000..d3e1aa7
--- /dev/null
+++ b/soundtrigger/aidl/cli/java/android/hardware/soundtrigger3/cli/SthalCli.java
@@ -0,0 +1,351 @@
+/*
+ * Copyright 2021 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.
+ */
+package android.hardware.soundtrigger3.cli;
+
+import android.annotation.NonNull;
+import android.hardware.soundtrigger3.ISoundTriggerHw;
+import android.hardware.soundtrigger3.ISoundTriggerHwCallback;
+import android.hardware.soundtrigger3.ISoundTriggerHwGlobalCallback;
+import android.media.audio.common.AudioConfig;
+import android.media.soundtrigger.ConfidenceLevel;
+import android.media.soundtrigger.ModelParameterRange;
+import android.media.soundtrigger.PhraseRecognitionEvent;
+import android.media.soundtrigger.PhraseRecognitionExtra;
+import android.media.soundtrigger.PhraseSoundModel;
+import android.media.soundtrigger.Properties;
+import android.media.soundtrigger.RecognitionConfig;
+import android.media.soundtrigger.RecognitionEvent;
+import android.media.soundtrigger.RecognitionMode;
+import android.media.soundtrigger.SoundModel;
+import android.media.soundtrigger.SoundModelType;
+import android.os.HwBinder;
+import android.os.ParcelFileDescriptor;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.os.SystemProperties;
+
+import java.util.Scanner;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+
+/**
+ * This is a quick-and-dirty sound trigger HAL console mock.
+ *
+ * It would only work on userdebug builds.
+ *
+ * When this app is started, it will initially:
+ * - Register a ISoundTriggerHw HAL with an instance name "mock".
+ * - Set a sysprop that tells SoundTriggerMiddlewareService to try to connect to the mock instance
+ * rather than the default one.
+ * - Reboot the real (default) HAL.
+ *
+ * In response to that, SoundTriggerMiddlewareService is going to connect to the mock HAL and resume
+ * normal operation.
+ *
+ * Our mock HAL will print to stdout every call it receives as well as expose a basic set of
+ * operations for sending event callbacks to the client. This allows us to simulate the frameworks
+ * behavior in response to different HAL behaviors.
+ */
+public class SthalCli {
+    private static SoundTriggerImpl mService;
+    private static final Scanner scanner = new Scanner(System.in);
+
+    public static void main(String[] args) {
+        try {
+            printUsage();
+
+            System.out.println("Registering mock STHAL");
+            mService = new SoundTriggerImpl();
+            // This allows us to register the service, even if it is not declared in the manifest.
+            mService.forceDowngradeToSystemStability();
+            ServiceManager.addService(ISoundTriggerHw.class.getCanonicalName() + "/mock", mService);
+
+            System.out.println("Rebooting STHAL");
+            SystemProperties.set("debug.soundtrigger_middleware.use_mock_hal", "3");
+            SystemProperties.set("sys.audio.restart.hal", "1");
+
+            while (processCommand()) ;
+        } catch (Exception e) {
+            e.printStackTrace();
+        } finally {
+            cleanup();
+        }
+    }
+
+    private static void cleanup() {
+        System.out.println("Cleaning up.");
+        SystemProperties.set("debug.soundtrigger_middleware.use_mock_hal", null);
+        HwBinder.setTrebleTestingOverride(false);
+    }
+
+    private static boolean processCommand() {
+        String line = scanner.nextLine();
+        String[] tokens = line.split("\\s+");
+        if (tokens.length < 1) {
+            return false;
+        }
+        switch (tokens[0]) {
+            case "q":
+                return false;
+
+            case "a":
+                mService.sendOnResourcesAvailable();
+                return true;
+
+            case "u":
+                mService.sendModelUnloaded(Integer.parseInt(tokens[1]));
+                return true;
+
+            case "r":
+                mService.sendRecognitionEvent(Integer.parseInt(tokens[1]),
+                        Integer.parseInt(tokens[2]));
+                return true;
+
+            case "p":
+                mService.sendPhraseRecognitionEvent(Integer.parseInt(tokens[1]),
+                        Integer.parseInt(tokens[2]));
+                return true;
+
+            case "d":
+                mService.dumpModels();
+                return true;
+
+            default:
+                printUsage();
+                return true;
+        }
+    }
+
+    private static void printUsage() {
+        System.out.print(
+                "Sound Trigger HAL v3 mock\n"
+                + "Available commands:\n"
+                + "h - help\n"
+                + "q - quit\n"
+                + "a - send onResourcesAvailable event\n"
+                + "u <model> - send modelUnloaded event\n"
+                + "r <model> <status> - send recognitionEvent\n"
+                + "p <model> <status> - send phraseRecognitionEvent\n"
+                + "d - dump models\n");
+    }
+
+    private static class SoundTriggerImpl extends ISoundTriggerHw.Stub {
+        static class Model {
+            final ISoundTriggerHwCallback callback;
+            final SoundModel model;
+            final PhraseSoundModel phraseModel;
+            public RecognitionConfig config = null;
+
+            Model(ISoundTriggerHwCallback callback, SoundModel model) {
+                this.callback = callback;
+                this.model = model;
+                this.phraseModel = null;
+            }
+
+            Model(ISoundTriggerHwCallback callback, PhraseSoundModel model) {
+                this.callback = callback;
+                this.model = null;
+                this.phraseModel = model;
+            }
+        }
+
+        private ISoundTriggerHwGlobalCallback mGlobalCallback;
+        private final ConcurrentMap<Integer, Model> mLoadedModels = new ConcurrentHashMap<>();
+        private int mHandleCounter = 1;
+
+        public void dumpModels() {
+            mLoadedModels.forEach((handle, model) -> {
+                System.out.println("+++ Model " + handle);
+                System.out.println("    config = " + model.config);
+                RecognitionConfig recognitionConfig = model.config;
+                if (recognitionConfig != null) {
+                    System.out.println("    ACTIVE recognitionConfig = " + recognitionConfig);
+                } else {
+                    System.out.println("    INACTIVE");
+                }
+            });
+        }
+
+        public void sendOnResourcesAvailable() {
+            if (mGlobalCallback != null) {
+                try {
+                    mGlobalCallback.onResourcesAvailable();
+                } catch (RemoteException e) {
+                    e.printStackTrace();
+                }
+            }
+        }
+
+        public void sendRecognitionEvent(int modelHandle, int status) {
+            Model model = mLoadedModels.get(modelHandle);
+            if (model != null && model.config != null) {
+                RecognitionEvent event = new RecognitionEvent();
+                event.type = SoundModelType.GENERIC;
+                event.status = status;
+                event.captureAvailable = true;
+                event.audioConfig.channelMask = 16;
+                event.audioConfig.format = 1;
+                event.audioConfig.sampleRateHz = 16000;
+                try {
+                    model.callback.recognitionCallback(modelHandle, event);
+                } catch (RemoteException e) {
+                    e.printStackTrace();
+                }
+                model.config = null;
+            }
+        }
+
+        public void sendPhraseRecognitionEvent(int modelHandle, int status) {
+            Model model = mLoadedModels.get(modelHandle);
+            if (model != null && model.config != null) {
+                PhraseRecognitionEvent event = new PhraseRecognitionEvent();
+                event.common = new RecognitionEvent();
+                event.common.type = SoundModelType.KEYPHRASE;
+                event.common.status = status;
+                event.common.captureAvailable = true;
+                event.common.audioConfig = new AudioConfig();
+                event.common.audioConfig.channelMask = 16;
+                event.common.audioConfig.format = 1;
+                event.common.audioConfig.sampleRateHz = 16000;
+                if (model.phraseModel.phrases.length > 0) {
+                    PhraseRecognitionExtra extra = new PhraseRecognitionExtra();
+                    extra.id = model.phraseModel.phrases[0].id;
+                    extra.confidenceLevel = 100;
+                    extra.recognitionModes = model.phraseModel.phrases[0].recognitionModes;
+                    extra.levels = new ConfidenceLevel[0];
+                    event.phraseExtras = new PhraseRecognitionExtra[]{extra};
+                } else {
+                    event.phraseExtras = new PhraseRecognitionExtra[0];
+                }
+                try {
+                    model.callback.phraseRecognitionCallback(modelHandle, event);
+                } catch (RemoteException e) {
+                    e.printStackTrace();
+                }
+                model.config = null;
+            }
+        }
+
+        public void sendModelUnloaded(int modelHandle) {
+            Model model = mLoadedModels.remove(modelHandle);
+            if (model != null) {
+                try {
+                    model.callback.modelUnloaded(modelHandle);
+                } catch (RemoteException e) {
+                    e.printStackTrace();
+                }
+            }
+        }
+
+        @Override
+        public void registerGlobalCallback(ISoundTriggerHwGlobalCallback callback) {
+            System.out.println("registerGlobalCallback()");
+            mGlobalCallback = callback;
+        }
+
+        @Override
+        public int loadSoundModel(SoundModel soundModel, ISoundTriggerHwCallback callback) {
+            int handle = mHandleCounter++;
+            System.out.printf("loadSoundModel(soundModel=%s) -> %d%n", soundModel, handle);
+            mLoadedModels.put(handle, new Model(callback, soundModel));
+            return handle;
+        }
+
+        @Override
+        public int loadPhraseSoundModel(PhraseSoundModel soundModel,
+                ISoundTriggerHwCallback callback) {
+            int handle = mHandleCounter++;
+            System.out.printf("loadPhraseSoundModel(soundModel=%s) -> %d%n", soundModel, handle);
+            mLoadedModels.put(handle, new Model(callback, soundModel));
+            return handle;
+        }
+
+        @Override
+        public void startRecognition(int modelHandle, int deviceHandle, int ioHandle,
+                RecognitionConfig config) {
+            System.out.printf("startRecognition(modelHandle=%d, deviceHandle=%d, ioHandle=%d)%n",
+                    modelHandle, deviceHandle, ioHandle);
+            Model model = mLoadedModels.get(modelHandle);
+            if (model != null) {
+                model.config = config;
+            }
+        }
+
+        @Override
+        public Properties getProperties() {
+            System.out.println("getProperties()");
+            Properties properties = new Properties();
+            properties.implementor = "Android";
+            properties.description = "Mock STHAL";
+            properties.maxSoundModels = 2;
+            properties.maxKeyPhrases = 1;
+            properties.recognitionModes =
+                    RecognitionMode.VOICE_TRIGGER | RecognitionMode.GENERIC_TRIGGER;
+            return properties;
+        }
+
+        @Override
+        public ModelParameterRange queryParameter(int modelHandle, int modelParam) {
+            System.out.printf("queryParameter(modelHandle=%d, modelParam=%d)%n", modelHandle,
+                    modelParam);
+            return null;
+        }
+
+        @Override
+        public void forceRecognitionEvent(int modelHandle) {
+            System.out.printf("getModelState(modelHandle=%d)%n", modelHandle);
+        }
+
+        @Override
+        public void unloadSoundModel(int modelHandle) {
+            System.out.printf("unloadSoundModel(modelHandle=%d)%n", modelHandle);
+        }
+
+        @Override
+        public void stopRecognition(int modelHandle) {
+            System.out.printf("stopRecognition(modelHandle=%d)%n", modelHandle);
+            Model model = mLoadedModels.get(modelHandle);
+            if (model != null) {
+                model.config = null;
+            }
+        }
+
+        @Override
+        public int handleShellCommand(@NonNull ParcelFileDescriptor in,
+                @NonNull ParcelFileDescriptor out, @NonNull ParcelFileDescriptor err,
+                @NonNull String[] args) {
+            if (args.length > 0) {
+                switch (args[0]) {
+                    case "reboot":
+                        System.out.println("Received a reboot request. Exiting.");
+                        cleanup();
+                        System.exit(1);
+                }
+            }
+            return 0;
+        }
+
+        @Override
+        public void setParameter(int modelHandle, int modelParam, int value) {
+            throw new IllegalArgumentException();
+        }
+
+        @Override
+        public int getParameter(int modelHandle, int modelParam) {
+            throw new IllegalArgumentException();
+        }
+    }
+}
diff --git a/soundtrigger/aidl/cli/sthal_cli_3 b/soundtrigger/aidl/cli/sthal_cli_3
new file mode 100644
index 0000000..f157c50
--- /dev/null
+++ b/soundtrigger/aidl/cli/sthal_cli_3
@@ -0,0 +1,6 @@
+#!/system/bin/sh
+# Script to start "sthal_cli_3" on the device
+#
+base=/system
+export CLASSPATH=$base/framework/sthal_cli_3.jar
+exec app_process $base/bin android.hardware.soundtrigger3.cli.SthalCli "$@"