Merge "Transpose the encoding matrix"
diff --git a/audio/6.0/config/api/current.txt b/audio/6.0/config/api/current.txt
index ddd4d1c..0407d69 100644
--- a/audio/6.0/config/api/current.txt
+++ b/audio/6.0/config/api/current.txt
@@ -361,6 +361,7 @@
     method public String getRawName();
     enum_constant public static final audio.policy.configuration.V6_0.Stream AUDIO_STREAM_ACCESSIBILITY;
     enum_constant public static final audio.policy.configuration.V6_0.Stream AUDIO_STREAM_ALARM;
+    enum_constant public static final audio.policy.configuration.V6_0.Stream AUDIO_STREAM_ASSISTANT;
     enum_constant public static final audio.policy.configuration.V6_0.Stream AUDIO_STREAM_BLUETOOTH_SCO;
     enum_constant public static final audio.policy.configuration.V6_0.Stream AUDIO_STREAM_DTMF;
     enum_constant public static final audio.policy.configuration.V6_0.Stream AUDIO_STREAM_ENFORCED_AUDIBLE;
diff --git a/audio/6.0/config/audio_policy_configuration.xsd b/audio/6.0/config/audio_policy_configuration.xsd
index 3fab7dc..05c8ab4 100644
--- a/audio/6.0/config/audio_policy_configuration.xsd
+++ b/audio/6.0/config/audio_policy_configuration.xsd
@@ -551,6 +551,7 @@
             <xs:enumeration value="AUDIO_STREAM_DTMF"/>
             <xs:enumeration value="AUDIO_STREAM_TTS"/>
             <xs:enumeration value="AUDIO_STREAM_ACCESSIBILITY"/>
+            <xs:enumeration value="AUDIO_STREAM_ASSISTANT"/>
             <xs:enumeration value="AUDIO_STREAM_REROUTING"/>
             <xs:enumeration value="AUDIO_STREAM_PATCH"/>
         </xs:restriction>
diff --git a/audio/common/6.0/types.hal b/audio/common/6.0/types.hal
index e69d969..563e05d 100644
--- a/audio/common/6.0/types.hal
+++ b/audio/common/6.0/types.hal
@@ -106,6 +106,7 @@
     TTS              = 9,  // Transmitted Through Speaker.  Plays over speaker
                            // only, silent on other devices
     ACCESSIBILITY    = 10, // For accessibility talk back prompts
+    ASSISTANT        = 11, // For virtual assistant service
 };
 
 @export(name="audio_source_t", value_prefix="AUDIO_SOURCE_")
diff --git a/audio/effect/6.0/xml/api/current.txt b/audio/effect/6.0/xml/api/current.txt
index 2021639..2dfcb9b 100644
--- a/audio/effect/6.0/xml/api/current.txt
+++ b/audio/effect/6.0/xml/api/current.txt
@@ -82,6 +82,7 @@
   public enum StreamOutputType {
     method public String getRawName();
     enum_constant public static final audio.effects.V6_0.StreamOutputType alarm;
+    enum_constant public static final audio.effects.V6_0.StreamOutputType assistant;
     enum_constant public static final audio.effects.V6_0.StreamOutputType bluetooth_sco;
     enum_constant public static final audio.effects.V6_0.StreamOutputType dtmf;
     enum_constant public static final audio.effects.V6_0.StreamOutputType enforced_audible;
diff --git a/audio/effect/6.0/xml/audio_effects_conf.xsd b/audio/effect/6.0/xml/audio_effects_conf.xsd
deleted file mode 120000
index 9d85fa7..0000000
--- a/audio/effect/6.0/xml/audio_effects_conf.xsd
+++ /dev/null
@@ -1 +0,0 @@
-../../2.0/xml/audio_effects_conf.xsd
\ No newline at end of file
diff --git a/audio/effect/6.0/xml/audio_effects_conf.xsd b/audio/effect/6.0/xml/audio_effects_conf.xsd
new file mode 100644
index 0000000..a7ff20b
--- /dev/null
+++ b/audio/effect/6.0/xml/audio_effects_conf.xsd
@@ -0,0 +1,230 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2017 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.
+-->
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
+           targetNamespace="http://schemas.android.com/audio/audio_effects_conf/v2_0"
+           xmlns:aec="http://schemas.android.com/audio/audio_effects_conf/v2_0"
+           elementFormDefault="qualified">
+  <!-- Simple types -->
+  <xs:simpleType name="versionType">
+    <xs:restriction base="xs:decimal">
+      <xs:enumeration value="2.0"/>
+    </xs:restriction>
+  </xs:simpleType>
+  <xs:simpleType name="uuidType">
+    <xs:restriction base="xs:string">
+      <xs:pattern value="[0-9A-Fa-f]{8}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{12}"/>
+    </xs:restriction>
+  </xs:simpleType>
+  <xs:simpleType name="streamInputType">
+    <xs:restriction base="xs:string">
+      <xs:enumeration value="mic"/>
+      <xs:enumeration value="voice_uplink"/>
+      <xs:enumeration value="voice_downlink"/>
+      <xs:enumeration value="voice_call"/>
+      <xs:enumeration value="camcorder"/>
+      <xs:enumeration value="voice_recognition"/>
+      <xs:enumeration value="voice_communication"/>
+      <xs:enumeration value="unprocessed"/>
+      <xs:enumeration value="voice_performance"/>
+    </xs:restriction>
+  </xs:simpleType>
+  <xs:simpleType name="streamOutputType">
+    <xs:restriction base="xs:string">
+      <xs:enumeration value="voice_call"/>
+      <xs:enumeration value="system"/>
+      <xs:enumeration value="ring"/>
+      <xs:enumeration value="music"/>
+      <xs:enumeration value="alarm"/>
+      <xs:enumeration value="notification"/>
+      <xs:enumeration value="bluetooth_sco"/>
+      <xs:enumeration value="enforced_audible"/>
+      <xs:enumeration value="dtmf"/>
+      <xs:enumeration value="tts"/>
+      <xs:enumeration value="assistant"/>
+    </xs:restriction>
+  </xs:simpleType>
+  <xs:simpleType name="relativePathType">
+    <xs:restriction base="xs:string">
+      <xs:pattern value="[^/].*"/>
+    </xs:restriction>
+  </xs:simpleType>
+  <!-- Complex types -->
+  <xs:complexType name="librariesType">
+    <xs:annotation>
+      <xs:documentation xml:lang="en">
+        List of effect libraries to load. Each library element must have "name" and
+        "path" attributes. The latter is giving the path of the library .so file
+        relative to the standard effect folders: /(vendor|odm|system)/lib(64)?/soundfx/
+        Example for a library in "/vendor/lib/soundfx/lib.so":
+        <library name="name" path="lib.so"/>
+      </xs:documentation>
+    </xs:annotation>
+    <xs:sequence>
+      <xs:element name="library" minOccurs="0" maxOccurs="unbounded">
+        <xs:complexType>
+          <xs:attribute name="name" type="xs:string" use="required"/>
+          <xs:attribute name="path" type="aec:relativePathType" use="required"/>
+        </xs:complexType>
+      </xs:element>
+    </xs:sequence>
+  </xs:complexType>
+  <xs:complexType name="effectImplType">
+    <xs:attribute name="library" type="xs:string" use="required"/>
+    <xs:attribute name="uuid" type="aec:uuidType" use="required"/>
+  </xs:complexType>
+  <xs:complexType name="effectType">
+    <xs:complexContent>
+      <xs:extension base="aec:effectImplType">
+        <xs:attribute name="name" type="xs:string" use="required"/>
+      </xs:extension>
+    </xs:complexContent>
+  </xs:complexType>
+  <xs:complexType name="effectProxyType">
+    <xs:complexContent>
+      <xs:extension base="aec:effectType">
+        <xs:sequence>
+          <xs:element name="libsw" type="aec:effectImplType"/>
+          <xs:element name="libhw" type="aec:effectImplType"/>
+        </xs:sequence>
+      </xs:extension>
+    </xs:complexContent>
+  </xs:complexType>
+  <xs:complexType name="effectsType">
+    <xs:annotation>
+      <xs:documentation xml:lang="en">
+        List of effects to load. Each effect element must contain "name",
+        "library", and "uuid" attrs. The value of the "library" attr must
+        correspond to the name of a "library" element. The name of the effect
+        element is indicative, only the value of the "uuid" element designates
+        the effect for the audio framework.  The uuid is the implementation
+        specific UUID as specified by the effect vendor. This is not the generic
+        effect type UUID.
+        For effect proxy implementations, SW and HW implemetations of the effect
+        can be specified.
+        Example:
+        <effect name="name" library="lib" uuid="uuuu"/>
+        <effectProxy name="proxied" library="proxy" uuid="xxxx">
+            <libsw library="sw_bundle" uuid="yyyy"/>
+            <libhw library="offload_bundle" uuid="zzzz"/>
+        </effectProxy>
+      </xs:documentation>
+    </xs:annotation>
+    <xs:choice maxOccurs="unbounded">
+      <xs:element name="effect" type="aec:effectType" minOccurs="0" maxOccurs="unbounded"/>
+      <xs:element name="effectProxy" type="aec:effectProxyType" minOccurs="0" maxOccurs="unbounded"/>
+    </xs:choice>
+  </xs:complexType>
+  <xs:complexType name="streamProcessingType">
+    <xs:sequence>
+      <xs:element name="apply" minOccurs="0" maxOccurs="unbounded">
+        <xs:complexType>
+          <xs:attribute name="effect" type="xs:string" use="required"/>
+        </xs:complexType>
+      </xs:element>
+    </xs:sequence>
+  </xs:complexType>
+  <xs:complexType name="streamPreprocessType">
+    <xs:annotation>
+      <xs:documentation xml:lang="en">
+        Audio preprocessing configuration. The processing configuration consists
+        of a list of elements each describing processing settings for a given
+        input stream. Valid input stream types are listed in "streamInputType".
+        Each stream element contains a list of "apply" elements. The value of the
+        "effect" attr must correspond to the name of an "effect" element.
+        Example:
+        <stream type="voice_communication">
+            <apply effect="effect1"/>
+            <apply effect="effect2"/>
+        </stream>
+      </xs:documentation>
+    </xs:annotation>
+    <xs:complexContent>
+      <xs:extension base="aec:streamProcessingType">
+        <xs:attribute name="type" type="aec:streamInputType" use="required"/>
+      </xs:extension>
+    </xs:complexContent>
+  </xs:complexType>
+  <xs:complexType name="streamPostprocessType">
+    <xs:annotation>
+      <xs:documentation xml:lang="en">
+        Audio postprocessing configuration. The processing configuration consists
+        of a list of elements each describing processing settings for a given
+        output stream. Valid output stream types are listed in "streamOutputType".
+        Each stream element contains a list of "apply" elements. The value of the
+        "effect" attr must correspond to the name of an "effect" element.
+        Example:
+        <stream type="music">
+            <apply effect="effect1"/>
+        </stream>
+      </xs:documentation>
+    </xs:annotation>
+    <xs:complexContent>
+      <xs:extension base="aec:streamProcessingType">
+        <xs:attribute name="type" type="aec:streamOutputType" use="required"/>
+      </xs:extension>
+    </xs:complexContent>
+  </xs:complexType>
+  <!-- Root element -->
+  <xs:element name="audio_effects_conf">
+    <xs:complexType>
+      <xs:sequence>
+        <xs:element name="libraries" type="aec:librariesType"/>
+        <xs:element name="effects" type="aec:effectsType"/>
+        <xs:element name="postprocess" minOccurs="0" maxOccurs="1">
+          <xs:complexType>
+            <xs:sequence>
+              <xs:element name="stream" type="aec:streamPostprocessType" minOccurs="0" maxOccurs="unbounded"/>
+            </xs:sequence>
+          </xs:complexType>
+        </xs:element>
+        <xs:element name="preprocess" minOccurs="0" maxOccurs="1">
+          <xs:complexType>
+            <xs:sequence>
+              <xs:element name="stream" type="aec:streamPreprocessType" minOccurs="0" maxOccurs="unbounded"/>
+            </xs:sequence>
+          </xs:complexType>
+        </xs:element>
+      </xs:sequence>
+      <xs:attribute name="version" type="aec:versionType" use="required"/>
+    </xs:complexType>
+    <!-- Keys and references -->
+    <xs:key name="libraryName">
+      <xs:selector xpath="aec:libraries/aec:library"/>
+      <xs:field xpath="@name"/>
+    </xs:key>
+    <xs:keyref name="libraryNameRef1" refer="aec:libraryName">
+      <xs:selector xpath="aec:effects/aec:effect"/>
+      <xs:field xpath="@library"/>
+    </xs:keyref>
+    <xs:keyref name="libraryNameRef2" refer="aec:libraryName">
+      <xs:selector xpath="aec:effects/aec:effect/aec:libsw"/>
+      <xs:field xpath="@library"/>
+    </xs:keyref>
+    <xs:keyref name="libraryNameRef3" refer="aec:libraryName">
+      <xs:selector xpath="aec:effects/aec:effect/aec:libhw"/>
+      <xs:field xpath="@library"/>
+    </xs:keyref>
+    <xs:key name="effectName">
+      <xs:selector xpath="aec:effects/aec:effect|aec:effects/aec:effectProxy"/>
+      <xs:field xpath="@name"/>
+    </xs:key>
+    <xs:keyref name="effectNamePreRef" refer="aec:effectName">
+      <xs:selector xpath="aec:preprocess/aec:stream/aec:apply"/>
+      <xs:field xpath="@effect"/>
+    </xs:keyref>
+    <xs:keyref name="effectNamePostRef" refer="aec:effectName">
+      <xs:selector xpath="aec:postprocess/aec:stream/aec:apply"/>
+      <xs:field xpath="@effect"/>
+    </xs:keyref>
+  </xs:element>
+</xs:schema>
\ No newline at end of file
diff --git a/automotive/can/1.0/default/CanBus.cpp b/automotive/can/1.0/default/CanBus.cpp
index 86df5dc..454ab00 100644
--- a/automotive/can/1.0/default/CanBus.cpp
+++ b/automotive/can/1.0/default/CanBus.cpp
@@ -25,12 +25,7 @@
 #include <linux/can/error.h>
 #include <linux/can/raw.h>
 
-namespace android {
-namespace hardware {
-namespace automotive {
-namespace can {
-namespace V1_0 {
-namespace implementation {
+namespace android::hardware::automotive::can::V1_0::implementation {
 
 /** Whether to log sent/received packets. */
 static constexpr bool kSuperVerbose = false;
@@ -345,9 +340,4 @@
     if (errcb != nullptr) errcb();
 }
 
-}  // namespace implementation
-}  // namespace V1_0
-}  // namespace can
-}  // namespace automotive
-}  // namespace hardware
-}  // namespace android
+}  // namespace android::hardware::automotive::can::V1_0::implementation
diff --git a/automotive/can/1.0/default/CanBus.h b/automotive/can/1.0/default/CanBus.h
index da3fc5a..8b73258 100644
--- a/automotive/can/1.0/default/CanBus.h
+++ b/automotive/can/1.0/default/CanBus.h
@@ -26,12 +26,7 @@
 #include <atomic>
 #include <thread>
 
-namespace android {
-namespace hardware {
-namespace automotive {
-namespace can {
-namespace V1_0 {
-namespace implementation {
+namespace android::hardware::automotive::can::V1_0::implementation {
 
 struct CanBus : public ICanBus {
     using ErrorCallback = std::function<void()>;
@@ -114,9 +109,4 @@
     ErrorCallback mErrCb;
 };
 
-}  // namespace implementation
-}  // namespace V1_0
-}  // namespace can
-}  // namespace automotive
-}  // namespace hardware
-}  // namespace android
+}  // namespace android::hardware::automotive::can::V1_0::implementation
diff --git a/automotive/can/1.0/default/CanBusNative.cpp b/automotive/can/1.0/default/CanBusNative.cpp
index 365b749..88f9175 100644
--- a/automotive/can/1.0/default/CanBusNative.cpp
+++ b/automotive/can/1.0/default/CanBusNative.cpp
@@ -20,12 +20,7 @@
 #include <libnetdevice/can.h>
 #include <libnetdevice/libnetdevice.h>
 
-namespace android {
-namespace hardware {
-namespace automotive {
-namespace can {
-namespace V1_0 {
-namespace implementation {
+namespace android::hardware::automotive::can::V1_0::implementation {
 
 CanBusNative::CanBusNative(const std::string& ifname, uint32_t baudrate)
     : CanBus(ifname), mBaudrate(baudrate) {}
@@ -49,9 +44,4 @@
     return ICanController::Result::OK;
 }
 
-}  // namespace implementation
-}  // namespace V1_0
-}  // namespace can
-}  // namespace automotive
-}  // namespace hardware
-}  // namespace android
+}  // namespace android::hardware::automotive::can::V1_0::implementation
diff --git a/automotive/can/1.0/default/CanBusNative.h b/automotive/can/1.0/default/CanBusNative.h
index 126f1cb..7eda683 100644
--- a/automotive/can/1.0/default/CanBusNative.h
+++ b/automotive/can/1.0/default/CanBusNative.h
@@ -18,12 +18,7 @@
 
 #include "CanBus.h"
 
-namespace android {
-namespace hardware {
-namespace automotive {
-namespace can {
-namespace V1_0 {
-namespace implementation {
+namespace android::hardware::automotive::can::V1_0::implementation {
 
 struct CanBusNative : public CanBus {
     CanBusNative(const std::string& ifname, uint32_t baudrate);
@@ -35,9 +30,4 @@
     const uint32_t mBaudrate;
 };
 
-}  // namespace implementation
-}  // namespace V1_0
-}  // namespace can
-}  // namespace automotive
-}  // namespace hardware
-}  // namespace android
+}  // namespace android::hardware::automotive::can::V1_0::implementation
diff --git a/automotive/can/1.0/default/CanBusSlcan.cpp b/automotive/can/1.0/default/CanBusSlcan.cpp
index 7dce838..29d9d3c 100644
--- a/automotive/can/1.0/default/CanBusSlcan.cpp
+++ b/automotive/can/1.0/default/CanBusSlcan.cpp
@@ -25,12 +25,7 @@
 #include <sys/stat.h>
 #include <termios.h>
 
-namespace android {
-namespace hardware {
-namespace automotive {
-namespace can {
-namespace V1_0 {
-namespace implementation {
+namespace android::hardware::automotive::can::V1_0::implementation {
 
 namespace slcanprotocol {
 static const std::string kOpenCommand = "O\r";
@@ -158,9 +153,4 @@
     return true;
 }
 
-}  // namespace implementation
-}  // namespace V1_0
-}  // namespace can
-}  // namespace automotive
-}  // namespace hardware
-}  // namespace android
+}  // namespace android::hardware::automotive::can::V1_0::implementation
diff --git a/automotive/can/1.0/default/CanBusSlcan.h b/automotive/can/1.0/default/CanBusSlcan.h
index 2713da8..3328a9f 100644
--- a/automotive/can/1.0/default/CanBusSlcan.h
+++ b/automotive/can/1.0/default/CanBusSlcan.h
@@ -22,12 +22,7 @@
 #include <termios.h>
 #include "CanBus.h"
 
-namespace android {
-namespace hardware {
-namespace automotive {
-namespace can {
-namespace V1_0 {
-namespace implementation {
+namespace android::hardware::automotive::can::V1_0::implementation {
 
 struct CanBusSlcan : public CanBus {
     CanBusSlcan(const std::string& uartName, uint32_t bitrate);
@@ -42,9 +37,4 @@
     base::unique_fd mFd;
 };
 
-}  // namespace implementation
-}  // namespace V1_0
-}  // namespace can
-}  // namespace automotive
-}  // namespace hardware
-}  // namespace android
+}  // namespace android::hardware::automotive::can::V1_0::implementation
diff --git a/automotive/can/1.0/default/CanBusVirtual.cpp b/automotive/can/1.0/default/CanBusVirtual.cpp
index cc59fa9..32fe8d6 100644
--- a/automotive/can/1.0/default/CanBusVirtual.cpp
+++ b/automotive/can/1.0/default/CanBusVirtual.cpp
@@ -19,12 +19,7 @@
 #include <android-base/logging.h>
 #include <libnetdevice/libnetdevice.h>
 
-namespace android {
-namespace hardware {
-namespace automotive {
-namespace can {
-namespace V1_0 {
-namespace implementation {
+namespace android::hardware::automotive::can::V1_0::implementation {
 
 CanBusVirtual::CanBusVirtual(const std::string& ifname) : CanBus(ifname) {}
 
@@ -52,9 +47,4 @@
     return true;
 }
 
-}  // namespace implementation
-}  // namespace V1_0
-}  // namespace can
-}  // namespace automotive
-}  // namespace hardware
-}  // namespace android
+}  // namespace android::hardware::automotive::can::V1_0::implementation
diff --git a/automotive/can/1.0/default/CanBusVirtual.h b/automotive/can/1.0/default/CanBusVirtual.h
index c2d5794..3990b20 100644
--- a/automotive/can/1.0/default/CanBusVirtual.h
+++ b/automotive/can/1.0/default/CanBusVirtual.h
@@ -18,12 +18,7 @@
 
 #include "CanBus.h"
 
-namespace android {
-namespace hardware {
-namespace automotive {
-namespace can {
-namespace V1_0 {
-namespace implementation {
+namespace android::hardware::automotive::can::V1_0::implementation {
 
 struct CanBusVirtual : public CanBus {
     CanBusVirtual(const std::string& ifname);
@@ -36,9 +31,4 @@
     bool mWasCreated = false;
 };
 
-}  // namespace implementation
-}  // namespace V1_0
-}  // namespace can
-}  // namespace automotive
-}  // namespace hardware
-}  // namespace android
+}  // namespace android::hardware::automotive::can::V1_0::implementation
diff --git a/automotive/can/1.0/default/CanController.cpp b/automotive/can/1.0/default/CanController.cpp
index ffdc912..cd17dd8 100644
--- a/automotive/can/1.0/default/CanController.cpp
+++ b/automotive/can/1.0/default/CanController.cpp
@@ -25,12 +25,7 @@
 
 #include <regex>
 
-namespace android {
-namespace hardware {
-namespace automotive {
-namespace can {
-namespace V1_0 {
-namespace implementation {
+namespace android::hardware::automotive::can::V1_0::implementation {
 
 using IfaceIdDisc = ICanController::BusConfiguration::InterfaceIdentifier::hidl_discriminator;
 
@@ -139,9 +134,4 @@
     return success;
 }
 
-}  // namespace implementation
-}  // namespace V1_0
-}  // namespace can
-}  // namespace automotive
-}  // namespace hardware
-}  // namespace android
+}  // namespace android::hardware::automotive::can::V1_0::implementation
diff --git a/automotive/can/1.0/default/CanController.h b/automotive/can/1.0/default/CanController.h
index 0674d0e..99a551a 100644
--- a/automotive/can/1.0/default/CanController.h
+++ b/automotive/can/1.0/default/CanController.h
@@ -20,12 +20,7 @@
 
 #include <android/hardware/automotive/can/1.0/ICanController.h>
 
-namespace android {
-namespace hardware {
-namespace automotive {
-namespace can {
-namespace V1_0 {
-namespace implementation {
+namespace android::hardware::automotive::can::V1_0::implementation {
 
 struct CanController : public ICanController {
     Return<void> getSupportedInterfaceTypes(getSupportedInterfaceTypes_cb _hidl_cb) override;
@@ -39,9 +34,4 @@
     std::map<std::string, sp<CanBus>> mCanBuses GUARDED_BY(mCanBusesGuard);
 };
 
-}  // namespace implementation
-}  // namespace V1_0
-}  // namespace can
-}  // namespace automotive
-}  // namespace hardware
-}  // namespace android
+}  // namespace android::hardware::automotive::can::V1_0::implementation
diff --git a/automotive/can/1.0/default/CanSocket.cpp b/automotive/can/1.0/default/CanSocket.cpp
index 86e12d1..86ccc0e 100644
--- a/automotive/can/1.0/default/CanSocket.cpp
+++ b/automotive/can/1.0/default/CanSocket.cpp
@@ -24,12 +24,7 @@
 
 #include <chrono>
 
-namespace android {
-namespace hardware {
-namespace automotive {
-namespace can {
-namespace V1_0 {
-namespace implementation {
+namespace android::hardware::automotive::can::V1_0::implementation {
 
 using namespace std::chrono_literals;
 
@@ -152,9 +147,4 @@
     LOG(VERBOSE) << "Reader thread stopped";
 }
 
-}  // namespace implementation
-}  // namespace V1_0
-}  // namespace can
-}  // namespace automotive
-}  // namespace hardware
-}  // namespace android
+}  // namespace android::hardware::automotive::can::V1_0::implementation
diff --git a/automotive/can/1.0/default/CanSocket.h b/automotive/can/1.0/default/CanSocket.h
index c98330b..fd956b5 100644
--- a/automotive/can/1.0/default/CanSocket.h
+++ b/automotive/can/1.0/default/CanSocket.h
@@ -24,12 +24,7 @@
 #include <chrono>
 #include <thread>
 
-namespace android {
-namespace hardware {
-namespace automotive {
-namespace can {
-namespace V1_0 {
-namespace implementation {
+namespace android::hardware::automotive::can::V1_0::implementation {
 
 /** Wrapper around SocketCAN socket. */
 struct CanSocket {
@@ -71,9 +66,4 @@
     DISALLOW_COPY_AND_ASSIGN(CanSocket);
 };
 
-}  // namespace implementation
-}  // namespace V1_0
-}  // namespace can
-}  // namespace automotive
-}  // namespace hardware
-}  // namespace android
+}  // namespace android::hardware::automotive::can::V1_0::implementation
diff --git a/automotive/can/1.0/default/CloseHandle.cpp b/automotive/can/1.0/default/CloseHandle.cpp
index aba2c49..e1ffe2b 100644
--- a/automotive/can/1.0/default/CloseHandle.cpp
+++ b/automotive/can/1.0/default/CloseHandle.cpp
@@ -16,12 +16,7 @@
 
 #include "CloseHandle.h"
 
-namespace android {
-namespace hardware {
-namespace automotive {
-namespace can {
-namespace V1_0 {
-namespace implementation {
+namespace android::hardware::automotive::can::V1_0::implementation {
 
 CloseHandle::CloseHandle(Callback callback) : mCallback(callback) {}
 
@@ -37,9 +32,4 @@
     return {};
 }
 
-}  // namespace implementation
-}  // namespace V1_0
-}  // namespace can
-}  // namespace automotive
-}  // namespace hardware
-}  // namespace android
+}  // namespace android::hardware::automotive::can::V1_0::implementation
diff --git a/automotive/can/1.0/default/CloseHandle.h b/automotive/can/1.0/default/CloseHandle.h
index eade109..c332d74 100644
--- a/automotive/can/1.0/default/CloseHandle.h
+++ b/automotive/can/1.0/default/CloseHandle.h
@@ -19,12 +19,7 @@
 #include <android-base/macros.h>
 #include <android/hardware/automotive/can/1.0/ICloseHandle.h>
 
-namespace android {
-namespace hardware {
-namespace automotive {
-namespace can {
-namespace V1_0 {
-namespace implementation {
+namespace android::hardware::automotive::can::V1_0::implementation {
 
 /** Generic ICloseHandle implementation ignoring double-close events. */
 struct CloseHandle : public ICloseHandle {
@@ -49,9 +44,4 @@
     DISALLOW_COPY_AND_ASSIGN(CloseHandle);
 };
 
-}  // namespace implementation
-}  // namespace V1_0
-}  // namespace can
-}  // namespace automotive
-}  // namespace hardware
-}  // namespace android
+}  // namespace android::hardware::automotive::can::V1_0::implementation
diff --git a/automotive/can/1.0/default/libnetdevice/NetlinkRequest.cpp b/automotive/can/1.0/default/libnetdevice/NetlinkRequest.cpp
index 9845bc7..556debf 100644
--- a/automotive/can/1.0/default/libnetdevice/NetlinkRequest.cpp
+++ b/automotive/can/1.0/default/libnetdevice/NetlinkRequest.cpp
@@ -18,9 +18,7 @@
 
 #include <android-base/logging.h>
 
-namespace android {
-namespace netdevice {
-namespace impl {
+namespace android::netdevice::impl {
 
 static struct rtattr* nlmsg_tail(struct nlmsghdr* n) {
     return reinterpret_cast<struct rtattr*>(  //
@@ -53,6 +51,4 @@
     nest->rta_len = nestLen;
 }
 
-}  // namespace impl
-}  // namespace netdevice
-}  // namespace android
+}  // namespace android::netdevice::impl
diff --git a/automotive/can/1.0/default/libnetdevice/NetlinkRequest.h b/automotive/can/1.0/default/libnetdevice/NetlinkRequest.h
index ba9b65b..3e28d78 100644
--- a/automotive/can/1.0/default/libnetdevice/NetlinkRequest.h
+++ b/automotive/can/1.0/default/libnetdevice/NetlinkRequest.h
@@ -21,8 +21,7 @@
 
 #include <string>
 
-namespace android {
-namespace netdevice {
+namespace android::netdevice {
 
 typedef unsigned short rtattrtype_t;  // as in rtnetlink.h
 typedef __u16 nlmsgtype_t;            // as in netlink.h
@@ -151,5 +150,4 @@
     }
 };
 
-}  // namespace netdevice
-}  // namespace android
+}  // namespace android::netdevice
diff --git a/automotive/can/1.0/default/libnetdevice/NetlinkSocket.cpp b/automotive/can/1.0/default/libnetdevice/NetlinkSocket.cpp
index 0514764..6a7f506 100644
--- a/automotive/can/1.0/default/libnetdevice/NetlinkSocket.cpp
+++ b/automotive/can/1.0/default/libnetdevice/NetlinkSocket.cpp
@@ -18,8 +18,7 @@
 
 #include <android-base/logging.h>
 
-namespace android {
-namespace netdevice {
+namespace android::netdevice {
 
 NetlinkSocket::NetlinkSocket(int protocol) {
     mFd.reset(socket(AF_NETLINK, SOCK_RAW, protocol));
@@ -110,5 +109,4 @@
     return false;
 }
 
-}  // namespace netdevice
-}  // namespace android
+}  // namespace android::netdevice
diff --git a/automotive/can/1.0/default/libnetdevice/NetlinkSocket.h b/automotive/can/1.0/default/libnetdevice/NetlinkSocket.h
index 90e1f3f..2b40ea2 100644
--- a/automotive/can/1.0/default/libnetdevice/NetlinkSocket.h
+++ b/automotive/can/1.0/default/libnetdevice/NetlinkSocket.h
@@ -23,8 +23,7 @@
 
 #include <linux/netlink.h>
 
-namespace android {
-namespace netdevice {
+namespace android::netdevice {
 
 /**
  * A wrapper around AF_NETLINK sockets.
@@ -64,5 +63,4 @@
     DISALLOW_COPY_AND_ASSIGN(NetlinkSocket);
 };
 
-}  // namespace netdevice
-}  // namespace android
+}  // namespace android::netdevice
diff --git a/automotive/can/1.0/default/libnetdevice/can.cpp b/automotive/can/1.0/default/libnetdevice/can.cpp
index 6452d9b..06d45d3 100644
--- a/automotive/can/1.0/default/libnetdevice/can.cpp
+++ b/automotive/can/1.0/default/libnetdevice/can.cpp
@@ -28,9 +28,7 @@
 #include <linux/can/netlink.h>
 #include <linux/can/raw.h>
 
-namespace android {
-namespace netdevice {
-namespace can {
+namespace android::netdevice::can {
 
 static constexpr can_err_mask_t kErrMask = CAN_ERR_MASK;
 
@@ -95,6 +93,4 @@
     return sock.send(req) && sock.receiveAck();
 }
 
-}  // namespace can
-}  // namespace netdevice
-}  // namespace android
+}  // namespace android::netdevice::can
diff --git a/automotive/can/1.0/default/libnetdevice/common.cpp b/automotive/can/1.0/default/libnetdevice/common.cpp
index 3deac3e..5c62443 100644
--- a/automotive/can/1.0/default/libnetdevice/common.cpp
+++ b/automotive/can/1.0/default/libnetdevice/common.cpp
@@ -20,8 +20,7 @@
 
 #include <net/if.h>
 
-namespace android {
-namespace netdevice {
+namespace android::netdevice {
 
 unsigned int nametoindex(const std::string& ifname) {
     const auto ifidx = if_nametoindex(ifname.c_str());
@@ -34,5 +33,4 @@
     return 0;
 }
 
-}  // namespace netdevice
-}  // namespace android
+}  // namespace android::netdevice
diff --git a/automotive/can/1.0/default/libnetdevice/common.h b/automotive/can/1.0/default/libnetdevice/common.h
index 9bdff4d..8097f37 100644
--- a/automotive/can/1.0/default/libnetdevice/common.h
+++ b/automotive/can/1.0/default/libnetdevice/common.h
@@ -18,8 +18,7 @@
 
 #include <string>
 
-namespace android {
-namespace netdevice {
+namespace android::netdevice {
 
 /**
  * Returns the index of a given network interface.
@@ -32,5 +31,4 @@
  */
 unsigned int nametoindex(const std::string& ifname);
 
-}  // namespace netdevice
-}  // namespace android
+}  // namespace android::netdevice
diff --git a/automotive/can/1.0/default/libnetdevice/include/libnetdevice/can.h b/automotive/can/1.0/default/libnetdevice/include/libnetdevice/can.h
index d75361e..3886acf 100644
--- a/automotive/can/1.0/default/libnetdevice/include/libnetdevice/can.h
+++ b/automotive/can/1.0/default/libnetdevice/include/libnetdevice/can.h
@@ -20,9 +20,7 @@
 
 #include <string>
 
-namespace android {
-namespace netdevice {
-namespace can {
+namespace android::netdevice::can {
 
 /**
  * Opens and binds SocketCAN socket.
@@ -40,6 +38,4 @@
  */
 bool setBitrate(std::string ifname, uint32_t bitrate);
 
-}  // namespace can
-}  // namespace netdevice
-}  // namespace android
+}  // namespace android::netdevice::can
diff --git a/automotive/can/1.0/default/libnetdevice/include/libnetdevice/libnetdevice.h b/automotive/can/1.0/default/libnetdevice/include/libnetdevice/libnetdevice.h
index e22eafb..3818a31 100644
--- a/automotive/can/1.0/default/libnetdevice/include/libnetdevice/libnetdevice.h
+++ b/automotive/can/1.0/default/libnetdevice/include/libnetdevice/libnetdevice.h
@@ -19,8 +19,7 @@
 #include <optional>
 #include <string>
 
-namespace android {
-namespace netdevice {
+namespace android::netdevice {
 
 /**
  * Checks, if the network interface exists.
@@ -71,5 +70,4 @@
  */
 bool del(std::string dev);
 
-}  // namespace netdevice
-}  // namespace android
+}  // namespace android::netdevice
diff --git a/automotive/can/1.0/default/libnetdevice/libnetdevice.cpp b/automotive/can/1.0/default/libnetdevice/libnetdevice.cpp
index fc2b193..aee8205 100644
--- a/automotive/can/1.0/default/libnetdevice/libnetdevice.cpp
+++ b/automotive/can/1.0/default/libnetdevice/libnetdevice.cpp
@@ -25,8 +25,7 @@
 #include <linux/can.h>
 #include <net/if.h>
 
-namespace android {
-namespace netdevice {
+namespace android::netdevice {
 
 bool exists(std::string ifname) {
     return nametoindex(ifname) != 0;
@@ -96,5 +95,4 @@
     return sock.send(req) && sock.receiveAck();
 }
 
-}  // namespace netdevice
-}  // namespace android
+}  // namespace android::netdevice
diff --git a/automotive/can/1.0/default/service.cpp b/automotive/can/1.0/default/service.cpp
index ebc2f8c..b52a54a 100644
--- a/automotive/can/1.0/default/service.cpp
+++ b/automotive/can/1.0/default/service.cpp
@@ -19,12 +19,7 @@
 #include <android-base/logging.h>
 #include <hidl/HidlTransportSupport.h>
 
-namespace android {
-namespace hardware {
-namespace automotive {
-namespace can {
-namespace V1_0 {
-namespace implementation {
+namespace android::hardware::automotive::can::V1_0::implementation {
 
 static void canControllerService() {
     base::SetDefaultTag("CanController");
@@ -42,12 +37,7 @@
     joinRpcThreadpool();
 }
 
-}  // namespace implementation
-}  // namespace V1_0
-}  // namespace can
-}  // namespace automotive
-}  // namespace hardware
-}  // namespace android
+}  // namespace android::hardware::automotive::can::V1_0::implementation
 
 int main() {
     ::android::hardware::automotive::can::V1_0::implementation::canControllerService();
diff --git a/automotive/can/1.0/hidl-utils/include/hidl-utils/hidl-utils.h b/automotive/can/1.0/hidl-utils/include/hidl-utils/hidl-utils.h
index 039f971..f63d43c 100644
--- a/automotive/can/1.0/hidl-utils/include/hidl-utils/hidl-utils.h
+++ b/automotive/can/1.0/hidl-utils/include/hidl-utils/hidl-utils.h
@@ -16,10 +16,7 @@
 
 #pragma once
 
-namespace android {
-namespace hardware {
-namespace automotive {
-namespace hidl_utils {
+namespace android::hardware::automotive::hidl_utils {
 
 /**
  * Helper functor to fetch results from multi-return HIDL calls.
@@ -61,7 +58,4 @@
     }
 };
 
-}  // namespace hidl_utils
-}  // namespace automotive
-}  // namespace hardware
-}  // namespace android
+}  // namespace android::hardware::automotive::hidl_utils
diff --git a/automotive/can/1.0/tools/canhalctrl.cpp b/automotive/can/1.0/tools/canhalctrl.cpp
index fa1048d..5c9849b 100644
--- a/automotive/can/1.0/tools/canhalctrl.cpp
+++ b/automotive/can/1.0/tools/canhalctrl.cpp
@@ -22,10 +22,7 @@
 #include <iostream>
 #include <string>
 
-namespace android {
-namespace hardware {
-namespace automotive {
-namespace can {
+namespace android::hardware::automotive::can {
 
 using ICanController = V1_0::ICanController;
 
@@ -170,10 +167,7 @@
     }
 }
 
-}  // namespace can
-}  // namespace automotive
-}  // namespace hardware
-}  // namespace android
+}  // namespace android::hardware::automotive::can
 
 int main(int argc, char* argv[]) {
     if (argc < 1) return -1;
diff --git a/automotive/can/1.0/tools/canhaldump.cpp b/automotive/can/1.0/tools/canhaldump.cpp
index 55b2a34..2f5ca61 100644
--- a/automotive/can/1.0/tools/canhaldump.cpp
+++ b/automotive/can/1.0/tools/canhaldump.cpp
@@ -27,10 +27,7 @@
 #include <string>
 #include <thread>
 
-namespace android {
-namespace hardware {
-namespace automotive {
-namespace can {
+namespace android::hardware::automotive::can {
 
 using namespace std::chrono_literals;
 
@@ -128,10 +125,7 @@
     return candump(argv[0]);
 }
 
-}  // namespace can
-}  // namespace automotive
-}  // namespace hardware
-}  // namespace android
+}  // namespace android::hardware::automotive::can
 
 int main(int argc, char* argv[]) {
     if (argc < 1) return -1;
diff --git a/automotive/can/1.0/tools/canhalsend.cpp b/automotive/can/1.0/tools/canhalsend.cpp
index 29330c9..7e6833a 100644
--- a/automotive/can/1.0/tools/canhalsend.cpp
+++ b/automotive/can/1.0/tools/canhalsend.cpp
@@ -21,10 +21,7 @@
 #include <iostream>
 #include <string>
 
-namespace android {
-namespace hardware {
-namespace automotive {
-namespace can {
+namespace android::hardware::automotive::can {
 
 using ICanBus = V1_0::ICanBus;
 using Result = V1_0::Result;
@@ -125,10 +122,7 @@
     return cansend(busname, msgid, payload);
 }
 
-}  // namespace can
-}  // namespace automotive
-}  // namespace hardware
-}  // namespace android
+}  // namespace android::hardware::automotive::can
 
 int main(int argc, char* argv[]) {
     if (argc < 1) return -1;
diff --git a/automotive/can/1.0/vts/functional/VtsHalCanBusV1_0TargetTest.cpp b/automotive/can/1.0/vts/functional/VtsHalCanBusV1_0TargetTest.cpp
index 250caf2..8deaed6 100644
--- a/automotive/can/1.0/vts/functional/VtsHalCanBusV1_0TargetTest.cpp
+++ b/automotive/can/1.0/vts/functional/VtsHalCanBusV1_0TargetTest.cpp
@@ -24,12 +24,7 @@
 #include <gmock/gmock.h>
 #include <hidl-utils/hidl-utils.h>
 
-namespace android {
-namespace hardware {
-namespace automotive {
-namespace can {
-namespace V1_0 {
-namespace vts {
+namespace android::hardware::automotive::can::V1_0::vts {
 
 using hardware::hidl_vec;
 
@@ -173,12 +168,7 @@
     ASSERT_NE(nullptr, closeHandle.get());
 }
 
-}  // namespace vts
-}  // namespace V1_0
-}  // namespace can
-}  // namespace automotive
-}  // namespace hardware
-}  // namespace android
+}  // namespace android::hardware::automotive::can::V1_0::vts
 
 /**
  * Example manual invocation:
diff --git a/automotive/can/1.0/vts/functional/VtsHalCanBusVirtualV1_0TargetTest.cpp b/automotive/can/1.0/vts/functional/VtsHalCanBusVirtualV1_0TargetTest.cpp
index 695b9fb..1663663 100644
--- a/automotive/can/1.0/vts/functional/VtsHalCanBusVirtualV1_0TargetTest.cpp
+++ b/automotive/can/1.0/vts/functional/VtsHalCanBusVirtualV1_0TargetTest.cpp
@@ -31,12 +31,7 @@
 #include <chrono>
 #include <thread>
 
-namespace android {
-namespace hardware {
-namespace automotive {
-namespace can {
-namespace V1_0 {
-namespace vts {
+namespace android::hardware::automotive::can::V1_0::vts {
 
 using namespace std::chrono_literals;
 
@@ -290,12 +285,7 @@
     ASSERT_EQ(expectedPositive, messagesPositive);
 }
 
-}  // namespace vts
-}  // namespace V1_0
-}  // namespace can
-}  // namespace automotive
-}  // namespace hardware
-}  // namespace android
+}  // namespace android::hardware::automotive::can::V1_0::vts
 
 /**
  * Example manual invocation:
diff --git a/automotive/can/1.0/vts/functional/VtsHalCanControllerV1_0TargetTest.cpp b/automotive/can/1.0/vts/functional/VtsHalCanControllerV1_0TargetTest.cpp
index 64e7a96..22dec2c 100644
--- a/automotive/can/1.0/vts/functional/VtsHalCanControllerV1_0TargetTest.cpp
+++ b/automotive/can/1.0/vts/functional/VtsHalCanControllerV1_0TargetTest.cpp
@@ -26,12 +26,7 @@
 #include <gmock/gmock.h>
 #include <hidl-utils/hidl-utils.h>
 
-namespace android {
-namespace hardware {
-namespace automotive {
-namespace can {
-namespace V1_0 {
-namespace vts {
+namespace android::hardware::automotive::can::V1_0::vts {
 
 using hardware::hidl_vec;
 using InterfaceType = ICanController::InterfaceType;
@@ -233,12 +228,7 @@
     assertRegistered(name, false);
 }
 
-}  // namespace vts
-}  // namespace V1_0
-}  // namespace can
-}  // namespace automotive
-}  // namespace hardware
-}  // namespace android
+}  // namespace android::hardware::automotive::can::V1_0::vts
 
 /**
  * Example manual invocation:
diff --git a/automotive/can/1.0/vts/utils/include/can-vts-utils/can-hal-printers.h b/automotive/can/1.0/vts/utils/include/can-vts-utils/can-hal-printers.h
index 0923998..3c30744 100644
--- a/automotive/can/1.0/vts/utils/include/can-vts-utils/can-hal-printers.h
+++ b/automotive/can/1.0/vts/utils/include/can-vts-utils/can-hal-printers.h
@@ -18,11 +18,7 @@
 
 #include <android/hardware/automotive/can/1.0/ICanController.h>
 
-namespace android {
-namespace hardware {
-namespace automotive {
-namespace can {
-namespace V1_0 {
+namespace android::hardware::automotive::can::V1_0 {
 
 /**
  * Define gTest printer for a given HIDL type, but skip definition for Return<T>.
@@ -48,8 +44,4 @@
 #undef DEFINE_CAN_HAL_PRINTER
 #undef DEFINE_CAN_HAL_PRINTER_SIMPLE
 
-}  // namespace V1_0
-}  // namespace can
-}  // namespace automotive
-}  // namespace hardware
-}  // namespace android
+}  // namespace android::hardware::automotive::can::V1_0
diff --git a/automotive/can/1.0/vts/utils/include/can-vts-utils/environment-utils.h b/automotive/can/1.0/vts/utils/include/can-vts-utils/environment-utils.h
index a722dd0..3eb9cc1 100644
--- a/automotive/can/1.0/vts/utils/include/can-vts-utils/environment-utils.h
+++ b/automotive/can/1.0/vts/utils/include/can-vts-utils/environment-utils.h
@@ -18,13 +18,7 @@
 
 #include <VtsHalHidlTargetTestEnvBase.h>
 
-namespace android {
-namespace hardware {
-namespace automotive {
-namespace can {
-namespace V1_0 {
-namespace vts {
-namespace utils {
+namespace android::hardware::automotive::can::V1_0::vts::utils {
 
 /**
  * Simple test environment.
@@ -63,10 +57,4 @@
     }
 };
 
-}  // namespace utils
-}  // namespace vts
-}  // namespace V1_0
-}  // namespace can
-}  // namespace automotive
-}  // namespace hardware
-}  // namespace android
+}  // namespace android::hardware::automotive::can::V1_0::vts::utils
diff --git a/automotive/vehicle/2.0/default/Android.bp b/automotive/vehicle/2.0/default/Android.bp
index f9c25d1..2050038 100644
--- a/automotive/vehicle/2.0/default/Android.bp
+++ b/automotive/vehicle/2.0/default/Android.bp
@@ -62,6 +62,7 @@
         "impl/vhal_v2_0/EmulatedVehicleHal.cpp",
         "impl/vhal_v2_0/VehicleEmulator.cpp",
         "impl/vhal_v2_0/PipeComm.cpp",
+        "impl/vhal_v2_0/ProtoMessageConverter.cpp",
         "impl/vhal_v2_0/SocketComm.cpp",
         "impl/vhal_v2_0/LinearFakeValueGenerator.cpp",
         "impl/vhal_v2_0/JsonFakeValueGenerator.cpp",
@@ -98,6 +99,21 @@
     test_suites: ["general-tests"],
 }
 
+cc_test {
+    name: "android.hardware.automotive.vehicle@2.0-default-impl-unit-tests",
+    vendor: true,
+    defaults: ["vhal_v2_0_defaults"],
+    srcs: [
+        "impl/vhal_v2_0/tests/ProtoMessageConverter_test.cpp",
+    ],
+    static_libs: [
+        "android.hardware.automotive.vehicle@2.0-default-impl-lib",
+        "android.hardware.automotive.vehicle@2.0-libproto-native",
+        "libprotobuf-cpp-lite",
+    ],
+    test_suites: ["general-tests"],
+}
+
 cc_binary {
     name: "android.hardware.automotive.vehicle@2.0-service",
     defaults: ["vhal_v2_0_defaults"],
diff --git a/automotive/vehicle/2.0/default/common/include/vhal_v2_0/VehicleConnector.h b/automotive/vehicle/2.0/default/common/include/vhal_v2_0/VehicleConnector.h
index 56ecd67..d40f122 100644
--- a/automotive/vehicle/2.0/default/common/include/vhal_v2_0/VehicleConnector.h
+++ b/automotive/vehicle/2.0/default/common/include/vhal_v2_0/VehicleConnector.h
@@ -57,10 +57,14 @@
     virtual std::vector<VehiclePropConfig> getAllPropertyConfig() const = 0;
 
     // Send the set property request to server
-    virtual StatusCode setProperty(const VehiclePropValue& value) = 0;
+    // updateStatus indicate if VHal should change the status of the value
+    // it should be false except injecting values for e2e tests
+    virtual StatusCode setProperty(const VehiclePropValue& value, bool updateStatus) = 0;
 
     // Receive a new property value from server
-    virtual void onPropertyValue(const VehiclePropValue& value) = 0;
+    // updateStatus is true if and only if the value is
+    // generated by car (ECU/fake generator/injected)
+    virtual void onPropertyValue(const VehiclePropValue& value, bool updateStatus) = 0;
 };
 
 /**
@@ -84,11 +88,15 @@
 
     // Receive the set property request from HAL.
     // Process the setting and return the status code
-    virtual StatusCode onSetProperty(const VehiclePropValue& value) = 0;
+    // updateStatus indicate if VHal should change the status of the value
+    // it should be false except injecting values for e2e tests
+    virtual StatusCode onSetProperty(const VehiclePropValue& value, bool updateStatus) = 0;
 
     // Receive a new property value from car (via direct connection to the car bus or the emulator)
     // and forward the value to HAL
-    virtual void onPropertyValueFromCar(const VehiclePropValue& value) = 0;
+    // updateStatus is true if and only if the value is
+    // generated by car (ECU/fake generator/injected)
+    virtual void onPropertyValueFromCar(const VehiclePropValue& value, bool updateStatus) = 0;
 };
 
 /**
@@ -118,12 +126,12 @@
         return this->onGetAllPropertyConfig();
     }
 
-    StatusCode setProperty(const VehiclePropValue& value) override {
-        return this->onSetProperty(value);
+    StatusCode setProperty(const VehiclePropValue& value, bool updateStatus) override {
+        return this->onSetProperty(value, updateStatus);
     }
 
-    void onPropertyValueFromCar(const VehiclePropValue& value) override {
-        return this->onPropertyValue(value);
+    void onPropertyValueFromCar(const VehiclePropValue& value, bool updateStatus) override {
+        return this->onPropertyValue(value, updateStatus);
     }
 
     // To be implemented:
diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/CommConn.cpp b/automotive/vehicle/2.0/default/impl/vhal_v2_0/CommConn.cpp
index bf1de81..136b2e0 100644
--- a/automotive/vehicle/2.0/default/impl/vhal_v2_0/CommConn.cpp
+++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/CommConn.cpp
@@ -41,7 +41,7 @@
     }
 }
 
-void CommConn::sendMessage(emulator::EmulatorMessage const& msg) {
+void CommConn::sendMessage(vhal_proto::EmulatorMessage const& msg) {
     int numBytes = msg.ByteSize();
     std::vector<uint8_t> buffer(static_cast<size_t>(numBytes));
     if (!msg.SerializeToArray(buffer.data(), numBytes)) {
@@ -61,9 +61,9 @@
             break;
         }
 
-        emulator::EmulatorMessage rxMsg;
+        vhal_proto::EmulatorMessage rxMsg;
         if (rxMsg.ParseFromArray(buffer.data(), static_cast<int32_t>(buffer.size()))) {
-            emulator::EmulatorMessage respMsg;
+            vhal_proto::EmulatorMessage respMsg;
             mMessageProcessor->processMessage(rxMsg, respMsg);
 
             sendMessage(respMsg);
diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/CommConn.h b/automotive/vehicle/2.0/default/impl/vhal_v2_0/CommConn.h
index 87b0dfc..6d36da4 100644
--- a/automotive/vehicle/2.0/default/impl/vhal_v2_0/CommConn.h
+++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/CommConn.h
@@ -44,8 +44,8 @@
      * Process a single message received over a CommConn. Populate the given respMsg with the reply
      * message we should send.
      */
-    virtual void processMessage(emulator::EmulatorMessage const& rxMsg,
-                                emulator::EmulatorMessage& respMsg) = 0;
+    virtual void processMessage(vhal_proto::EmulatorMessage const& rxMsg,
+                                vhal_proto::EmulatorMessage& respMsg) = 0;
 };
 
 /**
@@ -93,7 +93,7 @@
     /**
      * Serialized and send the given message to the other side.
      */
-    void sendMessage(emulator::EmulatorMessage const& msg);
+    void sendMessage(vhal_proto::EmulatorMessage const& msg);
 
    protected:
     std::unique_ptr<std::thread> mReadThread;
diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleConnector.cpp b/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleConnector.cpp
index 168999d..222fe5e 100644
--- a/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleConnector.cpp
+++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleConnector.cpp
@@ -30,12 +30,12 @@
 
 namespace impl {
 
-void EmulatedVehicleClient::onPropertyValue(const VehiclePropValue& value) {
+void EmulatedVehicleClient::onPropertyValue(const VehiclePropValue& value, bool updateStatus) {
     if (!mPropCallback) {
         LOG(ERROR) << __func__ << ": PropertyCallBackType is not registered!";
         return;
     }
-    return mPropCallback(value);
+    return mPropCallback(value, updateStatus);
 }
 
 void EmulatedVehicleClient::registerPropertyValueCallback(PropertyCallBackType&& callback) {
@@ -65,12 +65,13 @@
 }
 
 void EmulatedVehicleServer::onFakeValueGenerated(const VehiclePropValue& value) {
+    constexpr bool updateStatus = true;
     LOG(DEBUG) << __func__ << ": " << toString(value);
     auto updatedPropValue = getValuePool()->obtain(value);
     if (updatedPropValue) {
         updatedPropValue->timestamp = value.timestamp;
         updatedPropValue->status = VehiclePropertyStatus::AVAILABLE;
-        onPropertyValueFromCar(*updatedPropValue);
+        onPropertyValueFromCar(*updatedPropValue, updateStatus);
     }
 }
 
@@ -86,6 +87,8 @@
 }
 
 StatusCode EmulatedVehicleServer::handleGenerateFakeDataRequest(const VehiclePropValue& request) {
+    constexpr bool updateStatus = true;
+
     LOG(INFO) << __func__;
     const auto& v = request.value;
     if (!v.int32Values.size()) {
@@ -153,9 +156,11 @@
             int32_t display = request.value.int32Values[3];
             // Send back to HAL
             onPropertyValueFromCar(
-                    *createHwInputKeyProp(VehicleHwKeyInputAction::ACTION_DOWN, keyCode, display));
+                    *createHwInputKeyProp(VehicleHwKeyInputAction::ACTION_DOWN, keyCode, display),
+                    updateStatus);
             onPropertyValueFromCar(
-                    *createHwInputKeyProp(VehicleHwKeyInputAction::ACTION_UP, keyCode, display));
+                    *createHwInputKeyProp(VehicleHwKeyInputAction::ACTION_UP, keyCode, display),
+                    updateStatus);
             break;
         }
         default: {
@@ -191,9 +196,41 @@
     return keyEvent;
 }
 
-StatusCode EmulatedVehicleServer::onSetProperty(const VehiclePropValue& value) {
+StatusCode EmulatedVehicleServer::onSetProperty(const VehiclePropValue& value, bool updateStatus) {
     // Some properties need to be treated non-trivially
     switch (value.prop) {
+        case kGenerateFakeDataControllingProperty:
+            return handleGenerateFakeDataRequest(value);
+
+        // set the value from vehcile side, used in end to end test.
+        case kSetIntPropertyFromVehcileForTest: {
+            auto updatedPropValue = createVehiclePropValue(VehiclePropertyType::INT32, 1);
+            updatedPropValue->prop = value.value.int32Values[0];
+            updatedPropValue->value.int32Values[0] = value.value.int32Values[1];
+            updatedPropValue->timestamp = value.value.int64Values[0];
+            updatedPropValue->areaId = value.areaId;
+            onPropertyValueFromCar(*updatedPropValue, updateStatus);
+            return StatusCode::OK;
+        }
+        case kSetFloatPropertyFromVehcileForTest: {
+            auto updatedPropValue = createVehiclePropValue(VehiclePropertyType::FLOAT, 1);
+            updatedPropValue->prop = value.value.int32Values[0];
+            updatedPropValue->value.floatValues[0] = value.value.floatValues[0];
+            updatedPropValue->timestamp = value.value.int64Values[0];
+            updatedPropValue->areaId = value.areaId;
+            onPropertyValueFromCar(*updatedPropValue, updateStatus);
+            return StatusCode::OK;
+        }
+        case kSetBooleanPropertyFromVehcileForTest: {
+            auto updatedPropValue = createVehiclePropValue(VehiclePropertyType::BOOLEAN, 1);
+            updatedPropValue->prop = value.value.int32Values[1];
+            updatedPropValue->value.int32Values[0] = value.value.int32Values[0];
+            updatedPropValue->timestamp = value.value.int64Values[0];
+            updatedPropValue->areaId = value.areaId;
+            onPropertyValueFromCar(*updatedPropValue, updateStatus);
+            return StatusCode::OK;
+        }
+
         case AP_POWER_STATE_REPORT:
             switch (value.value.int32Values[0]) {
                 case toInt(VehicleApPowerStateReport::DEEP_SLEEP_EXIT):
@@ -201,15 +238,18 @@
                 case toInt(VehicleApPowerStateReport::WAIT_FOR_VHAL):
                     // CPMS is in WAIT_FOR_VHAL state, simply move to ON
                     // Send back to HAL
-                    onPropertyValueFromCar(
-                            *createApPowerStateReq(VehicleApPowerStateReq::ON, 0));
+                    // ALWAYS update status for generated property value
+                    onPropertyValueFromCar(*createApPowerStateReq(VehicleApPowerStateReq::ON, 0),
+                                           true /* updateStatus */);
                     break;
                 case toInt(VehicleApPowerStateReport::DEEP_SLEEP_ENTRY):
                 case toInt(VehicleApPowerStateReport::SHUTDOWN_START):
                     // CPMS is in WAIT_FOR_FINISH state, send the FINISHED command
                     // Send back to HAL
+                    // ALWAYS update status for generated property value
                     onPropertyValueFromCar(
-                            *createApPowerStateReq(VehicleApPowerStateReq::FINISHED, 0));
+                            *createApPowerStateReq(VehicleApPowerStateReq::FINISHED, 0),
+                            true /* updateStatus */);
                     break;
                 case toInt(VehicleApPowerStateReport::ON):
                 case toInt(VehicleApPowerStateReport::SHUTDOWN_POSTPONE):
@@ -226,19 +266,12 @@
     }
 
     // In the real vhal, the value will be sent to Car ECU.
-    // We just pretend it is done here.
-    return StatusCode::OK;
-}
+    // We just pretend it is done here and send back to HAL
+    auto updatedPropValue = getValuePool()->obtain(value);
+    updatedPropValue->timestamp = elapsedRealtimeNano();
 
-StatusCode EmulatedVehicleServer::onSetPropertyFromVehicle(const VehiclePropValue& value) {
-    if (value.prop == kGenerateFakeDataControllingProperty) {
-        auto status = handleGenerateFakeDataRequest(value);
-        return status;
-    } else {
-        // Send back to HAL
-        onPropertyValueFromCar(value);
-        return StatusCode::OK;
-    }
+    onPropertyValueFromCar(*updatedPropValue, updateStatus);
+    return StatusCode::OK;
 }
 
 EmulatedPassthroughConnectorPtr makeEmulatedPassthroughConnector() {
diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleConnector.h b/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleConnector.h
index d424cd8..5fc6493 100644
--- a/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleConnector.h
+++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleConnector.h
@@ -35,13 +35,10 @@
 class EmulatedVehicleClient : public IVehicleClient {
   public:
     // Type of callback function for handling the new property values
-    using PropertyCallBackType = std::function<void(const VehiclePropValue&)>;
+    using PropertyCallBackType = std::function<void(const VehiclePropValue&, bool updateStatus)>;
 
     // Method from IVehicleClient
-    void onPropertyValue(const VehiclePropValue& value) override;
-
-    // Request to change the value on the VEHICLE side (for testing)
-    virtual StatusCode setPropertyFromVehicle(const VehiclePropValue& value) = 0;
+    void onPropertyValue(const VehiclePropValue& value, bool updateStatus) override;
 
     void registerPropertyValueCallback(PropertyCallBackType&& callback);
 
@@ -55,10 +52,7 @@
 
     std::vector<VehiclePropConfig> onGetAllPropertyConfig() const override;
 
-    StatusCode onSetProperty(const VehiclePropValue& value) override;
-
-    // Process the request to change the value on the VEHICLE side (for testing)
-    StatusCode onSetPropertyFromVehicle(const VehiclePropValue& value);
+    StatusCode onSetProperty(const VehiclePropValue& value, bool updateStatus) override;
 
     // Set the Property Value Pool used in this server
     void setValuePool(VehiclePropValuePool* valuePool);
@@ -85,16 +79,10 @@
     VehiclePropValuePool* mValuePool{nullptr};
 };
 
-class EmulatedPassthroughConnector
-    : public IPassThroughConnector<EmulatedVehicleClient, EmulatedVehicleServer> {
-  public:
-    StatusCode setPropertyFromVehicle(const VehiclePropValue& value) override {
-        return this->onSetPropertyFromVehicle(value);
-    }
-};
-
 // Helper functions
 
+using EmulatedPassthroughConnector =
+        IPassThroughConnector<EmulatedVehicleClient, EmulatedVehicleServer>;
 using EmulatedPassthroughConnectorPtr = std::unique_ptr<EmulatedPassthroughConnector>;
 
 EmulatedPassthroughConnectorPtr makeEmulatedPassthroughConnector();
diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleHal.cpp b/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleHal.cpp
index 6508efe..5c16bf7 100644
--- a/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleHal.cpp
+++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleHal.cpp
@@ -98,8 +98,9 @@
     for (size_t i = 0; i < arraysize(kVehicleProperties); i++) {
         mPropStore->registerProperty(kVehicleProperties[i].config);
     }
-    mVehicleClient->registerPropertyValueCallback(
-        std::bind(&EmulatedVehicleHal::onPropertyValue, this, std::placeholders::_1));
+    mVehicleClient->registerPropertyValueCallback(std::bind(&EmulatedVehicleHal::onPropertyValue,
+                                                            this, std::placeholders::_1,
+                                                            std::placeholders::_2));
 }
 
 VehicleHal::VehiclePropValuePtr EmulatedVehicleHal::get(
@@ -131,41 +132,15 @@
 }
 
 StatusCode EmulatedVehicleHal::set(const VehiclePropValue& propValue) {
-    static constexpr bool shouldUpdateStatus = false;
-
-    // set the value from vehcile side, used in end to end test.
-    if (propValue.prop == kSetIntPropertyFromVehcileForTest) {
-        auto mockValue = createVehiclePropValue(VehiclePropertyType::INT32, 1);
-        mockValue->prop = propValue.value.int32Values[0];
-        mockValue->value.int32Values[0] = propValue.value.int32Values[1];
-        mockValue->timestamp = propValue.value.int64Values[0];
-        mockValue->areaId = propValue.areaId;
-        setPropertyFromVehicle(*mockValue);
-        return StatusCode::OK;
-    }
-
-    if (propValue.prop == kSetFloatPropertyFromVehcileForTest) {
-        auto mockValue = createVehiclePropValue(VehiclePropertyType::FLOAT, 1);
-        mockValue->prop = propValue.value.int32Values[0];
-        mockValue->value.floatValues[0] = propValue.value.floatValues[0];
-        mockValue->timestamp = propValue.value.int64Values[0];
-        mockValue->areaId = propValue.areaId;
-        setPropertyFromVehicle(*mockValue);
-        return StatusCode::OK;
-    }
-    if (propValue.prop == kSetBooleanPropertyFromVehcileForTest) {
-        auto mockValue = createVehiclePropValue(VehiclePropertyType::BOOLEAN, 1);
-        mockValue->prop = propValue.value.int32Values[1];
-        mockValue->value.int32Values[0] = propValue.value.int32Values[0];
-        mockValue->timestamp = propValue.value.int64Values[0];
-        mockValue->areaId = propValue.areaId;
-        setPropertyFromVehicle(*mockValue);
-        return StatusCode::OK;
-    }
+    constexpr bool updateStatus = false;
 
     if (propValue.prop == kGenerateFakeDataControllingProperty) {
-        // send the generator controlling request to the server
-        auto status = mVehicleClient->setPropertyFromVehicle(propValue);
+        // Send the generator controlling request to the server.
+        // 'updateStatus' flag is only for the value sent by setProperty (propValue in this case)
+        // instead of the generated values triggered by it. 'propValue' works as a control signal
+        // here, since we never send the control signal back, the value of 'updateStatus' flag
+        // does not matter here.
+        auto status = mVehicleClient->setProperty(propValue, updateStatus);
         if (status != StatusCode::OK) {
             return status;
         }
@@ -212,22 +187,13 @@
      * After checking all conditions, such as the property is available, a real vhal will
      * sent the events to Car ECU to take actions.
      */
-    VehiclePropValuePtr updatedPropValue = getValuePool()->obtain(propValue);
-    updatedPropValue->timestamp = elapsedRealtimeNano();
 
     // Send the value to the vehicle server, the server will talk to the (real or emulated) car
-    auto setValueStatus = mVehicleClient->setProperty(*updatedPropValue);
+    auto setValueStatus = mVehicleClient->setProperty(propValue, updateStatus);
     if (setValueStatus != StatusCode::OK) {
         return setValueStatus;
     }
 
-    if (!mPropStore->writeValue(*updatedPropValue, shouldUpdateStatus)) {
-        return StatusCode::INTERNAL_ERROR;
-    }
-
-    getEmulatorOrDie()->doSetValueFromClient(*updatedPropValue);
-    doHalEvent(std::move(updatedPropValue));
-
     return StatusCode::OK;
 }
 
@@ -314,7 +280,6 @@
         }
 
         if (v.get()) {
-            v->timestamp = elapsedRealtimeNano();
             doHalEvent(std::move(v));
         }
     }
@@ -347,18 +312,19 @@
 }
 
 bool EmulatedVehicleHal::setPropertyFromVehicle(const VehiclePropValue& propValue) {
-    return mVehicleClient->setPropertyFromVehicle(propValue) == StatusCode::OK;
+    constexpr bool updateStatus = true;
+    return mVehicleClient->setProperty(propValue, updateStatus) == StatusCode::OK;
 }
 
 std::vector<VehiclePropValue> EmulatedVehicleHal::getAllProperties() const  {
     return mPropStore->readAllValues();
 }
 
-void EmulatedVehicleHal::onPropertyValue(const VehiclePropValue& value) {
-    static constexpr bool shouldUpdateStatus = true;
+void EmulatedVehicleHal::onPropertyValue(const VehiclePropValue& value, bool updateStatus) {
     VehiclePropValuePtr updatedPropValue = getValuePool()->obtain(value);
 
-    if (mPropStore->writeValue(*updatedPropValue, shouldUpdateStatus)) {
+    if (mPropStore->writeValue(*updatedPropValue, updateStatus)) {
+        getEmulatorOrDie()->doSetValueFromClient(*updatedPropValue);
         doHalEvent(std::move(updatedPropValue));
     }
 }
diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleHal.h b/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleHal.h
index 98315ec..a8378da 100644
--- a/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleHal.h
+++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleHal.h
@@ -68,7 +68,7 @@
     }
 
     StatusCode handleGenerateFakeDataRequest(const VehiclePropValue& request);
-    void onPropertyValue(const VehiclePropValue& value);
+    void onPropertyValue(const VehiclePropValue& value, bool updateStatus);
 
     void onContinuousPropertyTimer(const std::vector<int32_t>& properties);
     bool isContinuousProperty(int32_t propId) const;
diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/ProtoMessageConverter.cpp b/automotive/vehicle/2.0/default/impl/vhal_v2_0/ProtoMessageConverter.cpp
new file mode 100644
index 0000000..77cb114
--- /dev/null
+++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/ProtoMessageConverter.cpp
@@ -0,0 +1,216 @@
+/*
+ * Copyright (C) 2019 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 "ProtoMsgConverter"
+
+#include <memory>
+#include <vector>
+
+#include <log/log.h>
+
+#include <vhal_v2_0/VehicleUtils.h>
+
+#include "ProtoMessageConverter.h"
+
+namespace android {
+namespace hardware {
+namespace automotive {
+namespace vehicle {
+namespace V2_0 {
+
+namespace impl {
+
+namespace proto_msg_converter {
+
+// If protobuf class PROTO_VALUE has value in field PROTO_VARNAME,
+// then casting the value by CAST and copying it to VHAL_TYPE_VALUE->VHAL_TYPE_VARNAME
+#define CHECK_CAST_COPY_PROTOBUF_VAR_TO_VHAL_TYPE(PROTO_VALUE, PROTO_VARNAME, VHAL_TYPE_VALUE, \
+                                                  VHAL_TYPE_VARNAME, CAST)                     \
+    if (PROTO_VALUE.has_##PROTO_VARNAME()) {                                                   \
+        (VHAL_TYPE_VALUE)->VHAL_TYPE_VARNAME = CAST(PROTO_VALUE.PROTO_VARNAME());              \
+    }
+
+// Copying the vector PROTO_VECNAME of protobuf class PROTO_VALUE to
+// VHAL_TYPE_VALUE->VHAL_TYPE_VECNAME, every element of PROTO_VECNAME
+// is casted by CAST
+#define CAST_COPY_PROTOBUF_VEC_TO_VHAL_TYPE(PROTO_VALUE, PROTO_VECNAME, VHAL_TYPE_VALUE, \
+                                            VHAL_TYPE_VECNAME, CAST)                     \
+    do {                                                                                 \
+        (VHAL_TYPE_VALUE)->VHAL_TYPE_VECNAME.resize(PROTO_VALUE.PROTO_VECNAME##_size()); \
+        size_t idx = 0;                                                                  \
+        for (auto& value : PROTO_VALUE.PROTO_VECNAME()) {                                \
+            VHAL_TYPE_VALUE->VHAL_TYPE_VECNAME[idx++] = CAST(value);                     \
+        }                                                                                \
+    } while (0)
+
+// If protobuf message has value in field PROTO_VARNAME,
+// then copying it to VHAL_TYPE_VALUE->VHAL_TYPE_VARNAME
+#define CHECK_COPY_PROTOBUF_VAR_TO_VHAL_TYPE(PROTO_VALUE, PROTO_VARNAME, VHAL_TYPE_VALUE, \
+                                             VHAL_TYPE_VARNAME)                           \
+    CHECK_CAST_COPY_PROTOBUF_VAR_TO_VHAL_TYPE(                                            \
+            PROTO_VALUE, PROTO_VARNAME, VHAL_TYPE_VALUE, VHAL_TYPE_VARNAME, /*NO CAST*/)
+
+// Copying the vector PROTO_VECNAME of protobuf class PROTO_VALUE to
+// VHAL_TYPE_VALUE->VHAL_TYPE_VECNAME
+#define COPY_PROTOBUF_VEC_TO_VHAL_TYPE(PROTO_VALUE, PROTO_VECNAME, VHAL_TYPE_VALUE, \
+                                       VHAL_TYPE_VECNAME)                           \
+    CAST_COPY_PROTOBUF_VEC_TO_VHAL_TYPE(                                            \
+            PROTO_VALUE, PROTO_VECNAME, VHAL_TYPE_VALUE, VHAL_TYPE_VECNAME, /*NO CAST*/)
+
+void toProto(vhal_proto::VehiclePropConfig* protoCfg, const VehiclePropConfig& cfg) {
+    protoCfg->set_prop(cfg.prop);
+    protoCfg->set_access(toInt(cfg.access));
+    protoCfg->set_change_mode(toInt(cfg.changeMode));
+    protoCfg->set_value_type(toInt(getPropType(cfg.prop)));
+
+    for (auto& configElement : cfg.configArray) {
+        protoCfg->add_config_array(configElement);
+    }
+
+    if (cfg.configString.size() > 0) {
+        protoCfg->set_config_string(cfg.configString.c_str(), cfg.configString.size());
+    }
+
+    protoCfg->clear_area_configs();
+    for (auto& areaConfig : cfg.areaConfigs) {
+        auto* protoACfg = protoCfg->add_area_configs();
+        protoACfg->set_area_id(areaConfig.areaId);
+
+        switch (getPropType(cfg.prop)) {
+            case VehiclePropertyType::STRING:
+            case VehiclePropertyType::BOOLEAN:
+            case VehiclePropertyType::INT32_VEC:
+            case VehiclePropertyType::INT64_VEC:
+            case VehiclePropertyType::FLOAT_VEC:
+            case VehiclePropertyType::BYTES:
+            case VehiclePropertyType::MIXED:
+                // Do nothing.  These types don't have min/max values
+                break;
+            case VehiclePropertyType::INT64:
+                protoACfg->set_min_int64_value(areaConfig.minInt64Value);
+                protoACfg->set_max_int64_value(areaConfig.maxInt64Value);
+                break;
+            case VehiclePropertyType::FLOAT:
+                protoACfg->set_min_float_value(areaConfig.minFloatValue);
+                protoACfg->set_max_float_value(areaConfig.maxFloatValue);
+                break;
+            case VehiclePropertyType::INT32:
+                protoACfg->set_min_int32_value(areaConfig.minInt32Value);
+                protoACfg->set_max_int32_value(areaConfig.maxInt32Value);
+                break;
+            default:
+                ALOGW("%s: Unknown property type:  0x%x", __func__, toInt(getPropType(cfg.prop)));
+                break;
+        }
+    }
+
+    protoCfg->set_min_sample_rate(cfg.minSampleRate);
+    protoCfg->set_max_sample_rate(cfg.maxSampleRate);
+}
+
+void fromProto(VehiclePropConfig* cfg, const vhal_proto::VehiclePropConfig& protoCfg) {
+    CHECK_COPY_PROTOBUF_VAR_TO_VHAL_TYPE(protoCfg, prop, cfg, prop);
+    CHECK_CAST_COPY_PROTOBUF_VAR_TO_VHAL_TYPE(protoCfg, access, cfg, access,
+                                              static_cast<VehiclePropertyAccess>);
+    CHECK_CAST_COPY_PROTOBUF_VAR_TO_VHAL_TYPE(protoCfg, change_mode, cfg, changeMode,
+                                              static_cast<VehiclePropertyChangeMode>);
+    COPY_PROTOBUF_VEC_TO_VHAL_TYPE(protoCfg, config_array, cfg, configArray);
+    CHECK_COPY_PROTOBUF_VAR_TO_VHAL_TYPE(protoCfg, config_string, cfg, configString);
+
+    auto cast_to_acfg = [](const vhal_proto::VehicleAreaConfig& protoAcfg) {
+        VehicleAreaConfig acfg;
+        CHECK_COPY_PROTOBUF_VAR_TO_VHAL_TYPE(protoAcfg, area_id, &acfg, areaId);
+        CHECK_COPY_PROTOBUF_VAR_TO_VHAL_TYPE(protoAcfg, min_int32_value, &acfg, minInt32Value);
+        CHECK_COPY_PROTOBUF_VAR_TO_VHAL_TYPE(protoAcfg, max_int32_value, &acfg, maxInt32Value);
+        CHECK_COPY_PROTOBUF_VAR_TO_VHAL_TYPE(protoAcfg, min_int64_value, &acfg, minInt64Value);
+        CHECK_COPY_PROTOBUF_VAR_TO_VHAL_TYPE(protoAcfg, max_int64_value, &acfg, maxInt64Value);
+        CHECK_COPY_PROTOBUF_VAR_TO_VHAL_TYPE(protoAcfg, min_float_value, &acfg, minFloatValue);
+        CHECK_COPY_PROTOBUF_VAR_TO_VHAL_TYPE(protoAcfg, max_float_value, &acfg, maxFloatValue);
+        return acfg;
+    };
+
+    CAST_COPY_PROTOBUF_VEC_TO_VHAL_TYPE(protoCfg, area_configs, cfg, areaConfigs, cast_to_acfg);
+
+    CHECK_COPY_PROTOBUF_VAR_TO_VHAL_TYPE(protoCfg, min_sample_rate, cfg, minSampleRate);
+    CHECK_COPY_PROTOBUF_VAR_TO_VHAL_TYPE(protoCfg, max_sample_rate, cfg, maxSampleRate);
+}
+
+void toProto(vhal_proto::VehiclePropValue* protoVal, const VehiclePropValue& val) {
+    protoVal->set_prop(val.prop);
+    protoVal->set_value_type(toInt(getPropType(val.prop)));
+    protoVal->set_timestamp(val.timestamp);
+    protoVal->set_status((vhal_proto::VehiclePropStatus)(val.status));
+    protoVal->set_area_id(val.areaId);
+
+    // Copy value data if it is set.
+    //  - for bytes and strings, this is indicated by size > 0
+    //  - for int32, int64, and float, copy the values if vectors have data
+    if (val.value.stringValue.size() > 0) {
+        protoVal->set_string_value(val.value.stringValue.c_str(), val.value.stringValue.size());
+    }
+
+    if (val.value.bytes.size() > 0) {
+        protoVal->set_bytes_value(val.value.bytes.data(), val.value.bytes.size());
+    }
+
+    for (auto& int32Value : val.value.int32Values) {
+        protoVal->add_int32_values(int32Value);
+    }
+
+    for (auto& int64Value : val.value.int64Values) {
+        protoVal->add_int64_values(int64Value);
+    }
+
+    for (auto& floatValue : val.value.floatValues) {
+        protoVal->add_float_values(floatValue);
+    }
+}
+
+void fromProto(VehiclePropValue* val, const vhal_proto::VehiclePropValue& protoVal) {
+    CHECK_COPY_PROTOBUF_VAR_TO_VHAL_TYPE(protoVal, prop, val, prop);
+    CHECK_COPY_PROTOBUF_VAR_TO_VHAL_TYPE(protoVal, timestamp, val, timestamp);
+    CHECK_CAST_COPY_PROTOBUF_VAR_TO_VHAL_TYPE(protoVal, status, val, status,
+                                              static_cast<VehiclePropertyStatus>);
+    CHECK_COPY_PROTOBUF_VAR_TO_VHAL_TYPE(protoVal, area_id, val, areaId);
+
+    // Copy value data
+    CHECK_COPY_PROTOBUF_VAR_TO_VHAL_TYPE(protoVal, string_value, val, value.stringValue);
+
+    auto cast_proto_bytes_to_vec = [](auto&& bytes) {
+        return std::vector<uint8_t>(bytes.begin(), bytes.end());
+    };
+    CHECK_CAST_COPY_PROTOBUF_VAR_TO_VHAL_TYPE(protoVal, bytes_value, val, value.bytes,
+                                              cast_proto_bytes_to_vec);
+
+    COPY_PROTOBUF_VEC_TO_VHAL_TYPE(protoVal, int32_values, val, value.int32Values);
+    COPY_PROTOBUF_VEC_TO_VHAL_TYPE(protoVal, int64_values, val, value.int64Values);
+    COPY_PROTOBUF_VEC_TO_VHAL_TYPE(protoVal, float_values, val, value.floatValues);
+}
+
+#undef COPY_PROTOBUF_VEC_TO_VHAL_TYPE
+#undef CHECK_COPY_PROTOBUF_VAR_TO_VHAL_TYPE
+#undef CAST_COPY_PROTOBUF_VEC_TO_VHAL_TYPE
+#undef CHECK_CAST_COPY_PROTOBUF_VAR_TO_VHAL_TYPE
+
+}  // namespace proto_msg_converter
+
+}  // namespace impl
+
+}  // namespace V2_0
+}  // namespace vehicle
+}  // namespace automotive
+}  // namespace hardware
+}  // namespace android
diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/ProtoMessageConverter.h b/automotive/vehicle/2.0/default/impl/vhal_v2_0/ProtoMessageConverter.h
new file mode 100644
index 0000000..01f3beb
--- /dev/null
+++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/ProtoMessageConverter.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2019 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.
+ */
+
+#ifndef android_hardware_automotive_vehicle_V2_0_impl_ProtoMessageConverter_H_
+#define android_hardware_automotive_vehicle_V2_0_impl_ProtoMessageConverter_H_
+
+#include <android/hardware/automotive/vehicle/2.0/types.h>
+
+#include "VehicleHalProto.pb.h"
+
+namespace android {
+namespace hardware {
+namespace automotive {
+namespace vehicle {
+namespace V2_0 {
+
+namespace impl {
+
+namespace proto_msg_converter {
+
+// VehiclePropConfig
+
+void toProto(vhal_proto::VehiclePropConfig* protoCfg, const VehiclePropConfig& cfg);
+
+void fromProto(VehiclePropConfig* cfg, const vhal_proto::VehiclePropConfig& protoCfg);
+
+// VehiclePropValue
+
+void toProto(vhal_proto::VehiclePropValue* protoVal, const VehiclePropValue& val);
+
+void fromProto(VehiclePropValue* val, const vhal_proto::VehiclePropValue& protoVal);
+
+}  // namespace proto_msg_converter
+
+}  // namespace impl
+
+}  // namespace V2_0
+}  // namespace vehicle
+}  // namespace automotive
+}  // namespace hardware
+}  // namespace android
+
+#endif  // android_hardware_automotive_vehicle_V2_0_impl_VehicleHalEmulator_H_
diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/SocketComm.cpp b/automotive/vehicle/2.0/default/impl/vhal_v2_0/SocketComm.cpp
index 068333c..916c320 100644
--- a/automotive/vehicle/2.0/default/impl/vhal_v2_0/SocketComm.cpp
+++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/SocketComm.cpp
@@ -60,7 +60,7 @@
     }
 }
 
-void SocketComm::sendMessage(emulator::EmulatorMessage const& msg) {
+void SocketComm::sendMessage(vhal_proto::EmulatorMessage const& msg) {
     std::lock_guard<std::mutex> lock(mMutex);
     for (std::unique_ptr<SocketConn> const& conn : mOpenConnections) {
         conn->sendMessage(msg);
diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/SocketComm.h b/automotive/vehicle/2.0/default/impl/vhal_v2_0/SocketComm.h
index 88b852b..52326b9 100644
--- a/automotive/vehicle/2.0/default/impl/vhal_v2_0/SocketComm.h
+++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/SocketComm.h
@@ -47,7 +47,7 @@
     /**
      * Serialized and send the given message to all connected clients.
      */
-    void sendMessage(emulator::EmulatorMessage const& msg);
+    void sendMessage(vhal_proto::EmulatorMessage const& msg);
 
    private:
     int mListenFd;
diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/VehicleEmulator.cpp b/automotive/vehicle/2.0/default/impl/vhal_v2_0/VehicleEmulator.cpp
index 9dc7085..263ca62 100644
--- a/automotive/vehicle/2.0/default/impl/vhal_v2_0/VehicleEmulator.cpp
+++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/VehicleEmulator.cpp
@@ -24,6 +24,7 @@
 #include <vhal_v2_0/VehicleUtils.h>
 
 #include "PipeComm.h"
+#include "ProtoMessageConverter.h"
 #include "SocketComm.h"
 
 #include "VehicleEmulator.h"
@@ -62,11 +63,11 @@
  * changed.
  */
 void VehicleEmulator::doSetValueFromClient(const VehiclePropValue& propValue) {
-    emulator::EmulatorMessage msg;
-    emulator::VehiclePropValue *val = msg.add_value();
+    vhal_proto::EmulatorMessage msg;
+    vhal_proto::VehiclePropValue* val = msg.add_value();
     populateProtoVehiclePropValue(val, &propValue);
-    msg.set_status(emulator::RESULT_OK);
-    msg.set_msg_type(emulator::SET_PROPERTY_ASYNC);
+    msg.set_status(vhal_proto::RESULT_OK);
+    msg.set_msg_type(vhal_proto::SET_PROPERTY_ASYNC);
 
     mSocketComm->sendMessage(msg);
     if (mPipeComm) {
@@ -77,17 +78,17 @@
 void VehicleEmulator::doGetConfig(VehicleEmulator::EmulatorMessage const& rxMsg,
                                   VehicleEmulator::EmulatorMessage& respMsg) {
     std::vector<VehiclePropConfig> configs = mHal->listProperties();
-    emulator::VehiclePropGet getProp = rxMsg.prop(0);
+    vhal_proto::VehiclePropGet getProp = rxMsg.prop(0);
 
-    respMsg.set_msg_type(emulator::GET_CONFIG_RESP);
-    respMsg.set_status(emulator::ERROR_INVALID_PROPERTY);
+    respMsg.set_msg_type(vhal_proto::GET_CONFIG_RESP);
+    respMsg.set_status(vhal_proto::ERROR_INVALID_PROPERTY);
 
     for (auto& config : configs) {
         // Find the config we are looking for
         if (config.prop == getProp.prop()) {
-            emulator::VehiclePropConfig* protoCfg = respMsg.add_config();
+            vhal_proto::VehiclePropConfig* protoCfg = respMsg.add_config();
             populateProtoVehicleConfig(protoCfg, config);
-            respMsg.set_status(emulator::RESULT_OK);
+            respMsg.set_status(vhal_proto::RESULT_OK);
             break;
         }
     }
@@ -97,11 +98,11 @@
                                      VehicleEmulator::EmulatorMessage& respMsg) {
     std::vector<VehiclePropConfig> configs = mHal->listProperties();
 
-    respMsg.set_msg_type(emulator::GET_CONFIG_ALL_RESP);
-    respMsg.set_status(emulator::RESULT_OK);
+    respMsg.set_msg_type(vhal_proto::GET_CONFIG_ALL_RESP);
+    respMsg.set_status(vhal_proto::RESULT_OK);
 
     for (auto& config : configs) {
-        emulator::VehiclePropConfig* protoCfg = respMsg.add_config();
+        vhal_proto::VehiclePropConfig* protoCfg = respMsg.add_config();
         populateProtoVehicleConfig(protoCfg, config);
     }
 }
@@ -109,11 +110,11 @@
 void VehicleEmulator::doGetProperty(VehicleEmulator::EmulatorMessage const& rxMsg,
                                     VehicleEmulator::EmulatorMessage& respMsg) {
     int32_t areaId = 0;
-    emulator::VehiclePropGet getProp = rxMsg.prop(0);
+    vhal_proto::VehiclePropGet getProp = rxMsg.prop(0);
     int32_t propId = getProp.prop();
-    emulator::Status status = emulator::ERROR_INVALID_PROPERTY;
+    vhal_proto::Status status = vhal_proto::ERROR_INVALID_PROPERTY;
 
-    respMsg.set_msg_type(emulator::GET_PROPERTY_RESP);
+    respMsg.set_msg_type(vhal_proto::GET_PROPERTY_RESP);
 
     if (getProp.has_area_id()) {
         areaId = getProp.area_id();
@@ -127,9 +128,9 @@
         StatusCode halStatus;
         auto val = mHal->get(request, &halStatus);
         if (val != nullptr) {
-            emulator::VehiclePropValue* protoVal = respMsg.add_value();
+            vhal_proto::VehiclePropValue* protoVal = respMsg.add_value();
             populateProtoVehiclePropValue(protoVal, val.get());
-            status = emulator::RESULT_OK;
+            status = vhal_proto::RESULT_OK;
         }
     }
 
@@ -138,12 +139,12 @@
 
 void VehicleEmulator::doGetPropertyAll(VehicleEmulator::EmulatorMessage const& /* rxMsg */,
                                        VehicleEmulator::EmulatorMessage& respMsg) {
-    respMsg.set_msg_type(emulator::GET_PROPERTY_ALL_RESP);
-    respMsg.set_status(emulator::RESULT_OK);
+    respMsg.set_msg_type(vhal_proto::GET_PROPERTY_ALL_RESP);
+    respMsg.set_status(vhal_proto::RESULT_OK);
 
     {
         for (const auto& prop : mHal->getAllProperties()) {
-            emulator::VehiclePropValue* protoVal = respMsg.add_value();
+            vhal_proto::VehiclePropValue* protoVal = respMsg.add_value();
             populateProtoVehiclePropValue(protoVal, &prop);
         }
     }
@@ -151,7 +152,7 @@
 
 void VehicleEmulator::doSetProperty(VehicleEmulator::EmulatorMessage const& rxMsg,
                                     VehicleEmulator::EmulatorMessage& respMsg) {
-    emulator::VehiclePropValue protoVal = rxMsg.value(0);
+    vhal_proto::VehiclePropValue protoVal = rxMsg.value(0);
     VehiclePropValue val = {
             .timestamp = elapsedRealtimeNano(),
             .areaId = protoVal.area_id(),
@@ -159,7 +160,7 @@
             .status = (VehiclePropertyStatus)protoVal.status(),
     };
 
-    respMsg.set_msg_type(emulator::SET_PROPERTY_RESP);
+    respMsg.set_msg_type(vhal_proto::SET_PROPERTY_RESP);
 
     // Copy value data if it is set.  This automatically handles complex data types if needed.
     if (protoVal.has_string_value()) {
@@ -187,120 +188,42 @@
     }
 
     bool halRes = mHal->setPropertyFromVehicle(val);
-    respMsg.set_status(halRes ? emulator::RESULT_OK : emulator::ERROR_INVALID_PROPERTY);
+    respMsg.set_status(halRes ? vhal_proto::RESULT_OK : vhal_proto::ERROR_INVALID_PROPERTY);
 }
 
-void VehicleEmulator::processMessage(emulator::EmulatorMessage const& rxMsg,
-                                     emulator::EmulatorMessage& respMsg) {
+void VehicleEmulator::processMessage(vhal_proto::EmulatorMessage const& rxMsg,
+                                     vhal_proto::EmulatorMessage& respMsg) {
     switch (rxMsg.msg_type()) {
-        case emulator::GET_CONFIG_CMD:
+        case vhal_proto::GET_CONFIG_CMD:
             doGetConfig(rxMsg, respMsg);
             break;
-        case emulator::GET_CONFIG_ALL_CMD:
+        case vhal_proto::GET_CONFIG_ALL_CMD:
             doGetConfigAll(rxMsg, respMsg);
             break;
-        case emulator::GET_PROPERTY_CMD:
+        case vhal_proto::GET_PROPERTY_CMD:
             doGetProperty(rxMsg, respMsg);
             break;
-        case emulator::GET_PROPERTY_ALL_CMD:
+        case vhal_proto::GET_PROPERTY_ALL_CMD:
             doGetPropertyAll(rxMsg, respMsg);
             break;
-        case emulator::SET_PROPERTY_CMD:
+        case vhal_proto::SET_PROPERTY_CMD:
             doSetProperty(rxMsg, respMsg);
             break;
         default:
             ALOGW("%s: Unknown message received, type = %d", __func__, rxMsg.msg_type());
-            respMsg.set_status(emulator::ERROR_UNIMPLEMENTED_CMD);
+            respMsg.set_status(vhal_proto::ERROR_UNIMPLEMENTED_CMD);
             break;
     }
 }
 
-void VehicleEmulator::populateProtoVehicleConfig(emulator::VehiclePropConfig* protoCfg,
+void VehicleEmulator::populateProtoVehicleConfig(vhal_proto::VehiclePropConfig* protoCfg,
                                                  const VehiclePropConfig& cfg) {
-    protoCfg->set_prop(cfg.prop);
-    protoCfg->set_access(toInt(cfg.access));
-    protoCfg->set_change_mode(toInt(cfg.changeMode));
-    protoCfg->set_value_type(toInt(getPropType(cfg.prop)));
-
-    for (auto& configElement : cfg.configArray) {
-        protoCfg->add_config_array(configElement);
-    }
-
-    if (cfg.configString.size() > 0) {
-        protoCfg->set_config_string(cfg.configString.c_str(), cfg.configString.size());
-    }
-
-    // Populate the min/max values based on property type
-    switch (getPropType(cfg.prop)) {
-        case VehiclePropertyType::STRING:
-        case VehiclePropertyType::BOOLEAN:
-        case VehiclePropertyType::INT32_VEC:
-        case VehiclePropertyType::INT64_VEC:
-        case VehiclePropertyType::FLOAT_VEC:
-        case VehiclePropertyType::BYTES:
-        case VehiclePropertyType::MIXED:
-            // Do nothing.  These types don't have min/max values
-            break;
-        case VehiclePropertyType::INT64:
-            if (cfg.areaConfigs.size() > 0) {
-                emulator::VehicleAreaConfig* aCfg = protoCfg->add_area_configs();
-                aCfg->set_min_int64_value(cfg.areaConfigs[0].minInt64Value);
-                aCfg->set_max_int64_value(cfg.areaConfigs[0].maxInt64Value);
-            }
-            break;
-        case VehiclePropertyType::FLOAT:
-            if (cfg.areaConfigs.size() > 0) {
-                emulator::VehicleAreaConfig* aCfg = protoCfg->add_area_configs();
-                aCfg->set_min_float_value(cfg.areaConfigs[0].minFloatValue);
-                aCfg->set_max_float_value(cfg.areaConfigs[0].maxFloatValue);
-            }
-            break;
-        case VehiclePropertyType::INT32:
-            if (cfg.areaConfigs.size() > 0) {
-                emulator::VehicleAreaConfig* aCfg = protoCfg->add_area_configs();
-                aCfg->set_min_int32_value(cfg.areaConfigs[0].minInt32Value);
-                aCfg->set_max_int32_value(cfg.areaConfigs[0].maxInt32Value);
-            }
-            break;
-        default:
-            ALOGW("%s: Unknown property type:  0x%x", __func__, toInt(getPropType(cfg.prop)));
-            break;
-    }
-
-    protoCfg->set_min_sample_rate(cfg.minSampleRate);
-    protoCfg->set_max_sample_rate(cfg.maxSampleRate);
+    return proto_msg_converter::toProto(protoCfg, cfg);
 }
 
-void VehicleEmulator::populateProtoVehiclePropValue(emulator::VehiclePropValue* protoVal,
+void VehicleEmulator::populateProtoVehiclePropValue(vhal_proto::VehiclePropValue* protoVal,
                                                     const VehiclePropValue* val) {
-    protoVal->set_prop(val->prop);
-    protoVal->set_value_type(toInt(getPropType(val->prop)));
-    protoVal->set_timestamp(val->timestamp);
-    protoVal->set_status((emulator::VehiclePropStatus)(val->status));
-    protoVal->set_area_id(val->areaId);
-
-    // Copy value data if it is set.
-    //  - for bytes and strings, this is indicated by size > 0
-    //  - for int32, int64, and float, copy the values if vectors have data
-    if (val->value.stringValue.size() > 0) {
-        protoVal->set_string_value(val->value.stringValue.c_str(), val->value.stringValue.size());
-    }
-
-    if (val->value.bytes.size() > 0) {
-        protoVal->set_bytes_value(val->value.bytes.data(), val->value.bytes.size());
-    }
-
-    for (auto& int32Value : val->value.int32Values) {
-        protoVal->add_int32_values(int32Value);
-    }
-
-    for (auto& int64Value : val->value.int64Values) {
-        protoVal->add_int64_values(int64Value);
-    }
-
-    for (auto& floatValue : val->value.floatValues) {
-        protoVal->add_float_values(floatValue);
-    }
+    return proto_msg_converter::toProto(protoVal, *val);
 }
 
 }  // impl
diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/VehicleEmulator.h b/automotive/vehicle/2.0/default/impl/vhal_v2_0/VehicleEmulator.h
index 58e387a..82947be 100644
--- a/automotive/vehicle/2.0/default/impl/vhal_v2_0/VehicleEmulator.h
+++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/VehicleEmulator.h
@@ -72,21 +72,21 @@
     virtual ~VehicleEmulator();
 
     void doSetValueFromClient(const VehiclePropValue& propValue);
-    void processMessage(emulator::EmulatorMessage const& rxMsg,
-                        emulator::EmulatorMessage& respMsg) override;
+    void processMessage(vhal_proto::EmulatorMessage const& rxMsg,
+                        vhal_proto::EmulatorMessage& respMsg) override;
 
    private:
     friend class ConnectionThread;
-    using EmulatorMessage = emulator::EmulatorMessage;
+    using EmulatorMessage = vhal_proto::EmulatorMessage;
 
     void doGetConfig(EmulatorMessage const& rxMsg, EmulatorMessage& respMsg);
     void doGetConfigAll(EmulatorMessage const& rxMsg, EmulatorMessage& respMsg);
     void doGetProperty(EmulatorMessage const& rxMsg, EmulatorMessage& respMsg);
     void doGetPropertyAll(EmulatorMessage const& rxMsg, EmulatorMessage& respMsg);
     void doSetProperty(EmulatorMessage const& rxMsg, EmulatorMessage& respMsg);
-    void populateProtoVehicleConfig(emulator::VehiclePropConfig* protoCfg,
+    void populateProtoVehicleConfig(vhal_proto::VehiclePropConfig* protoCfg,
                                     const VehiclePropConfig& cfg);
-    void populateProtoVehiclePropValue(emulator::VehiclePropValue* protoVal,
+    void populateProtoVehiclePropValue(vhal_proto::VehiclePropValue* protoVal,
                                        const VehiclePropValue* val);
 
 private:
diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/proto/VehicleHalProto.proto b/automotive/vehicle/2.0/default/impl/vhal_v2_0/proto/VehicleHalProto.proto
index 04df5a8..4902a5d 100644
--- a/automotive/vehicle/2.0/default/impl/vhal_v2_0/proto/VehicleHalProto.proto
+++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/proto/VehicleHalProto.proto
@@ -16,7 +16,7 @@
 
 syntax = "proto2";
 
-package emulator;
+package vhal_proto;
 
 // CMD messages are from workstation --> VHAL
 // RESP messages are from VHAL --> workstation
diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/proto/VehicleServer.proto b/automotive/vehicle/2.0/default/impl/vhal_v2_0/proto/VehicleServer.proto
index 7ce3c32..2cc6595 100644
--- a/automotive/vehicle/2.0/default/impl/vhal_v2_0/proto/VehicleServer.proto
+++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/proto/VehicleServer.proto
@@ -14,9 +14,9 @@
  * limitations under the License.
  */
 
-syntax = "proto2";
+syntax = "proto3";
 
-package emulator;
+package vhal_proto;
 
 import "google/protobuf/empty.proto";
 import "VehicleHalProto.proto";
@@ -32,7 +32,7 @@
 }
 
 message VehicleHalCallStatus {
-    required VehicleHalStatusCode status_code      = 1;
+    VehicleHalStatusCode status_code    = 1;
 }
 
 service VehicleServer {
diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/tests/ProtoMessageConverter_test.cpp b/automotive/vehicle/2.0/default/impl/vhal_v2_0/tests/ProtoMessageConverter_test.cpp
new file mode 100644
index 0000000..3817e44
--- /dev/null
+++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/tests/ProtoMessageConverter_test.cpp
@@ -0,0 +1,110 @@
+/*
+ * Copyright (C) 2019 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 <gtest/gtest.h>
+
+#include <utils/SystemClock.h>
+
+#include "vhal_v2_0/DefaultConfig.h"
+#include "vhal_v2_0/ProtoMessageConverter.h"
+#include "vhal_v2_0/VehicleUtils.h"
+
+namespace android {
+namespace hardware {
+namespace automotive {
+namespace vehicle {
+namespace V2_0 {
+namespace impl {
+namespace proto_msg_converter {
+
+namespace {
+
+void CheckPropConfigConversion(const VehiclePropConfig& config) {
+    vhal_proto::VehiclePropConfig protoCfg;
+    VehiclePropConfig tmpConfig;
+
+    toProto(&protoCfg, config);
+    fromProto(&tmpConfig, protoCfg);
+
+    EXPECT_EQ(config.prop, tmpConfig.prop);
+    EXPECT_EQ(config.access, tmpConfig.access);
+    EXPECT_EQ(config.changeMode, tmpConfig.changeMode);
+    EXPECT_EQ(config.configString, tmpConfig.configString);
+    EXPECT_EQ(config.minSampleRate, tmpConfig.minSampleRate);
+    EXPECT_EQ(config.maxSampleRate, tmpConfig.maxSampleRate);
+    EXPECT_EQ(config.configArray, tmpConfig.configArray);
+
+    EXPECT_EQ(config.areaConfigs.size(), tmpConfig.areaConfigs.size());
+
+    auto cfgType = getPropType(config.prop);
+    for (size_t idx = 0; idx < std::min(config.areaConfigs.size(), tmpConfig.areaConfigs.size());
+         ++idx) {
+        auto& lhs = config.areaConfigs[idx];
+        auto& rhs = tmpConfig.areaConfigs[idx];
+        EXPECT_EQ(lhs.areaId, rhs.areaId);
+        switch (cfgType) {
+            case VehiclePropertyType::INT64:
+                EXPECT_EQ(lhs.minInt64Value, rhs.minInt64Value);
+                EXPECT_EQ(lhs.maxInt64Value, rhs.maxInt64Value);
+                break;
+            case VehiclePropertyType::FLOAT:
+                EXPECT_EQ(lhs.minFloatValue, rhs.minFloatValue);
+                EXPECT_EQ(lhs.maxFloatValue, rhs.maxFloatValue);
+                break;
+            case VehiclePropertyType::INT32:
+                EXPECT_EQ(lhs.minInt32Value, rhs.minInt32Value);
+                EXPECT_EQ(lhs.maxInt32Value, rhs.maxInt32Value);
+                break;
+            default:
+                // ignore min/max values
+                break;
+        }
+    }
+}
+
+void CheckPropValueConversion(const VehiclePropValue& val) {
+    vhal_proto::VehiclePropValue protoVal;
+    VehiclePropValue tmpVal;
+
+    toProto(&protoVal, val);
+    fromProto(&tmpVal, protoVal);
+
+    EXPECT_EQ(val, tmpVal);
+}
+
+TEST(ProtoMessageConverterTest, basic) {
+    for (auto& property : impl::kVehicleProperties) {
+        CheckPropConfigConversion(property.config);
+
+        VehiclePropValue prop;
+        prop.timestamp = elapsedRealtimeNano();
+        prop.areaId = 123;
+        prop.prop = property.config.prop;
+        prop.value = property.initialValue;
+        prop.status = VehiclePropertyStatus::ERROR;
+        CheckPropValueConversion(prop);
+    }
+}
+
+}  // namespace
+
+}  // namespace proto_msg_converter
+}  // namespace impl
+}  // namespace V2_0
+}  // namespace vehicle
+}  // namespace automotive
+}  // namespace hardware
+}  // namespace android
diff --git a/current.txt b/current.txt
index 30bee15..f026d7d 100644
--- a/current.txt
+++ b/current.txt
@@ -606,7 +606,7 @@
 2df5d5866b37776f25079c0e54b54350a2abe4e025a59c9e02a7d3abe8ca00e8 android.hardware.audio@6.0::IStreamIn
 78e4138cc8307c11fc777c3bd376e581ba4ba48196b05ca1d7cdfa515c87b48a android.hardware.audio@6.0::IStreamOut
 997fdaad7a9d17ee7e01feb7031a753e2365e72ad30b11d950e9183fabdf3844 android.hardware.audio@6.0::IStreamOutCallback
-1349686814402fa10f711cc5763bc629aafc64a5f5843b4b21b8cd86ffb923e6 android.hardware.audio.common@6.0::types
+8c4232772efeb9905b4c287723e0ee8b2c4bf5ba11728d051171b070e3d79144 android.hardware.audio.common@6.0::types
 817930d58412d662cb45e641c50cb62c727e4a3e3ffe7029a53cad9677b97d58 android.hardware.audio.effect@6.0::types
 525bec6b44f1103869c269a128d51b8dccd73af5340ba863c8886c68357c7faf android.hardware.audio.effect@6.0::IAcousticEchoCancelerEffect
 8d76bbe3719d051a8e9a1dcf9244f37f5b0a491feb249fa48391edf7cb4f3131 android.hardware.audio.effect@6.0::IAutomaticGainControlEffect
@@ -653,14 +653,14 @@
 36b3acf78ac4ecf8156be8741c1d8332cdce7a1ebf4dfa1562952f14a94e6c87 android.hardware.wifi.hostapd@1.2::IHostapd
 2defa258951e25a132aaeb36e3febe6f41bf9c6dbb1b1ebdf0b41708ab4e107e android.hardware.wifi.hostapd@1.2::types
 a64467bae843569f0d465c5be7f0c7a5b987985b55a3ef4794dd5afc68538650 android.hardware.wifi.supplicant@1.3::ISupplicant
-213457930af81ff3ea344fbc9d4a0d0a2bb70527f96b7b6a32ee3b5e4c17057e android.hardware.wifi.supplicant@1.3::ISupplicantStaIface
-619fc9839ec6e369cfa9b28e3e9412e6885720ff8f9b5750c1b6ffb905120391 android.hardware.wifi.supplicant@1.3::ISupplicantStaIfaceCallback
-a6163000e2804472924733bcf8b4269db776460cc4df64f9c4dc8350d7aeafc5 android.hardware.wifi.supplicant@1.3::ISupplicantStaNetwork
-9b0a3ab6f4f74b971ed094426d8a443e29b512ff03e1ab50c07156396cdb2483 android.hardware.wifi.supplicant@1.3::types
-0e3c23f1c815469fdcdc39bc33a486817771c7c6b6e5303f2f25569499fc6c69 android.hardware.radio@1.5::types
-2bc87cde08fcd8d9a0f5d4a2b8560ea793264d94f5b763a6b22d4a63d0f3cd5a android.hardware.radio@1.5::IRadio
+c72cb37b3f66ef65aeb5c6438a3fbe17bbe847fdf62d1a76eafd7f3a8a526105 android.hardware.wifi.supplicant@1.3::ISupplicantStaIface
+342a8e12db4dca643f2755eb4167e8f103d96502053a25a1f51f42107a4530f1 android.hardware.wifi.supplicant@1.3::ISupplicantStaIfaceCallback
+5477f8bafb29548875622fa83f1c0a29cee641acee613315eb747731001f4aff android.hardware.wifi.supplicant@1.3::ISupplicantStaNetwork
+91015479f5a0fba9872e98d3cca4680995de64f42ae71461b4b7e5acc5a196ab android.hardware.wifi.supplicant@1.3::types
+7a4ba60b5ddedf497e5d2bdff7d72b7d4a811969000e28677dd9e2389e683b34 android.hardware.radio@1.5::types
+afa2d6cf4c0ba4b8482d5bcc097594ad5bc49be0bf3003034f75955cdaf66045 android.hardware.radio@1.5::IRadio
 3afac66f21a33bc9c4b80481c7d5540038348651d9a7d8af64ea13610af138da android.hardware.radio@1.5::IRadioIndication
-67c8d90dab3f5b8f1e9cf123d6d1f9e581d382846eacc14476335798b9670885 android.hardware.radio@1.5::IRadioResponse
+f4888f9676890b43a459c6380f335fea7a6ad32ed3bafafeb018a88d6c0be8a4 android.hardware.radio@1.5::IRadioResponse
 55f0a15642869ec98a55ea0a5ac049d3e1a6245ff7750deb6bcb7182057eee83 android.hardware.radio.config@1.3::types
 b27ab0cd40b0b078cdcd024bfe1061c4c4c065f3519eeb9347fa359a3268a5ae android.hardware.radio.config@1.3::IRadioConfig
 742360c775313438b0f82256eac62fb5bbc76a6ae6f388573f3aa142fb2c1eea android.hardware.radio.config@1.3::IRadioConfigIndication
diff --git a/graphics/common/aidl/android/hardware/graphics/common/Cta861_3.aidl b/graphics/common/aidl/android/hardware/graphics/common/Cta861_3.aidl
new file mode 100644
index 0000000..4fbc6b2
--- /dev/null
+++ b/graphics/common/aidl/android/hardware/graphics/common/Cta861_3.aidl
@@ -0,0 +1,34 @@
+/**
+ * Copyright (c) 2019, 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.graphics.common;
+
+/**
+ * HDR static metadata extension as specified by CTA-861.3.
+ *
+ * This is an AIDL counterpart of the NDK struct `AHdrMetadata_cta861_3`.
+ */
+@VintfStability
+parcelable Cta861_3 {
+    /**
+     * Maximum content light level.
+     */
+    float maxContentLightLevel;
+    /**
+     * Maximum frame average light level.
+     */
+    float maxFrameAverageLightLevel;
+}
diff --git a/graphics/common/aidl/android/hardware/graphics/common/Smpte2086.aidl b/graphics/common/aidl/android/hardware/graphics/common/Smpte2086.aidl
new file mode 100644
index 0000000..60614cd
--- /dev/null
+++ b/graphics/common/aidl/android/hardware/graphics/common/Smpte2086.aidl
@@ -0,0 +1,51 @@
+/**
+ * Copyright (c) 2019, 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.graphics.common;
+import android.hardware.graphics.common.XyColor;
+
+/**
+ * Mastering display metadata as specified by SMPTE ST 2086.
+ *
+ * This is an AIDL counterpart of the NDK struct `AHdrMetadata_smpte2086`.
+ */
+@VintfStability
+parcelable Smpte2086 {
+    /**
+     * CIE XYZ chromaticity for red in the RGB primaries.
+     */
+    XyColor primaryRed;
+    /**
+     * CIE XYZ chromaticity for green in the RGB primaries.
+     */
+    XyColor primaryGreen;
+    /**
+     * CIE XYZ chromaticity for blue in the RGB primaries.
+     */
+    XyColor primaryBlue;
+    /**
+     * CIE XYZ chromaticity for the white point.
+     */
+    XyColor whitePoint;
+    /**
+     * Maximum luminance in candelas per square meter.
+     */
+    float maxLuminance;
+    /**
+     * Minimum luminance in candelas per square meter.
+     */
+    float minLuminance;
+}
diff --git a/graphics/common/aidl/android/hardware/graphics/common/StandardMetadataType.aidl b/graphics/common/aidl/android/hardware/graphics/common/StandardMetadataType.aidl
index 060d12c..43cf672 100644
--- a/graphics/common/aidl/android/hardware/graphics/common/StandardMetadataType.aidl
+++ b/graphics/common/aidl/android/hardware/graphics/common/StandardMetadataType.aidl
@@ -24,6 +24,15 @@
  *
  * IMapper@4.x must support getting the following standard buffer metadata types. IMapper@4.x may
  * support setting these standard buffer metadata types as well.
+ *
+ * When encoding these StandardMetadataTypes into a byte stream, the associated MetadataType is
+ * is first encoded followed by the StandardMetadataType value. The MetadataType is encoded by
+ * writing the length of MetadataType.name using 8 bytes in little endian, followed by a char
+ * array of MetadataType.name's characters. The char array is not null terminated. Finally,
+ * MetadataType.value is represented by 8 bytes written in little endian.
+ *
+ * The StandardMetadataType encode/decode support library can be found in:
+ * frameworks/native/libs/gralloc/types/include/gralloctypes/Gralloc4.h.
  */
 @VintfStability
 @Backing(type="long")
@@ -279,4 +288,43 @@
      * 4 bytes written in little endian.
      */
     BLEND_MODE = 17,
+
+    /**
+     * Can be used to get or set static HDR metadata specified by SMPTE ST 2086.
+     *
+     * This metadata is a stable aidl android.hardware.graphics.common.Smpte2086.
+     *
+     * This is not used in tone mapping until it has been set for the first time.
+     *
+     * When it is encoded into a byte stream, each float member is represented by 4 bytes written in
+     * little endian. The ordering of float values follows the definition of Smpte2086 and XyColor.
+     * If this is unset when encoded into a byte stream, the byte stream is empty.
+     */
+    SMPTE2086 = 18,
+
+    /**
+     * Can be used to get or set static HDR metadata specified by CTA 861.3.
+     *
+     * This metadata is a stable aidl android.hardware.graphics.common.Cta861_3.
+     *
+     * This is not used in tone mapping until it has been set for the first time.
+     *
+     * When it is encoded into a byte stream, each float member is represented by 4 bytes written in
+     * little endian. The ordering of float values follows the definition of Cta861_3.
+     * If this is unset when encoded into a byte stream, the byte stream is empty.
+     */
+    CTA861_3 = 19,
+
+    /**
+     * Can be used to get or set dynamic HDR metadata specified by SMPTE ST 2094-40:2016.
+     *
+     * This metadata is uint8_t byte array.
+     *
+     * This is not used in tone mapping until it has been set for the first time.
+     *
+     * When it is encoded into a byte stream, the length of the HDR metadata byte array is written
+     * using 8 bytes in little endian. It is followed by the uint8_t byte array.
+     * If this is unset when encoded into a byte stream, the byte stream is empty.
+     */
+    SMPTE2094_40 = 20,
 }
diff --git a/graphics/common/aidl/android/hardware/graphics/common/XyColor.aidl b/graphics/common/aidl/android/hardware/graphics/common/XyColor.aidl
new file mode 100644
index 0000000..9571273
--- /dev/null
+++ b/graphics/common/aidl/android/hardware/graphics/common/XyColor.aidl
@@ -0,0 +1,30 @@
+/**
+ * Copyright (c) 2019, 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.graphics.common;
+
+/**
+ * Chromaticity based on 2 parameters.
+ *
+ * This is an AIDL counterpart of the NDK struct `AColor_xy`.
+ *
+ * @note This can be used to represent any 2-dimensional chromaticity.
+ */
+@VintfStability
+parcelable XyColor {
+    float x;
+    float y;
+}
diff --git a/graphics/mapper/4.0/IMapper.hal b/graphics/mapper/4.0/IMapper.hal
index 03dfef1..93c85bd 100644
--- a/graphics/mapper/4.0/IMapper.hal
+++ b/graphics/mapper/4.0/IMapper.hal
@@ -206,6 +206,9 @@
      * outside of @p accessRegion is undefined, except that it must not cause
      * process termination.
      *
+     * An accessRegion of all-zeros means the entire buffer. That is, it is
+     * equivalent to '(0,0)-(buffer width, buffer height)'.
+     *
      * This function can lock both single-planar and multi-planar formats. The caller
      * should use get() to get information about the buffer they are locking.
      * get() can be used to get information about the planes, offsets, stride,
@@ -478,7 +481,7 @@
      * particular Metadata field.
      *
      * The framework may attempt to set the following StandardMetadataType
-     * values: DATASPACE, PER_FRAME_METADATA, PER_FRAME_METADATA_BLOB and BLEND_MODE.
+     * values: DATASPACE, SMPTE2086, CTA861_3, SMPTE2094_40 and BLEND_MODE.
      * We strongly encourage everyone to support setting as many of those fields as
      * possible. If a device's Composer implementation supports a field, it should be
      * supported here. Over time these metadata fields will be moved out of
diff --git a/graphics/mapper/4.0/vts/functional/VtsHalGraphicsMapperV4_0TargetTest.cpp b/graphics/mapper/4.0/vts/functional/VtsHalGraphicsMapperV4_0TargetTest.cpp
index c4b1c53..2aad242 100644
--- a/graphics/mapper/4.0/vts/functional/VtsHalGraphicsMapperV4_0TargetTest.cpp
+++ b/graphics/mapper/4.0/vts/functional/VtsHalGraphicsMapperV4_0TargetTest.cpp
@@ -44,11 +44,13 @@
 using android::hardware::graphics::common::V1_2::PixelFormat;
 using MetadataType = android::hardware::graphics::mapper::V4_0::IMapper::MetadataType;
 using aidl::android::hardware::graphics::common::BlendMode;
+using aidl::android::hardware::graphics::common::Cta861_3;
 using aidl::android::hardware::graphics::common::Dataspace;
 using aidl::android::hardware::graphics::common::ExtendableType;
 using aidl::android::hardware::graphics::common::PlaneLayout;
 using aidl::android::hardware::graphics::common::PlaneLayoutComponent;
 using aidl::android::hardware::graphics::common::PlaneLayoutComponentType;
+using aidl::android::hardware::graphics::common::Smpte2086;
 using aidl::android::hardware::graphics::common::StandardMetadataType;
 
 using DecodeFunction = std::function<void(const IMapper::BufferDescriptorInfo& descriptorInfo,
@@ -1020,6 +1022,42 @@
 }
 
 /**
+ * Test IMapper::get(Smpte2086)
+ */
+TEST_P(GraphicsMapperHidlTest, GetSmpte2086) {
+    testGet(mDummyDescriptorInfo, gralloc4::MetadataType_Smpte2086,
+            [](const IMapper::BufferDescriptorInfo& /*info*/, const hidl_vec<uint8_t>& vec) {
+                std::optional<Smpte2086> smpte2086;
+                ASSERT_EQ(NO_ERROR, gralloc4::decodeSmpte2086(vec, &smpte2086));
+                EXPECT_FALSE(smpte2086.has_value());
+            });
+}
+
+/**
+ * Test IMapper::get(Cta861_3)
+ */
+TEST_P(GraphicsMapperHidlTest, GetCta861_3) {
+    testGet(mDummyDescriptorInfo, gralloc4::MetadataType_Cta861_3,
+            [](const IMapper::BufferDescriptorInfo& /*info*/, const hidl_vec<uint8_t>& vec) {
+                std::optional<Cta861_3> cta861_3;
+                ASSERT_EQ(NO_ERROR, gralloc4::decodeCta861_3(vec, &cta861_3));
+                EXPECT_FALSE(cta861_3.has_value());
+            });
+}
+
+/**
+ * Test IMapper::get(Smpte2094_40)
+ */
+TEST_P(GraphicsMapperHidlTest, GetSmpte2094_40) {
+    testGet(mDummyDescriptorInfo, gralloc4::MetadataType_Smpte2094_40,
+            [](const IMapper::BufferDescriptorInfo& /*info*/, const hidl_vec<uint8_t>& vec) {
+                std::optional<std::vector<uint8_t>> smpte2094_40;
+                ASSERT_EQ(NO_ERROR, gralloc4::decodeSmpte2094_40(vec, &smpte2094_40));
+                EXPECT_FALSE(smpte2094_40.has_value());
+            });
+}
+
+/**
  * Test IMapper::get(metadata) with a bad buffer
  */
 TEST_P(GraphicsMapperHidlTest, GetMetadataBadValue) {
@@ -1072,6 +1110,15 @@
     ASSERT_EQ(Error::BAD_BUFFER,
               mGralloc->get(bufferHandle, gralloc4::MetadataType_BlendMode, &vec));
     ASSERT_EQ(0, vec.size());
+    ASSERT_EQ(Error::BAD_BUFFER,
+              mGralloc->get(bufferHandle, gralloc4::MetadataType_Smpte2086, &vec));
+    ASSERT_EQ(0, vec.size());
+    ASSERT_EQ(Error::BAD_BUFFER,
+              mGralloc->get(bufferHandle, gralloc4::MetadataType_Cta861_3, &vec));
+    ASSERT_EQ(0, vec.size());
+    ASSERT_EQ(Error::BAD_BUFFER,
+              mGralloc->get(bufferHandle, gralloc4::MetadataType_Smpte2094_40, &vec));
+    ASSERT_EQ(0, vec.size());
 }
 
 /**
@@ -1428,6 +1475,90 @@
 }
 
 /**
+ * Test IMapper::set(Smpte2086)
+ */
+TEST_P(GraphicsMapperHidlTest, SetSmpte2086) {
+    /**
+     * DISPLAY_P3 is a color space that uses the DCI_P3 primaries,
+     * the D65 white point and the SRGB transfer functions.
+     * Rendering Intent: Colorimetric
+     * Primaries:
+     *                  x       y
+     *  green           0.265   0.690
+     *  blue            0.150   0.060
+     *  red             0.680   0.320
+     *  white (D65)     0.3127  0.3290
+     */
+    std::optional<Smpte2086> smpte2086;
+    smpte2086->primaryRed.x = 0.680;
+    smpte2086->primaryRed.y = 0.320;
+    smpte2086->primaryGreen.x = 0.265;
+    smpte2086->primaryGreen.y = 0.690;
+    smpte2086->primaryBlue.x = 0.150;
+    smpte2086->primaryBlue.y = 0.060;
+    smpte2086->whitePoint.x = 0.3127;
+    smpte2086->whitePoint.y = 0.3290;
+    smpte2086->maxLuminance = 100.0;
+    smpte2086->minLuminance = 0.1;
+
+    hidl_vec<uint8_t> vec;
+    ASSERT_EQ(NO_ERROR, gralloc4::encodeSmpte2086(smpte2086, &vec));
+
+    testSet(mDummyDescriptorInfo, gralloc4::MetadataType_Smpte2086, vec,
+            [&](const IMapper::BufferDescriptorInfo& /*info*/, const hidl_vec<uint8_t>& vec) {
+                std::optional<Smpte2086> realSmpte2086;
+                ASSERT_EQ(NO_ERROR, gralloc4::decodeSmpte2086(vec, &realSmpte2086));
+                ASSERT_TRUE(realSmpte2086.has_value());
+                EXPECT_EQ(smpte2086->primaryRed.x, realSmpte2086->primaryRed.x);
+                EXPECT_EQ(smpte2086->primaryRed.y, realSmpte2086->primaryRed.y);
+                EXPECT_EQ(smpte2086->primaryGreen.x, realSmpte2086->primaryGreen.x);
+                EXPECT_EQ(smpte2086->primaryGreen.y, realSmpte2086->primaryGreen.y);
+                EXPECT_EQ(smpte2086->primaryBlue.x, realSmpte2086->primaryBlue.x);
+                EXPECT_EQ(smpte2086->primaryBlue.y, realSmpte2086->primaryBlue.y);
+                EXPECT_EQ(smpte2086->whitePoint.x, realSmpte2086->whitePoint.x);
+                EXPECT_EQ(smpte2086->whitePoint.y, realSmpte2086->whitePoint.y);
+                EXPECT_EQ(smpte2086->maxLuminance, realSmpte2086->maxLuminance);
+                EXPECT_EQ(smpte2086->minLuminance, realSmpte2086->minLuminance);
+            });
+}
+
+/**
+ * Test IMapper::set(Cta8613)
+ */
+TEST_P(GraphicsMapperHidlTest, SetCta861_3) {
+    std::optional<Cta861_3> cta861_3;
+    cta861_3->maxContentLightLevel = 78.0;
+    cta861_3->maxFrameAverageLightLevel = 62.0;
+
+    hidl_vec<uint8_t> vec;
+    ASSERT_EQ(NO_ERROR, gralloc4::encodeCta861_3(cta861_3, &vec));
+
+    testSet(mDummyDescriptorInfo, gralloc4::MetadataType_Cta861_3, vec,
+            [&](const IMapper::BufferDescriptorInfo& /*info*/, const hidl_vec<uint8_t>& vec) {
+                std::optional<Cta861_3> realCta861_3;
+                ASSERT_EQ(NO_ERROR, gralloc4::decodeCta861_3(vec, &realCta861_3));
+                ASSERT_TRUE(realCta861_3.has_value());
+                EXPECT_EQ(cta861_3->maxContentLightLevel, realCta861_3->maxContentLightLevel);
+                EXPECT_EQ(cta861_3->maxFrameAverageLightLevel,
+                          realCta861_3->maxFrameAverageLightLevel);
+            });
+}
+
+/**
+ * Test IMapper::set(Smpte2094_40)
+ */
+TEST_P(GraphicsMapperHidlTest, SetSmpte2094_40) {
+    hidl_vec<uint8_t> vec;
+
+    testSet(mDummyDescriptorInfo, gralloc4::MetadataType_Smpte2094_40, vec,
+            [&](const IMapper::BufferDescriptorInfo& /*info*/, const hidl_vec<uint8_t>& vec) {
+                std::optional<std::vector<uint8_t>> realSmpte2094_40;
+                ASSERT_EQ(NO_ERROR, gralloc4::decodeSmpte2094_40(vec, &realSmpte2094_40));
+                EXPECT_FALSE(realSmpte2094_40.has_value());
+            });
+}
+
+/**
  * Test IMapper::set(metadata) with a bad buffer
  */
 TEST_P(GraphicsMapperHidlTest, SetMetadataNullBuffer) {
@@ -1462,6 +1593,11 @@
               mGralloc->set(bufferHandle, gralloc4::MetadataType_Dataspace, vec));
     ASSERT_EQ(Error::BAD_BUFFER,
               mGralloc->set(bufferHandle, gralloc4::MetadataType_BlendMode, vec));
+    ASSERT_EQ(Error::BAD_BUFFER,
+              mGralloc->set(bufferHandle, gralloc4::MetadataType_Smpte2086, vec));
+    ASSERT_EQ(Error::BAD_BUFFER, mGralloc->set(bufferHandle, gralloc4::MetadataType_Cta861_3, vec));
+    ASSERT_EQ(Error::BAD_BUFFER,
+              mGralloc->set(bufferHandle, gralloc4::MetadataType_Smpte2094_40, vec));
 }
 
 /**
@@ -1521,6 +1657,10 @@
               mGralloc->set(bufferHandle, gralloc4::MetadataType_Dataspace, vec));
     ASSERT_EQ(Error::UNSUPPORTED,
               mGralloc->set(bufferHandle, gralloc4::MetadataType_BlendMode, vec));
+    ASSERT_EQ(Error::UNSUPPORTED,
+              mGralloc->set(bufferHandle, gralloc4::MetadataType_Smpte2086, vec));
+    ASSERT_EQ(Error::UNSUPPORTED,
+              mGralloc->set(bufferHandle, gralloc4::MetadataType_Cta861_3, vec));
 }
 
 /**
@@ -1753,6 +1893,45 @@
 }
 
 /**
+ * Test IMapper::getFromBufferDescriptorInfo(Smpte2086)
+ */
+TEST_P(GraphicsMapperHidlTest, GetFromBufferDescriptorInfoSmpte2086) {
+    hidl_vec<uint8_t> vec;
+    ASSERT_EQ(Error::NONE, mGralloc->getFromBufferDescriptorInfo(
+                                   mDummyDescriptorInfo, gralloc4::MetadataType_Smpte2086, &vec));
+
+    std::optional<Smpte2086> smpte2086;
+    ASSERT_EQ(NO_ERROR, gralloc4::decodeSmpte2086(vec, &smpte2086));
+    EXPECT_FALSE(smpte2086.has_value());
+}
+
+/**
+ * Test IMapper::getFromBufferDescriptorInfo(Cta861_3)
+ */
+TEST_P(GraphicsMapperHidlTest, GetFromBufferDescriptorInfoCta861_3) {
+    hidl_vec<uint8_t> vec;
+    ASSERT_EQ(Error::NONE, mGralloc->getFromBufferDescriptorInfo(
+                                   mDummyDescriptorInfo, gralloc4::MetadataType_Cta861_3, &vec));
+
+    std::optional<Cta861_3> cta861_3;
+    ASSERT_EQ(NO_ERROR, gralloc4::decodeCta861_3(vec, &cta861_3));
+    EXPECT_FALSE(cta861_3.has_value());
+}
+
+/**
+ * Test IMapper::getFromBufferDescriptorInfo(Smpte2094_40)
+ */
+TEST_P(GraphicsMapperHidlTest, GetFromBufferDescriptorInfoSmpte2094_40) {
+    hidl_vec<uint8_t> vec;
+    ASSERT_EQ(Error::NONE,
+              mGralloc->getFromBufferDescriptorInfo(mDummyDescriptorInfo,
+                                                    gralloc4::MetadataType_Smpte2094_40, &vec));
+    std::optional<std::vector<uint8_t>> smpte2094_40;
+    ASSERT_EQ(NO_ERROR, gralloc4::decodeSmpte2094_40(vec, &smpte2094_40));
+    EXPECT_FALSE(smpte2094_40.has_value());
+}
+
+/**
  * Test IMapper::getFromBufferDescriptorInfo(metadata) for unsupported metadata
  */
 TEST_P(GraphicsMapperHidlTest, GetFromBufferDescriptorInfoUnsupportedMetadata) {
diff --git a/radio/1.5/IRadio.hal b/radio/1.5/IRadio.hal
index 62a2c61..fafc6e2 100644
--- a/radio/1.5/IRadio.hal
+++ b/radio/1.5/IRadio.hal
@@ -18,8 +18,10 @@
 
 import @1.2::DataRequestReason;
 import @1.4::IRadio;
+import @1.4::DataProfileInfo;
 import @1.5::AccessNetwork;
 import @1.5::DataProfileInfo;
+import @1.5::LinkAddress;
 import @1.5::NetworkScanRequest;
 import @1.5::RadioAccessSpecifier;
 import @1.5::SignalThresholdInfo;
@@ -149,12 +151,8 @@
      * @param reason The request reason. Must be DataRequestReason.NORMAL or
      *     DataRequestReason.HANDOVER.
      * @param addresses If the reason is DataRequestReason.HANDOVER, this indicates the list of link
-     *     addresses of the existing data connection. The format is IP address with optional "/"
-     *     prefix length (The format is defined in RFC-4291 section 2.3). For example, "192.0.1.3",
-     *     "192.0.1.11/16", or "2001:db8::1/64". Typically one IPv4 or one IPv6 or one of each. If
-     *     the prefix length is absent, then the addresses are assumed to be point to point with
-     *     IPv4 with prefix length 32 or IPv6 with prefix length 128. This parameter must be ignored
-     *     unless reason is DataRequestReason.HANDOVER.
+     *     addresses of the existing data connection. This parameter must be ignored unless reason
+     *     is DataRequestReason.HANDOVER.
      * @param dnses If the reason is DataRequestReason.HANDOVER, this indicates the list of DNS
      *     addresses of the existing data connection. The format is defined in RFC-4291 section
      *     2.2. For example, "192.0.1.3" or "2001:db8::1". This parameter must be ignored unless
@@ -163,11 +161,11 @@
      * Response function is IRadioResponse.setupDataCallResponse_1_5()
      *
      * Note this API is the same as the 1.4 version except using the
-     * 1.5 AccessNetwork and DataProfileInto as the input param.
+     * 1.5 AccessNetwork, DataProfileInto, and link addresses as the input param.
      */
     oneway setupDataCall_1_5(int32_t serial, AccessNetwork accessNetwork,
             DataProfileInfo dataProfileInfo, bool roamingAllowed,
-            DataRequestReason reason, vec<string> addresses, vec<string> dnses);
+            DataRequestReason reason, vec<LinkAddress> addresses, vec<string> dnses);
 
     /**
      * Set an apn to initial attach network
diff --git a/radio/1.5/IRadioResponse.hal b/radio/1.5/IRadioResponse.hal
index 7a0bc57..968948b 100644
--- a/radio/1.5/IRadioResponse.hal
+++ b/radio/1.5/IRadioResponse.hal
@@ -18,7 +18,7 @@
 
 import @1.0::RadioResponseInfo;
 import @1.4::IRadioResponse;
-import @1.4::SetupDataCallResult;
+import @1.5::SetupDataCallResult;
 
 /**
  * Interface declaring response functions to solicited radio requests.
diff --git a/radio/1.5/types.hal b/radio/1.5/types.hal
index 5795f7b..73751b8 100644
--- a/radio/1.5/types.hal
+++ b/radio/1.5/types.hal
@@ -25,7 +25,10 @@
 import @1.2::NetworkScanRequest;
 import @1.4::AccessNetwork;
 import @1.4::ApnTypes;
+import @1.4::DataCallFailCause;
+import @1.4::DataConnActiveStatus;
 import @1.4::DataProfileInfo;
+import @1.4::PdpProtocolType;
 
 /**
  * Defining signal strength type.
@@ -289,3 +292,108 @@
     /** Supported APN types bitmap. See ApnTypes for the value of each bit. */
     bitfield<ApnTypes> supportedApnTypesBitmap;
 };
+
+/**
+ * The properties of the link address. This enum reflects the definition in
+ * if_addr.h in Linux kernel.
+ */
+enum AddressProperty : int32_t {
+    NONE = 0,
+
+    /** Indicates this address is deprecated */
+    DEPRECATED = 0x20,
+};
+
+/**
+ * Describes a data link address for mobile data connection.
+ */
+struct LinkAddress {
+    /**
+     * The format is IP address with optional "/"
+     * prefix length (The format is defined in RFC-4291 section 2.3). For example, "192.0.1.3",
+     * "192.0.1.11/16", or "2001:db8::1/64". Typically one IPv4 or one IPv6 or one of each. If
+     * the prefix length is absent, then the addresses are assumed to be point to point with
+     * IPv4 with prefix length 32 or IPv6 with prefix length 128.
+     */
+    string address;
+
+    /**
+     * The properties of the link address
+     */
+    bitfield<AddressProperty> properties;
+
+    /**
+     * The UTC time that this link address will be deprecated. 0 indicates this information is not
+     * available.
+     */
+    uint64_t deprecatedTime;
+
+    /**
+     * The UTC time that this link address will expire and no longer valid. 0 indicates this
+     * information is not available.
+     */
+    uint64_t expiredTime;
+};
+
+/**
+ * Overwritten from @1.4::SetupDataCallResult in order to update the addresses to 1.5
+ * version. In 1.5 the type of addresses changes to vector of LinkAddress.
+ */
+struct SetupDataCallResult {
+    /** Data call fail cause. DataCallFailCause.NONE if no error. */
+    DataCallFailCause cause;
+
+    /**
+     * If status != DataCallFailCause.NONE, this field indicates the suggested retry back-off timer
+     * value RIL wants to override the one pre-configured in FW. The unit is milliseconds.
+     * The value < 0 means no value is suggested.
+     * The value 0 means retry must be done ASAP.
+     * The value of INT_MAX(0x7fffffff) means no retry.
+     */
+    int32_t suggestedRetryTime;
+
+    /** Context ID, uniquely identifies this call. */
+    int32_t cid;
+
+    /** Data connection active status. */
+    DataConnActiveStatus active;
+
+    /**
+     * PDP_type values. If cause is DataCallFailCause.ONLY_SINGLE_BEARER_ALLOWED, this is the type
+     * supported such as "IP" or "IPV6".
+     */
+    PdpProtocolType type;
+
+    /** The network interface name. */
+    string ifname;
+
+    /**
+     * List of link address.
+     */
+    vec<LinkAddress> addresses;
+
+    /**
+     * List of DNS server addresses, e.g., "192.0.1.3" or "192.0.1.11 2001:db8::1". Empty if no dns
+     * server addresses returned.
+     */
+    vec<string> dnses;
+
+    /**
+     * List of default gateway addresses, e.g., "192.0.1.3" or "192.0.1.11 2001:db8::1".
+     * When empty, the addresses represent point to point connections.
+     */
+    vec<string> gateways;
+
+    /**
+     * List of P-CSCF(Proxy Call State Control Function) addresses via PCO(Protocol Configuration
+     * Option), e.g., "2001:db8::1 2001:db8::2 2001:db8::3". Empty if not IMS client.
+     */
+    vec<string> pcscf;
+
+    /**
+     * MTU received from network. Value <= 0 means network has either not sent a value or sent an
+     * invalid value.
+     */
+    int32_t mtu;
+};
+
diff --git a/radio/1.5/vts/functional/radio_hidl_hal_api.cpp b/radio/1.5/vts/functional/radio_hidl_hal_api.cpp
index d05d2cb..77d9a02 100644
--- a/radio/1.5/vts/functional/radio_hidl_hal_api.cpp
+++ b/radio/1.5/vts/functional/radio_hidl_hal_api.cpp
@@ -853,10 +853,11 @@
 
     bool roamingAllowed = false;
 
+    std::vector<::android::hardware::radio::V1_5::LinkAddress> addresses = {};
+    std::vector<hidl_string> dnses = {};
+
     ::android::hardware::radio::V1_2::DataRequestReason reason =
             ::android::hardware::radio::V1_2::DataRequestReason::NORMAL;
-    std::vector<hidl_string> addresses = {""};
-    std::vector<hidl_string> dnses = {""};
 
     Return<void> res = radio_v1_5->setupDataCall_1_5(serial, accessNetwork, dataProfileInfo,
                                                      roamingAllowed, reason, addresses, dnses);
diff --git a/radio/1.5/vts/functional/radio_hidl_hal_utils_v1_5.h b/radio/1.5/vts/functional/radio_hidl_hal_utils_v1_5.h
index c2ee94e..ba11257 100644
--- a/radio/1.5/vts/functional/radio_hidl_hal_utils_v1_5.h
+++ b/radio/1.5/vts/functional/radio_hidl_hal_utils_v1_5.h
@@ -544,7 +544,7 @@
 
     Return<void> setupDataCallResponse_1_5(
             const RadioResponseInfo& info,
-            const android::hardware::radio::V1_4::SetupDataCallResult& dcResponse);
+            const android::hardware::radio::V1_5::SetupDataCallResult& dcResponse);
 
     Return<void> setInitialAttachApnResponse_1_5(const RadioResponseInfo& info);
 
diff --git a/radio/1.5/vts/functional/radio_response.cpp b/radio/1.5/vts/functional/radio_response.cpp
index 8932a64..a0b3d5f 100644
--- a/radio/1.5/vts/functional/radio_response.cpp
+++ b/radio/1.5/vts/functional/radio_response.cpp
@@ -931,7 +931,7 @@
 
 Return<void> RadioResponse_v1_5::setupDataCallResponse_1_5(
         const RadioResponseInfo& info,
-        const android::hardware::radio::V1_4::SetupDataCallResult& /* dcResponse */) {
+        const android::hardware::radio::V1_5::SetupDataCallResult& /* dcResponse */) {
     rspInfo = info;
     parent_v1_5.notify(info.serial);
     return Void();
diff --git a/rebootescrow/aidl/default/Android.bp b/rebootescrow/aidl/default/Android.bp
index eb228ad..c8cbf48 100644
--- a/rebootescrow/aidl/default/Android.bp
+++ b/rebootescrow/aidl/default/Android.bp
@@ -15,6 +15,47 @@
 //
 
 cc_library_static {
+    name: "librebootescrowdefaultimpl",
+    vendor: true,
+    shared_libs: [
+        "libbase",
+        "libbinder_ndk",
+        "vintf-rebootescrow-ndk_platform",
+    ],
+    export_include_dirs: ["include"],
+    srcs: [
+        "RebootEscrow.cpp",
+    ],
+    visibility: [
+        ":__subpackages__",
+    ],
+}
+
+cc_binary {
+    name: "android.hardware.rebootescrow-service.default",
+    init_rc: ["rebootescrow-default.rc"],
+    relative_install_path: "hw",
+    vintf_fragments: ["rebootescrow-default.xml"],
+    vendor: true,
+    srcs: [
+        "service.cpp",
+    ],
+    cflags: [
+        "-Wall",
+        "-Werror",
+    ],
+    shared_libs: [
+        "libbase",
+        "libbinder_ndk",
+        "vintf-rebootescrow-ndk_platform",
+    ],
+    static_libs: [
+        "libhadamardutils",
+        "librebootescrowdefaultimpl",
+    ],
+}
+
+cc_library_static {
     name: "libhadamardutils",
     vendor_available: true,
     host_supported: true,
diff --git a/rebootescrow/aidl/default/RebootEscrow.cpp b/rebootescrow/aidl/default/RebootEscrow.cpp
new file mode 100644
index 0000000..94d0901
--- /dev/null
+++ b/rebootescrow/aidl/default/RebootEscrow.cpp
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2019 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 <android-base/file.h>
+#include <android-base/logging.h>
+#include <android-base/unique_fd.h>
+
+#include "HadamardUtils.h"
+#include "rebootescrow-impl/RebootEscrow.h"
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace rebootescrow {
+
+using ::android::base::unique_fd;
+
+ndk::ScopedAStatus RebootEscrow::storeKey(const std::vector<int8_t>& kek) {
+    int rawFd = TEMP_FAILURE_RETRY(::open(REBOOT_ESCROW_DEVICE, O_WRONLY | O_NOFOLLOW | O_CLOEXEC));
+    unique_fd fd(rawFd);
+    if (fd.get() < 0) {
+        LOG(WARNING) << "Could not open reboot escrow device";
+        return ndk::ScopedAStatus(AStatus_fromExceptionCode(EX_UNSUPPORTED_OPERATION));
+    }
+
+    std::vector<uint8_t> ukek(kek.begin(), kek.end());
+    auto encoded = hadamard::EncodeKey(ukek);
+
+    if (!::android::base::WriteFully(fd, encoded.data(), encoded.size())) {
+        LOG(WARNING) << "Could not write data fully to character device";
+        return ndk::ScopedAStatus(AStatus_fromExceptionCode(EX_UNSUPPORTED_OPERATION));
+    }
+
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RebootEscrow::retrieveKey(std::vector<int8_t>* _aidl_return) {
+    int rawFd = TEMP_FAILURE_RETRY(::open(REBOOT_ESCROW_DEVICE, O_RDONLY | O_NOFOLLOW | O_CLOEXEC));
+    unique_fd fd(rawFd);
+    if (fd.get() < 0) {
+        LOG(WARNING) << "Could not open reboot escrow device";
+        return ndk::ScopedAStatus(AStatus_fromExceptionCode(EX_UNSUPPORTED_OPERATION));
+    }
+
+    std::string encodedString;
+    if (!::android::base::ReadFdToString(fd, &encodedString)) {
+        LOG(WARNING) << "Could not read device to string";
+        return ndk::ScopedAStatus(AStatus_fromExceptionCode(EX_UNSUPPORTED_OPERATION));
+    }
+
+    std::vector<uint8_t> encodedBytes(encodedString.begin(), encodedString.end());
+    auto keyBytes = hadamard::DecodeKey(encodedBytes);
+
+    std::vector<int8_t> signedKeyBytes(keyBytes.begin(), keyBytes.end());
+    *_aidl_return = signedKeyBytes;
+    return ndk::ScopedAStatus::ok();
+}
+
+}  // namespace rebootescrow
+}  // namespace hardware
+}  // namespace android
+}  // namespace aidl
diff --git a/rebootescrow/aidl/default/include/rebootescrow-impl/RebootEscrow.h b/rebootescrow/aidl/default/include/rebootescrow-impl/RebootEscrow.h
new file mode 100644
index 0000000..1ed7397
--- /dev/null
+++ b/rebootescrow/aidl/default/include/rebootescrow-impl/RebootEscrow.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2019 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 <aidl/android/hardware/rebootescrow/BnRebootEscrow.h>
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace rebootescrow {
+
+static const char* REBOOT_ESCROW_DEVICE = "/dev/access-kregistry";
+
+class RebootEscrow : public BnRebootEscrow {
+    ndk::ScopedAStatus storeKey(const std::vector<int8_t>& kek) override;
+    ndk::ScopedAStatus retrieveKey(std::vector<int8_t>* _aidl_return) override;
+};
+
+}  // namespace rebootescrow
+}  // namespace hardware
+}  // namespace android
+}  // namespace aidl
diff --git a/rebootescrow/aidl/default/rebootescrow-default.rc b/rebootescrow/aidl/default/rebootescrow-default.rc
new file mode 100644
index 0000000..e7a9cfc
--- /dev/null
+++ b/rebootescrow/aidl/default/rebootescrow-default.rc
@@ -0,0 +1,9 @@
+service vendor.rebootescrow-default /vendor/bin/hw/android.hardware.rebootescrow-service.default
+    interface aidl android.hardware.rebootescrow.IRebootEscrow/default
+    class hal
+    user system
+    group system
+
+on boot
+    chmod 770 /dev/access-kregistry
+    chown system system /dev/access-kregistry
diff --git a/rebootescrow/aidl/default/rebootescrow-default.xml b/rebootescrow/aidl/default/rebootescrow-default.xml
new file mode 100644
index 0000000..0499fcc
--- /dev/null
+++ b/rebootescrow/aidl/default/rebootescrow-default.xml
@@ -0,0 +1,6 @@
+<manifest version="1.0" type="device">
+    <hal format="aidl">
+        <name>android.hardware.rebootescrow</name>
+        <fqname>IRebootEscrow/default</fqname>
+    </hal>
+</manifest>
diff --git a/rebootescrow/aidl/default/service.cpp b/rebootescrow/aidl/default/service.cpp
new file mode 100644
index 0000000..bd2378e
--- /dev/null
+++ b/rebootescrow/aidl/default/service.cpp
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.1 (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.1
+ *
+ * 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 "rebootescrow-impl/RebootEscrow.h"
+
+#include <android-base/logging.h>
+#include <android/binder_manager.h>
+#include <android/binder_process.h>
+
+using aidl::android::hardware::rebootescrow::RebootEscrow;
+
+int main() {
+    ABinderProcess_setThreadPoolMaxThreadCount(0);
+
+    auto re = ndk::SharedRefBase::make<RebootEscrow>();
+    const std::string instance = std::string() + RebootEscrow::descriptor + "/default";
+    binder_status_t status = AServiceManager_addService(re->asBinder().get(), instance.c_str());
+    CHECK(status == STATUS_OK);
+
+    ABinderProcess_joinThreadPool();
+    return EXIT_FAILURE;
+}
diff --git a/wifi/supplicant/1.2/vts/functional/Android.bp b/wifi/supplicant/1.2/vts/functional/Android.bp
index b7949d1..7e9d4f6 100644
--- a/wifi/supplicant/1.2/vts/functional/Android.bp
+++ b/wifi/supplicant/1.2/vts/functional/Android.bp
@@ -51,6 +51,7 @@
         "android.hardware.wifi.supplicant@1.0",
         "android.hardware.wifi.supplicant@1.1",
         "android.hardware.wifi.supplicant@1.2",
+        "android.hardware.wifi.supplicant@1.3",
         "android.hardware.wifi@1.0",
         "android.hardware.wifi@1.1",
         "libgmock",
diff --git a/wifi/supplicant/1.2/vts/functional/supplicant_sta_iface_hidl_test.cpp b/wifi/supplicant/1.2/vts/functional/supplicant_sta_iface_hidl_test.cpp
index 2ff7751..6272d30 100644
--- a/wifi/supplicant/1.2/vts/functional/supplicant_sta_iface_hidl_test.cpp
+++ b/wifi/supplicant/1.2/vts/functional/supplicant_sta_iface_hidl_test.cpp
@@ -22,6 +22,8 @@
 #include <android/hardware/wifi/supplicant/1.2/ISupplicantStaIfaceCallback.h>
 #include <android/hardware/wifi/supplicant/1.2/ISupplicantStaNetwork.h>
 #include <android/hardware/wifi/supplicant/1.2/types.h>
+#include <android/hardware/wifi/supplicant/1.3/ISupplicantStaIface.h>
+#include <android/hardware/wifi/supplicant/1.3/types.h>
 #include <hidl/HidlSupport.h>
 #include <hidl/Status.h>
 
@@ -318,6 +320,19 @@
         return;
     }
 
+    /* Check if the underlying HAL version is 1.3 or higher and skip the test
+     * in this case. The 1.3 HAL uses different callbacks which are not
+     * supported by 1.2. This will cause this test to fail because the callbacks
+     * it is waiting for will never be called. Note that this test is also
+     * implemented in the 1.3 VTS test.
+     */
+    sp<::android::hardware::wifi::supplicant::V1_3::ISupplicantStaIface> v1_3 =
+        ::android::hardware::wifi::supplicant::V1_3::ISupplicantStaIface::
+            castFrom(sta_iface_);
+    if (v1_3 != nullptr) {
+        GTEST_SKIP() << "Test not supported with this HAL version";
+    }
+
     hidl_string uri =
         "DPP:C:81/1;M:48d6d5bd1de1;I:G1197843;K:MDkwEwYHKoZIzj0CAQYIKoZIzj"
         "0DAQcDIgAD0edY4X3N//HhMFYsZfMbQJTiNFtNIWF/cIwMB/gzqOM=;;";
@@ -369,6 +384,21 @@
         return;
     }
 
+    /* Check if the underlying HAL version is 1.3 or higher and skip the test
+     * in this case. The 1.3 HAL uses different callbacks which are not
+     * supported by 1.2. This will cause this test to fail because the callbacks
+     * it is waiting for will never be called. Note that this test is also
+     * implemented in the 1.3 VTS test.
+     */
+    sp<::android::hardware::wifi::supplicant::V1_3::ISupplicantStaIface> v1_3 =
+        ::android::hardware::wifi::supplicant::V1_3::ISupplicantStaIface::
+            castFrom(sta_iface_);
+
+    if (v1_3 != nullptr) {
+        GTEST_SKIP() << "Test not supported with this HAL version";
+        return;
+    }
+
     hidl_string uri =
         "DPP:C:81/1;M:48d6d5bd1de1;I:G1197843;K:MDkwEwYHKoZIzj0CAQYIKoZIzj"
         "0DAQcDIgAD0edY4X3N//HhMFYsZfMbQJTiNFtNIWF/cIwMB/gzqOM=;;";
diff --git a/wifi/supplicant/1.3/ISupplicantStaIface.hal b/wifi/supplicant/1.3/ISupplicantStaIface.hal
index fa88b91..58ef165 100644
--- a/wifi/supplicant/1.3/ISupplicantStaIface.hal
+++ b/wifi/supplicant/1.3/ISupplicantStaIface.hal
@@ -18,7 +18,7 @@
 
 import @1.0::SupplicantStatus;
 import @1.2::ISupplicantStaIface;
-import @1.3::ISupplicantStaNetwork;
+import ISupplicantStaNetwork;
 import ISupplicantStaIfaceCallback;
 
 /**
diff --git a/wifi/supplicant/1.3/ISupplicantStaIfaceCallback.hal b/wifi/supplicant/1.3/ISupplicantStaIfaceCallback.hal
index 107e0fc..72ba160 100644
--- a/wifi/supplicant/1.3/ISupplicantStaIfaceCallback.hal
+++ b/wifi/supplicant/1.3/ISupplicantStaIfaceCallback.hal
@@ -28,6 +28,121 @@
  */
 interface ISupplicantStaIfaceCallback extends @1.2::ISupplicantStaIfaceCallback {
     /**
+     * IEEE Std 802.11-2016 - Table 9-357.
+     * BTM status code filled in BSS transition management response frame.
+     */
+    enum BssTmStatusCode : uint8_t {
+        ACCEPT = 0,
+        REJECT_UNSPECIFIED = 1,
+        REJECT_INSUFFICIENT_BEACON = 2,
+        REJECT_INSUFFICIENT_CAPABITY = 3,
+        REJECT_BSS_TERMINATION_UNDESIRED = 4,
+        REJECT_BSS_TERMINATION_DELAY_REQUEST = 5,
+        REJECT_STA_CANDIDATE_LIST_PROVIDED = 6,
+        REJECT_NO_SUITABLE_CANDIDATES = 7,
+        REJECT_LEAVING_ESS = 8,
+    };
+
+    /**
+     * Bitmask of various information retrieved from BSS transition management request frame.
+     */
+    enum BssTmDataFlagsMask : uint32_t {
+        /**
+         * Preferred candidate list included.
+         */
+        WNM_MODE_PREFERRED_CANDIDATE_LIST_INCLUDED = 1 << 0,
+        /**
+         * Abridged.
+         */
+        WNM_MODE_ABRIDGED = 1 << 1,
+        /**
+         * Disassociation Imminent.
+         */
+        WNM_MODE_DISASSOCIATION_IMMINENT = 1 << 2,
+        /**
+         * BSS termination included.
+         */
+        WNM_MODE_BSS_TERMINATION_INCLUDED = 1 << 3,
+        /**
+         * ESS Disassociation Imminent.
+         */
+        WNM_MODE_ESS_DISASSOCIATION_IMMINENT = 1 << 4,
+        /**
+         * MBO transition reason code included.
+         */
+        MBO_TRANSITION_REASON_CODE_INCLUDED = 1 << 5,
+        /**
+         * MBO retry delay time included.
+         */
+        MBO_ASSOC_RETRY_DELAY_INCLUDED = 1 << 6,
+        /**
+         * MBO cellular data connection preference value included.
+         */
+        MBO_CELLULAR_DATA_CONNECTION_PREFERENCE_INCLUDED = 1 << 7,
+    };
+
+    /**
+     *  MBO spec v1.2, 4.2.6 Table 18: MBO transition reason code attribute
+     *  values.
+     */
+    enum MboTransitionReasonCode : uint8_t {
+        UNSPECIFIED = 0,
+        EXCESSIVE_FRAME_LOSS = 1,
+        EXCESSIVE_TRAFFIC_DELAY = 2,
+        INSUFFICIENT_BANDWIDTH = 3,
+        LOAD_BALANCING = 4,
+        LOW_RSSI = 5,
+        RX_EXCESSIVE_RETRIES = 6,
+        HIGH_INTERFERENCE = 7,
+        GRAY_ZONE = 8,
+        TRANSITION_TO_PREMIUM_AP = 9,
+    };
+
+    /**
+     *  MBO spec v1.2, 4.2.5 Table 16: MBO Cellular Data connection preference
+     *  attribute values. AP use this to indicate STA, its preference for the
+     *  STA to move from BSS to cellular network.
+     */
+    enum MboCellularDataConnectionPrefValue : uint8_t {
+        EXCLUDED = 0,
+        NOT_PREFERRED = 1,
+        /*
+         * 2-254 Reserved.
+         */
+        PREFERRED = 255,
+    };
+
+    /**
+     * Data retrieved from received BSS transition management request frame.
+     */
+    struct BssTmData {
+        /*
+         * Status code filled in BSS transition management response frame
+         */
+        BssTmStatusCode status;
+
+        /*
+         * Bitmask of BssTmDataFlagsMask
+         */
+        bitfield<BssTmDataFlagsMask> flags;
+
+        /*
+         * Duration for which STA shouldn't try to re-associate.
+         */
+        uint32_t assocRetryDelayMs;
+
+        /*
+         * Reason for BSS transition request.
+         */
+        MboTransitionReasonCode mboTransitionReason;
+
+        /*
+         * Cellular Data Connection preference value.
+         */
+        MboCellularDataConnectionPrefValue mboCellPreference;
+    };
+
+    /**
      * Indicates PMK cache added event.
      *
      * @param expirationTimeInSec expiration time in seconds
@@ -35,4 +150,39 @@
      *              opaque for the framework and depends on the native implementation.
      */
     oneway onPmkCacheAdded(int64_t expirationTimeInSec, vec<uint8_t> serializedEntry);
+
+    /**
+     * Indicates a DPP success event.
+     */
+    oneway onDppSuccess(DppSuccessCode code);
+
+    /**
+     * Indicates a DPP progress event.
+     */
+    oneway onDppProgress_1_3(DppProgressCode code);
+
+    /**
+     * Indicates a DPP failure event.
+     *
+     * ssid: A string indicating the SSID for the AP that the Enrollee attempted to connect.
+     * channelList: A string containing a list of operating channels and operating classes
+     *     indicating the channels that the Enrollee scanned in attempting to discover the AP.
+     *     The list conforms to the following ABNF syntax:
+     *         channel-list2 = class-and-channels *(“,” class-and-channels)
+     *         class-and-channels = class “/” channel *(“,” channel)
+     *         class = 1*3DIGIT
+     *         channel = 1*3DIGIT
+     * bandList: A list of band parameters that are supported by the Enrollee expressed as the
+     *     Operating Class.
+     */
+    oneway onDppFailure_1_3(DppFailureCode code, string ssid, string channelList,
+        vec<uint16_t> bandList);
+
+    /**
+     * Indicates BTM request frame handling status.
+     *
+     * @param BssTmData Data retrieved from received BSS transition management
+     * request frame.
+     */
+    oneway onBssTmHandlingDone(BssTmData tmData);
 };
diff --git a/wifi/supplicant/1.3/ISupplicantStaNetwork.hal b/wifi/supplicant/1.3/ISupplicantStaNetwork.hal
index 1bcf7bc..c18bffc 100644
--- a/wifi/supplicant/1.3/ISupplicantStaNetwork.hal
+++ b/wifi/supplicant/1.3/ISupplicantStaNetwork.hal
@@ -25,29 +25,44 @@
  * configuration it controls.
  */
 interface ISupplicantStaNetwork extends @1.2::ISupplicantStaNetwork {
-    /** Possble mask of values for Proto param. */
+    /**
+     * Possble mask of values for Proto param.
+     */
     enum ProtoMask : @1.0::ISupplicantStaNetwork.ProtoMask {
         WAPI = 1 << 2,
     };
 
-    /** Possble mask of values for KeyMgmt param. */
+    /**
+     * Possble mask of values for KeyMgmt param.
+     */
     enum KeyMgmtMask : @1.2::ISupplicantStaNetwork.KeyMgmtMask {
-        /* WAPI Psk */
+        /*
+         * WAPI Psk
+         */
         WAPI_PSK = 1 << 12,
-
-        /** WAPI Cert */
+        /**
+         * WAPI Cert
+         */
         WAPI_CERT = 1 << 13,
     };
 
-    /** Possble mask of values for PairwiseCipher param. */
+    /**
+     * Possble mask of values for PairwiseCipher param.
+     */
     enum PairwiseCipherMask : @1.2::ISupplicantStaNetwork.PairwiseCipherMask {
-        /** SMS4 Pairwise Cipher */
+        /**
+         * SMS4 Pairwise Cipher
+         */
         SMS4 = 1 << 7,
     };
 
-    /** Possble mask of values for GroupCipher param. */
+    /**
+     * Possble mask of values for GroupCipher param.
+     */
     enum GroupCipherMask : @1.2::ISupplicantStaNetwork.GroupCipherMask {
-        /** SMS4 Group Cipher */
+        /**
+         * SMS4 Group Cipher
+         */
         SMS4 = 1 << 7,
     };
 
@@ -99,8 +114,7 @@
      *         |SupplicantStatusCode.FAILURE_UNKNOWN|
      * @return keyMgmtMask Combination of |KeyMgmtMask| values.
      */
-    getKeyMgmt_1_3()
-        generates (SupplicantStatus status, bitfield<KeyMgmtMask> keyMgmtMask);
+    getKeyMgmt_1_3() generates (SupplicantStatus status, bitfield<KeyMgmtMask> keyMgmtMask);
 
     /**
      * Set proto mask for the network.
@@ -154,8 +168,7 @@
      * @return pairwiseCipherMask Combination of |PairwiseCipherMask| values.
      */
     getPairwiseCipher_1_3()
-        generates (SupplicantStatus status,
-            bitfield<PairwiseCipherMask> pairwiseCipherMask);
+        generates (SupplicantStatus status, bitfield<PairwiseCipherMask> pairwiseCipherMask);
 
     /**
      * Set pairwise cipher mask for the network.
@@ -183,8 +196,7 @@
      * @return groupCipherMask Combination of |GroupCipherMask| values.
      */
     getGroupCipher_1_3()
-        generates (SupplicantStatus status,
-            bitfield<GroupCipherMask> groupCipherMask);
+        generates (SupplicantStatus status, bitfield<GroupCipherMask> groupCipherMask);
 
     /**
      * Set WAPI certificate suite for this network.
diff --git a/wifi/supplicant/1.3/types.hal b/wifi/supplicant/1.3/types.hal
index 4e01ab1..05f4760 100644
--- a/wifi/supplicant/1.3/types.hal
+++ b/wifi/supplicant/1.3/types.hal
@@ -16,6 +16,9 @@
 
 package android.hardware.wifi.supplicant@1.3;
 
+import @1.2::DppProgressCode;
+import @1.2::DppFailureCode;
+
 /**
  * OcspType: The type of OCSP request.
  */
@@ -72,3 +75,31 @@
      */
     OCE = 1 << 1,
 };
+
+/**
+ * DppProgressCode: Progress codes for DPP (Easy Connect)
+ */
+enum DppProgressCode : @1.2::DppProgressCode {
+    CONFIGURATION_SENT_WAITING_RESPONSE,
+    CONFIGURATION_ACCEPTED,
+};
+
+/**
+ * DppSuccessCode: Success codes for DPP (Easy Connect) Configurator
+ */
+enum DppSuccessCode : uint32_t {
+    /*
+     * Replaces @1.2::onDppSuccessConfigSent()
+     */
+    CONFIGURATION_SENT,
+    CONFIGURATION_APPLIED,
+};
+
+/**
+ * DppFailureCode: Error codes for DPP (Easy Connect)
+ */
+enum DppFailureCode : @1.2::DppFailureCode {
+    CONFIGURATION_REJECTED,
+    CANNOT_FIND_NETWORK,
+    ENROLLEE_AUTHENTICATION,
+};
diff --git a/wifi/supplicant/1.3/vts/functional/supplicant_sta_iface_hidl_test.cpp b/wifi/supplicant/1.3/vts/functional/supplicant_sta_iface_hidl_test.cpp
index ca3265e..8c9f9cd 100644
--- a/wifi/supplicant/1.3/vts/functional/supplicant_sta_iface_hidl_test.cpp
+++ b/wifi/supplicant/1.3/vts/functional/supplicant_sta_iface_hidl_test.cpp
@@ -36,13 +36,18 @@
 using ::android::hardware::wifi::supplicant::V1_0::SupplicantStatusCode;
 using ::android::hardware::wifi::supplicant::V1_2::DppAkm;
 using ::android::hardware::wifi::supplicant::V1_2::DppFailureCode;
+using ::android::hardware::wifi::supplicant::V1_2::DppNetRole;
 using ::android::hardware::wifi::supplicant::V1_2::DppProgressCode;
 using ::android::hardware::wifi::supplicant::V1_3::ConnectionCapabilities;
+using ::android::hardware::wifi::supplicant::V1_3::DppSuccessCode;
 using ::android::hardware::wifi::supplicant::V1_3::ISupplicantStaIface;
 using ::android::hardware::wifi::supplicant::V1_3::ISupplicantStaIfaceCallback;
 using ::android::hardware::wifi::supplicant::V1_3::ISupplicantStaNetwork;
 using ::android::hardware::wifi::supplicant::V1_3::WpaDriverCapabilitiesMask;
 
+#define TIMEOUT_PERIOD 60
+class IfaceDppCallback;
+
 class SupplicantStaIfaceHidlTest : public ::testing::VtsHalHidlTargetTestBase {
    public:
     virtual void SetUp() override {
@@ -57,9 +62,67 @@
     int64_t pmkCacheExpirationTimeInSec;
     std::vector<uint8_t> serializedPmkCacheEntry;
 
+    // Data retrieved from BSS transition management frame.
+    ISupplicantStaIfaceCallback::BssTmData tmData;
+
+    enum DppCallbackType {
+        ANY_CALLBACK = -2,
+        INVALID = -1,
+
+        EVENT_SUCCESS = 0,
+        EVENT_PROGRESS,
+        EVENT_FAILURE,
+    };
+
+    DppCallbackType dppCallbackType;
+    uint32_t code;
+
+    /* Used as a mechanism to inform the test about data/event callback */
+    inline void notify() {
+        std::unique_lock<std::mutex> lock(mtx_);
+        count_++;
+        cv_.notify_one();
+    }
+
+    /* Test code calls this function to wait for data/event callback */
+    inline std::cv_status wait(DppCallbackType waitForCallbackType) {
+        std::unique_lock<std::mutex> lock(mtx_);
+        EXPECT_NE(INVALID, waitForCallbackType);  // can't ASSERT in a
+                                                  // non-void-returning method
+        auto now = std::chrono::system_clock::now();
+        std::cv_status status =
+            cv_.wait_until(lock, now + std::chrono::seconds(TIMEOUT_PERIOD));
+        return status;
+    }
+
+   private:
+    // synchronization objects
+    std::mutex mtx_;
+    std::condition_variable cv_;
+    int count_;
+
    protected:
     // ISupplicantStaIface object used for all tests in this fixture.
     sp<ISupplicantStaIface> sta_iface_;
+    bool isDppSupported() {
+        uint32_t keyMgmtMask = 0;
+
+        // We need to first get the key management capabilities from the device.
+        // If DPP is not supported, we just pass the test.
+        sta_iface_->getKeyMgmtCapabilities(
+            [&](const SupplicantStatus& status, uint32_t keyMgmtMaskInternal) {
+                EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+
+                keyMgmtMask = keyMgmtMaskInternal;
+            });
+
+        if (!(keyMgmtMask & ISupplicantStaNetwork::KeyMgmtMask::DPP)) {
+            // DPP not supported
+            return false;
+        }
+
+        return true;
+    }
 };
 
 class IfaceCallback : public ISupplicantStaIfaceCallback {
@@ -150,11 +213,29 @@
     Return<void> onDppFailure(DppFailureCode /* code */) override {
         return Void();
     }
+    Return<void> onDppSuccess(DppSuccessCode /* code */) override {
+        return Void();
+    }
+    Return<void> onDppProgress_1_3(
+        ::android::hardware::wifi::supplicant::V1_3::DppProgressCode /* code */)
+        override {
+        return Void();
+    }
+    Return<void> onDppFailure_1_3(
+        ::android::hardware::wifi::supplicant::V1_3::DppFailureCode /* code */,
+        const hidl_string& /* ssid */, const hidl_string& /* channelList */,
+        const hidl_vec<uint16_t>& /* bandList */) override {
+        return Void();
+    }
     Return<void> onPmkCacheAdded(
         int64_t /* expirationTimeInSec */,
         const hidl_vec<uint8_t>& /* serializedEntry */) override {
         return Void();
     }
+    Return<void> onBssTmHandlingDone(
+        const ISupplicantStaIfaceCallback::BssTmData& /* data */) override {
+        return Void();
+    }
 };
 
 class IfacePmkCacheCallback : public IfaceCallback {
@@ -172,6 +253,53 @@
         : parent_(parent) {}
 };
 
+class IfaceDppCallback : public IfaceCallback {
+    SupplicantStaIfaceHidlTest& parent_;
+    Return<void> onDppSuccess(DppSuccessCode code) override {
+        parent_.code = (uint32_t)code;
+        parent_.dppCallbackType =
+            SupplicantStaIfaceHidlTest::DppCallbackType::EVENT_SUCCESS;
+        parent_.notify();
+        return Void();
+    }
+    Return<void> onDppProgress_1_3(
+        ::android::hardware::wifi::supplicant::V1_3::DppProgressCode code)
+        override {
+        parent_.code = (uint32_t)code;
+        parent_.dppCallbackType =
+            SupplicantStaIfaceHidlTest::DppCallbackType::EVENT_PROGRESS;
+        parent_.notify();
+        return Void();
+    }
+    Return<void> onDppFailure_1_3(
+        ::android::hardware::wifi::supplicant::V1_3::DppFailureCode code,
+        const hidl_string& ssid __attribute__((unused)),
+        const hidl_string& channelList __attribute__((unused)),
+        const hidl_vec<uint16_t>& bandList __attribute__((unused))) override {
+        parent_.code = (uint32_t)code;
+        parent_.dppCallbackType =
+            SupplicantStaIfaceHidlTest::DppCallbackType::EVENT_FAILURE;
+        parent_.notify();
+        return Void();
+    }
+
+   public:
+    IfaceDppCallback(SupplicantStaIfaceHidlTest& parent) : parent_(parent){};
+};
+
+class IfaceBssTmHandlingDoneCallback : public IfaceCallback {
+    SupplicantStaIfaceHidlTest& parent_;
+    Return<void> onBssTmHandlingDone(
+        const ISupplicantStaIfaceCallback::BssTmData& data) override {
+        parent_.tmData = data;
+        return Void();
+    }
+
+   public:
+    IfaceBssTmHandlingDoneCallback(SupplicantStaIfaceHidlTest& parent)
+        : parent_(parent) {}
+};
+
 /*
  * RegisterCallback_1_3
  */
@@ -246,3 +374,110 @@
         }
     });
 }
+
+/*
+ * StartDppEnrolleeInitiator
+ */
+TEST_F(SupplicantStaIfaceHidlTest, StartDppEnrolleeInitiator) {
+    // We need to first get the key management capabilities from the device.
+    // If DPP is not supported, we just pass the test.
+    if (!isDppSupported()) {
+        // DPP not supported
+        return;
+    }
+
+    hidl_string uri =
+        "DPP:C:81/1;M:48d6d5bd1de1;I:G1197843;K:MDkwEwYHKoZIzj0CAQYIKoZIzj"
+        "0DAQcDIgAD0edY4X3N//HhMFYsZfMbQJTiNFtNIWF/cIwMB/gzqOM=;;";
+    uint32_t peer_id = 0;
+
+    // Register callbacks
+    sta_iface_->registerCallback_1_3(
+        new IfaceDppCallback(*this), [](const SupplicantStatus& status) {
+            EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+        });
+
+    // Add a peer URI
+    sta_iface_->addDppPeerUri(
+        uri, [&](const SupplicantStatus& status, uint32_t id) {
+            EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+            EXPECT_NE(0, id);
+            EXPECT_NE(-1, id);
+
+            peer_id = id;
+        });
+
+    // Start DPP as Enrollee-Initiator. Since this operation requires two
+    // devices, we start the operation and expect a timeout.
+    sta_iface_->startDppEnrolleeInitiator(
+        peer_id, 0, [&](const SupplicantStatus& status) {
+            EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+        });
+
+    // Wait for the timeout callback
+    ASSERT_EQ(std::cv_status::no_timeout,
+              wait(SupplicantStaIfaceHidlTest::DppCallbackType::EVENT_FAILURE));
+    ASSERT_EQ(SupplicantStaIfaceHidlTest::DppCallbackType::EVENT_FAILURE,
+              dppCallbackType);
+
+    // ...and then remove the peer URI.
+    sta_iface_->removeDppUri(peer_id, [&](const SupplicantStatus& status) {
+        EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+    });
+}
+
+/*
+ * StartDppConfiguratorInitiator
+ */
+TEST_F(SupplicantStaIfaceHidlTest, StartDppConfiguratorInitiator) {
+    // We need to first get the key management capabilities from the device.
+    // If DPP is not supported, we just pass the test.
+    if (!isDppSupported()) {
+        // DPP not supported
+        return;
+    }
+
+    hidl_string uri =
+        "DPP:C:81/1;M:48d6d5bd1de1;I:G1197843;K:MDkwEwYHKoZIzj0CAQYIKoZIzj"
+        "0DAQcDIgAD0edY4X3N//HhMFYsZfMbQJTiNFtNIWF/cIwMB/gzqOM=;;";
+    uint32_t peer_id = 0;
+
+    // Register callbacks
+    sta_iface_->registerCallback_1_3(
+        new IfaceDppCallback(*this), [](const SupplicantStatus& status) {
+            EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+        });
+
+    // Add a peer URI
+    sta_iface_->addDppPeerUri(
+        uri, [&](const SupplicantStatus& status, uint32_t id) {
+            EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+            EXPECT_NE(0, id);
+            EXPECT_NE(-1, id);
+
+            peer_id = id;
+        });
+
+    std::string ssid =
+        "6D795F746573745F73736964";  // 'my_test_ssid' encoded in hex
+    std::string password = "746F70736563726574";  // 'topsecret' encoded in hex
+
+    // Start DPP as Configurator-Initiator. Since this operation requires two
+    // devices, we start the operation and expect a timeout.
+    sta_iface_->startDppConfiguratorInitiator(
+        peer_id, 0, ssid, password, NULL, DppNetRole::STA, DppAkm::PSK,
+        [&](const SupplicantStatus& status) {
+            EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+        });
+
+    // Wait for the timeout callback
+    ASSERT_EQ(std::cv_status::no_timeout,
+              wait(SupplicantStaIfaceHidlTest::DppCallbackType::EVENT_FAILURE));
+    ASSERT_EQ(SupplicantStaIfaceHidlTest::DppCallbackType::EVENT_FAILURE,
+              dppCallbackType);
+
+    // ...and then remove the peer URI.
+    sta_iface_->removeDppUri(peer_id, [&](const SupplicantStatus& status) {
+        EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+    });
+}