Merge changes I1d41c6ed,I1e04e734,I4c2a968a

* changes:
  Refactor SensorEventsChecker
  Create SensorsHidlEnvironmentBase
  Extract SensorsHidlEnvironment
diff --git a/audio/4.1/config/audio_policy_configuration.xsd b/audio/4.1/config/audio_policy_configuration.xsd
new file mode 100644
index 0000000..311b9c1
--- /dev/null
+++ b/audio/4.1/config/audio_policy_configuration.xsd
@@ -0,0 +1,595 @@
+<?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.
+-->
+<!-- TODO: define a targetNamespace. Note that it will break retrocompatibility -->
+<xs:schema version="2.0"
+           elementFormDefault="qualified"
+           attributeFormDefault="unqualified"
+           xmlns:xs="http://www.w3.org/2001/XMLSchema">
+    <!-- List the config versions supported by audio policy. -->
+    <xs:simpleType name="version">
+        <xs:restriction base="xs:decimal">
+            <xs:enumeration value="1.0"/>
+        </xs:restriction>
+    </xs:simpleType>
+    <xs:simpleType name="halVersion">
+        <xs:annotation>
+            <xs:documentation xml:lang="en">
+                Version of the interface the hal implements.
+            </xs:documentation>
+        </xs:annotation>
+        <xs:restriction base="xs:decimal">
+            <!-- List of HAL versions supported by the framework. -->
+            <xs:enumeration value="2.0"/>
+            <xs:enumeration value="3.0"/>
+        </xs:restriction>
+    </xs:simpleType>
+    <xs:element name="audioPolicyConfiguration">
+        <xs:complexType>
+            <xs:sequence>
+                <xs:element name="globalConfiguration" type="globalConfiguration"/>
+                <xs:element name="modules" type="modules" maxOccurs="unbounded"/>
+                <xs:element name="volumes" type="volumes" maxOccurs="unbounded"/>
+                <xs:element name="surroundSound" type="surroundSound" />
+            </xs:sequence>
+            <xs:attribute name="version" type="version"/>
+        </xs:complexType>
+        <xs:key name="moduleNameKey">
+            <xs:selector xpath="modules/module"/>
+            <xs:field xpath="@name"/>
+        </xs:key>
+        <xs:unique name="volumeTargetUniqueness">
+            <xs:selector xpath="volumes/volume"/>
+            <xs:field xpath="@stream"/>
+            <xs:field xpath="@deviceCategory"/>
+        </xs:unique>
+        <xs:key name="volumeCurveNameKey">
+            <xs:selector xpath="volumes/reference"/>
+            <xs:field xpath="@name"/>
+        </xs:key>
+        <xs:keyref name="volumeCurveRef" refer="volumeCurveNameKey">
+            <xs:selector xpath="volumes/volume"/>
+            <xs:field xpath="@ref"/>
+        </xs:keyref>
+    </xs:element>
+    <xs:complexType name="globalConfiguration">
+        <xs:attribute name="speaker_drc_enabled" type="xs:boolean" use="required"/>
+    </xs:complexType>
+    <xs:complexType name="modules">
+        <xs:annotation>
+            <xs:documentation xml:lang="en">
+                There should be one section per audio HW module present on the platform.
+                Each <module/> contains two mandatory tags: “halVersion” and “name”.
+                The module "name" is the same as in previous .conf file.
+                Each module must contain the following sections:
+                 - <devicePorts/>: a list of device descriptors for all
+                   input and output devices accessible via this module.
+                   This contains both permanently attached devices and removable devices.
+                 - <mixPorts/>: listing all output and input streams exposed by the audio HAL
+                 - <routes/>: list of possible connections between input
+                   and output devices or between stream and devices.
+                   A <route/> is defined by a set of 3 attributes:
+                        -"type": mux|mix means all sources are mutual exclusive (mux) or can be mixed (mix)
+                        -"sink": the sink involved in this route
+                        -"sources": all the sources than can be connected to the sink via this route
+                 - <attachedDevices/>: permanently attached devices.
+                   The attachedDevices section is a list of devices names.
+                   Their names correspond to device names defined in "devicePorts" section.
+                 - <defaultOutputDevice/> is the device to be used when no policy rule applies
+            </xs:documentation>
+        </xs:annotation>
+        <xs:sequence>
+            <xs:element name="module" maxOccurs="unbounded">
+                <xs:complexType>
+                    <xs:sequence>
+                        <xs:element name="attachedDevices" type="attachedDevices" minOccurs="0">
+                            <xs:unique name="attachedDevicesUniqueness">
+                                <xs:selector xpath="item"/>
+                                <xs:field xpath="."/>
+                            </xs:unique>
+                        </xs:element>
+                        <xs:element name="defaultOutputDevice" type="xs:token" minOccurs="0"/>
+                        <xs:element name="mixPorts" type="mixPorts" minOccurs="0"/>
+                        <xs:element name="devicePorts" type="devicePorts" minOccurs="0"/>
+                        <xs:element name="routes" type="routes" minOccurs="0"/>
+                    </xs:sequence>
+                    <xs:attribute name="name" type="xs:string" use="required"/>
+                    <xs:attribute name="halVersion" type="halVersion" use="required"/>
+                </xs:complexType>
+                <xs:unique name="mixPortNameUniqueness">
+                    <xs:selector xpath="mixPorts/mixPort"/>
+                    <xs:field xpath="@name"/>
+                </xs:unique>
+                <xs:key name="devicePortNameKey">
+                    <xs:selector xpath="devicePorts/devicePort"/>
+                    <xs:field xpath="@tagName"/>
+                </xs:key>
+                <xs:unique name="devicePortUniqueness">
+                    <xs:selector xpath="devicePorts/devicePort"/>
+                    <xs:field xpath="@type"/>
+                    <xs:field xpath="@address"/>
+                </xs:unique>
+                <xs:keyref name="defaultOutputDeviceRef" refer="devicePortNameKey">
+                    <xs:selector xpath="defaultOutputDevice"/>
+                    <xs:field xpath="."/>
+                </xs:keyref>
+                <xs:keyref name="attachedDeviceRef" refer="devicePortNameKey">
+                    <xs:selector xpath="attachedDevices/item"/>
+                    <xs:field xpath="."/>
+                </xs:keyref>
+                <!-- The following 3 constraints try to make sure each sink port
+                     is reference in one an only one route. -->
+                <xs:key name="routeSinkKey">
+                    <!-- predicate [@type='sink'] does not work in xsd 1.0 -->
+                    <xs:selector xpath="devicePorts/devicePort|mixPorts/mixPort"/>
+                    <xs:field xpath="@tagName|@name"/>
+                </xs:key>
+                <xs:keyref name="routeSinkRef" refer="routeSinkKey">
+                    <xs:selector xpath="routes/route"/>
+                    <xs:field xpath="@sink"/>
+                </xs:keyref>
+                <xs:unique name="routeUniqueness">
+                    <xs:selector xpath="routes/route"/>
+                    <xs:field xpath="@sink"/>
+                </xs:unique>
+            </xs:element>
+        </xs:sequence>
+    </xs:complexType>
+    <xs:complexType name="attachedDevices">
+        <xs:sequence>
+            <xs:element name="item" type="xs:token" minOccurs="0" maxOccurs="unbounded"/>
+        </xs:sequence>
+    </xs:complexType>
+    <!-- TODO: separate values by space for better xsd validations. -->
+    <xs:simpleType name="audioInOutFlags">
+        <xs:annotation>
+            <xs:documentation xml:lang="en">
+                "|" separated list of audio_output_flags_t or audio_input_flags_t.
+            </xs:documentation>
+        </xs:annotation>
+        <xs:restriction base="xs:string">
+            <xs:pattern value="|[_A-Z]+(\|[_A-Z]+)*"/>
+        </xs:restriction>
+    </xs:simpleType>
+    <xs:simpleType name="role">
+        <xs:restriction base="xs:string">
+            <xs:enumeration value="sink"/>
+            <xs:enumeration value="source"/>
+        </xs:restriction>
+    </xs:simpleType>
+    <xs:complexType name="mixPorts">
+        <xs:sequence>
+            <xs:element name="mixPort" minOccurs="0" maxOccurs="unbounded">
+                <xs:complexType>
+                    <xs:sequence>
+                        <xs:element name="profile" type="profile" minOccurs="0" maxOccurs="unbounded"/>
+                        <xs:element name="gains" type="gains" minOccurs="0"/>
+                    </xs:sequence>
+                    <xs:attribute name="name" type="xs:token" use="required"/>
+                    <xs:attribute name="role" type="role" use="required"/>
+                    <xs:attribute name="flags" type="audioInOutFlags"/>
+                    <xs:attribute name="maxOpenCount" type="xs:unsignedInt"/>
+                    <xs:attribute name="maxActiveCount" type="xs:unsignedInt"/>
+                    <xs:attribute name="preferredUsage" type="audioUsageList">
+                        <xs:annotation>
+                            <xs:documentation xml:lang="en">
+                                When choosing the mixPort of an audio track, the audioPolicy
+                                first considers the mixPorts with a preferredUsage including
+                                the track AudioUsage preferred .
+                                If non support the track format, the other mixPorts are considered.
+                                Eg: a <mixPort preferredUsage="AUDIO_USAGE_MEDIA" /> will receive
+                                    the audio of all apps playing with a MEDIA usage.
+                                    It may receive audio from ALARM if there are no audio compatible
+                                    <mixPort preferredUsage="AUDIO_USAGE_ALARM" />.
+                             </xs:documentation>
+                        </xs:annotation>
+                    </xs:attribute>
+                </xs:complexType>
+                <xs:unique name="mixPortProfileUniqueness">
+                    <xs:selector xpath="profile"/>
+                    <xs:field xpath="format"/>
+                    <xs:field xpath="samplingRate"/>
+                    <xs:field xpath="channelMasks"/>
+                </xs:unique>
+                <xs:unique name="mixPortGainUniqueness">
+                    <xs:selector xpath="gains/gain"/>
+                    <xs:field xpath="@name"/>
+                </xs:unique>
+            </xs:element>
+        </xs:sequence>
+    </xs:complexType>
+    <!-- Enum values of audio_device_t in audio.h
+         TODO: generate from hidl to avoid manual sync.
+         TODO: separate source and sink in the xml for better xsd validations. -->
+    <xs:simpleType name="audioDevice">
+        <xs:restriction base="xs:string">
+            <xs:enumeration value="AUDIO_DEVICE_NONE"/>
+
+            <xs:enumeration value="AUDIO_DEVICE_OUT_EARPIECE"/>
+            <xs:enumeration value="AUDIO_DEVICE_OUT_SPEAKER"/>
+            <xs:enumeration value="AUDIO_DEVICE_OUT_WIRED_HEADSET"/>
+            <xs:enumeration value="AUDIO_DEVICE_OUT_WIRED_HEADPHONE"/>
+            <xs:enumeration value="AUDIO_DEVICE_OUT_BLUETOOTH_SCO"/>
+            <xs:enumeration value="AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET"/>
+            <xs:enumeration value="AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT"/>
+            <xs:enumeration value="AUDIO_DEVICE_OUT_BLUETOOTH_A2DP"/>
+            <xs:enumeration value="AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES"/>
+            <xs:enumeration value="AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER"/>
+            <xs:enumeration value="AUDIO_DEVICE_OUT_AUX_DIGITAL"/>
+            <xs:enumeration value="AUDIO_DEVICE_OUT_HDMI"/>
+            <xs:enumeration value="AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET"/>
+            <xs:enumeration value="AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET"/>
+            <xs:enumeration value="AUDIO_DEVICE_OUT_USB_ACCESSORY"/>
+            <xs:enumeration value="AUDIO_DEVICE_OUT_USB_DEVICE"/>
+            <xs:enumeration value="AUDIO_DEVICE_OUT_REMOTE_SUBMIX"/>
+            <xs:enumeration value="AUDIO_DEVICE_OUT_TELEPHONY_TX"/>
+            <xs:enumeration value="AUDIO_DEVICE_OUT_LINE"/>
+            <xs:enumeration value="AUDIO_DEVICE_OUT_HDMI_ARC"/>
+            <xs:enumeration value="AUDIO_DEVICE_OUT_SPDIF"/>
+            <xs:enumeration value="AUDIO_DEVICE_OUT_FM"/>
+            <xs:enumeration value="AUDIO_DEVICE_OUT_AUX_LINE"/>
+            <xs:enumeration value="AUDIO_DEVICE_OUT_SPEAKER_SAFE"/>
+            <xs:enumeration value="AUDIO_DEVICE_OUT_IP"/>
+            <xs:enumeration value="AUDIO_DEVICE_OUT_BUS"/>
+            <xs:enumeration value="AUDIO_DEVICE_OUT_PROXY"/>
+            <xs:enumeration value="AUDIO_DEVICE_OUT_USB_HEADSET"/>
+            <xs:enumeration value="AUDIO_DEVICE_OUT_HEARING_AID"/>
+            <xs:enumeration value="AUDIO_DEVICE_OUT_ECHO_CANCELLER"/>
+            <xs:enumeration value="AUDIO_DEVICE_OUT_DEFAULT"/>
+            <xs:enumeration value="AUDIO_DEVICE_OUT_STUB"/>
+
+            <!-- Due to the xml format, IN types can not be a separated from OUT types -->
+            <xs:enumeration value="AUDIO_DEVICE_IN_COMMUNICATION"/>
+            <xs:enumeration value="AUDIO_DEVICE_IN_AMBIENT"/>
+            <xs:enumeration value="AUDIO_DEVICE_IN_BUILTIN_MIC"/>
+            <xs:enumeration value="AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET"/>
+            <xs:enumeration value="AUDIO_DEVICE_IN_WIRED_HEADSET"/>
+            <xs:enumeration value="AUDIO_DEVICE_IN_AUX_DIGITAL"/>
+            <xs:enumeration value="AUDIO_DEVICE_IN_HDMI"/>
+            <xs:enumeration value="AUDIO_DEVICE_IN_VOICE_CALL"/>
+            <xs:enumeration value="AUDIO_DEVICE_IN_TELEPHONY_RX"/>
+            <xs:enumeration value="AUDIO_DEVICE_IN_BACK_MIC"/>
+            <xs:enumeration value="AUDIO_DEVICE_IN_REMOTE_SUBMIX"/>
+            <xs:enumeration value="AUDIO_DEVICE_IN_ANLG_DOCK_HEADSET"/>
+            <xs:enumeration value="AUDIO_DEVICE_IN_DGTL_DOCK_HEADSET"/>
+            <xs:enumeration value="AUDIO_DEVICE_IN_USB_ACCESSORY"/>
+            <xs:enumeration value="AUDIO_DEVICE_IN_USB_DEVICE"/>
+            <xs:enumeration value="AUDIO_DEVICE_IN_FM_TUNER"/>
+            <xs:enumeration value="AUDIO_DEVICE_IN_TV_TUNER"/>
+            <xs:enumeration value="AUDIO_DEVICE_IN_LINE"/>
+            <xs:enumeration value="AUDIO_DEVICE_IN_SPDIF"/>
+            <xs:enumeration value="AUDIO_DEVICE_IN_BLUETOOTH_A2DP"/>
+            <xs:enumeration value="AUDIO_DEVICE_IN_LOOPBACK"/>
+            <xs:enumeration value="AUDIO_DEVICE_IN_IP"/>
+            <xs:enumeration value="AUDIO_DEVICE_IN_BUS"/>
+            <xs:enumeration value="AUDIO_DEVICE_IN_PROXY"/>
+            <xs:enumeration value="AUDIO_DEVICE_IN_USB_HEADSET"/>
+            <xs:enumeration value="AUDIO_DEVICE_IN_BLUETOOTH_BLE"/>
+            <xs:enumeration value="AUDIO_DEVICE_IN_DEFAULT"/>
+            <xs:enumeration value="AUDIO_DEVICE_IN_STUB"/>
+        </xs:restriction>
+    </xs:simpleType>
+    <!-- Enum values of audio_format_t in audio.h
+         TODO: generate from hidl to avoid manual sync. -->
+    <xs:simpleType name="audioFormat">
+        <xs:restriction base="xs:string">
+            <xs:enumeration value="AUDIO_FORMAT_PCM_16_BIT" />
+            <xs:enumeration value="AUDIO_FORMAT_PCM_8_BIT"/>
+            <xs:enumeration value="AUDIO_FORMAT_PCM_32_BIT"/>
+            <xs:enumeration value="AUDIO_FORMAT_PCM_8_24_BIT"/>
+            <xs:enumeration value="AUDIO_FORMAT_PCM_FLOAT"/>
+            <xs:enumeration value="AUDIO_FORMAT_PCM_24_BIT_PACKED"/>
+            <xs:enumeration value="AUDIO_FORMAT_MP3"/>
+            <xs:enumeration value="AUDIO_FORMAT_AMR_NB"/>
+            <xs:enumeration value="AUDIO_FORMAT_AMR_WB"/>
+            <xs:enumeration value="AUDIO_FORMAT_AAC"/>
+            <xs:enumeration value="AUDIO_FORMAT_AAC_MAIN"/>
+            <xs:enumeration value="AUDIO_FORMAT_AAC_LC"/>
+            <xs:enumeration value="AUDIO_FORMAT_AAC_SSR"/>
+            <xs:enumeration value="AUDIO_FORMAT_AAC_LTP"/>
+            <xs:enumeration value="AUDIO_FORMAT_AAC_HE_V1"/>
+            <xs:enumeration value="AUDIO_FORMAT_AAC_SCALABLE"/>
+            <xs:enumeration value="AUDIO_FORMAT_AAC_ERLC"/>
+            <xs:enumeration value="AUDIO_FORMAT_AAC_LD"/>
+            <xs:enumeration value="AUDIO_FORMAT_AAC_HE_V2"/>
+            <xs:enumeration value="AUDIO_FORMAT_AAC_ELD"/>
+            <xs:enumeration value="AUDIO_FORMAT_AAC_ADTS_MAIN"/>
+            <xs:enumeration value="AUDIO_FORMAT_AAC_ADTS_LC"/>
+            <xs:enumeration value="AUDIO_FORMAT_AAC_ADTS_SSR"/>
+            <xs:enumeration value="AUDIO_FORMAT_AAC_ADTS_LTP"/>
+            <xs:enumeration value="AUDIO_FORMAT_AAC_ADTS_HE_V1"/>
+            <xs:enumeration value="AUDIO_FORMAT_AAC_ADTS_SCALABLE"/>
+            <xs:enumeration value="AUDIO_FORMAT_AAC_ADTS_ERLC"/>
+            <xs:enumeration value="AUDIO_FORMAT_AAC_ADTS_LD"/>
+            <xs:enumeration value="AUDIO_FORMAT_AAC_ADTS_HE_V2"/>
+            <xs:enumeration value="AUDIO_FORMAT_AAC_ADTS_ELD"/>
+            <xs:enumeration value="AUDIO_FORMAT_VORBIS"/>
+            <xs:enumeration value="AUDIO_FORMAT_HE_AAC_V1"/>
+            <xs:enumeration value="AUDIO_FORMAT_HE_AAC_V2"/>
+            <xs:enumeration value="AUDIO_FORMAT_OPUS"/>
+            <xs:enumeration value="AUDIO_FORMAT_AC3"/>
+            <xs:enumeration value="AUDIO_FORMAT_E_AC3"/>
+            <xs:enumeration value="AUDIO_FORMAT_DTS"/>
+            <xs:enumeration value="AUDIO_FORMAT_DTS_HD"/>
+            <xs:enumeration value="AUDIO_FORMAT_IEC61937"/>
+            <xs:enumeration value="AUDIO_FORMAT_DOLBY_TRUEHD"/>
+            <xs:enumeration value="AUDIO_FORMAT_EVRC"/>
+            <xs:enumeration value="AUDIO_FORMAT_EVRCB"/>
+            <xs:enumeration value="AUDIO_FORMAT_EVRCWB"/>
+            <xs:enumeration value="AUDIO_FORMAT_EVRCNW"/>
+            <xs:enumeration value="AUDIO_FORMAT_AAC_ADIF"/>
+            <xs:enumeration value="AUDIO_FORMAT_WMA"/>
+            <xs:enumeration value="AUDIO_FORMAT_WMA_PRO"/>
+            <xs:enumeration value="AUDIO_FORMAT_AMR_WB_PLUS"/>
+            <xs:enumeration value="AUDIO_FORMAT_MP2"/>
+            <xs:enumeration value="AUDIO_FORMAT_QCELP"/>
+            <xs:enumeration value="AUDIO_FORMAT_DSD"/>
+            <xs:enumeration value="AUDIO_FORMAT_FLAC"/>
+            <xs:enumeration value="AUDIO_FORMAT_ALAC"/>
+            <xs:enumeration value="AUDIO_FORMAT_APE"/>
+            <xs:enumeration value="AUDIO_FORMAT_AAC_ADTS"/>
+            <xs:enumeration value="AUDIO_FORMAT_SBC"/>
+            <xs:enumeration value="AUDIO_FORMAT_APTX"/>
+            <xs:enumeration value="AUDIO_FORMAT_APTX_HD"/>
+            <xs:enumeration value="AUDIO_FORMAT_AC4"/>
+            <xs:enumeration value="AUDIO_FORMAT_LDAC"/>
+            <xs:enumeration value="AUDIO_FORMAT_E_AC3_JOC"/>
+            <xs:enumeration value="AUDIO_FORMAT_MAT_1_0"/>
+            <xs:enumeration value="AUDIO_FORMAT_MAT_2_0"/>
+            <xs:enumeration value="AUDIO_FORMAT_MAT_2_1"/>
+            <xs:enumeration value="AUDIO_FORMAT_AAC_XHE"/>
+            <xs:enumeration value="AUDIO_FORMAT_AAC_ADTS_XHE"/>
+        </xs:restriction>
+    </xs:simpleType>
+    <!-- Enum values of audio::common::4_0::AudioUsage
+         TODO: generate from HIDL to avoid manual sync. -->
+    <xs:simpleType name="audioUsage">
+        <xs:restriction base="xs:string">
+            <xs:enumeration value="AUDIO_USAGE_UNKNOWN" />
+            <xs:enumeration value="AUDIO_USAGE_MEDIA" />
+            <xs:enumeration value="AUDIO_USAGE_VOICE_COMMUNICATION" />
+            <xs:enumeration value="AUDIO_USAGE_VOICE_COMMUNICATION_SIGNALLING" />
+            <xs:enumeration value="AUDIO_USAGE_ALARM" />
+            <xs:enumeration value="AUDIO_USAGE_NOTIFICATION" />
+            <xs:enumeration value="AUDIO_USAGE_NOTIFICATION_TELEPHONY_RINGTONE" />
+            <xs:enumeration value="AUDIO_USAGE_ASSISTANCE_ACCESSIBILITY" />
+            <xs:enumeration value="AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE" />
+            <xs:enumeration value="AUDIO_USAGE_ASSISTANCE_SONIFICATION" />
+            <xs:enumeration value="AUDIO_USAGE_GAME" />
+            <xs:enumeration value="AUDIO_USAGE_VIRTUAL_SOURCE" />
+            <xs:enumeration value="AUDIO_USAGE_ASSISTANT" />
+        </xs:restriction>
+    </xs:simpleType>
+    <xs:simpleType name="audioUsageList">
+        <xs:list itemType="audioUsage"/>
+    </xs:simpleType>
+    <!-- TODO: Change to a space separated list to xsd enforce correctness. -->
+    <xs:simpleType name="samplingRates">
+        <xs:restriction base="xs:string">
+            <xs:pattern value="[0-9]+(,[0-9]+)*"/>
+        </xs:restriction>
+    </xs:simpleType>
+    <!-- TODO: Change to a space separated list to xsd enforce correctness. -->
+    <xs:simpleType name="channelMask">
+        <xs:annotation>
+            <xs:documentation xml:lang="en">
+                Comma (",") separated list of channel flags
+                from audio_channel_mask_t.
+            </xs:documentation>
+        </xs:annotation>
+        <xs:restriction base="xs:string">
+            <xs:pattern value="[_A-Z][_A-Z0-9]*(,[_A-Z][_A-Z0-9]*)*"/>
+        </xs:restriction>
+    </xs:simpleType>
+    <xs:complexType name="profile">
+        <xs:attribute name="name" type="xs:token" use="optional"/>
+        <xs:attribute name="format" type="audioFormat" use="optional"/>
+        <xs:attribute name="samplingRates" type="samplingRates" use="optional"/>
+        <xs:attribute name="channelMasks" type="channelMask" use="optional"/>
+    </xs:complexType>
+    <xs:simpleType name="gainMode">
+        <xs:restriction base="xs:string">
+            <xs:enumeration value="AUDIO_GAIN_MODE_JOINT"/>
+            <xs:enumeration value="AUDIO_GAIN_MODE_CHANNELS"/>
+            <xs:enumeration value="AUDIO_GAIN_MODE_RAMP"/>
+        </xs:restriction>
+    </xs:simpleType>
+    <xs:complexType name="gains">
+        <xs:sequence>
+            <xs:element name="gain" minOccurs="0" maxOccurs="unbounded">
+                <xs:complexType>
+                    <xs:attribute name="name" type="xs:token" use="required"/>
+                    <xs:attribute name="mode" type="gainMode" use="required"/>
+                    <xs:attribute name="channel_mask" type="channelMask" use="optional"/>
+                    <xs:attribute name="minValueMB" type="xs:int" use="optional"/>
+                    <xs:attribute name="maxValueMB" type="xs:int" use="optional"/>
+                    <xs:attribute name="defaultValueMB" type="xs:int" use="optional"/>
+                    <xs:attribute name="stepValueMB" type="xs:int" use="optional"/>
+                    <xs:attribute name="minRampMs" type="xs:int" use="optional"/>
+                    <xs:attribute name="maxRampMs" type="xs:int" use="optional"/>
+                </xs:complexType>
+            </xs:element>
+        </xs:sequence>
+    </xs:complexType>
+    <xs:complexType name="devicePorts">
+        <xs:sequence>
+            <xs:element name="devicePort" minOccurs="0" maxOccurs="unbounded">
+                <xs:complexType>
+                    <xs:sequence>
+                        <xs:element name="profile" type="profile" minOccurs="0" maxOccurs="unbounded"/>
+                        <xs:element name="gains" type="gains" minOccurs="0"/>
+                    </xs:sequence>
+                    <xs:attribute name="tagName" type="xs:token" use="required"/>
+                    <xs:attribute name="type" type="audioDevice" use="required"/>
+                    <xs:attribute name="role" type="role" use="required"/>
+                    <xs:attribute name="address" type="xs:string" use="optional" default=""/>
+                    <!-- Note that XSD 1.0 can not check that a type only has one default. -->
+                    <xs:attribute name="default" type="xs:boolean" use="optional">
+                        <xs:annotation>
+                            <xs:documentation xml:lang="en">
+                                The default device will be used if multiple have the same type
+                                and no explicit route request exists for a specific device of
+                                that type.
+                            </xs:documentation>
+                        </xs:annotation>
+                    </xs:attribute>
+                </xs:complexType>
+                <xs:unique name="devicePortProfileUniqueness">
+                    <xs:selector xpath="profile"/>
+                    <xs:field xpath="format"/>
+                    <xs:field xpath="samplingRate"/>
+                    <xs:field xpath="channelMasks"/>
+                </xs:unique>
+                <xs:unique name="devicePortGainUniqueness">
+                    <xs:selector xpath="gains/gain"/>
+                    <xs:field xpath="@name"/>
+                </xs:unique>
+            </xs:element>
+        </xs:sequence>
+    </xs:complexType>
+    <xs:simpleType name="mixType">
+        <xs:restriction base="xs:string">
+            <xs:enumeration value="mix"/>
+            <xs:enumeration value="mux"/>
+        </xs:restriction>
+    </xs:simpleType>
+    <xs:complexType name="routes">
+        <xs:sequence>
+            <xs:element name="route" minOccurs="0" maxOccurs="unbounded">
+                <xs:annotation>
+                    <xs:documentation xml:lang="en">
+                        List all available sources for a given sink.
+                    </xs:documentation>
+                </xs:annotation>
+                <xs:complexType>
+                    <xs:attribute name="type" type="mixType" use="required"/>
+                    <xs:attribute name="sink" type="xs:string" use="required"/>
+                    <xs:attribute name="sources" type="xs:string" use="required"/>
+                </xs:complexType>
+            </xs:element>
+        </xs:sequence>
+    </xs:complexType>
+    <xs:complexType name="volumes">
+        <xs:sequence>
+            <xs:element name="volume" type="volume" minOccurs="0" maxOccurs="unbounded"/>
+            <xs:element name="reference" type="reference" minOccurs="0" maxOccurs="unbounded">
+            </xs:element>
+        </xs:sequence>
+    </xs:complexType>
+    <!-- TODO: Always require a ref for better xsd validations.
+               Currently a volume could have no points nor ref
+               as it can not be forbidden by xsd 1.0.-->
+    <xs:simpleType name="volumePoint">
+        <xs:annotation>
+            <xs:documentation xml:lang="en">
+                Comma separated pair of number.
+                The fist one is the framework level (between 0 and 100).
+                The second one is the volume to send to the HAL.
+                The framework will interpolate volumes not specified.
+                Their MUST be at least 2 points specified.
+            </xs:documentation>
+        </xs:annotation>
+        <xs:restriction base="xs:string">
+            <xs:pattern value="([0-9]{1,2}|100),-?[0-9]+"/>
+        </xs:restriction>
+    </xs:simpleType>
+    <!-- Enum values of audio_stream_type_t in audio-base.h
+         TODO: generate from hidl to avoid manual sync. -->
+    <xs:simpleType name="stream">
+        <xs:restriction base="xs:string">
+            <xs:enumeration value="AUDIO_STREAM_VOICE_CALL"/>
+            <xs:enumeration value="AUDIO_STREAM_SYSTEM"/>
+            <xs:enumeration value="AUDIO_STREAM_RING"/>
+            <xs:enumeration value="AUDIO_STREAM_MUSIC"/>
+            <xs:enumeration value="AUDIO_STREAM_ALARM"/>
+            <xs:enumeration value="AUDIO_STREAM_NOTIFICATION"/>
+            <xs:enumeration value="AUDIO_STREAM_BLUETOOTH_SCO"/>
+            <xs:enumeration value="AUDIO_STREAM_ENFORCED_AUDIBLE"/>
+            <xs:enumeration value="AUDIO_STREAM_DTMF"/>
+            <xs:enumeration value="AUDIO_STREAM_TTS"/>
+            <xs:enumeration value="AUDIO_STREAM_ACCESSIBILITY"/>
+            <xs:enumeration value="AUDIO_STREAM_REROUTING"/>
+            <xs:enumeration value="AUDIO_STREAM_PATCH"/>
+        </xs:restriction>
+    </xs:simpleType>
+    <!-- Enum values of device_category from Volume.h.
+         TODO: generate from hidl to avoid manual sync. -->
+    <xs:simpleType name="deviceCategory">
+        <xs:restriction base="xs:string">
+            <xs:enumeration value="DEVICE_CATEGORY_HEADSET"/>
+            <xs:enumeration value="DEVICE_CATEGORY_SPEAKER"/>
+            <xs:enumeration value="DEVICE_CATEGORY_EARPIECE"/>
+            <xs:enumeration value="DEVICE_CATEGORY_EXT_MEDIA"/>
+            <xs:enumeration value="DEVICE_CATEGORY_HEARING_AID"/>
+        </xs:restriction>
+    </xs:simpleType>
+    <xs:complexType name="volume">
+        <xs:annotation>
+            <xs:documentation xml:lang="en">
+                Volume section defines a volume curve for a given use case and device category.
+                It contains a list of points of this curve expressing the attenuation in Millibels
+                for a given volume index from 0 to 100.
+                <volume stream="AUDIO_STREAM_MUSIC" deviceCategory="DEVICE_CATEGORY_SPEAKER">
+                    <point>0,-9600</point>
+                    <point>100,0</point>
+                </volume>
+
+                It may also reference a reference/@name to avoid duplicating curves.
+                <volume stream="AUDIO_STREAM_MUSIC" deviceCategory="DEVICE_CATEGORY_SPEAKER"
+                        ref="DEFAULT_MEDIA_VOLUME_CURVE"/>
+                <reference name="DEFAULT_MEDIA_VOLUME_CURVE">
+                    <point>0,-9600</point>
+                    <point>100,0</point>
+                </reference>
+            </xs:documentation>
+        </xs:annotation>
+        <xs:sequence>
+            <xs:element name="point" type="volumePoint" minOccurs="0" maxOccurs="unbounded"/>
+        </xs:sequence>
+        <xs:attribute name="stream" type="stream"/>
+        <xs:attribute name="deviceCategory" type="deviceCategory"/>
+        <xs:attribute name="ref" type="xs:token" use="optional"/>
+    </xs:complexType>
+    <xs:complexType name="reference">
+        <xs:sequence>
+            <xs:element name="point" type="volumePoint" minOccurs="2" maxOccurs="unbounded"/>
+        </xs:sequence>
+        <xs:attribute name="name" type="xs:token" use="required"/>
+    </xs:complexType>
+    <xs:complexType name="surroundSound">
+        <xs:annotation>
+            <xs:documentation xml:lang="en">
+                Surround Sound section provides configuration related to handling of
+                multi-channel formats.
+            </xs:documentation>
+        </xs:annotation>
+        <xs:sequence>
+            <xs:element name="formats" type="surroundFormats"/>
+        </xs:sequence>
+    </xs:complexType>
+    <xs:simpleType name="surroundFormatsList">
+        <xs:list itemType="audioFormat" />
+    </xs:simpleType>
+    <xs:complexType name="surroundFormats">
+        <xs:sequence>
+            <xs:element name="format" minOccurs="0" maxOccurs="unbounded">
+                <xs:complexType>
+                    <xs:attribute name="name" type="audioFormat" use="required"/>
+                    <xs:attribute name="subformats" type="surroundFormatsList" />
+                </xs:complexType>
+            </xs:element>
+        </xs:sequence>
+    </xs:complexType>
+</xs:schema>
diff --git a/audio/common/all-versions/default/service/Android.mk b/audio/common/all-versions/default/service/Android.mk
index 43d7fe1..e6ae03e 100644
--- a/audio/common/all-versions/default/service/Android.mk
+++ b/audio/common/all-versions/default/service/Android.mk
@@ -31,12 +31,14 @@
 LOCAL_CFLAGS := -Wall -Werror
 
 LOCAL_SHARED_LIBRARIES := \
+    libcutils \
     libbinder \
     libhidlbase \
     libhidltransport \
     liblog \
     libutils \
     libhardware \
+    libhwbinder \
     android.hardware.audio@2.0 \
     android.hardware.audio@4.0 \
     android.hardware.audio.common@2.0 \
diff --git a/audio/common/all-versions/default/service/service.cpp b/audio/common/all-versions/default/service/service.cpp
index c7ce638..ff1394e 100644
--- a/audio/common/all-versions/default/service/service.cpp
+++ b/audio/common/all-versions/default/service/service.cpp
@@ -24,16 +24,26 @@
 #include <android/hardware/soundtrigger/2.0/ISoundTriggerHw.h>
 #include <android/hardware/soundtrigger/2.1/ISoundTriggerHw.h>
 #include <binder/ProcessState.h>
+#include <cutils/properties.h>
 #include <hidl/HidlTransportSupport.h>
 #include <hidl/LegacySupport.h>
+#include <hwbinder/ProcessState.h>
 
 using namespace android::hardware;
 using android::OK;
 
 int main(int /* argc */, char* /* argv */ []) {
-    android::ProcessState::initWithDriver("/dev/vndbinder");
+    ::android::ProcessState::initWithDriver("/dev/vndbinder");
     // start a threadpool for vndbinder interactions
-    android::ProcessState::self()->startThreadPool();
+    ::android::ProcessState::self()->startThreadPool();
+
+    const int32_t defaultValue = -1;
+    int32_t value =
+        property_get_int32("persist.vendor.audio.service.hwbinder.size_kbyte", defaultValue);
+    if (value != defaultValue) {
+        ALOGD("Configuring hwbinder with mmap size %d KBytes", value);
+        ProcessState::initWithMmapSize(static_cast<size_t>(value) * 1024);
+    }
     configureRpcThreadpool(16, true /*callerWillJoin*/);
 
     bool fail = registerPassthroughServiceImplementation<audio::V4_0::IDevicesFactory>() != OK &&
diff --git a/audio/core/2.0/vts/functional/AudioPrimaryHidlHalTest.cpp b/audio/core/2.0/vts/functional/AudioPrimaryHidlHalTest.cpp
index bb1d26f..a08a2d6 100644
--- a/audio/core/2.0/vts/functional/AudioPrimaryHidlHalTest.cpp
+++ b/audio/core/2.0/vts/functional/AudioPrimaryHidlHalTest.cpp
@@ -661,8 +661,8 @@
         code;                                          \
     }
 
-TEST_IO_STREAM(GetFrameCount, "Check that the stream frame count == the one it was opened with",
-               ASSERT_EQ(audioConfig.frameCount, extract(stream->getFrameCount())))
+TEST_IO_STREAM(GetFrameCount, "Check that getting stream frame count does not crash the HAL.",
+               ASSERT_TRUE(stream->getFrameCount().isOk()))
 
 TEST_IO_STREAM(GetSampleRate, "Check that the stream sample rate == the one it was opened with",
                ASSERT_EQ(audioConfig.sampleRateHz, extract(stream->getSampleRate())))
diff --git a/audio/core/4.0/vts/functional/AudioPrimaryHidlHalTest.cpp b/audio/core/4.0/vts/functional/AudioPrimaryHidlHalTest.cpp
index 3a7c284..f1e0b21 100644
--- a/audio/core/4.0/vts/functional/AudioPrimaryHidlHalTest.cpp
+++ b/audio/core/4.0/vts/functional/AudioPrimaryHidlHalTest.cpp
@@ -823,8 +823,8 @@
         code;                                          \
     }
 
-TEST_IO_STREAM(GetFrameCount, "Check that the stream frame count == the one it was opened with",
-               ASSERT_EQ(audioConfig.frameCount, extract(stream->getFrameCount())))
+TEST_IO_STREAM(GetFrameCount, "Check that getting stream frame count does not crash the HAL.",
+               ASSERT_TRUE(stream->getFrameCount().isOk()))
 
 TEST_IO_STREAM(GetSampleRate, "Check that the stream sample rate == the one it was opened with",
                ASSERT_EQ(audioConfig.sampleRateHz, extract(stream->getSampleRate())))
diff --git a/biometrics/face/1.0/IBiometricsFace.hal b/biometrics/face/1.0/IBiometricsFace.hal
index 1c7bfb9..0ac788e 100644
--- a/biometrics/face/1.0/IBiometricsFace.hal
+++ b/biometrics/face/1.0/IBiometricsFace.hal
@@ -225,7 +225,10 @@
      * Authenticates the active user.
      *
      * An optional operationId can be specified as a token from the transaction
-     * being authorized.
+     * being authorized. The hardware may enter a standby state during
+     * authentication, where the device is idle to conserve power while
+     * authenticating, e.g. after 3 seconds without finding a face. See
+     * IBiometricsFace#userActivity() for more info.
      *
      * @param operationId A non-zero operation id associated with a crypto
      * object instance; or 0 if not being used.
@@ -233,4 +236,17 @@
      */
     @callflow(next={"cancel", "generateChallenge", "remove"})
     authenticate(uint64_t operationId) generates (Status status);
+
+    /**
+     * A hint to the HAL to continue looking for faces.
+     *
+     * This method should only be used when the HAL is in the authenticating
+     * or standby state. Using this method when the HAL is not in one of the
+     * mentioned states must return OPERATION_NOT_SUPPORTED. Calling this
+     * method while the HAL is already authenticating may extend the duration
+     * where it's looking for a face.
+     *
+     * @return status The status of this method call.
+     */
+    userActivity() generates (Status status);
 };
diff --git a/bluetooth/1.0/vts/functional/VtsHalBluetoothV1_0TargetTest.cpp b/bluetooth/1.0/vts/functional/VtsHalBluetoothV1_0TargetTest.cpp
index bf8b547..439c5fb 100644
--- a/bluetooth/1.0/vts/functional/VtsHalBluetoothV1_0TargetTest.cpp
+++ b/bluetooth/1.0/vts/functional/VtsHalBluetoothV1_0TargetTest.cpp
@@ -170,8 +170,9 @@
     acl_cb_count = 0;
     sco_cb_count = 0;
 
-    ASSERT_EQ(initialized, false);
-    bluetooth->initialize(bluetooth_cb);
+    ASSERT_FALSE(initialized);
+    // Should not be checked in production code
+    ASSERT_TRUE(bluetooth->initialize(bluetooth_cb).isOk());
 
     bluetooth_cb->SetWaitTimeout(kCallbackNameInitializationComplete,
                                  WAIT_FOR_INIT_TIMEOUT);
@@ -186,15 +187,16 @@
         bluetooth_cb->WaitForCallback(kCallbackNameInitializationComplete)
             .no_timeout);
 
-    ASSERT_EQ(initialized, true);
+    ASSERT_TRUE(initialized);
   }
 
   virtual void TearDown() override {
-    bluetooth->close();
-    handle_no_ops();
-    EXPECT_EQ(static_cast<size_t>(0), event_queue.size());
-    EXPECT_EQ(static_cast<size_t>(0), sco_queue.size());
-    EXPECT_EQ(static_cast<size_t>(0), acl_queue.size());
+      // Should not be checked in production code
+      ASSERT_TRUE(bluetooth->close().isOk());
+      handle_no_ops();
+      EXPECT_EQ(static_cast<size_t>(0), event_queue.size());
+      EXPECT_EQ(static_cast<size_t>(0), sco_queue.size());
+      EXPECT_EQ(static_cast<size_t>(0), acl_queue.size());
   }
 
   void setBufferSizes();
diff --git a/boot/1.0/default/Android.bp b/boot/1.0/default/Android.bp
index 67dee08..397c56d 100644
--- a/boot/1.0/default/Android.bp
+++ b/boot/1.0/default/Android.bp
@@ -2,7 +2,7 @@
     name: "android.hardware.boot@1.0-impl",
     defaults: ["hidl_defaults"],
     relative_install_path: "hw",
-    vendor_available: true,
+    vendor: true,
     recovery_available: true,
     srcs: ["BootControl.cpp"],
 
diff --git a/camera/common/1.0/default/CameraModule.cpp b/camera/common/1.0/default/CameraModule.cpp
index eb840a7..392ebbc 100644
--- a/camera/common/1.0/default/CameraModule.cpp
+++ b/camera/common/1.0/default/CameraModule.cpp
@@ -235,7 +235,7 @@
     chars.update(keyTag, availableKeys);
 }
 
-CameraModule::CameraModule(camera_module_t *module) {
+CameraModule::CameraModule(camera_module_t *module) : mNumberOfCameras(0) {
     if (module == NULL) {
         ALOGE("%s: camera hardware module must not be null", __FUNCTION__);
         assert(0);
@@ -264,7 +264,8 @@
         res = mModule->init();
         ATRACE_END();
     }
-    mCameraInfoMap.setCapacity(getNumberOfCameras());
+    mNumberOfCameras = getNumberOfCameras();
+    mCameraInfoMap.setCapacity(mNumberOfCameras);
     return res;
 }
 
@@ -322,7 +323,7 @@
 int CameraModule::getPhysicalCameraInfo(int physicalCameraId, camera_metadata_t **physicalInfo) {
     ATRACE_CALL();
     Mutex::Autolock lock(mCameraInfoLock);
-    if (physicalCameraId < 0) {
+    if (physicalCameraId < mNumberOfCameras) {
         ALOGE("%s: Invalid physical camera ID %d", __FUNCTION__, physicalCameraId);
         return -EINVAL;
     }
@@ -334,6 +335,10 @@
                 __FUNCTION__);
         return -ENODEV;
     }
+    if (mModule->get_physical_camera_info == nullptr) {
+        ALOGE("%s: get_physical_camera is NULL for module version 2.5", __FUNCTION__);
+        return -EINVAL;
+    }
 
     ssize_t index = mPhysicalCameraInfoMap.indexOfKey(physicalCameraId);
     if (index == NAME_NOT_FOUND) {
diff --git a/camera/common/1.0/default/include/CameraModule.h b/camera/common/1.0/default/include/CameraModule.h
index ed853bf..aee9654 100644
--- a/camera/common/1.0/default/include/CameraModule.h
+++ b/camera/common/1.0/default/include/CameraModule.h
@@ -75,6 +75,7 @@
             int32_t keyTag, const Vector<int32_t>& appendKeys);
     status_t filterOpenErrorCode(status_t err);
     camera_module_t *mModule;
+    int mNumberOfCameras;
     KeyedVector<int, camera_info> mCameraInfoMap;
     KeyedVector<int, int> mDeviceVersionMap;
     KeyedVector<int, camera_metadata_t*> mPhysicalCameraInfoMap;
diff --git a/camera/device/3.2/ICameraDevice.hal b/camera/device/3.2/ICameraDevice.hal
index 1f523e4..5236bb1 100644
--- a/camera/device/3.2/ICameraDevice.hal
+++ b/camera/device/3.2/ICameraDevice.hal
@@ -148,7 +148,9 @@
      * session handle for active operations.
      *
      * @param callback Interface to invoke by the HAL for device asynchronous
-     *     events.
+     *     events. For HALs newer than version 3.2, HAL must use castFrom
+     *     method to check the exact version of callback sent by camera service.
+     *
      * @return status Status code for the operation, one of:
      *     OK:
      *         On a successful open of the camera device.
diff --git a/camera/device/3.2/ICameraDeviceSession.hal b/camera/device/3.2/ICameraDeviceSession.hal
index 477a3cc..225e52b 100644
--- a/camera/device/3.2/ICameraDeviceSession.hal
+++ b/camera/device/3.2/ICameraDeviceSession.hal
@@ -149,9 +149,8 @@
      *           - Including too many output streams of a certain format.
      *           - Unsupported rotation configuration
      *           - Stream sizes/formats don't satisfy the
-     *             camera3_stream_configuration_t->operation_mode requirements
-     *             for non-NORMAL mode, or the requested operation_mode is not
-     *             supported by the HAL.
+     *             StreamConfigurationMode requirements for non-NORMAL mode, or
+     *             the requested operation_mode is not supported by the HAL.
      *           - Unsupported usage flag
      *         The camera service cannot filter out all possible illegal stream
      *         configurations, since some devices may support more simultaneous
diff --git a/camera/device/3.4/ICameraDeviceSession.hal b/camera/device/3.4/ICameraDeviceSession.hal
index c41d90e..e1663e6 100644
--- a/camera/device/3.4/ICameraDeviceSession.hal
+++ b/camera/device/3.4/ICameraDeviceSession.hal
@@ -54,7 +54,7 @@
      *           - Including too many output streams of a certain format.
      *           - Unsupported rotation configuration
      *           - Stream sizes/formats don't satisfy the
-     *             camera3_stream_configuration_t->operation_mode requirements
+     *             StreamConfigurationMode requirements
      *             for non-NORMAL mode, or the requested operation_mode is not
      *             supported by the HAL.
      *           - Unsupported usage flag
diff --git a/camera/device/3.5/Android.bp b/camera/device/3.5/Android.bp
index a4e9ee2..2a9ba05 100644
--- a/camera/device/3.5/Android.bp
+++ b/camera/device/3.5/Android.bp
@@ -7,7 +7,9 @@
         enabled: true,
     },
     srcs: [
+        "types.hal",
         "ICameraDevice.hal",
+        "ICameraDeviceCallback.hal",
         "ICameraDeviceSession.hal",
     ],
     interfaces: [
@@ -18,6 +20,14 @@
         "android.hardware.graphics.common@1.0",
         "android.hidl.base@1.0",
     ],
+    types: [
+        "BufferRequest",
+        "BufferRequestStatus",
+        "StreamBufferRequestError",
+        "StreamBufferRet",
+        "StreamBuffersVal",
+        "StreamConfiguration",
+    ],
     gen_java: false,
 }
 
diff --git a/camera/device/3.5/ICameraDevice.hal b/camera/device/3.5/ICameraDevice.hal
index e7e8dd3..a77380f 100644
--- a/camera/device/3.5/ICameraDevice.hal
+++ b/camera/device/3.5/ICameraDevice.hal
@@ -36,11 +36,24 @@
      * this logical camera device. This information may not change between consecutive calls.
      *
      * Note that HAL must support this function for physical camera IDs that are
-     * not exposed via ICameraProvider::getCameraIdList().
+     * not exposed via ICameraProvider::getCameraIdList(). Calling
+     * getCameraDeviceInterface_V3_x() on these camera IDs must return ILLEGAL_ARGUMENT.
+     *
+     * The characteristics of all cameras returned by
+     * ICameraProvider::getCameraIdList() must be queried via
+     * getCameraCharacteristics(). Calling getPhysicalCameraCharacteristics() on
+     * those cameras must return ILLEGAL_ARGUMENT.
+     *
+     * @param physicalCameraId The physical camera id parsed from the logical
+     *     camera's ANDROID_LOGICAL_MULTI_CAMERA_PHYSICAL_IDS static metadata
+     *     key. The framework assumes that this ID is just the <id> part of fully
+     *     qualified camera device name "device@<major>.<minor>/<type>/<id>". And
+     *     the physical camera must be of the same version and type as the parent
+     *     logical camera device.
      *
      * @return status Status code for the operation, one of:
      *     OK:
-     *         On a successful query of the camera device characteristics
+     *         On a successful query of the physical camera device characteristics
      *     INTERNAL_ERROR:
      *         The camera device cannot be opened due to an internal
      *         error.
@@ -50,6 +63,9 @@
      *         instance must be acquired if the device is reconnected. All
      *         subsequent calls on this interface must return
      *         CAMERA_DISCONNECTED.
+     *     ILLEGAL_ARGUMENT:
+     *         If the physicalCameraId is not a valid physical camera Id outside
+     *         of ICameraProvider::getCameraIdList().
      *
      * @return cameraCharacteristics
      *     The static metadata for this logical camera device's physical device, or an empty
diff --git a/camera/device/3.5/ICameraDeviceCallback.hal b/camera/device/3.5/ICameraDeviceCallback.hal
new file mode 100644
index 0000000..aa4ad22
--- /dev/null
+++ b/camera/device/3.5/ICameraDeviceCallback.hal
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2018 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.camera.device@3.5;
+
+import @3.2::StreamBuffer;
+import @3.4::ICameraDeviceCallback;
+
+/**
+ * Callback methods for the HAL to call into the framework.
+ */
+interface ICameraDeviceCallback extends @3.4::ICameraDeviceCallback {
+
+    /**
+     * requestStreamBuffers:
+     *
+     * Synchronous callback for HAL to ask for output buffers from camera service.
+     *
+     * This call may be serialized in camera service so it is strongly
+     * recommended to only call this method from one thread.
+     *
+     * When camera device advertises
+     * (CameraMetadataEnumAndroidInfoSupportedBufferManagementVersion ==
+     * ANDROID_INFO_SUPPORTED_BUFFER_MANAGEMENT_VERSION_HIDL_DEVICE_3_5), HAL
+     * can use this method to request buffers from camera service.
+     *
+     * @return status Status code for the operation, one of:
+     *     OK: all requested buffers are returned
+     *     FAILED_PARTIAL: some streams failed while some succeeds. Check
+     *             individual StreamBufferRet for details.
+     *     FAILED_CONFIGURING: the request failed because camera servicve is
+     *             performing configureStreams and no buffers are returned.
+     *     FAILED_UNKNOWN: the request failed for unknown reason and no buffers
+     *             are returned.
+     *
+     * Performance requirements:
+     * This is a blocking call that takes more time with more buffers requested.
+     * HAL must not request large amount of buffers on a latency critical code
+     * path. It is highly recommended to use a dedicated thread to perform
+     * all requestStreamBuffers calls, and adjust the thread priority and/or
+     * timing of making the call in order for buffers to arrive before HAL is
+     * ready to fill the buffer.
+     */
+    requestStreamBuffers(vec<BufferRequest> bufReqs)
+            generates (BufferRequestStatus st, vec<StreamBufferRet> buffers);
+
+    /**
+     * returnStreamBuffers:
+     *
+     * Synchronous callback for HAL to return output buffers to camera service.
+     *
+     * If this method is called during a configureStreams call, it must be blocked
+     * until camera service finishes the ongoing configureStreams call.
+     */
+    returnStreamBuffers(vec<StreamBuffer> buffers);
+
+};
diff --git a/camera/device/3.5/ICameraDeviceSession.hal b/camera/device/3.5/ICameraDeviceSession.hal
index 8406685..b2b71cd 100644
--- a/camera/device/3.5/ICameraDeviceSession.hal
+++ b/camera/device/3.5/ICameraDeviceSession.hal
@@ -18,6 +18,7 @@
 
 import android.hardware.camera.common@1.0::Status;
 import @3.4::ICameraDeviceSession;
+import @3.4::HalStreamConfiguration;
 
 /**
  * Camera device active session interface.
@@ -26,4 +27,76 @@
  * configure and request captures from an active camera device.
  */
 interface ICameraDeviceSession extends @3.4::ICameraDeviceSession {
+
+    /**
+     * configureStreams_3_5:
+     *
+     * Identical to @3.4::ICameraDeviceSession.configureStreams, except that:
+     *
+     * - a streamConfigCounter counter is provided to check for race condition
+     *   between configureStreams_3_5 and signalStreamFlush call.
+     *
+     * @return status Status code for the operation, one of:
+     *     OK:
+     *         On successful stream configuration.
+     *     INTERNAL_ERROR:
+     *         If there has been a fatal error and the device is no longer
+     *         operational. Only close() can be called successfully by the
+     *         framework after this error is returned.
+     *     ILLEGAL_ARGUMENT:
+     *         If the requested stream configuration is invalid. Some examples
+     *         of invalid stream configurations include:
+     *           - Including more than 1 INPUT stream
+     *           - Not including any OUTPUT streams
+     *           - Including streams with unsupported formats, or an unsupported
+     *             size for that format.
+     *           - Including too many output streams of a certain format.
+     *           - Unsupported rotation configuration
+     *           - Stream sizes/formats don't satisfy the
+     *             StreamConfigurationMode requirements
+     *             for non-NORMAL mode, or the requested operation_mode is not
+     *             supported by the HAL.
+     *           - Unsupported usage flag
+     *         The camera service cannot filter out all possible illegal stream
+     *         configurations, since some devices may support more simultaneous
+     *         streams or larger stream resolutions than the minimum required
+     *         for a given camera device hardware level. The HAL must return an
+     *         ILLEGAL_ARGUMENT for any unsupported stream set, and then be
+     *         ready to accept a future valid stream configuration in a later
+     *         configureStreams call.
+     * @return halConfiguration The stream parameters desired by the HAL for
+     *     each stream, including maximum buffers, the usage flags, and the
+     *     override format.
+     */
+    configureStreams_3_5(@3.5::StreamConfiguration requestedConfiguration)
+            generates (Status status,
+                       @3.4::HalStreamConfiguration halConfiguration);
+
+
+    /**
+     * signalStreamFlush:
+     *
+     * Signaling HAL camera service is about to perform configureStreams_3_5 and
+     * HAL must return all buffers of designated streams. HAL must finish
+     * inflight requests normally and return all buffers that belongs to the
+     * designated streams through processCaptureResult or returnStreamBuffer
+     * API in a timely manner, or camera service will run into a fatal error.
+     *
+     * Note that this call serves as an optional hint and camera service may
+     * skip sending this call if all buffers are already returned.
+     *
+     * @param streamIds The ID of streams camera service need all of its
+     *     buffers returned.
+     *
+     * @param streamConfigCounter Note that due to concurrency nature, it is
+     *     possible the signalStreamFlush call arrives later than the
+     *     corresponding configureStreams_3_5 call, HAL must check
+     *     streamConfigCounter for such race condition. If the counter is less
+     *     than the counter in the last configureStreams_3_5 call HAL last
+     *     received, the call is stale and HAL should just return this call.
+     */
+    oneway signalStreamFlush(
+        vec<int32_t> streamIds,
+        uint32_t streamConfigCounter
+    );
 };
diff --git a/camera/device/3.5/default/Android.bp b/camera/device/3.5/default/Android.bp
index 341f573..09cf3a4 100644
--- a/camera/device/3.5/default/Android.bp
+++ b/camera/device/3.5/default/Android.bp
@@ -27,6 +27,7 @@
     vendor: true,
     srcs: [
         "CameraDevice.cpp",
+        "CameraDeviceSession.cpp",
     ],
     shared_libs: [
         "libhidlbase",
diff --git a/camera/device/3.5/default/CameraDevice.cpp b/camera/device/3.5/default/CameraDevice.cpp
index fcd1c96..a6969af 100644
--- a/camera/device/3.5/default/CameraDevice.cpp
+++ b/camera/device/3.5/default/CameraDevice.cpp
@@ -39,6 +39,22 @@
 CameraDevice::~CameraDevice() {
 }
 
+sp<V3_2::implementation::CameraDeviceSession> CameraDevice::createSession(camera3_device_t* device,
+        const camera_metadata_t* deviceInfo,
+        const sp<V3_2::ICameraDeviceCallback>& callback) {
+    sp<CameraDeviceSession> session = new CameraDeviceSession(device, deviceInfo, callback);
+    IF_ALOGV() {
+        session->getInterface()->interfaceChain([](
+            ::android::hardware::hidl_vec<::android::hardware::hidl_string> interfaceChain) {
+                ALOGV("Session interface chain:");
+                for (auto iface : interfaceChain) {
+                    ALOGV("  %s", iface.c_str());
+                }
+            });
+    }
+    return session;
+}
+
 Return<void> CameraDevice::getPhysicalCameraCharacteristics(const hidl_string& physicalCameraId,
         V3_5::ICameraDevice::getPhysicalCameraCharacteristics_cb _hidl_cb) {
     Status status = initStatus();
@@ -63,6 +79,10 @@
                 int ret = mModule->getPhysicalCameraInfo((int)id, &physicalInfo);
                 if (ret == OK) {
                     V3_2::implementation::convertToHidl(physicalInfo, &cameraCharacteristics);
+                } else if (ret == -EINVAL) {
+                    ALOGE("%s: %s is not a valid physical camera Id outside of getCameraIdList()",
+                            __FUNCTION__, physicalCameraId.c_str());
+                    status = Status::ILLEGAL_ARGUMENT;
                 } else {
                     ALOGE("%s: Failed to get physical camera %s info: %s (%d)!", __FUNCTION__,
                             physicalCameraId.c_str(), strerror(-ret), ret);
diff --git a/camera/device/3.5/default/CameraDeviceSession.cpp b/camera/device/3.5/default/CameraDeviceSession.cpp
new file mode 100644
index 0000000..5336ca9
--- /dev/null
+++ b/camera/device/3.5/default/CameraDeviceSession.cpp
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2018 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 "CamDevSession@3.5-impl"
+#include <android/log.h>
+
+#include <utils/Trace.h>
+#include "CameraDeviceSession.h"
+
+namespace android {
+namespace hardware {
+namespace camera {
+namespace device {
+namespace V3_5 {
+namespace implementation {
+
+CameraDeviceSession::CameraDeviceSession(
+    camera3_device_t* device,
+    const camera_metadata_t* deviceInfo,
+    const sp<V3_2::ICameraDeviceCallback>& callback) :
+        V3_4::implementation::CameraDeviceSession(device, deviceInfo, callback) {
+
+    mHasCallback_3_5 = false;
+
+    auto castResult = ICameraDeviceCallback::castFrom(callback);
+    if (castResult.isOk()) {
+        sp<ICameraDeviceCallback> callback3_5 = castResult;
+        if (callback3_5 != nullptr) {
+            mHasCallback_3_5 = true;
+        }
+    }
+}
+
+CameraDeviceSession::~CameraDeviceSession() {
+}
+
+Return<void> CameraDeviceSession::configureStreams_3_5(
+        const StreamConfiguration& /*requestedConfiguration*/,
+        ICameraDeviceSession::configureStreams_3_5_cb _hidl_cb)  {
+    HalStreamConfiguration outStreams;
+    _hidl_cb(Status::OPERATION_NOT_SUPPORTED, outStreams);
+    return Void();
+}
+
+Return<void> CameraDeviceSession::signalStreamFlush(
+        const hidl_vec<int32_t>& /*requests*/, uint32_t /*streamConfigCounter*/) {
+    return Void();
+}
+
+} // namespace implementation
+}  // namespace V3_5
+}  // namespace device
+}  // namespace camera
+}  // namespace hardware
+}  // namespace android
diff --git a/camera/device/3.5/default/include/device_v3_5_impl/CameraDeviceSession.h b/camera/device/3.5/default/include/device_v3_5_impl/CameraDeviceSession.h
new file mode 100644
index 0000000..ec34769
--- /dev/null
+++ b/camera/device/3.5/default/include/device_v3_5_impl/CameraDeviceSession.h
@@ -0,0 +1,157 @@
+/*
+ * Copyright (C) 2018 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_CAMERA_DEVICE_V3_5_CAMERADEVICE3SESSION_H
+#define ANDROID_HARDWARE_CAMERA_DEVICE_V3_5_CAMERADEVICE3SESSION_H
+
+#include <android/hardware/camera/device/3.5/ICameraDevice.h>
+#include <android/hardware/camera/device/3.5/ICameraDeviceSession.h>
+#include <android/hardware/camera/device/3.5/ICameraDeviceCallback.h>
+#include <../../3.4/default/include/device_v3_4_impl/CameraDeviceSession.h>
+
+namespace android {
+namespace hardware {
+namespace camera {
+namespace device {
+namespace V3_5 {
+namespace implementation {
+
+using namespace ::android::hardware::camera::device;
+using ::android::hardware::camera::device::V3_2::CaptureRequest;
+using ::android::hardware::camera::device::V3_5::StreamConfiguration;
+using ::android::hardware::camera::device::V3_4::HalStreamConfiguration;
+using ::android::hardware::camera::device::V3_5::ICameraDeviceSession;
+using ::android::hardware::camera::device::V3_5::ICameraDeviceCallback;
+using ::android::hardware::camera::common::V1_0::Status;
+using ::android::hardware::camera::common::V1_0::helper::HandleImporter;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::hidl_string;
+using ::android::sp;
+using ::android::Mutex;
+
+struct CameraDeviceSession : public V3_4::implementation::CameraDeviceSession {
+
+    CameraDeviceSession(camera3_device_t*,
+            const camera_metadata_t* deviceInfo,
+            const sp<V3_2::ICameraDeviceCallback>&);
+    virtual ~CameraDeviceSession();
+
+    virtual sp<V3_2::ICameraDeviceSession> getInterface() override {
+        return new TrampolineSessionInterface_3_5(this);
+    }
+
+protected:
+    // Methods from v3.4 and earlier will trampoline to inherited implementation
+    Return<void> configureStreams_3_5(
+            const StreamConfiguration& requestedConfiguration,
+            ICameraDeviceSession::configureStreams_3_5_cb _hidl_cb);
+
+    Return<void> signalStreamFlush(
+            const hidl_vec<int32_t>& requests,
+            uint32_t streamConfigCounter);
+
+
+    // Whether this camera device session is created with version 3.5 callback.
+    bool mHasCallback_3_5;
+
+private:
+
+    struct TrampolineSessionInterface_3_5 : public ICameraDeviceSession {
+        TrampolineSessionInterface_3_5(sp<CameraDeviceSession> parent) :
+                mParent(parent) {}
+
+        virtual Return<void> constructDefaultRequestSettings(
+                V3_2::RequestTemplate type,
+                V3_3::ICameraDeviceSession::constructDefaultRequestSettings_cb _hidl_cb) override {
+            return mParent->constructDefaultRequestSettings(type, _hidl_cb);
+        }
+
+        virtual Return<void> configureStreams(
+                const V3_2::StreamConfiguration& requestedConfiguration,
+                V3_3::ICameraDeviceSession::configureStreams_cb _hidl_cb) override {
+            return mParent->configureStreams(requestedConfiguration, _hidl_cb);
+        }
+
+        virtual Return<void> processCaptureRequest_3_4(
+                const hidl_vec<V3_4::CaptureRequest>& requests,
+                const hidl_vec<V3_2::BufferCache>& cachesToRemove,
+                ICameraDeviceSession::processCaptureRequest_3_4_cb _hidl_cb) override {
+            return mParent->processCaptureRequest_3_4(requests, cachesToRemove, _hidl_cb);
+        }
+
+        virtual Return<void> processCaptureRequest(const hidl_vec<V3_2::CaptureRequest>& requests,
+                const hidl_vec<V3_2::BufferCache>& cachesToRemove,
+                V3_3::ICameraDeviceSession::processCaptureRequest_cb _hidl_cb) override {
+            return mParent->processCaptureRequest(requests, cachesToRemove, _hidl_cb);
+        }
+
+        virtual Return<void> getCaptureRequestMetadataQueue(
+                V3_3::ICameraDeviceSession::getCaptureRequestMetadataQueue_cb _hidl_cb) override  {
+            return mParent->getCaptureRequestMetadataQueue(_hidl_cb);
+        }
+
+        virtual Return<void> getCaptureResultMetadataQueue(
+                V3_3::ICameraDeviceSession::getCaptureResultMetadataQueue_cb _hidl_cb) override  {
+            return mParent->getCaptureResultMetadataQueue(_hidl_cb);
+        }
+
+        virtual Return<Status> flush() override {
+            return mParent->flush();
+        }
+
+        virtual Return<void> close() override {
+            return mParent->close();
+        }
+
+        virtual Return<void> configureStreams_3_3(
+                const V3_2::StreamConfiguration& requestedConfiguration,
+                configureStreams_3_3_cb _hidl_cb) override {
+            return mParent->configureStreams_3_3(requestedConfiguration, _hidl_cb);
+        }
+
+        virtual Return<void> configureStreams_3_4(
+                const V3_4::StreamConfiguration& requestedConfiguration,
+                configureStreams_3_4_cb _hidl_cb) override {
+            return mParent->configureStreams_3_4(requestedConfiguration, _hidl_cb);
+        }
+
+        virtual Return<void> configureStreams_3_5(
+                const StreamConfiguration& requestedConfiguration,
+                configureStreams_3_5_cb _hidl_cb) override {
+            return mParent->configureStreams_3_5(requestedConfiguration, _hidl_cb);
+        }
+
+        virtual Return<void> signalStreamFlush(
+                const hidl_vec<int32_t>& requests,
+                uint32_t streamConfigCounter) override {
+            return mParent->signalStreamFlush(requests, streamConfigCounter);
+        }
+
+    private:
+        sp<CameraDeviceSession> mParent;
+    };
+};
+
+}  // namespace implementation
+}  // namespace V3_5
+}  // namespace device
+}  // namespace camera
+}  // namespace hardware
+}  // namespace android
+
+#endif  // ANDROID_HARDWARE_CAMERA_DEVICE_V3_5_CAMERADEVICE3SESSION_H
diff --git a/camera/device/3.5/default/include/device_v3_5_impl/CameraDevice_3_5.h b/camera/device/3.5/default/include/device_v3_5_impl/CameraDevice_3_5.h
index f250bc9..6bdc60f 100644
--- a/camera/device/3.5/default/include/device_v3_5_impl/CameraDevice_3_5.h
+++ b/camera/device/3.5/default/include/device_v3_5_impl/CameraDevice_3_5.h
@@ -17,7 +17,7 @@
 #ifndef ANDROID_HARDWARE_CAMERA_DEVICE_V3_5_CAMERADEVICE_H
 #define ANDROID_HARDWARE_CAMERA_DEVICE_V3_5_CAMERADEVICE_H
 
-#include "CameraModule.h"
+#include "CameraDeviceSession.h"
 #include <../../../../3.4/default/include/device_v3_4_impl/CameraDevice_3_4.h>
 
 #include <android/hardware/camera/device/3.5/ICameraDevice.h>
@@ -57,6 +57,10 @@
     }
 
 protected:
+    virtual sp<V3_2::implementation::CameraDeviceSession> createSession(camera3_device_t*,
+            const camera_metadata_t* deviceInfo,
+            const sp<V3_2::ICameraDeviceCallback>&) override;
+
     Return<void> getPhysicalCameraCharacteristics(const hidl_string& physicalCameraId,
             V3_5::ICameraDevice::getPhysicalCameraCharacteristics_cb _hidl_cb);
 
diff --git a/camera/device/3.5/types.hal b/camera/device/3.5/types.hal
new file mode 100644
index 0000000..613187d
--- /dev/null
+++ b/camera/device/3.5/types.hal
@@ -0,0 +1,131 @@
+/*
+ * Copyright (C) 2018 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.camera.device@3.5;
+
+import @3.2::StreamBuffer;
+import @3.4::StreamConfiguration;
+
+/**
+ * StreamConfiguration:
+ *
+ * Identical to @3.4::StreamConfiguration, except that it contains streamConfigCounter
+ */
+struct StreamConfiguration {
+    @3.4::StreamConfiguration v3_4;
+
+    /**
+     * An incrementing counter used for HAL to keep track of the stream
+     * configuration and the paired oneway signalStreamFlush call. When the
+     * counter in signalStreamFlush call is less than the counter here, that
+     * signalStreamFlush call is stale.
+     */
+    uint32_t streamConfigCounter;
+};
+
+enum StreamBufferRequestError : uint32_t {
+    /**
+     * Get buffer failed due to timeout waiting for an available buffer. This is
+     * likely due to the client application holding too many buffers, or the
+     * system is under memory pressure.
+     * This is not a fatal error. HAL may try to request buffer for this stream
+     * later. If HAL cannot get a buffer for certain capture request in time
+     * due to this error, HAL can send an ERROR_REQUEST to camera service and
+     * drop processing that request.
+     */
+    NO_BUFFER_AVAILABLE = 1,
+
+    /**
+     * Get buffer failed due to HAL has reached its maxBuffer count. This is not
+     * a fatal error. HAL may try to request buffer for this stream again after
+     * it returns at least one buffer of that stream to camera service.
+     */
+    MAX_BUFFER_EXCEEDED = 2,
+
+    /**
+     * Get buffer failed due to the stream is disconnected by client
+     * application, has been removed, or not recognized by camera service.
+     * This means application is no longer interested in this stream.
+     * Requesting buffer for this stream must never succeed after this error is
+     * returned. HAL must safely return all buffers of this stream after
+     * getting this error. If HAL gets another capture request later targeting
+     * a disconnected stream, HAL must send an ERROR_REQUEST to camera service
+     * and drop processing that request.
+     */
+    STREAM_DISCONNECTED = 3,
+
+    /**
+     * Get buffer failed for unknown reasons. This is a fatal error and HAL must
+     * send ERROR_DEVICE to camera service and be ready to be closed.
+     */
+    UNKNOWN_ERROR = 4
+};
+
+/**
+ * Per-stream return value for requestStreamBuffers.
+ * For each stream, either an StreamBufferRequestError error code, or all
+ * requested buffers for this stream is returned, so buffers.size() must be
+ * equal to BufferRequest::numBuffersRequested of corresponding stream.
+ */
+safe_union StreamBuffersVal {
+    StreamBufferRequestError error;
+    vec<@3.2::StreamBuffer> buffers;
+};
+
+struct StreamBufferRet {
+    int32_t streamId;
+    StreamBuffersVal val;
+};
+
+enum BufferRequestStatus : uint32_t {
+    /**
+     * Method call succeeded and all requested buffers are returned.
+     */
+    OK = 0,
+
+    /**
+     * Method call failed for some streams. Check per stream status for each
+     * returned StreamBufferRet.
+     */
+    FAILED_PARTIAL = 1,
+
+    /**
+     * Method call failed for all streams and no buffers are returned at all.
+     * Camera service is about to or is performing configureStreams. HAL must
+     * wait until next configureStreams call is finished before requesting
+     * buffers again.
+     */
+    FAILED_CONFIGURING = 2,
+
+    /**
+     * Method call failed for all streams and no buffers are returned at all.
+     * Failure due to bad BufferRequest input, eg: unknown streamId or repeated
+     * streamId.
+     */
+    FAILED_ILLEGAL_ARGUMENTS = 3,
+
+    /**
+     * Method call failed for all streams and no buffers are returned at all.
+     * Failure due to unknown reason.
+     */
+    FAILED_UNKNOWN = 4,
+};
+
+struct BufferRequest {
+    int32_t streamId;
+    uint32_t numBuffersRequested;
+};
+
diff --git a/camera/metadata/3.4/Android.bp b/camera/metadata/3.4/Android.bp
index 04a00ef..388df68 100644
--- a/camera/metadata/3.4/Android.bp
+++ b/camera/metadata/3.4/Android.bp
@@ -14,6 +14,7 @@
         "android.hardware.camera.metadata@3.3",
     ],
     types: [
+        "CameraMetadataEnumAndroidInfoSupportedBufferManagementVersion",
         "CameraMetadataTag",
     ],
     gen_java: true,
diff --git a/camera/provider/2.4/Android.bp b/camera/provider/2.4/Android.bp
index 27329f3..63d7fd5 100644
--- a/camera/provider/2.4/Android.bp
+++ b/camera/provider/2.4/Android.bp
@@ -14,7 +14,6 @@
         "android.hardware.camera.common@1.0",
         "android.hardware.camera.device@1.0",
         "android.hardware.camera.device@3.2",
-        "android.hardware.camera.device@3.5",
         "android.hidl.base@1.0",
     ],
     gen_java: false,
diff --git a/camera/provider/2.4/default/CameraProvider.cpp b/camera/provider/2.4/default/CameraProvider.cpp
index b69fe1a..488b9af 100644
--- a/camera/provider/2.4/default/CameraProvider.cpp
+++ b/camera/provider/2.4/default/CameraProvider.cpp
@@ -552,6 +552,7 @@
         return Void();
     }
 
+    // ICameraDevice 3.4 or upper
     sp<android::hardware::camera::device::V3_2::implementation::CameraDevice> deviceImpl;
     if (deviceVersion >= kHAL3_4) {
         ALOGV("Constructing v3.4 camera device");
@@ -580,6 +581,7 @@
         return Void();
     }
 
+    // ICameraDevice 3.2 and 3.3
     // Since some Treble HAL revisions can map to the same legacy HAL version(s), we default
     // to the newest possible Treble HAL revision, but allow for override if needed via
     // system property.
diff --git a/camera/provider/2.4/vts/functional/Android.bp b/camera/provider/2.4/vts/functional/Android.bp
index ead4083..eb8d43e 100644
--- a/camera/provider/2.4/vts/functional/Android.bp
+++ b/camera/provider/2.4/vts/functional/Android.bp
@@ -37,6 +37,7 @@
         "android.hardware.camera.device@3.2",
         "android.hardware.camera.device@3.3",
         "android.hardware.camera.device@3.4",
+        "android.hardware.camera.device@3.5",
         "android.hardware.camera.provider@2.4",
         "android.hardware.graphics.allocator@2.0",
         "android.hardware.graphics.common@1.0",
diff --git a/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp b/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp
index f2a7836..94d06e8 100644
--- a/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp
+++ b/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp
@@ -28,6 +28,7 @@
 
 #include <android/hardware/camera/device/1.0/ICameraDevice.h>
 #include <android/hardware/camera/device/3.2/ICameraDevice.h>
+#include <android/hardware/camera/device/3.5/ICameraDevice.h>
 #include <android/hardware/camera/device/3.3/ICameraDeviceSession.h>
 #include <android/hardware/camera/device/3.4/ICameraDeviceSession.h>
 #include <android/hardware/camera/device/3.4/ICameraDeviceCallback.h>
@@ -144,10 +145,12 @@
 namespace {
     // "device@<version>/legacy/<id>"
     const char *kDeviceNameRE = "device@([0-9]+\\.[0-9]+)/%s/(.+)";
+    const int CAMERA_DEVICE_API_VERSION_3_5 = 0x305;
     const int CAMERA_DEVICE_API_VERSION_3_4 = 0x304;
     const int CAMERA_DEVICE_API_VERSION_3_3 = 0x303;
     const int CAMERA_DEVICE_API_VERSION_3_2 = 0x302;
     const int CAMERA_DEVICE_API_VERSION_1_0 = 0x100;
+    const char *kHAL3_5 = "3.5";
     const char *kHAL3_4 = "3.4";
     const char *kHAL3_3 = "3.3";
     const char *kHAL3_2 = "3.2";
@@ -182,7 +185,9 @@
             return -1;
         }
 
-        if (version.compare(kHAL3_4) == 0) {
+        if (version.compare(kHAL3_5) == 0) {
+            return CAMERA_DEVICE_API_VERSION_3_5;
+        } else if (version.compare(kHAL3_4) == 0) {
             return CAMERA_DEVICE_API_VERSION_3_4;
         } else if (version.compare(kHAL3_3) == 0) {
             return CAMERA_DEVICE_API_VERSION_3_3;
@@ -670,12 +675,19 @@
             HalStreamConfiguration *halStreamConfig /*out*/,
             bool *supportsPartialResults /*out*/,
             uint32_t *partialResultCount /*out*/);
+
+    void verifyLogicalCameraMetadata(const std::string& cameraName,
+            const ::android::sp<::android::hardware::camera::device::V3_2::ICameraDevice>& device,
+            const CameraMetadata& chars, int deviceVersion,
+            const hidl_vec<hidl_string>& deviceNames);
+    void verifyCameraCharacteristics(Status status, const CameraMetadata& chars);
+
     static Status getAvailableOutputStreams(camera_metadata_t *staticMeta,
             std::vector<AvailableStream> &outputStreams,
             const AvailableStream *threshold = nullptr);
     static Status isConstrainedModeAvailable(camera_metadata_t *staticMeta);
-    static Status isLogicalMultiCamera(camera_metadata_t *staticMeta);
-    static Status getPhysicalCameraIds(camera_metadata_t *staticMeta,
+    static Status isLogicalMultiCamera(const camera_metadata_t *staticMeta);
+    static Status getPhysicalCameraIds(const camera_metadata_t *staticMeta,
             std::unordered_set<std::string> *physicalIds/*out*/);
     static Status getSupportedKeys(camera_metadata_t *staticMeta,
             uint32_t tagId, std::unordered_set<int32_t> *requestIDs/*out*/);
@@ -1172,6 +1184,14 @@
     }
     ASSERT_GT(firstApiLevel, 0); // first_api_level must exist
 
+    // all devices with first API level == 28 and <= 1GB of RAM must set low_ram
+    // and thus be allowed to continue using HAL1
+    if ((firstApiLevel == HAL1_PHASE_OUT_API_LEVEL) &&
+        (property_get_bool("ro.config.low_ram", /*default*/ false))) {
+        ALOGI("Hal1 allowed for low ram device");
+        return;
+    }
+
     if (firstApiLevel >= HAL1_PHASE_OUT_API_LEVEL) {
         hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider);
         for (const auto& name : cameraDeviceNames) {
@@ -1258,6 +1278,7 @@
     for (const auto& name : cameraDeviceNames) {
         int deviceVersion = getCameraDeviceVersion(name, mProviderType);
         switch (deviceVersion) {
+            case CAMERA_DEVICE_API_VERSION_3_5:
             case CAMERA_DEVICE_API_VERSION_3_4:
             case CAMERA_DEVICE_API_VERSION_3_3:
             case CAMERA_DEVICE_API_VERSION_3_2: {
@@ -1299,6 +1320,7 @@
     for (const auto& name : cameraDeviceNames) {
         int deviceVersion = getCameraDeviceVersion(name, mProviderType);
         switch (deviceVersion) {
+            case CAMERA_DEVICE_API_VERSION_3_5:
             case CAMERA_DEVICE_API_VERSION_3_4:
             case CAMERA_DEVICE_API_VERSION_3_3:
             case CAMERA_DEVICE_API_VERSION_3_2: {
@@ -2039,6 +2061,7 @@
     for (const auto& name : cameraDeviceNames) {
         int deviceVersion = getCameraDeviceVersion(name, mProviderType);
         switch (deviceVersion) {
+            case CAMERA_DEVICE_API_VERSION_3_5:
             case CAMERA_DEVICE_API_VERSION_3_4:
             case CAMERA_DEVICE_API_VERSION_3_3:
             case CAMERA_DEVICE_API_VERSION_3_2: {
@@ -2055,41 +2078,31 @@
                 ASSERT_TRUE(ret.isOk());
 
                 ret = device3_x->getCameraCharacteristics([&](auto status, const auto& chars) {
-                    ALOGI("getCameraCharacteristics returns status:%d", (int)status);
-                    ASSERT_EQ(Status::OK, status);
-                    const camera_metadata_t* metadata = (camera_metadata_t*)chars.data();
-                    size_t expectedSize = chars.size();
-                    int result = validate_camera_metadata_structure(metadata, &expectedSize);
-                    ASSERT_TRUE((result == 0) || (result == CAMERA_METADATA_VALIDATION_SHIFTED));
-                    size_t entryCount = get_camera_metadata_entry_count(metadata);
-                    // TODO: we can do better than 0 here. Need to check how many required
-                    // characteristics keys we've defined.
-                    ASSERT_GT(entryCount, 0u);
-                    ALOGI("getCameraCharacteristics metadata entry count is %zu", entryCount);
+                    verifyCameraCharacteristics(status, chars);
 
-                    camera_metadata_ro_entry entry;
-                    int retcode = find_camera_metadata_ro_entry(metadata,
-                            ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL, &entry);
-                    if ((0 == retcode) && (entry.count > 0)) {
-                        uint8_t hardwareLevel = entry.data.u8[0];
-                        ASSERT_TRUE(
-                                hardwareLevel == ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED ||
-                                hardwareLevel == ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL_FULL ||
-                                hardwareLevel == ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL_3 ||
-                                hardwareLevel == ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL_EXTERNAL);
-                    } else {
-                        ADD_FAILURE() << "Get camera hardware level failed!";
-                    }
-
-                    entry.count = 0;
-                    retcode = find_camera_metadata_ro_entry(metadata,
-                            ANDROID_REQUEST_CHARACTERISTIC_KEYS_NEEDING_PERMISSION, &entry);
-                    if ((0 == retcode) || (entry.count > 0)) {
-                        ADD_FAILURE() << "ANDROID_REQUEST_CHARACTERISTIC_KEYS_NEEDING_PERMISSION "
-                            << " per API contract should never be set by Hal!";
-                    }
+                    verifyLogicalCameraMetadata(name, device3_x, chars, deviceVersion,
+                            cameraDeviceNames);
                 });
                 ASSERT_TRUE(ret.isOk());
+
+                //getPhysicalCameraCharacteristics will fail for publicly
+                //advertised camera IDs.
+                if (deviceVersion >= CAMERA_DEVICE_API_VERSION_3_5) {
+                    auto castResult = device::V3_5::ICameraDevice::castFrom(device3_x);
+                    ASSERT_TRUE(castResult.isOk());
+                    ::android::sp<::android::hardware::camera::device::V3_5::ICameraDevice>
+                            device3_5 = castResult;
+                    ASSERT_NE(device3_5, nullptr);
+
+                    std::string version, cameraId;
+                    ASSERT_TRUE(::matchDeviceName(name, mProviderType, &version, &cameraId));
+                    Return<void> ret = device3_5->getPhysicalCameraCharacteristics(cameraId,
+                            [&](auto status, const auto& chars) {
+                        ASSERT_TRUE(Status::ILLEGAL_ARGUMENT == status);
+                        ASSERT_EQ(0, chars.size());
+                    });
+                    ASSERT_TRUE(ret.isOk());
+                }
             }
             break;
             case CAMERA_DEVICE_API_VERSION_1_0: {
@@ -2126,6 +2139,7 @@
     for (const auto& name : cameraDeviceNames) {
         int deviceVersion = getCameraDeviceVersion(name, mProviderType);
         switch (deviceVersion) {
+            case CAMERA_DEVICE_API_VERSION_3_5:
             case CAMERA_DEVICE_API_VERSION_3_4:
             case CAMERA_DEVICE_API_VERSION_3_3:
             case CAMERA_DEVICE_API_VERSION_3_2: {
@@ -2251,6 +2265,7 @@
     for (const auto& name : cameraDeviceNames) {
         int deviceVersion = getCameraDeviceVersion(name, mProviderType);
         switch (deviceVersion) {
+            case CAMERA_DEVICE_API_VERSION_3_5:
             case CAMERA_DEVICE_API_VERSION_3_4:
             case CAMERA_DEVICE_API_VERSION_3_3:
             case CAMERA_DEVICE_API_VERSION_3_2: {
@@ -2315,6 +2330,7 @@
     for (const auto& name : cameraDeviceNames) {
         int deviceVersion = getCameraDeviceVersion(name, mProviderType);
         switch (deviceVersion) {
+            case CAMERA_DEVICE_API_VERSION_3_5:
             case CAMERA_DEVICE_API_VERSION_3_4:
             case CAMERA_DEVICE_API_VERSION_3_3:
             case CAMERA_DEVICE_API_VERSION_3_2: {
@@ -2343,7 +2359,8 @@
                 sp<device::V3_3::ICameraDeviceSession> sessionV3_3;
                 sp<device::V3_4::ICameraDeviceSession> sessionV3_4;
                 castSession(session, deviceVersion, &sessionV3_3, &sessionV3_4);
-                if (deviceVersion == CAMERA_DEVICE_API_VERSION_3_4) {
+                if (deviceVersion == CAMERA_DEVICE_API_VERSION_3_4 ||
+                        deviceVersion == CAMERA_DEVICE_API_VERSION_3_5) {
                     ASSERT_TRUE(sessionV3_4.get() != nullptr);
                 } else if (deviceVersion == CAMERA_DEVICE_API_VERSION_3_3) {
                     ASSERT_TRUE(sessionV3_3.get() != nullptr);
@@ -2401,6 +2418,7 @@
     for (const auto& name : cameraDeviceNames) {
         int deviceVersion = getCameraDeviceVersion(name, mProviderType);
         switch (deviceVersion) {
+            case CAMERA_DEVICE_API_VERSION_3_5:
             case CAMERA_DEVICE_API_VERSION_3_4:
             case CAMERA_DEVICE_API_VERSION_3_3:
             case CAMERA_DEVICE_API_VERSION_3_2: {
@@ -4144,7 +4162,7 @@
 }
 
 // Check if the camera device has logical multi-camera capability.
-Status CameraHidlTest::isLogicalMultiCamera(camera_metadata_t *staticMeta) {
+Status CameraHidlTest::isLogicalMultiCamera(const camera_metadata_t *staticMeta) {
     Status ret = Status::METHOD_NOT_SUPPORTED;
     if (nullptr == staticMeta) {
         return Status::ILLEGAL_ARGUMENT;
@@ -4168,7 +4186,7 @@
 }
 
 // Generate a list of physical camera ids backing a logical multi-camera.
-Status CameraHidlTest::getPhysicalCameraIds(camera_metadata_t *staticMeta,
+Status CameraHidlTest::getPhysicalCameraIds(const camera_metadata_t *staticMeta,
         std::unordered_set<std::string> *physicalIds) {
     if ((nullptr == staticMeta) || (nullptr == physicalIds)) {
         return Status::ILLEGAL_ARGUMENT;
@@ -4641,6 +4659,7 @@
     ASSERT_NE(nullptr, session3_4);
 
     switch (deviceVersion) {
+        case CAMERA_DEVICE_API_VERSION_3_5:
         case CAMERA_DEVICE_API_VERSION_3_4: {
             auto castResult = device::V3_4::ICameraDeviceSession::castFrom(session);
             ASSERT_TRUE(castResult.isOk());
@@ -4659,6 +4678,101 @@
     }
 }
 
+// Verify logical camera static metadata
+void CameraHidlTest::verifyLogicalCameraMetadata(const std::string& cameraName,
+        const ::android::sp<::android::hardware::camera::device::V3_2::ICameraDevice>& device,
+        const CameraMetadata &chars, int deviceVersion,
+        const hidl_vec<hidl_string>& deviceNames) {
+    const camera_metadata_t* metadata = (camera_metadata_t*)chars.data();
+    ASSERT_NE(nullptr, metadata);
+
+    Status rc = isLogicalMultiCamera(metadata);
+    ASSERT_TRUE(Status::OK == rc || Status::METHOD_NOT_SUPPORTED == rc);
+    if (Status::METHOD_NOT_SUPPORTED == rc) {
+        return;
+    }
+
+    std::string version, cameraId;
+    ASSERT_TRUE(::matchDeviceName(cameraName, mProviderType, &version, &cameraId));
+    std::unordered_set<std::string> physicalIds;
+    ASSERT_TRUE(Status::OK == getPhysicalCameraIds(metadata, &physicalIds));
+    for (auto physicalId : physicalIds) {
+        ASSERT_NE(physicalId, cameraId);
+        bool isPublicId = false;
+        for (auto& deviceName : deviceNames) {
+            std::string publicVersion, publicId;
+            ASSERT_TRUE(::matchDeviceName(deviceName, mProviderType, &publicVersion, &publicId));
+            if (physicalId == publicId) {
+                isPublicId = true;
+                break;
+            }
+        }
+        if (isPublicId) {
+            continue;
+        }
+
+        ASSERT_TRUE(deviceVersion >= CAMERA_DEVICE_API_VERSION_3_5);
+        auto castResult = device::V3_5::ICameraDevice::castFrom(device);
+        ASSERT_TRUE(castResult.isOk());
+        ::android::sp<::android::hardware::camera::device::V3_5::ICameraDevice> device3_5 =
+                castResult;
+        ASSERT_NE(device3_5, nullptr);
+
+        // Check camera characteristics for hidden camera id
+        Return<void> ret = device3_5->getPhysicalCameraCharacteristics(physicalId,
+                [&](auto status, const auto& chars) {
+            verifyCameraCharacteristics(status, chars);
+        });
+        ASSERT_TRUE(ret.isOk());
+
+        // Check calling getCameraDeviceInterface_V3_x() on hidden camera id returns
+        // ILLEGAL_ARGUMENT.
+        std::stringstream s;
+        s << "device@" << version << "/" << mProviderType << "/" << physicalId;
+        hidl_string fullPhysicalId(s.str());
+        ret = mProvider->getCameraDeviceInterface_V3_x(fullPhysicalId,
+                [&](auto status, const auto& device3_x) {
+            ASSERT_EQ(Status::ILLEGAL_ARGUMENT, status);
+            ASSERT_EQ(device3_x, nullptr);
+        });
+        ASSERT_TRUE(ret.isOk());
+    }
+}
+
+void CameraHidlTest::verifyCameraCharacteristics(Status status, const CameraMetadata& chars) {
+    ASSERT_EQ(Status::OK, status);
+    const camera_metadata_t* metadata = (camera_metadata_t*)chars.data();
+    size_t expectedSize = chars.size();
+    int result = validate_camera_metadata_structure(metadata, &expectedSize);
+    ASSERT_TRUE((result == 0) || (result == CAMERA_METADATA_VALIDATION_SHIFTED));
+    size_t entryCount = get_camera_metadata_entry_count(metadata);
+    // TODO: we can do better than 0 here. Need to check how many required
+    // characteristics keys we've defined.
+    ASSERT_GT(entryCount, 0u);
+
+    camera_metadata_ro_entry entry;
+    int retcode = find_camera_metadata_ro_entry(metadata,
+            ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL, &entry);
+    if ((0 == retcode) && (entry.count > 0)) {
+        uint8_t hardwareLevel = entry.data.u8[0];
+        ASSERT_TRUE(
+                hardwareLevel == ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED ||
+                hardwareLevel == ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL_FULL ||
+                hardwareLevel == ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL_3 ||
+                hardwareLevel == ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL_EXTERNAL);
+    } else {
+        ADD_FAILURE() << "Get camera hardware level failed!";
+    }
+
+    entry.count = 0;
+    retcode = find_camera_metadata_ro_entry(metadata,
+            ANDROID_REQUEST_CHARACTERISTIC_KEYS_NEEDING_PERMISSION, &entry);
+    if ((0 == retcode) || (entry.count > 0)) {
+        ADD_FAILURE() << "ANDROID_REQUEST_CHARACTERISTIC_KEYS_NEEDING_PERMISSION "
+            << " per API contract should never be set by Hal!";
+    }
+}
+
 // Open a device session with empty callbacks and return static metadata.
 void CameraHidlTest::openEmptyDeviceSession(const std::string &name,
         sp<ICameraProvider> provider,
diff --git a/current.txt b/current.txt
index edaed0f..4709ab3 100644
--- a/current.txt
+++ b/current.txt
@@ -385,6 +385,9 @@
 10ff2fae516346b86121368ce5790d5accdfcb73983246b813f3d488b66db45a android.hardware.wifi.supplicant@1.1::ISupplicantStaNetwork
 
 # ABI preserving changes to HALs during Android Q
+2a55e224aa9bc62c0387cd85ad3c97e33f0c33a4e1489cbae86b2523e6f9df35 android.hardware.camera.device@3.2::ICameraDevice
+f61b616732d8f374e030f90575d7eba3ecc99d209a05b945949ba892bcb81e1d android.hardware.camera.device@3.2::ICameraDeviceSession
+684702a60deef03a1e8093961dc0a18c555c857ad5a77ba7340b0635ae01eb70 android.hardware.camera.device@3.4::ICameraDeviceSession
 a95745bbf76aea16a76518bd7efe70cabc5886d09eaeffc993c2e1787a22ed23 android.hardware.camera.metadata@3.3::types
 da33234403ff5d60f3473711917b9948e6484a4260b5247acdafb111193a9de2 android.hardware.configstore@1.0::ISurfaceFlingerConfigs
 b7ecf29927055ec422ec44bf776223f07d79ad9f92ccf9becf167e62c2607e7a android.hardware.keymaster@4.0::IKeymasterDevice
diff --git a/fastboot/1.0/IFastboot.hal b/fastboot/1.0/IFastboot.hal
index c5979d9..dce3ad7 100644
--- a/fastboot/1.0/IFastboot.hal
+++ b/fastboot/1.0/IFastboot.hal
@@ -34,7 +34,7 @@
      * Executes a fastboot OEM command.
      *
      * @param oemCmdArgs The oem command that is passed to the fastboot HAL.
-     * @response result Returns the status SUCCESS if the operation is successful,
+     * @return result Returns the status SUCCESS if the operation is successful,
      *     INVALID_ARGUMENT for bad arguments,
      *     FAILURE_UNKNOWN for an invalid/unsupported command.
      */
@@ -44,10 +44,29 @@
      * Returns an OEM-defined string indicating the variant of the device, for
      * example, US and ROW.
      *
-     * @response variant Indicates the device variant.
-     * @response result Returns the status SUCCESS if the operation is successful,
+     * @return variant Indicates the device variant.
+     * @return result Returns the status SUCCESS if the operation is successful,
      *     FAILURE_UNKNOWN otherwise.
      */
     getVariant() generates (string variant, Result result);
 
+    /**
+     * Returns whether off-mode-charging is enabled. If enabled, the device
+     * autoboots into a special mode when power is applied.
+     *
+     * @return state Returns whether off mode charging is enabled.
+     * @return result Returns the status SUCCESS if the operation is successful,
+     *     FAILURE_UNKNOWN otherwise.
+     */
+    getOffModeChargeState() generates (bool state, Result result);
+
+    /**
+     * Returns the minimum battery voltage required for flashing in mV.
+     *
+     * @return batteryVoltage Minimum batterery voltage (in mV) required for
+     *     flashing to be successful.
+     * @return result Returns the status SUCCESS if the operation is successful,
+     *     FAILURE_UNKNOWN otherwise.
+     */
+    getBatteryVoltageFlashingThreshold() generates (int32_t batteryVoltage, Result result);
 };
diff --git a/gnss/1.1/vts/functional/gnss_hal_test_cases.cpp b/gnss/1.1/vts/functional/gnss_hal_test_cases.cpp
index c9f840e..2d901f3 100644
--- a/gnss/1.1/vts/functional/gnss_hal_test_cases.cpp
+++ b/gnss/1.1/vts/functional/gnss_hal_test_cases.cpp
@@ -119,6 +119,11 @@
     struct ComparableBlacklistedSource {
         IGnssConfiguration::BlacklistedSource id;
 
+        ComparableBlacklistedSource() {
+            id.constellation = GnssConstellationType::UNKNOWN;
+            id.svid = 0;
+        }
+
         bool operator<(const ComparableBlacklistedSource& compare) const {
             return ((id.svid < compare.id.svid) || ((id.svid == compare.id.svid) &&
                                                     (id.constellation < compare.id.constellation)));
@@ -191,18 +196,21 @@
  * 3) Restart location, wait for 3 locations, ensuring they are valid, and checks corresponding
  * GnssStatus does not use those satellites.
  * 4a & b) Turns off location, and send in empty blacklist.
- * 5) Restart location, wait for 3 locations, ensuring they are valid, and checks corresponding
+ * 5a) Restart location, wait for 3 locations, ensuring they are valid, and checks corresponding
  * GnssStatus does re-use at least the previously strongest satellite
+ * 5b) Retry a few times, in case GNSS search strategy takes a while to reacquire even the
+ * formerly strongest satellite
  */
 TEST_F(GnssHalTest, BlacklistIndividualSatellites) {
     const int kLocationsToAwait = 3;
+    const int kRetriesToUnBlacklist = 10;
 
     StartAndCheckLocations(kLocationsToAwait);
 
     // Tolerate 1 less sv status to handle edge cases in reporting.
     EXPECT_GE((int)list_gnss_sv_status_.size() + 1, kLocationsToAwait);
-    ALOGD("Observed %d GnssSvStatus, while awaiting %d Locations", (int)list_gnss_sv_status_.size(),
-          kLocationsToAwait);
+    ALOGD("Observed %d GnssSvStatus, while awaiting %d Locations (%d received)",
+          (int)list_gnss_sv_status_.size(), kLocationsToAwait, location_called_count_);
 
     /*
      * Identify strongest SV seen at least kLocationsToAwait -1 times
@@ -237,13 +245,18 @@
     // retry and ensure satellite not used
     list_gnss_sv_status_.clear();
 
-    location_called_count_ = 0;
     StartAndCheckLocations(kLocationsToAwait);
 
+    // early exit if test is being run with insufficient signal
+    if (location_called_count_ == 0) {
+        ALOGE("0 Gnss locations received - ensure sufficient signal and retry");
+    }
+    ASSERT_TRUE(location_called_count_ > 0);
+
     // Tolerate 1 less sv status to handle edge cases in reporting.
     EXPECT_GE((int)list_gnss_sv_status_.size() + 1, kLocationsToAwait);
-    ALOGD("Observed %d GnssSvStatus, while awaiting %d Locations", (int)list_gnss_sv_status_.size(),
-          kLocationsToAwait);
+    ALOGD("Observed %d GnssSvStatus, while awaiting %d Locations (%d received)",
+          (int)list_gnss_sv_status_.size(), kLocationsToAwait, location_called_count_);
     for (const auto& gnss_sv_status : list_gnss_sv_status_) {
         for (uint32_t iSv = 0; iSv < gnss_sv_status.numSvs; iSv++) {
             const auto& gnss_sv = gnss_sv_status.gnssSvList[iSv];
@@ -260,28 +273,40 @@
     ASSERT_TRUE(result.isOk());
     EXPECT_TRUE(result);
 
-    StopAndClearLocations();
-    list_gnss_sv_status_.clear();
-
-    StartAndCheckLocations(kLocationsToAwait);
-
-    // Tolerate 1 less sv status to handle edge cases in reporting.
-    EXPECT_GE((int)list_gnss_sv_status_.size() + 1, kLocationsToAwait);
-    ALOGD("Observed %d GnssSvStatus, while awaiting %d Locations", (int)list_gnss_sv_status_.size(),
-          kLocationsToAwait);
-
     bool strongest_sv_is_reobserved = false;
-    for (const auto& gnss_sv_status : list_gnss_sv_status_) {
-        for (uint32_t iSv = 0; iSv < gnss_sv_status.numSvs; iSv++) {
-            const auto& gnss_sv = gnss_sv_status.gnssSvList[iSv];
-            if ((gnss_sv.svid == source_to_blacklist.svid) &&
-                (gnss_sv.constellation == source_to_blacklist.constellation) &&
-                (gnss_sv.svFlag & IGnssCallback::GnssSvFlags::USED_IN_FIX)) {
-                strongest_sv_is_reobserved = true;
-                break;
-            }
+    // do several loops awaiting a few locations, allowing non-immediate reacquisition strategies
+    int unblacklist_loops_remaining = kRetriesToUnBlacklist;
+    while (!strongest_sv_is_reobserved && (unblacklist_loops_remaining-- > 0)) {
+        StopAndClearLocations();
+        list_gnss_sv_status_.clear();
+
+        StartAndCheckLocations(kLocationsToAwait);
+
+        // early exit loop if test is being run with insufficient signal
+        if (location_called_count_ == 0) {
+            ALOGE("0 Gnss locations received - ensure sufficient signal and retry");
         }
-        if (strongest_sv_is_reobserved) break;
+        ASSERT_TRUE(location_called_count_ > 0);
+
+        // Tolerate 1 less sv status to handle edge cases in reporting.
+        EXPECT_GE((int)list_gnss_sv_status_.size() + 1, kLocationsToAwait);
+        ALOGD(
+            "Clear blacklist, observed %d GnssSvStatus, while awaiting %d Locations"
+            ", tries remaining %d",
+            (int)list_gnss_sv_status_.size(), kLocationsToAwait, unblacklist_loops_remaining);
+
+        for (const auto& gnss_sv_status : list_gnss_sv_status_) {
+            for (uint32_t iSv = 0; iSv < gnss_sv_status.numSvs; iSv++) {
+                const auto& gnss_sv = gnss_sv_status.gnssSvList[iSv];
+                if ((gnss_sv.svid == source_to_blacklist.svid) &&
+                    (gnss_sv.constellation == source_to_blacklist.constellation) &&
+                    (gnss_sv.svFlag & IGnssCallback::GnssSvFlags::USED_IN_FIX)) {
+                    strongest_sv_is_reobserved = true;
+                    break;
+                }
+            }
+            if (strongest_sv_is_reobserved) break;
+        }
     }
     EXPECT_TRUE(strongest_sv_is_reobserved);
     StopAndClearLocations();
@@ -304,8 +329,8 @@
 
     // Tolerate 1 less sv status to handle edge cases in reporting.
     EXPECT_GE((int)list_gnss_sv_status_.size() + 1, kLocationsToAwait);
-    ALOGD("Observed %d GnssSvStatus, while awaiting %d Locations", (int)list_gnss_sv_status_.size(),
-          kLocationsToAwait);
+    ALOGD("Observed %d GnssSvStatus, while awaiting %d Locations (%d received)",
+          (int)list_gnss_sv_status_.size(), kLocationsToAwait, location_called_count_);
 
     // Find first non-GPS constellation to blacklist
     GnssConstellationType constellation_to_blacklist = GnssConstellationType::UNKNOWN;
diff --git a/graphics/composer/2.2/vts/functional/VtsHalGraphicsComposerV2_2ReadbackTest.cpp b/graphics/composer/2.2/vts/functional/VtsHalGraphicsComposerV2_2ReadbackTest.cpp
index 91318bc..da8858e 100644
--- a/graphics/composer/2.2/vts/functional/VtsHalGraphicsComposerV2_2ReadbackTest.cpp
+++ b/graphics/composer/2.2/vts/functional/VtsHalGraphicsComposerV2_2ReadbackTest.cpp
@@ -44,6 +44,12 @@
 using V2_1::Layer;
 using V2_1::vts::TestCommandReader;
 
+static const IComposerClient::Color BLACK = {0, 0, 0, 0xff};
+static const IComposerClient::Color RED = {0xff, 0, 0, 0xff};
+static const IComposerClient::Color TRANSLUCENT_RED = {0xff, 0, 0, 0x33};
+static const IComposerClient::Color GREEN = {0, 0xff, 0, 0xff};
+static const IComposerClient::Color BLUE = {0, 0, 0xff, 0xff};
+
 // Test environment for graphics.composer
 class GraphicsComposerHidlEnvironment : public ::testing::VtsHalHidlTargetTestEnvBase {
    public:
@@ -61,106 +67,57 @@
 
 class TestLayer {
    public:
-    TestLayer(std::shared_ptr<ComposerClient> const client, Display display)
-        : mLayer(client->createLayer(display, kBufferSlotCount)),
-          mComposerClient(client),
-          mDisplay(display) {}
+    TestLayer(const std::shared_ptr<ComposerClient>& client, Display display)
+        : mLayer(client->createLayer(display, kBufferSlotCount)), mComposerClient(client) {}
 
-    virtual ~TestLayer() { mComposerClient->destroyLayer(mDisplay, mLayer); }
+    // ComposerClient will take care of destroying layers, no need to explicitly
+    // call destroyLayers here
+    virtual ~TestLayer(){};
 
-    virtual void write(std::shared_ptr<CommandWriterBase> writer) {
+    virtual void write(const std::shared_ptr<CommandWriterBase>& writer) {
         writer->selectLayer(mLayer);
         writer->setLayerDisplayFrame(mDisplayFrame);
+        writer->setLayerSourceCrop(mSourceCrop);
         writer->setLayerZOrder(mZOrder);
+        writer->setLayerSurfaceDamage(mSurfaceDamage);
+        writer->setLayerTransform(mTransform);
+        writer->setLayerPlaneAlpha(mAlpha);
+        writer->setLayerBlendMode(mBlendMode);
     }
 
     void setDisplayFrame(IComposerClient::Rect frame) { mDisplayFrame = frame; }
+    void setSourceCrop(IComposerClient::FRect crop) { mSourceCrop = crop; }
     void setZOrder(uint32_t z) { mZOrder = z; }
 
+    void setSurfaceDamage(std::vector<IComposerClient::Rect> surfaceDamage) {
+        mSurfaceDamage = surfaceDamage;
+    }
+
+    void setTransform(Transform transform) { mTransform = transform; }
+    void setAlpha(float alpha) { mAlpha = alpha; }
+    void setBlendMode(IComposerClient::BlendMode blendMode) { mBlendMode = blendMode; }
+
+    static constexpr uint32_t kBufferSlotCount = 64;
+
+    IComposerClient::Rect mDisplayFrame = {0, 0, 0, 0};
+    uint32_t mZOrder = 0;
+    std::vector<IComposerClient::Rect> mSurfaceDamage;
+    Transform mTransform = static_cast<Transform>(0);
+    IComposerClient::FRect mSourceCrop = {0, 0, 0, 0};
+    float mAlpha = 1.0;
+    IComposerClient::BlendMode mBlendMode = IComposerClient::BlendMode::NONE;
+
    protected:
     Layer mLayer;
-    IComposerClient::Rect mDisplayFrame = {0, 0, 0, 0};
-    uint32_t mZOrder = 0;
 
    private:
     std::shared_ptr<ComposerClient> const mComposerClient;
-    const Display mDisplay;
-    static constexpr uint32_t kBufferSlotCount = 64;
-};
-
-class TestColorLayer : public TestLayer {
-   public:
-    TestColorLayer(std::shared_ptr<ComposerClient> const client, Display display)
-        : TestLayer{client, display} {}
-
-    void write(std::shared_ptr<CommandWriterBase> writer) override {
-        TestLayer::write(writer);
-        writer->setLayerCompositionType(IComposerClient::Composition::SOLID_COLOR);
-        writer->setLayerColor(mColor);
-    }
-
-    void setColor(IComposerClient::Color color) { mColor = color; }
-
-   private:
-    IComposerClient::Color mColor = {0xff, 0xff, 0xff, 0xff};
 };
 
 class GraphicsComposerReadbackTest : public ::testing::VtsHalHidlTargetTestBase {
-   protected:
-    using PowerMode = V2_1::IComposerClient::PowerMode;
-    void SetUp() override {
-        ASSERT_NO_FATAL_FAILURE(
-            mComposer = std::make_unique<Composer>(
-                GraphicsComposerHidlEnvironment::Instance()->getServiceName<IComposer>()));
-        ASSERT_NO_FATAL_FAILURE(mComposerClient = mComposer->createClient());
-        mComposerCallback = new V2_1::vts::GraphicsComposerCallback;
-        mComposerClient->registerCallback(mComposerCallback);
-
-        // assume the first display is primary and is never removed
-        mPrimaryDisplay = waitForFirstDisplay();
-        Config activeConfig = mComposerClient->getActiveConfig(mPrimaryDisplay);
-        mDisplayWidth = mComposerClient->getDisplayAttribute(mPrimaryDisplay, activeConfig,
-                                                             IComposerClient::Attribute::WIDTH);
-        mDisplayHeight = mComposerClient->getDisplayAttribute(mPrimaryDisplay, activeConfig,
-                                                              IComposerClient::Attribute::HEIGHT);
-
-        // explicitly disable vsync
-        mComposerClient->setVsyncEnabled(mPrimaryDisplay, false);
-        mComposerCallback->setVsyncAllowed(false);
-
-        // set up command writer/reader and gralloc
-        mWriter = std::make_shared<CommandWriterBase>(1024);
-        mReader = std::make_unique<TestCommandReader>();
-        mGralloc = std::make_unique<Gralloc>();
-
-        mComposerClient->getRaw()->getReadbackBufferAttributes(
-            mPrimaryDisplay, [&](const auto& tmpError, const auto&, const auto&) {
-                mHasReadbackBuffer = tmpError == Error::NONE;
-            });
-    }
-
-    ~GraphicsComposerReadbackTest() override {
-        if (mComposerCallback != nullptr) {
-            EXPECT_EQ(0, mComposerCallback->getInvalidHotplugCount());
-            EXPECT_EQ(0, mComposerCallback->getInvalidRefreshCount());
-            EXPECT_EQ(0, mComposerCallback->getInvalidVsyncCount());
-        }
-    }
-
-    void execute() { mComposerClient->execute(mReader.get(), mWriter.get()); }
-
-    void render(const std::vector<std::shared_ptr<TestLayer>>& layers) {
-        for (auto layer : layers) {
-            layer->write(mWriter);
-        }
-        execute();
-        mWriter->validateDisplay();
-        mWriter->presentDisplay();
-        execute();
-    }
-
-    int32_t GetBytesPerPixel(PixelFormat format) {
-        switch (format) {
+   public:
+    static int32_t GetBytesPerPixel(PixelFormat pixelFormat) {
+        switch (pixelFormat) {
             case PixelFormat::RGBA_8888:
                 return 4;
             case PixelFormat::RGB_888:
@@ -170,9 +127,122 @@
         }
     }
 
+    static void fillBuffer(int32_t width, int32_t height, uint32_t stride, void* bufferData,
+                           PixelFormat pixelFormat,
+                           std::vector<IComposerClient::Color> desiredPixelColors) {
+        ASSERT_TRUE(pixelFormat == PixelFormat::RGB_888 || pixelFormat == PixelFormat::RGBA_8888);
+        int32_t bytesPerPixel = GetBytesPerPixel(pixelFormat);
+        ASSERT_NE(-1, bytesPerPixel);
+        for (int row = 0; row < height; row++) {
+            for (int col = 0; col < width; col++) {
+                int pixel = row * width + col;
+                IComposerClient::Color srcColor = desiredPixelColors[pixel];
+
+                int offset = (row * stride + col) * bytesPerPixel;
+                uint8_t* pixelColor = (uint8_t*)bufferData + offset;
+                pixelColor[0] = srcColor.r;
+                pixelColor[1] = srcColor.g;
+                pixelColor[2] = srcColor.b;
+
+                if (bytesPerPixel == 4) {
+                    pixelColor[3] = srcColor.a;
+                }
+            }
+        }
+    }
+
+   protected:
+    using PowerMode = V2_1::IComposerClient::PowerMode;
+    void SetUp() override {
+        VtsHalHidlTargetTestBase::SetUp();
+        ASSERT_NO_FATAL_FAILURE(
+            mComposer = std::make_unique<Composer>(
+                GraphicsComposerHidlEnvironment::Instance()->getServiceName<IComposer>()));
+        ASSERT_NO_FATAL_FAILURE(mComposerClient = mComposer->createClient());
+        mComposerCallback = new V2_1::vts::GraphicsComposerCallback;
+        mComposerClient->registerCallback(mComposerCallback);
+
+        // assume the first display is primary and is never removed
+        mPrimaryDisplay = waitForFirstDisplay();
+        Config activeConfig;
+        ASSERT_NO_FATAL_FAILURE(activeConfig = mComposerClient->getActiveConfig(mPrimaryDisplay));
+        ASSERT_NO_FATAL_FAILURE(
+            mDisplayWidth = mComposerClient->getDisplayAttribute(
+                mPrimaryDisplay, activeConfig, IComposerClient::Attribute::WIDTH));
+        ASSERT_NO_FATAL_FAILURE(
+            mDisplayHeight = mComposerClient->getDisplayAttribute(
+                mPrimaryDisplay, activeConfig, IComposerClient::Attribute::HEIGHT));
+
+        // explicitly disable vsync
+        ASSERT_NO_FATAL_FAILURE(mComposerClient->setVsyncEnabled(mPrimaryDisplay, false));
+        mComposerCallback->setVsyncAllowed(false);
+
+        // set up command writer/reader and gralloc
+        mWriter = std::make_shared<CommandWriterBase>(1024);
+        mReader = std::make_unique<TestCommandReader>();
+        mGralloc = std::make_shared<Gralloc>();
+
+        mComposerClient->getRaw()->getReadbackBufferAttributes(
+            mPrimaryDisplay,
+            [&](const auto& tmpError, const auto& tmpPixelFormat, const auto& tmpDataspace) {
+                mHasReadbackBuffer = readbackSupported(tmpPixelFormat, tmpDataspace, tmpError);
+                mPixelFormat = tmpPixelFormat;
+                mDataspace = tmpDataspace;
+            });
+        ASSERT_NO_FATAL_FAILURE(mComposerClient->setPowerMode(mPrimaryDisplay, PowerMode::ON));
+    }
+
+    void TearDown() override {
+        ASSERT_NO_FATAL_FAILURE(mComposerClient->setPowerMode(mPrimaryDisplay, PowerMode::OFF));
+        EXPECT_EQ(0, mReader->mErrors.size());
+        EXPECT_EQ(0, mReader->mCompositionChanges.size());
+        if (mComposerCallback != nullptr) {
+            EXPECT_EQ(0, mComposerCallback->getInvalidHotplugCount());
+            EXPECT_EQ(0, mComposerCallback->getInvalidRefreshCount());
+            EXPECT_EQ(0, mComposerCallback->getInvalidVsyncCount());
+        }
+        VtsHalHidlTargetTestBase::TearDown();
+    }
+
+    void clearCommandReaderState() {
+        mReader->mCompositionChanges.clear();
+        mReader->mErrors.clear();
+    }
+
+    void execute() {
+        ASSERT_NO_FATAL_FAILURE(mComposerClient->execute(mReader.get(), mWriter.get()));
+    }
+
+    void writeLayers(const std::vector<std::shared_ptr<TestLayer>>& layers) {
+        for (auto layer : layers) {
+            layer->write(mWriter);
+        }
+        execute();
+    }
+
+    void clearColors(std::vector<IComposerClient::Color>& expectedColors, int32_t width,
+                     int32_t height) {
+        for (int row = 0; row < height; row++) {
+            for (int col = 0; col < width; col++) {
+                int pixel = row * mDisplayWidth + col;
+                expectedColors[pixel] = BLACK;
+            }
+        }
+    }
+
+    void fillColorsArea(std::vector<IComposerClient::Color>& expectedColors, int32_t stride,
+                        IComposerClient::Rect area, IComposerClient::Color color) {
+        for (int row = area.top; row < area.bottom; row++) {
+            for (int col = area.left; col < area.right; col++) {
+                int pixel = row * stride + col;
+                expectedColors[pixel] = color;
+            }
+        }
+    }
+
     bool readbackSupported(const PixelFormat& pixelFormat, const Dataspace& dataspace,
                            const Error error) {
-        if (error == Error::UNSUPPORTED) {
+        if (error != Error::NONE) {
             return false;
         }
         // TODO: add support for RGBA_1010102
@@ -185,33 +255,6 @@
         return true;
     }
 
-    void getReadbackBufferAttributes(Display display, PixelFormat* outPixelFormat,
-                                     Dataspace* outDataspace) {
-        mComposerClient->getRaw()->getReadbackBufferAttributes(
-            display, [&](const auto&, const auto& tmpOutPixelFormat, const auto& tmpOutDataspace) {
-                *outPixelFormat = tmpOutPixelFormat;
-                *outDataspace = tmpOutDataspace;
-            });
-    }
-
-    void checkReadbackBuffer(IMapper::BufferDescriptorInfo info, uint32_t stride, void* bufferData,
-                             std::vector<IComposerClient::Color> expectedColors) {
-        int32_t bytesPerPixel = GetBytesPerPixel(info.format);
-        ASSERT_NE(-1, bytesPerPixel)
-            << "unexpected pixel format " << static_cast<int32_t>(info.format)
-            << "(expected RGBA_8888 or RGB_888)";
-        for (int row = 0; row < mDisplayHeight; row++) {
-            for (int col = 0; col < mDisplayWidth; col++) {
-                int pixel = row * mDisplayWidth + col;
-                int offset = (row * stride + col) * bytesPerPixel;
-                uint8_t* pixelColor = (uint8_t*)bufferData + offset;
-
-                EXPECT_EQ(expectedColors[pixel].r, pixelColor[0]);
-                EXPECT_EQ(expectedColors[pixel].g, pixelColor[1]);
-                EXPECT_EQ(expectedColors[pixel].b, pixelColor[2]);
-            }
-        }
-    }
 
     std::unique_ptr<Composer> mComposer;
     std::shared_ptr<ComposerClient> mComposerClient;
@@ -223,9 +266,13 @@
     int32_t mDisplayHeight;
     std::shared_ptr<CommandWriterBase> mWriter;
     std::unique_ptr<TestCommandReader> mReader;
-    std::unique_ptr<Gralloc> mGralloc;
+    std::shared_ptr<Gralloc> mGralloc;
 
     bool mHasReadbackBuffer;
+    PixelFormat mPixelFormat;
+    Dataspace mDataspace;
+
+    static constexpr uint32_t kClientTargetSlotCount = 64;
 
    private:
     Display waitForFirstDisplay() {
@@ -239,6 +286,178 @@
         }
     }
 };
+class ReadbackBuffer {
+   public:
+    ReadbackBuffer(Display display, const std::shared_ptr<ComposerClient>& client,
+                   const std::shared_ptr<Gralloc>& gralloc, uint32_t width, uint32_t height,
+                   PixelFormat pixelFormat, Dataspace dataspace) {
+        mDisplay = display;
+
+        mComposerClient = client;
+        mGralloc = gralloc;
+
+        mPixelFormat = pixelFormat;
+        mDataspace = dataspace;
+
+        mInfo.width = width;
+        mInfo.height = height;
+        mInfo.layerCount = 1;
+        mInfo.format = mPixelFormat;
+        mInfo.usage = static_cast<uint64_t>(BufferUsage::CPU_READ_OFTEN | BufferUsage::GPU_TEXTURE);
+
+        mAccessRegion.top = 0;
+        mAccessRegion.left = 0;
+        mAccessRegion.width = width;
+        mAccessRegion.height = height;
+    };
+
+    ~ReadbackBuffer() {
+        if (mBufferHandle != nullptr) {
+            mGralloc->freeBuffer(mBufferHandle);
+        }
+    }
+
+    void setReadbackBuffer() {
+        if (mBufferHandle != nullptr) {
+            mGralloc->freeBuffer(mBufferHandle);
+            mBufferHandle = nullptr;
+        }
+        mBufferHandle = mGralloc->allocate(mInfo, /*import*/ true, &mStride);
+        ASSERT_NE(false, mGralloc->validateBufferSize(mBufferHandle, mInfo, mStride));
+        ASSERT_NO_FATAL_FAILURE(mComposerClient->setReadbackBuffer(mDisplay, mBufferHandle, -1));
+    }
+
+    void checkReadbackBuffer(std::vector<IComposerClient::Color> expectedColors) {
+        // lock buffer for reading
+        int32_t fenceHandle;
+        ASSERT_NO_FATAL_FAILURE(mComposerClient->getReadbackBufferFence(mDisplay, &fenceHandle));
+
+        void* bufData = mGralloc->lock(mBufferHandle, mInfo.usage, mAccessRegion, fenceHandle);
+        ASSERT_TRUE(mPixelFormat == PixelFormat::RGB_888 || mPixelFormat == PixelFormat::RGBA_8888);
+        int32_t bytesPerPixel = GraphicsComposerReadbackTest::GetBytesPerPixel(mPixelFormat);
+        ASSERT_NE(-1, bytesPerPixel);
+        for (int row = 0; row < mInfo.height; row++) {
+            for (int col = 0; col < mInfo.width; col++) {
+                int pixel = row * mInfo.width + col;
+                int offset = (row * mStride + col) * bytesPerPixel;
+                uint8_t* pixelColor = (uint8_t*)bufData + offset;
+
+                ASSERT_EQ(expectedColors[pixel].r, pixelColor[0]);
+                ASSERT_EQ(expectedColors[pixel].g, pixelColor[1]);
+                ASSERT_EQ(expectedColors[pixel].b, pixelColor[2]);
+            }
+        }
+        int32_t unlockFence = mGralloc->unlock(mBufferHandle);
+        if (unlockFence != -1) {
+            sync_wait(unlockFence, -1);
+            close(unlockFence);
+        }
+    }
+
+   protected:
+    IMapper::BufferDescriptorInfo mInfo;
+    IMapper::Rect mAccessRegion;
+    uint32_t mStride;
+    const native_handle_t* mBufferHandle = nullptr;
+    PixelFormat mPixelFormat;
+    Dataspace mDataspace;
+    Display mDisplay;
+    std::shared_ptr<Gralloc> mGralloc;
+    std::shared_ptr<ComposerClient> mComposerClient;
+};
+
+class TestColorLayer : public TestLayer {
+   public:
+    TestColorLayer(const std::shared_ptr<ComposerClient>& client, Display display)
+        : TestLayer{client, display} {}
+
+    void write(const std::shared_ptr<CommandWriterBase>& writer) override {
+        TestLayer::write(writer);
+        writer->setLayerCompositionType(IComposerClient::Composition::SOLID_COLOR);
+        writer->setLayerColor(mColor);
+    }
+
+    void setColor(IComposerClient::Color color) { mColor = color; }
+
+   private:
+    IComposerClient::Color mColor = {0xff, 0xff, 0xff, 0xff};
+};
+
+class TestBufferLayer : public TestLayer {
+   public:
+    TestBufferLayer(const std::shared_ptr<ComposerClient>& client,
+                    const std::shared_ptr<Gralloc>& gralloc, Display display, int32_t width,
+                    int32_t height, PixelFormat format,
+                    IComposerClient::Composition composition = IComposerClient::Composition::DEVICE)
+        : TestLayer{client, display} {
+        mGralloc = gralloc;
+        mComposition = composition;
+        mInfo.width = width;
+        mInfo.height = height;
+        mInfo.layerCount = 1;
+        mInfo.format = format;
+        mInfo.usage =
+            static_cast<uint64_t>(BufferUsage::CPU_READ_OFTEN | BufferUsage::CPU_WRITE_OFTEN |
+                                  BufferUsage::COMPOSER_OVERLAY);
+
+        mAccessRegion.top = 0;
+        mAccessRegion.left = 0;
+        mAccessRegion.width = width;
+        mAccessRegion.height = height;
+
+        setSourceCrop({0, 0, (float)width, (float)height});
+    }
+
+    ~TestBufferLayer() {
+        if (mBufferHandle != nullptr) {
+            mGralloc->freeBuffer(mBufferHandle);
+        }
+    }
+
+    void write(const std::shared_ptr<CommandWriterBase>& writer) override {
+        TestLayer::write(writer);
+        writer->setLayerCompositionType(mComposition);
+        writer->setLayerDataspace(Dataspace::UNKNOWN);
+        writer->setLayerVisibleRegion(std::vector<IComposerClient::Rect>(1, mDisplayFrame));
+        if (mBufferHandle != nullptr) writer->setLayerBuffer(0, mBufferHandle, mFillFence);
+    }
+
+    void fillBuffer(std::vector<IComposerClient::Color> expectedColors) {
+        void* bufData = mGralloc->lock(mBufferHandle, mInfo.usage, mAccessRegion, -1);
+        ASSERT_NO_FATAL_FAILURE(GraphicsComposerReadbackTest::fillBuffer(
+            mInfo.width, mInfo.height, mStride, bufData, mInfo.format, expectedColors));
+        mFillFence = mGralloc->unlock(mBufferHandle);
+        if (mFillFence != -1) {
+            sync_wait(mFillFence, -1);
+            close(mFillFence);
+        }
+    }
+    void setBuffer(std::vector<IComposerClient::Color> colors) {
+        if (mBufferHandle != nullptr) {
+            mGralloc->freeBuffer(mBufferHandle);
+            mBufferHandle = nullptr;
+        }
+        mBufferHandle = mGralloc->allocate(mInfo, /*import*/ true, &mStride);
+        ASSERT_NE(nullptr, mBufferHandle);
+        ASSERT_NO_FATAL_FAILURE(fillBuffer(colors));
+        ASSERT_NE(false, mGralloc->validateBufferSize(mBufferHandle, mInfo, mStride));
+    }
+
+    void setToClientComposition(const std::shared_ptr<CommandWriterBase>& writer) {
+        writer->selectLayer(mLayer);
+        writer->setLayerCompositionType(IComposerClient::Composition::CLIENT);
+    }
+
+    IMapper::BufferDescriptorInfo mInfo;
+    IMapper::Rect mAccessRegion;
+    uint32_t mStride;
+
+   protected:
+    IComposerClient::Composition mComposition;
+    std::shared_ptr<Gralloc> mGralloc;
+    int32_t mFillFence;
+    const native_handle_t* mBufferHandle = nullptr;
+};
 
 TEST_F(GraphicsComposerReadbackTest, SingleSolidColorLayer) {
     if (!mHasReadbackBuffer) {
@@ -246,13 +465,12 @@
         return;
     }
     mWriter->selectDisplay(mPrimaryDisplay);
-    mComposerClient->setPowerMode(mPrimaryDisplay, PowerMode::ON);
-    mComposerClient->setColorMode(mPrimaryDisplay, ColorMode::SRGB, RenderIntent::COLORIMETRIC);
+    ASSERT_NO_FATAL_FAILURE(mComposerClient->setColorMode(mPrimaryDisplay, ColorMode::SRGB,
+                                                          RenderIntent::COLORIMETRIC));
 
     auto layer = std::make_shared<TestColorLayer>(mComposerClient, mPrimaryDisplay);
-    IComposerClient::Color color({0, 0, 0xff, 0xff});
-    IComposerClient::Rect coloredSquare({100, 100, 500, 500});
-    layer->setColor(color);
+    IComposerClient::Rect coloredSquare({0, 0, mDisplayWidth, mDisplayHeight});
+    layer->setColor(BLUE);
     layer->setDisplayFrame(coloredSquare);
     layer->setZOrder(10);
 
@@ -260,58 +478,853 @@
 
     // expected color for each pixel
     std::vector<IComposerClient::Color> expectedColors(mDisplayWidth * mDisplayHeight);
-    for (int row = 0; row < mDisplayHeight; row++) {
-        for (int col = 0; col < mDisplayWidth; col++) {
-            int pixel = row * mDisplayWidth + col;
-            if (row >= coloredSquare.top && row < coloredSquare.bottom &&
-                col >= coloredSquare.left && col < coloredSquare.right) {
-                expectedColors[pixel] = color;
-            } else {
-                expectedColors[pixel] = {0, 0, 0, 0xff};
+    fillColorsArea(expectedColors, mDisplayWidth, coloredSquare, BLUE);
+
+    ReadbackBuffer readbackBuffer(mPrimaryDisplay, mComposerClient, mGralloc, mDisplayWidth,
+                                  mDisplayHeight, mPixelFormat, mDataspace);
+    ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
+
+    writeLayers(layers);
+    ASSERT_EQ(0, mReader->mErrors.size());
+    mWriter->validateDisplay();
+    execute();
+    // if hwc cannot handle and asks for composition change,
+    // just succeed the test
+    if (mReader->mCompositionChanges.size() != 0) {
+        clearCommandReaderState();
+        GTEST_SUCCEED();
+        return;
+    }
+    ASSERT_EQ(0, mReader->mErrors.size());
+    mWriter->presentDisplay();
+    execute();
+    ASSERT_EQ(0, mReader->mErrors.size());
+
+    ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
+}
+
+TEST_F(GraphicsComposerReadbackTest, SetLayerBuffer) {
+    if (!mHasReadbackBuffer) {
+        GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace";
+        return;
+    }
+
+    mWriter->selectDisplay(mPrimaryDisplay);
+
+    ReadbackBuffer readbackBuffer(mPrimaryDisplay, mComposerClient, mGralloc, mDisplayWidth,
+                                  mDisplayHeight, mPixelFormat, mDataspace);
+    ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
+    std::vector<IComposerClient::Color> expectedColors(mDisplayWidth * mDisplayHeight);
+    fillColorsArea(expectedColors, mDisplayWidth, {0, 0, mDisplayWidth, mDisplayHeight / 4}, RED);
+    fillColorsArea(expectedColors, mDisplayWidth,
+                   {0, mDisplayHeight / 4, mDisplayWidth, mDisplayHeight / 2}, GREEN);
+    fillColorsArea(expectedColors, mDisplayWidth,
+                   {0, mDisplayHeight / 2, mDisplayWidth, mDisplayHeight}, BLUE);
+
+    auto layer =
+        std::make_shared<TestBufferLayer>(mComposerClient, mGralloc, mPrimaryDisplay, mDisplayWidth,
+                                          mDisplayHeight, PixelFormat::RGBA_8888);
+    layer->setDisplayFrame({0, 0, mDisplayWidth, mDisplayHeight});
+    layer->setZOrder(10);
+    ASSERT_NO_FATAL_FAILURE(layer->setBuffer(expectedColors));
+
+    std::vector<std::shared_ptr<TestLayer>> layers = {layer};
+
+    writeLayers(layers);
+    ASSERT_EQ(0, mReader->mErrors.size());
+    mWriter->validateDisplay();
+    execute();
+
+    if (mReader->mCompositionChanges.size() != 0) {
+        clearCommandReaderState();
+        GTEST_SUCCEED();
+        return;
+    }
+    ASSERT_EQ(0, mReader->mErrors.size());
+
+    mWriter->presentDisplay();
+    execute();
+
+    ASSERT_EQ(0, mReader->mErrors.size());
+
+    ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
+}
+
+TEST_F(GraphicsComposerReadbackTest, SetLayerBufferNoEffect) {
+    if (!mHasReadbackBuffer) {
+        GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace";
+        return;
+    }
+
+    mWriter->selectDisplay(mPrimaryDisplay);
+    ASSERT_NO_FATAL_FAILURE(mComposerClient->setColorMode(mPrimaryDisplay, ColorMode::SRGB,
+                                                          RenderIntent::COLORIMETRIC));
+
+    auto layer = std::make_shared<TestColorLayer>(mComposerClient, mPrimaryDisplay);
+    IComposerClient::Rect coloredSquare({0, 0, mDisplayWidth, mDisplayHeight});
+    layer->setColor(BLUE);
+    layer->setDisplayFrame(coloredSquare);
+    layer->setZOrder(10);
+    layer->write(mWriter);
+
+    // This following buffer call should have no effect
+    IMapper::BufferDescriptorInfo bufferInfo{};
+    bufferInfo.width = mDisplayWidth;
+    bufferInfo.height = mDisplayHeight;
+    bufferInfo.layerCount = 1;
+    bufferInfo.format = PixelFormat::RGBA_8888;
+    bufferInfo.usage =
+        static_cast<uint64_t>(BufferUsage::CPU_READ_OFTEN | BufferUsage::CPU_WRITE_OFTEN);
+    const native_handle_t* bufferHandle = mGralloc->allocate(bufferInfo);
+    mWriter->setLayerBuffer(0, bufferHandle, -1);
+
+    // expected color for each pixel
+    std::vector<IComposerClient::Color> expectedColors(mDisplayWidth * mDisplayHeight);
+    fillColorsArea(expectedColors, mDisplayWidth, coloredSquare, BLUE);
+
+    ReadbackBuffer readbackBuffer(mPrimaryDisplay, mComposerClient, mGralloc, mDisplayWidth,
+                                  mDisplayHeight, mPixelFormat, mDataspace);
+    ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
+
+    mWriter->validateDisplay();
+    execute();
+
+    if (mReader->mCompositionChanges.size() != 0) {
+        clearCommandReaderState();
+        GTEST_SUCCEED();
+        return;
+    }
+    ASSERT_EQ(0, mReader->mErrors.size());
+    mWriter->presentDisplay();
+    execute();
+    ASSERT_EQ(0, mReader->mErrors.size());
+
+    ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
+}
+
+TEST_F(GraphicsComposerReadbackTest, ClientComposition) {
+    if (!mHasReadbackBuffer) {
+        GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace";
+        return;
+    }
+
+    mWriter->selectDisplay(mPrimaryDisplay);
+
+    std::vector<IComposerClient::Color> expectedColors(mDisplayWidth * mDisplayHeight);
+    fillColorsArea(expectedColors, mDisplayWidth, {0, 0, mDisplayWidth, mDisplayHeight / 4}, RED);
+    fillColorsArea(expectedColors, mDisplayWidth,
+                   {0, mDisplayHeight / 4, mDisplayWidth, mDisplayHeight / 2}, GREEN);
+    fillColorsArea(expectedColors, mDisplayWidth,
+                   {0, mDisplayHeight / 2, mDisplayWidth, mDisplayHeight}, BLUE);
+
+    auto layer =
+        std::make_shared<TestBufferLayer>(mComposerClient, mGralloc, mPrimaryDisplay, mDisplayWidth,
+                                          mDisplayHeight, PixelFormat::RGBA_FP16);
+    layer->setDisplayFrame({0, 0, mDisplayWidth, mDisplayHeight});
+    layer->setZOrder(10);
+
+    std::vector<std::shared_ptr<TestLayer>> layers = {layer};
+
+    ReadbackBuffer readbackBuffer(mPrimaryDisplay, mComposerClient, mGralloc, mDisplayWidth,
+                                  mDisplayHeight, mPixelFormat, mDataspace);
+    ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
+    writeLayers(layers);
+    ASSERT_EQ(0, mReader->mErrors.size());
+    mWriter->validateDisplay();
+    execute();
+
+    if (mReader->mCompositionChanges.size() != 0) {
+        ASSERT_EQ(1, mReader->mCompositionChanges.size());
+        ASSERT_EQ(1, mReader->mCompositionChanges[0].second);
+
+        ASSERT_NO_FATAL_FAILURE(
+            mComposerClient->setClientTargetSlotCount(mPrimaryDisplay, kClientTargetSlotCount));
+
+        // create client target buffer
+        uint32_t clientStride;
+        IMapper::BufferDescriptorInfo clientInfo;
+        clientInfo.width = layer->mInfo.width;
+        clientInfo.height = layer->mInfo.height;
+        clientInfo.layerCount = layer->mInfo.layerCount;
+        clientInfo.format = PixelFormat::RGBA_8888;
+        clientInfo.usage =
+            static_cast<uint64_t>(BufferUsage::CPU_READ_OFTEN | BufferUsage::CPU_WRITE_OFTEN |
+                                  BufferUsage::COMPOSER_CLIENT_TARGET);
+        const native_handle_t* clientBufferHandle =
+            mGralloc->allocate(clientInfo, /*import*/ true, &clientStride);
+        ASSERT_NE(nullptr, clientBufferHandle);
+
+        void* clientBufData =
+            mGralloc->lock(clientBufferHandle, clientInfo.usage, layer->mAccessRegion, -1);
+
+        ASSERT_NO_FATAL_FAILURE(fillBuffer(clientInfo.width, clientInfo.height, clientStride,
+                                           clientBufData, clientInfo.format, expectedColors));
+        int clientFence = mGralloc->unlock(clientBufferHandle);
+        if (clientFence != -1) {
+            sync_wait(clientFence, -1);
+            close(clientFence);
+        }
+
+        IComposerClient::Rect damage{0, 0, mDisplayWidth, mDisplayHeight};
+        mWriter->setClientTarget(0, clientBufferHandle, clientFence, Dataspace::UNKNOWN,
+                                 std::vector<IComposerClient::Rect>(1, damage));
+
+        layer->setToClientComposition(mWriter);
+        mWriter->validateDisplay();
+        execute();
+        ASSERT_EQ(0, mReader->mCompositionChanges.size());
+    }
+    ASSERT_EQ(0, mReader->mErrors.size());
+
+    mWriter->presentDisplay();
+    execute();
+
+    ASSERT_EQ(0, mReader->mErrors.size());
+
+    ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
+}
+
+TEST_F(GraphicsComposerReadbackTest, DeviceAndClientComposition) {
+    if (!mHasReadbackBuffer) {
+        GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace";
+        return;
+    }
+
+    mWriter->selectDisplay(mPrimaryDisplay);
+    ASSERT_NO_FATAL_FAILURE(
+        mComposerClient->setClientTargetSlotCount(mPrimaryDisplay, kClientTargetSlotCount));
+
+    std::vector<IComposerClient::Color> expectedColors(mDisplayWidth * mDisplayHeight);
+    fillColorsArea(expectedColors, mDisplayWidth, {0, 0, mDisplayWidth, mDisplayHeight / 2}, GREEN);
+    fillColorsArea(expectedColors, mDisplayWidth,
+                   {0, mDisplayHeight / 2, mDisplayWidth, mDisplayHeight}, RED);
+
+    ReadbackBuffer readbackBuffer(mPrimaryDisplay, mComposerClient, mGralloc, mDisplayWidth,
+                                  mDisplayHeight, mPixelFormat, mDataspace);
+    ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
+
+    auto deviceLayer =
+        std::make_shared<TestBufferLayer>(mComposerClient, mGralloc, mPrimaryDisplay, mDisplayWidth,
+                                          mDisplayHeight / 2, PixelFormat::RGBA_8888);
+    std::vector<IComposerClient::Color> deviceColors(deviceLayer->mInfo.width *
+                                                     deviceLayer->mInfo.height);
+    fillColorsArea(deviceColors, deviceLayer->mInfo.width,
+                   {0, 0, static_cast<int32_t>(deviceLayer->mInfo.width),
+                    static_cast<int32_t>(deviceLayer->mInfo.height)},
+                   GREEN);
+    deviceLayer->setDisplayFrame({0, 0, static_cast<int32_t>(deviceLayer->mInfo.width),
+                                  static_cast<int32_t>(deviceLayer->mInfo.height)});
+    deviceLayer->setZOrder(10);
+    ASSERT_NO_FATAL_FAILURE(deviceLayer->setBuffer(deviceColors));
+    deviceLayer->write(mWriter);
+
+    auto clientLayer = std::make_shared<TestBufferLayer>(
+        mComposerClient, mGralloc, mPrimaryDisplay, mDisplayWidth, mDisplayHeight / 2,
+        PixelFormat::RGBA_8888, IComposerClient::Composition::CLIENT);
+    IComposerClient::Rect clientFrame = {0, mDisplayHeight / 2, mDisplayWidth, mDisplayHeight};
+    clientLayer->setDisplayFrame(clientFrame);
+    clientLayer->setZOrder(0);
+    clientLayer->write(mWriter);
+    execute();
+    ASSERT_EQ(0, mReader->mErrors.size());
+
+    IMapper::BufferDescriptorInfo clientInfo;
+    clientInfo.width = mDisplayWidth;
+    clientInfo.height = mDisplayHeight;
+    clientInfo.layerCount = 1;
+    clientInfo.format = PixelFormat::RGBA_8888;
+    clientInfo.usage =
+        static_cast<uint64_t>(BufferUsage::CPU_READ_OFTEN | BufferUsage::CPU_WRITE_OFTEN |
+                              BufferUsage::COMPOSER_CLIENT_TARGET);
+
+    uint32_t clientStride;
+    const native_handle_t* clientBufferHandle =
+        mGralloc->allocate(clientInfo, /*import*/ true, &clientStride);
+    ASSERT_NE(nullptr, clientBufferHandle);
+
+    IMapper::Rect clientAccessRegion;
+    clientAccessRegion.left = 0;
+    clientAccessRegion.top = 0;
+    clientAccessRegion.width = mDisplayWidth;
+    clientAccessRegion.height = mDisplayHeight;
+    void* clientData = mGralloc->lock(clientBufferHandle, clientInfo.usage, clientAccessRegion, -1);
+    std::vector<IComposerClient::Color> clientColors(clientInfo.width * clientInfo.height);
+    fillColorsArea(clientColors, clientInfo.width, clientFrame, RED);
+    ASSERT_NO_FATAL_FAILURE(fillBuffer(clientInfo.width, clientInfo.height, clientStride,
+                                       clientData, clientInfo.format, clientColors));
+    int clientFence = mGralloc->unlock(clientBufferHandle);
+    if (clientFence != -1) {
+        sync_wait(clientFence, -1);
+        close(clientFence);
+    }
+
+    mWriter->setClientTarget(0, clientBufferHandle, clientFence, Dataspace::UNKNOWN,
+                             std::vector<IComposerClient::Rect>(1, clientFrame));
+    execute();
+    ASSERT_EQ(0, mReader->mErrors.size());
+    mWriter->validateDisplay();
+    execute();
+    if (mReader->mCompositionChanges.size() != 0) {
+        clearCommandReaderState();
+        GTEST_SUCCEED();
+        return;
+    }
+    ASSERT_EQ(0, mReader->mErrors.size());
+    mWriter->presentDisplay();
+    execute();
+    ASSERT_EQ(0, mReader->mErrors.size());
+    ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
+}
+
+TEST_F(GraphicsComposerReadbackTest, SetLayerDamage) {
+    if (!mHasReadbackBuffer) {
+        GTEST_SUCCEED() << "Readback not supported or unsupported pixelformat/dataspace";
+        return;
+    }
+
+    mWriter->selectDisplay(mPrimaryDisplay);
+
+    IComposerClient::Rect redRect = {0, 0, mDisplayWidth / 4, mDisplayHeight / 4};
+
+    std::vector<IComposerClient::Color> expectedColors(mDisplayWidth * mDisplayHeight);
+    fillColorsArea(expectedColors, mDisplayWidth, redRect, RED);
+
+    auto layer =
+        std::make_shared<TestBufferLayer>(mComposerClient, mGralloc, mPrimaryDisplay, mDisplayWidth,
+                                          mDisplayHeight, PixelFormat::RGBA_8888);
+    layer->setDisplayFrame({0, 0, mDisplayWidth, mDisplayHeight});
+    layer->setZOrder(10);
+    ASSERT_NO_FATAL_FAILURE(layer->setBuffer(expectedColors));
+
+    std::vector<std::shared_ptr<TestLayer>> layers = {layer};
+
+    ReadbackBuffer readbackBuffer(mPrimaryDisplay, mComposerClient, mGralloc, mDisplayWidth,
+                                  mDisplayHeight, mPixelFormat, mDataspace);
+    ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
+
+    writeLayers(layers);
+    ASSERT_EQ(0, mReader->mErrors.size());
+    mWriter->validateDisplay();
+    execute();
+    if (mReader->mCompositionChanges.size() != 0) {
+        clearCommandReaderState();
+        GTEST_SUCCEED();
+        return;
+    }
+    ASSERT_EQ(0, mReader->mErrors.size());
+    mWriter->presentDisplay();
+    execute();
+    ASSERT_EQ(0, mReader->mErrors.size());
+
+    ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
+
+    // update surface damage and recheck
+    redRect = {mDisplayWidth / 4, mDisplayHeight / 4, mDisplayWidth / 2, mDisplayHeight / 2};
+    clearColors(expectedColors, mDisplayWidth, mDisplayHeight);
+    fillColorsArea(expectedColors, mDisplayWidth, redRect, RED);
+
+    ASSERT_NO_FATAL_FAILURE(layer->fillBuffer(expectedColors));
+    layer->setSurfaceDamage(
+        std::vector<IComposerClient::Rect>(1, {0, 0, mDisplayWidth / 2, mDisplayWidth / 2}));
+
+    ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
+
+    writeLayers(layers);
+    ASSERT_EQ(0, mReader->mErrors.size());
+    mWriter->validateDisplay();
+    execute();
+    ASSERT_EQ(0, mReader->mErrors.size());
+    ASSERT_EQ(0, mReader->mCompositionChanges.size());
+    mWriter->presentDisplay();
+    execute();
+    ASSERT_EQ(0, mReader->mErrors.size());
+
+    ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
+}
+
+TEST_F(GraphicsComposerReadbackTest, SetLayerPlaneAlpha) {
+    if (!mHasReadbackBuffer) {
+        GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace";
+        return;
+    }
+
+    mWriter->selectDisplay(mPrimaryDisplay);
+    ASSERT_NO_FATAL_FAILURE(mComposerClient->setColorMode(mPrimaryDisplay, ColorMode::SRGB,
+                                                          RenderIntent::COLORIMETRIC));
+
+    auto layer = std::make_shared<TestColorLayer>(mComposerClient, mPrimaryDisplay);
+    layer->setColor(RED);
+    layer->setDisplayFrame({0, 0, mDisplayWidth, mDisplayHeight});
+    layer->setZOrder(10);
+    layer->setAlpha(0);
+    layer->setBlendMode(IComposerClient::BlendMode::PREMULTIPLIED);
+
+    std::vector<std::shared_ptr<TestLayer>> layers = {layer};
+
+    ReadbackBuffer readbackBuffer(mPrimaryDisplay, mComposerClient, mGralloc, mDisplayWidth,
+                                  mDisplayHeight, mPixelFormat, mDataspace);
+
+    ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
+
+    writeLayers(layers);
+    ASSERT_EQ(0, mReader->mErrors.size());
+    mWriter->validateDisplay();
+    execute();
+    if (mReader->mCompositionChanges.size() != 0) {
+        clearCommandReaderState();
+        GTEST_SUCCEED();
+        return;
+    }
+    ASSERT_EQ(0, mReader->mErrors.size());
+
+    mWriter->presentDisplay();
+    execute();
+    ASSERT_EQ(0, mReader->mErrors.size());
+
+    std::vector<IComposerClient::Color> expectedColors(mDisplayWidth * mDisplayHeight);
+
+    ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
+}
+
+TEST_F(GraphicsComposerReadbackTest, SetLayerSourceCrop) {
+    if (!mHasReadbackBuffer) {
+        GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace";
+        return;
+    }
+
+    mWriter->selectDisplay(mPrimaryDisplay);
+
+    std::vector<IComposerClient::Color> expectedColors(mDisplayWidth * mDisplayHeight);
+    fillColorsArea(expectedColors, mDisplayWidth, {0, 0, mDisplayWidth, mDisplayHeight / 4}, RED);
+    fillColorsArea(expectedColors, mDisplayWidth,
+                   {0, mDisplayHeight / 2, mDisplayWidth, mDisplayHeight}, BLUE);
+
+    auto layer =
+        std::make_shared<TestBufferLayer>(mComposerClient, mGralloc, mPrimaryDisplay, mDisplayWidth,
+                                          mDisplayHeight, PixelFormat::RGBA_8888);
+    layer->setDisplayFrame({0, 0, mDisplayWidth, mDisplayHeight});
+    layer->setZOrder(10);
+    layer->setSourceCrop({0, static_cast<float>(mDisplayHeight / 2),
+                          static_cast<float>(mDisplayWidth), static_cast<float>(mDisplayHeight)});
+    ASSERT_NO_FATAL_FAILURE(layer->setBuffer(expectedColors));
+
+    std::vector<std::shared_ptr<TestLayer>> layers = {layer};
+
+    // update expected colors to match crop
+    fillColorsArea(expectedColors, mDisplayWidth, {0, 0, mDisplayWidth, mDisplayHeight}, BLUE);
+    ReadbackBuffer readbackBuffer(mPrimaryDisplay, mComposerClient, mGralloc, mDisplayWidth,
+                                  mDisplayHeight, mPixelFormat, mDataspace);
+    ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
+    writeLayers(layers);
+    ASSERT_EQ(0, mReader->mErrors.size());
+    mWriter->validateDisplay();
+    execute();
+    if (mReader->mCompositionChanges.size() != 0) {
+        clearCommandReaderState();
+        GTEST_SUCCEED();
+        return;
+    }
+    ASSERT_EQ(0, mReader->mErrors.size());
+    mWriter->presentDisplay();
+    execute();
+    ASSERT_EQ(0, mReader->mErrors.size());
+    ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
+}
+
+TEST_F(GraphicsComposerReadbackTest, SetLayerZOrder) {
+    if (!mHasReadbackBuffer) {
+        GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace";
+        return;
+    }
+
+    mWriter->selectDisplay(mPrimaryDisplay);
+    ASSERT_NO_FATAL_FAILURE(mComposerClient->setColorMode(mPrimaryDisplay, ColorMode::SRGB,
+                                                          RenderIntent::COLORIMETRIC));
+
+    IComposerClient::Rect redRect = {0, 0, mDisplayWidth, mDisplayHeight / 2};
+    IComposerClient::Rect blueRect = {0, mDisplayHeight / 4, mDisplayWidth, mDisplayHeight};
+    auto redLayer = std::make_shared<TestColorLayer>(mComposerClient, mPrimaryDisplay);
+    redLayer->setColor(RED);
+    redLayer->setDisplayFrame(redRect);
+
+    auto blueLayer = std::make_shared<TestColorLayer>(mComposerClient, mPrimaryDisplay);
+    blueLayer->setColor(BLUE);
+    blueLayer->setDisplayFrame(blueRect);
+    blueLayer->setZOrder(5);
+
+    std::vector<std::shared_ptr<TestLayer>> layers = {redLayer, blueLayer};
+    std::vector<IComposerClient::Color> expectedColors(mDisplayWidth * mDisplayHeight);
+
+    // red in front of blue
+    redLayer->setZOrder(10);
+
+    // fill blue first so that red will overwrite on overlap
+    fillColorsArea(expectedColors, mDisplayWidth, blueRect, BLUE);
+    fillColorsArea(expectedColors, mDisplayWidth, redRect, RED);
+
+    ReadbackBuffer readbackBuffer(mPrimaryDisplay, mComposerClient, mGralloc, mDisplayWidth,
+                                  mDisplayHeight, mPixelFormat, mDataspace);
+    ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
+
+    writeLayers(layers);
+    ASSERT_EQ(0, mReader->mErrors.size());
+    mWriter->validateDisplay();
+    execute();
+    if (mReader->mCompositionChanges.size() != 0) {
+        clearCommandReaderState();
+        GTEST_SUCCEED();
+        return;
+    }
+    mWriter->presentDisplay();
+    execute();
+    ASSERT_EQ(0, mReader->mErrors.size());
+
+    ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
+
+    redLayer->setZOrder(1);
+    clearColors(expectedColors, mDisplayWidth, mDisplayHeight);
+    fillColorsArea(expectedColors, mDisplayWidth, redRect, RED);
+    fillColorsArea(expectedColors, mDisplayWidth, blueRect, BLUE);
+
+    ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
+
+    writeLayers(layers);
+    ASSERT_EQ(0, mReader->mErrors.size());
+    mWriter->validateDisplay();
+    execute();
+    ASSERT_EQ(0, mReader->mCompositionChanges.size());
+    ASSERT_EQ(0, mReader->mErrors.size());
+    mWriter->presentDisplay();
+    execute();
+    ASSERT_EQ(0, mReader->mErrors.size());
+
+    ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
+}
+
+class GraphicsComposerBlendModeReadbackTest : public GraphicsComposerReadbackTest,
+                                              public ::testing::WithParamInterface<float> {
+   public:
+    void SetUp() override {
+        GraphicsComposerReadbackTest::SetUp();
+        mBackgroundColor = BLACK;
+        mTopLayerColor = RED;
+    }
+
+    void TearDown() override { GraphicsComposerReadbackTest::TearDown(); }
+
+    void setBackgroundColor(IComposerClient::Color color) { mBackgroundColor = color; }
+
+    void setTopLayerColor(IComposerClient::Color color) { mTopLayerColor = color; }
+
+    void setUpLayers(IComposerClient::BlendMode blendMode) {
+        mLayers.clear();
+        std::vector<IComposerClient::Color> topLayerPixelColors(mDisplayWidth * mDisplayHeight);
+        fillColorsArea(topLayerPixelColors, mDisplayWidth, {0, 0, mDisplayWidth, mDisplayHeight},
+                       mTopLayerColor);
+
+        auto backgroundLayer = std::make_shared<TestColorLayer>(mComposerClient, mPrimaryDisplay);
+        backgroundLayer->setDisplayFrame({0, 0, mDisplayWidth, mDisplayHeight});
+        backgroundLayer->setZOrder(0);
+        backgroundLayer->setColor(mBackgroundColor);
+
+        auto layer = std::make_shared<TestBufferLayer>(mComposerClient, mGralloc, mPrimaryDisplay,
+                                                       mDisplayWidth, mDisplayHeight,
+                                                       PixelFormat::RGBA_8888);
+        layer->setDisplayFrame({0, 0, mDisplayWidth, mDisplayHeight});
+        layer->setZOrder(10);
+        ASSERT_NO_FATAL_FAILURE(layer->setBuffer(topLayerPixelColors));
+
+        layer->setBlendMode(blendMode);
+        layer->setAlpha(GetParam());
+
+        mLayers.push_back(backgroundLayer);
+        mLayers.push_back(layer);
+    }
+
+    void setExpectedColors(std::vector<IComposerClient::Color>& expectedColors) {
+        ASSERT_EQ(2, mLayers.size());
+        clearColors(expectedColors, mDisplayWidth, mDisplayHeight);
+
+        auto layer = mLayers[1];
+        IComposerClient::BlendMode blendMode = layer->mBlendMode;
+        float alpha = mTopLayerColor.a / 255.0 * layer->mAlpha;
+        if (blendMode == IComposerClient::BlendMode::NONE) {
+            for (int i = 0; i < expectedColors.size(); i++) {
+                expectedColors[i].r = mTopLayerColor.r * layer->mAlpha;
+                expectedColors[i].g = mTopLayerColor.g * layer->mAlpha;
+                expectedColors[i].b = mTopLayerColor.b * layer->mAlpha;
+                expectedColors[i].a = alpha * 255.0;
+            }
+        } else if (blendMode == IComposerClient::BlendMode::PREMULTIPLIED) {
+            for (int i = 0; i < expectedColors.size(); i++) {
+                expectedColors[i].r =
+                    mTopLayerColor.r * layer->mAlpha + mBackgroundColor.r * (1.0 - alpha);
+                expectedColors[i].g =
+                    mTopLayerColor.g * layer->mAlpha + mBackgroundColor.g * (1.0 - alpha);
+                expectedColors[i].b =
+                    mTopLayerColor.b * layer->mAlpha + mBackgroundColor.b * (1.0 - alpha);
+                expectedColors[i].a = alpha + mBackgroundColor.a * (1.0 - alpha);
+            }
+        } else if (blendMode == IComposerClient::BlendMode::COVERAGE) {
+            for (int i = 0; i < expectedColors.size(); i++) {
+                expectedColors[i].r = mTopLayerColor.r * alpha + mBackgroundColor.r * (1.0 - alpha);
+                expectedColors[i].g = mTopLayerColor.g * alpha + mBackgroundColor.g * (1.0 - alpha);
+                expectedColors[i].b = mTopLayerColor.b * alpha + mBackgroundColor.b * (1.0 - alpha);
+                expectedColors[i].a = mTopLayerColor.a * alpha + mBackgroundColor.a * (1.0 - alpha);
             }
         }
     }
 
-    PixelFormat pixelFormat;
-    Dataspace dataspace;
+   protected:
+    std::vector<std::shared_ptr<TestLayer>> mLayers;
+    IComposerClient::Color mBackgroundColor;
+    IComposerClient::Color mTopLayerColor;
+};
 
-    getReadbackBufferAttributes(mPrimaryDisplay, &pixelFormat, &dataspace);
-
-    IMapper::BufferDescriptorInfo info;
-    info.width = mDisplayWidth;
-    info.height = mDisplayHeight;
-    info.layerCount = 1;
-    info.format = pixelFormat;
-    info.usage = static_cast<uint64_t>(BufferUsage::CPU_READ_OFTEN | BufferUsage::GPU_TEXTURE);
-
-    uint32_t stride;
-    const native_handle_t* buffer = mGralloc->allocate(info, /*import*/ true, &stride);
-    mComposerClient->setReadbackBuffer(mPrimaryDisplay, buffer, -1);
-
-    render(layers);
-
-    int32_t fenceHandle;
-    mComposerClient->getReadbackBufferFence(mPrimaryDisplay, &fenceHandle);
-
-    // lock buffer
-    // Create Rect accessRegion to specify reading the entire buffer
-    IMapper::Rect accessRegion;
-    accessRegion.left = 0;
-    accessRegion.top = 0;
-    accessRegion.width = info.width;
-    accessRegion.height = info.height;
-
-    void* bufData = mGralloc->lock(buffer, info.usage, accessRegion, fenceHandle);
-    checkReadbackBuffer(info, stride, bufData, expectedColors);
-    int unlockFence = mGralloc->unlock(buffer);
-
-    if (unlockFence != -1) {
-        close(unlockFence);
+TEST_P(GraphicsComposerBlendModeReadbackTest, None) {
+    if (!mHasReadbackBuffer) {
+        GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace";
+        return;
     }
 
+    mWriter->selectDisplay(mPrimaryDisplay);
+
+    std::vector<IComposerClient::Color> expectedColors(mDisplayWidth * mDisplayHeight);
+
+    setBackgroundColor(BLACK);
+    setTopLayerColor(TRANSLUCENT_RED);
+    setUpLayers(IComposerClient::BlendMode::NONE);
+    setExpectedColors(expectedColors);
+
+    ReadbackBuffer readbackBuffer(mPrimaryDisplay, mComposerClient, mGralloc, mDisplayWidth,
+                                  mDisplayHeight, mPixelFormat, mDataspace);
+    ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
+    writeLayers(mLayers);
+    ASSERT_EQ(0, mReader->mErrors.size());
     mWriter->validateDisplay();
+    execute();
+    if (mReader->mCompositionChanges.size() != 0) {
+        clearCommandReaderState();
+        GTEST_SUCCEED();
+        return;
+    }
+    ASSERT_EQ(0, mReader->mErrors.size());
     mWriter->presentDisplay();
     execute();
+    ASSERT_EQ(0, mReader->mErrors.size());
+
+    ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
+}
+
+// TODO: bug 116865056: Readback returns (245, 0, 0) for layer plane
+// alpha of .2, expected 10.2
+TEST_P(GraphicsComposerBlendModeReadbackTest, DISABLED_Coverage) {
+    if (!mHasReadbackBuffer) {
+        GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace";
+        return;
+    }
+
+    mWriter->selectDisplay(mPrimaryDisplay);
+
+    std::vector<IComposerClient::Color> expectedColors(mDisplayWidth * mDisplayHeight);
+
+    setBackgroundColor(BLACK);
+    setTopLayerColor(TRANSLUCENT_RED);
+
+    setUpLayers(IComposerClient::BlendMode::COVERAGE);
+    setExpectedColors(expectedColors);
+
+    ReadbackBuffer readbackBuffer(mPrimaryDisplay, mComposerClient, mGralloc, mDisplayWidth,
+                                  mDisplayHeight, mPixelFormat, mDataspace);
+    ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
+    writeLayers(mLayers);
+    ASSERT_EQ(0, mReader->mErrors.size());
+    mWriter->validateDisplay();
+    execute();
+    if (mReader->mCompositionChanges.size() != 0) {
+        clearCommandReaderState();
+        GTEST_SUCCEED();
+        return;
+    }
+    ASSERT_EQ(0, mReader->mErrors.size());
+    mWriter->presentDisplay();
+    execute();
+    ASSERT_EQ(0, mReader->mErrors.size());
+    ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
+}
+
+TEST_P(GraphicsComposerBlendModeReadbackTest, Premultiplied) {
+    if (!mHasReadbackBuffer) {
+        GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace";
+        return;
+    }
+
+    mWriter->selectDisplay(mPrimaryDisplay);
+
+    std::vector<IComposerClient::Color> expectedColors(mDisplayWidth * mDisplayHeight);
+
+    setBackgroundColor(BLACK);
+    setTopLayerColor(TRANSLUCENT_RED);
+    setUpLayers(IComposerClient::BlendMode::PREMULTIPLIED);
+    setExpectedColors(expectedColors);
+
+    ReadbackBuffer readbackBuffer(mPrimaryDisplay, mComposerClient, mGralloc, mDisplayWidth,
+                                  mDisplayHeight, mPixelFormat, mDataspace);
+    ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
+    writeLayers(mLayers);
+    ASSERT_EQ(0, mReader->mErrors.size());
+    mWriter->validateDisplay();
+    execute();
+    if (mReader->mCompositionChanges.size() != 0) {
+        clearCommandReaderState();
+        GTEST_SUCCEED();
+        return;
+    }
+    ASSERT_EQ(0, mReader->mErrors.size());
+    mWriter->presentDisplay();
+    execute();
+    ASSERT_EQ(0, mReader->mErrors.size());
+    ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
+}
+
+INSTANTIATE_TEST_CASE_P(BlendModeTest, GraphicsComposerBlendModeReadbackTest,
+                        ::testing::Values(.2, 1.0));
+
+class GraphicsComposerTransformReadbackTest : public GraphicsComposerReadbackTest {
+   protected:
+    void SetUp() override {
+        GraphicsComposerReadbackTest::SetUp();
+
+        mWriter->selectDisplay(mPrimaryDisplay);
+        ASSERT_NO_FATAL_FAILURE(mComposerClient->setColorMode(mPrimaryDisplay, ColorMode::SRGB,
+                                                              RenderIntent::COLORIMETRIC));
+
+        auto backgroundLayer = std::make_shared<TestColorLayer>(mComposerClient, mPrimaryDisplay);
+        backgroundLayer->setColor({0, 0, 0, 0});
+        backgroundLayer->setDisplayFrame({0, 0, mDisplayWidth, mDisplayHeight});
+        backgroundLayer->setZOrder(0);
+
+        mSideLength = mDisplayWidth < mDisplayHeight ? mDisplayWidth : mDisplayHeight;
+        IComposerClient::Rect redRect = {0, 0, mSideLength / 2, mSideLength / 2};
+        IComposerClient::Rect blueRect = {mSideLength / 2, mSideLength / 2, mSideLength,
+                                          mSideLength};
+
+        mLayer =
+            std::make_shared<TestBufferLayer>(mComposerClient, mGralloc, mPrimaryDisplay,
+                                              mSideLength, mSideLength, PixelFormat::RGBA_8888);
+        mLayer->setDisplayFrame({0, 0, mSideLength, mSideLength});
+        mLayer->setZOrder(10);
+
+        std::vector<IComposerClient::Color> baseColors(mSideLength * mSideLength);
+        fillColorsArea(baseColors, mSideLength, redRect, RED);
+        fillColorsArea(baseColors, mSideLength, blueRect, BLUE);
+        ASSERT_NO_FATAL_FAILURE(mLayer->setBuffer(baseColors));
+
+        mLayers = {backgroundLayer, mLayer};
+    }
+
+   protected:
+    std::shared_ptr<TestBufferLayer> mLayer;
+    std::vector<IComposerClient::Color> baseColors;
+    std::vector<std::shared_ptr<TestLayer>> mLayers;
+    int mSideLength;
+};
+
+TEST_F(GraphicsComposerTransformReadbackTest, FLIP_H) {
+    if (!mHasReadbackBuffer) {
+        GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace";
+        return;
+    }
+    ReadbackBuffer readbackBuffer(mPrimaryDisplay, mComposerClient, mGralloc, mDisplayWidth,
+                                  mDisplayHeight, mPixelFormat, mDataspace);
+    ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
+    mLayer->setTransform(Transform::FLIP_H);
+    std::vector<IComposerClient::Color> expectedColors(mDisplayWidth * mDisplayHeight);
+    fillColorsArea(expectedColors, mDisplayWidth,
+                   {mSideLength / 2, 0, mSideLength, mSideLength / 2}, RED);
+    fillColorsArea(expectedColors, mDisplayWidth,
+                   {0, mSideLength / 2, mSideLength / 2, mSideLength}, BLUE);
+
+    writeLayers(mLayers);
+    ASSERT_EQ(0, mReader->mErrors.size());
+    mWriter->validateDisplay();
+    execute();
+    if (mReader->mCompositionChanges.size() != 0) {
+        clearCommandReaderState();
+        GTEST_SUCCEED();
+        return;
+    }
+    ASSERT_EQ(0, mReader->mErrors.size());
+    mWriter->presentDisplay();
+    execute();
+    ASSERT_EQ(0, mReader->mErrors.size());
+
+    ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
+}
+
+TEST_F(GraphicsComposerTransformReadbackTest, FLIP_V) {
+    if (!mHasReadbackBuffer) {
+        GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace";
+        return;
+    }
+    ReadbackBuffer readbackBuffer(mPrimaryDisplay, mComposerClient, mGralloc, mDisplayWidth,
+                                  mDisplayHeight, mPixelFormat, mDataspace);
+    ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
+
+    mLayer->setTransform(Transform::FLIP_V);
+
+    std::vector<IComposerClient::Color> expectedColors(mDisplayWidth * mDisplayHeight);
+    fillColorsArea(expectedColors, mDisplayWidth,
+                   {0, mSideLength / 2, mSideLength / 2, mSideLength}, RED);
+    fillColorsArea(expectedColors, mDisplayWidth,
+                   {mSideLength / 2, 0, mSideLength, mSideLength / 2}, BLUE);
+
+    writeLayers(mLayers);
+    ASSERT_EQ(0, mReader->mErrors.size());
+    mWriter->validateDisplay();
+    execute();
+    if (mReader->mCompositionChanges.size() != 0) {
+        clearCommandReaderState();
+        GTEST_SUCCEED();
+        return;
+    }
+    ASSERT_EQ(0, mReader->mErrors.size());
+    mWriter->presentDisplay();
+    execute();
+    ASSERT_EQ(0, mReader->mErrors.size());
+    ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
+}
+
+TEST_F(GraphicsComposerTransformReadbackTest, ROT_180) {
+    if (!mHasReadbackBuffer) {
+        GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace";
+        return;
+    }
+    ReadbackBuffer readbackBuffer(mPrimaryDisplay, mComposerClient, mGralloc, mDisplayWidth,
+                                  mDisplayHeight, mPixelFormat, mDataspace);
+    ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
+
+    mLayer->setTransform(Transform::ROT_180);
+
+    std::vector<IComposerClient::Color> expectedColors(mDisplayWidth * mDisplayHeight);
+    fillColorsArea(expectedColors, mDisplayWidth,
+                   {mSideLength / 2, mSideLength / 2, mSideLength, mSideLength}, RED);
+    fillColorsArea(expectedColors, mDisplayWidth, {0, 0, mSideLength / 2, mSideLength / 2}, BLUE);
+
+    writeLayers(mLayers);
+    ASSERT_EQ(0, mReader->mErrors.size());
+    mWriter->validateDisplay();
+    execute();
+    if (mReader->mCompositionChanges.size() != 0) {
+        clearCommandReaderState();
+        GTEST_SUCCEED();
+        return;
+    }
+    ASSERT_EQ(0, mReader->mErrors.size());
+    mWriter->presentDisplay();
+    execute();
+    ASSERT_EQ(0, mReader->mErrors.size());
+    ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
 }
 
 }  // anonymous namespace
diff --git a/health/2.0/default/Health.cpp b/health/2.0/default/Health.cpp
index 6d3be99..a2b81d1 100644
--- a/health/2.0/default/Health.cpp
+++ b/health/2.0/default/Health.cpp
@@ -46,7 +46,7 @@
     }
 
     {
-        std::lock_guard<std::mutex> _lock(callbacks_lock_);
+        std::lock_guard<decltype(callbacks_lock_)> lock(callbacks_lock_);
         callbacks_.push_back(callback);
         // unlock
     }
@@ -58,14 +58,14 @@
         // ignore the error
     }
 
-    return update();
+    return updateAndNotify(callback);
 }
 
 bool Health::unregisterCallbackInternal(const sp<IBase>& callback) {
     if (callback == nullptr) return false;
 
     bool removed = false;
-    std::lock_guard<std::mutex> _lock(callbacks_lock_);
+    std::lock_guard<decltype(callbacks_lock_)> lock(callbacks_lock_);
     for (auto it = callbacks_.begin(); it != callbacks_.end();) {
         if (interfacesEqual(*it, callback)) {
             it = callbacks_.erase(it);
@@ -142,7 +142,7 @@
 Return<Result> Health::update() {
     if (!healthd_mode_ops || !healthd_mode_ops->battery_update) {
         LOG(WARNING) << "health@2.0: update: not initialized. "
-                     << "update() should not be called in charger / recovery.";
+                     << "update() should not be called in charger";
         return Result::UNKNOWN;
     }
 
@@ -156,6 +156,18 @@
     return Result::SUCCESS;
 }
 
+Return<Result> Health::updateAndNotify(const sp<IHealthInfoCallback>& callback) {
+    std::lock_guard<decltype(callbacks_lock_)> lock(callbacks_lock_);
+    std::vector<sp<IHealthInfoCallback>> storedCallbacks{std::move(callbacks_)};
+    callbacks_.clear();
+    if (callback != nullptr) {
+        callbacks_.push_back(callback);
+    }
+    Return<Result> result = update();
+    callbacks_ = std::move(storedCallbacks);
+    return result;
+}
+
 void Health::notifyListeners(HealthInfo* healthInfo) {
     std::vector<StorageInfo> info;
     get_storage_info(info);
@@ -175,7 +187,7 @@
     healthInfo->diskStats = stats;
     healthInfo->storageInfos = info;
 
-    std::lock_guard<std::mutex> _lock(callbacks_lock_);
+    std::lock_guard<decltype(callbacks_lock_)> lock(callbacks_lock_);
     for (auto it = callbacks_.begin(); it != callbacks_.end();) {
         auto ret = (*it)->healthInfoChanged(*healthInfo);
         if (!ret.isOk() && ret.isDeadObject()) {
@@ -233,7 +245,7 @@
 Return<void> Health::getHealthInfo(getHealthInfo_cb _hidl_cb) {
     using android::hardware::health::V1_0::hal_conversion::convertToHealthInfo;
 
-    update();
+    updateAndNotify(nullptr);
     struct android::BatteryProperties p = getBatteryProperties(battery_monitor_.get());
 
     V1_0::HealthInfo batteryInfo;
diff --git a/health/2.0/default/HealthImplDefault.cpp b/health/2.0/default/HealthImplDefault.cpp
index 15346bf..e3cbefd 100644
--- a/health/2.0/default/HealthImplDefault.cpp
+++ b/health/2.0/default/HealthImplDefault.cpp
@@ -46,9 +46,32 @@
     return 0;
 }
 
+void healthd_mode_default_impl_init(struct healthd_config*) {
+    // noop
+}
+
+int healthd_mode_default_impl_preparetowait(void) {
+    return -1;
+}
+
+void healthd_mode_default_impl_heartbeat(void) {
+    // noop
+}
+
+void healthd_mode_default_impl_battery_update(struct android::BatteryProperties*) {
+    // noop
+}
+
+static struct healthd_mode_ops healthd_mode_default_impl_ops = {
+    .init = healthd_mode_default_impl_init,
+    .preparetowait = healthd_mode_default_impl_preparetowait,
+    .heartbeat = healthd_mode_default_impl_heartbeat,
+    .battery_update = healthd_mode_default_impl_battery_update,
+};
+
 extern "C" IHealth* HIDL_FETCH_IHealth(const char* name) {
     const static std::string providedInstance{"backup"};
-
+    healthd_mode_ops = &healthd_mode_default_impl_ops;
     if (providedInstance == name) {
         // use defaults
         // Health class stores static instance
diff --git a/health/2.0/default/include/health2/Health.h b/health/2.0/default/include/health2/Health.h
index 134cdc6..6410474 100644
--- a/health/2.0/default/include/health2/Health.h
+++ b/health/2.0/default/include/health2/Health.h
@@ -31,12 +31,10 @@
     // Should only be called by implementation itself (-impl, -service).
     // Clients should not call this function. Instead, initInstance() initializes and returns the
     // global instance that has fewer functions.
-    // TODO(b/62229583): clean up and hide these functions after update() logic is simplified.
     static sp<Health> getImplementation();
 
     Health(struct healthd_config* c);
 
-    // TODO(b/62229583): clean up and hide these functions after update() logic is simplified.
     void notifyListeners(HealthInfo* info);
 
     // Methods from IHealth follow.
@@ -61,11 +59,15 @@
    private:
     static sp<Health> instance_;
 
-    std::mutex callbacks_lock_;
+    std::recursive_mutex callbacks_lock_;
     std::vector<sp<IHealthInfoCallback>> callbacks_;
     std::unique_ptr<BatteryMonitor> battery_monitor_;
 
     bool unregisterCallbackInternal(const sp<IBase>& cb);
+
+    // update() and only notify the given callback, but none of the other callbacks.
+    // If cb is null, do not notify any callback at all.
+    Return<Result> updateAndNotify(const sp<IHealthInfoCallback>& cb);
 };
 
 }  // namespace implementation
diff --git a/health/2.0/vts/functional/VtsHalHealthV2_0TargetTest.cpp b/health/2.0/vts/functional/VtsHalHealthV2_0TargetTest.cpp
index bba4661..f895aec 100644
--- a/health/2.0/vts/functional/VtsHalHealthV2_0TargetTest.cpp
+++ b/health/2.0/vts/functional/VtsHalHealthV2_0TargetTest.cpp
@@ -222,38 +222,83 @@
 }
 
 /*
- * Tests the values returned by getChargeCounter(),
- * getCurrentNow(), getCurrentAverage(), getCapacity(), getEnergyCounter(),
- * getChargeStatus(), getStorageInfo(), getDiskStats() and getHealthInfo() from
- * interface IHealth.
+ * Tests the values returned by getChargeCounter() from interface IHealth.
  */
-TEST_F(HealthHidlTest, Properties) {
+TEST_F(HealthHidlTest, getChargeCounter) {
     EXPECT_OK(mHealth->getChargeCounter([](auto result, auto value) {
         EXPECT_VALID_OR_UNSUPPORTED_PROP(result, std::to_string(value), value > 0);
     }));
+}
+
+/*
+ * Tests the values returned by getCurrentNow() from interface IHealth.
+ */
+TEST_F(HealthHidlTest, getCurrentNow) {
     EXPECT_OK(mHealth->getCurrentNow([](auto result, auto value) {
         EXPECT_VALID_OR_UNSUPPORTED_PROP(result, std::to_string(value), value != INT32_MIN);
     }));
+}
+
+/*
+ * Tests the values returned by getCurrentAverage() from interface IHealth.
+ */
+TEST_F(HealthHidlTest, getCurrentAverage) {
     EXPECT_OK(mHealth->getCurrentAverage([](auto result, auto value) {
         EXPECT_VALID_OR_UNSUPPORTED_PROP(result, std::to_string(value), value != INT32_MIN);
     }));
+}
+
+/*
+ * Tests the values returned by getCapacity() from interface IHealth.
+ */
+TEST_F(HealthHidlTest, getCapacity) {
     EXPECT_OK(mHealth->getCapacity([](auto result, auto value) {
         EXPECT_VALID_OR_UNSUPPORTED_PROP(result, std::to_string(value), 0 <= value && value <= 100);
     }));
+}
+
+/*
+ * Tests the values returned by getEnergyCounter() from interface IHealth.
+ */
+TEST_F(HealthHidlTest, getEnergyCounter) {
     EXPECT_OK(mHealth->getEnergyCounter([](auto result, auto value) {
         EXPECT_VALID_OR_UNSUPPORTED_PROP(result, std::to_string(value), value != INT64_MIN);
     }));
+}
+
+/*
+ * Tests the values returned by getChargeStatus() from interface IHealth.
+ */
+TEST_F(HealthHidlTest, getChargeStatus) {
     EXPECT_OK(mHealth->getChargeStatus([](auto result, auto value) {
         EXPECT_VALID_OR_UNSUPPORTED_PROP(
             result, toString(value),
             value != BatteryStatus::UNKNOWN && verifyEnum<BatteryStatus>(value));
     }));
+}
+
+/*
+ * Tests the values returned by getStorageInfo() from interface IHealth.
+ */
+TEST_F(HealthHidlTest, getStorageInfo) {
     EXPECT_OK(mHealth->getStorageInfo([](auto result, auto& value) {
         EXPECT_VALID_OR_UNSUPPORTED_PROP(result, toString(value), verifyStorageInfo(value));
     }));
+}
+
+/*
+ * Tests the values returned by getDiskStats() from interface IHealth.
+ */
+TEST_F(HealthHidlTest, getDiskStats) {
     EXPECT_OK(mHealth->getDiskStats([](auto result, auto& value) {
         EXPECT_VALID_OR_UNSUPPORTED_PROP(result, toString(value), true);
     }));
+}
+
+/*
+ * Tests the values returned by getHealthInfo() from interface IHealth.
+ */
+TEST_F(HealthHidlTest, getHealthInfo) {
     EXPECT_OK(mHealth->getHealthInfo([](auto result, auto& value) {
         EXPECT_VALID_OR_UNSUPPORTED_PROP(result, toString(value), verifyHealthInfo(value));
     }));
diff --git a/keymaster/4.0/support/include/keymasterV4_0/authorization_set.h b/keymaster/4.0/support/include/keymasterV4_0/authorization_set.h
index 1869682..193e4ea 100644
--- a/keymaster/4.0/support/include/keymasterV4_0/authorization_set.h
+++ b/keymaster/4.0/support/include/keymasterV4_0/authorization_set.h
@@ -46,7 +46,7 @@
     AuthorizationSet(const AuthorizationSet& other) : data_(other.data_) {}
 
     // Move constructor.
-    AuthorizationSet(AuthorizationSet&& other) : data_(std::move(other.data_)) {}
+    AuthorizationSet(AuthorizationSet&& other) noexcept : data_(std::move(other.data_)) {}
 
     // Constructor from hidl_vec<KeyParameter>
     AuthorizationSet(const hidl_vec<KeyParameter>& other) { *this = other; }
@@ -58,7 +58,7 @@
     }
 
     // Move assignment.
-    AuthorizationSet& operator=(AuthorizationSet&& other) {
+    AuthorizationSet& operator=(AuthorizationSet&& other) noexcept {
         data_ = std::move(other.data_);
         return *this;
     }
diff --git a/media/bufferpool/2.0/Android.bp b/media/bufferpool/2.0/Android.bp
index 405990e..1f8bbdb 100644
--- a/media/bufferpool/2.0/Android.bp
+++ b/media/bufferpool/2.0/Android.bp
@@ -11,12 +11,14 @@
         "IAccessor.hal",
         "IClientManager.hal",
         "IConnection.hal",
+        "IObserver.hal",
     ],
     interfaces: [
         "android.hidl.base@1.0",
     ],
     types: [
         "Buffer",
+        "BufferInvalidationMessage",
         "BufferStatus",
         "BufferStatusMessage",
         "ResultStatus",
diff --git a/media/bufferpool/2.0/IAccessor.hal b/media/bufferpool/2.0/IAccessor.hal
index bd70945..66707fe 100644
--- a/media/bufferpool/2.0/IAccessor.hal
+++ b/media/bufferpool/2.0/IAccessor.hal
@@ -17,6 +17,7 @@
 package android.hardware.media.bufferpool@2.0;
 
 import IConnection;
+import IObserver;
 /**
  * IAccessor creates IConnection which is used from IClientManager in order to
  * use functionality of the specified buffer pool.
@@ -49,6 +50,13 @@
      * made and kept private. Also part of transaction ID is a sender ID in
      * order to prevent fake transactions from other clients. This must be
      * verified with an FMQ message from a buffer pool.
+
+     * @param observer The buffer pool event observer from the client.
+     *     Observer is provided to ensure FMQ messages are processed even when
+     *     client processes are idle. Buffer invalidation caused by
+     *     reconfiguration does not call observer. Buffer invalidation caused
+     *     by termination of pipeline call observer in order to ensure
+     *     invalidation is done after pipeline completion.
      *
      * @return status The status of the call.
      *     OK               - A connection is made successfully.
@@ -64,9 +72,9 @@
      * @return fromFmqDesc FMQ descriptor. The descriptor is used to
      *     receive buffer invalidation messages from the buffer pool.
      */
-    connect()
+    connect(IObserver observer)
         generates (ResultStatus status, IConnection connection,
                    int64_t connectionId,
                    fmq_sync<BufferStatusMessage> toFmqDesc,
-                   fmq_sync<BufferInvalidationMessage> fromFmqDesc);
+                   fmq_unsync<BufferInvalidationMessage> fromFmqDesc);
 };
diff --git a/media/bufferpool/2.0/IObserver.hal b/media/bufferpool/2.0/IObserver.hal
new file mode 100644
index 0000000..a998836
--- /dev/null
+++ b/media/bufferpool/2.0/IObserver.hal
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2018 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.media.bufferpool@2.0;
+
+/**
+ * IObserver listens on notifications from the buffer pool. On receiving
+ * notifications, FMQ messages from the specific buffer pool which are already
+ * in the FMQ are processed.
+ */
+interface IObserver {
+
+    /**
+     * The specific buffer pool sent a message to the client. Calling this
+     * method from the buffer pool enforces a buffer pool client process the
+     * message.
+     *
+     * @param connectionId the connection Id of the specific buffer pool client
+     */
+    oneway onMessage(int64_t connectionId);
+};
diff --git a/media/bufferpool/2.0/types.hal b/media/bufferpool/2.0/types.hal
index 7ce53b1..597e7b3 100644
--- a/media/bufferpool/2.0/types.hal
+++ b/media/bufferpool/2.0/types.hal
@@ -65,6 +65,8 @@
     TRANSFER_OK         = 7,
     /** Buffer transaction failure. */
     TRANSFER_ERROR      = 8,
+    /** Buffer invalidation ack. */
+    INVALIDATION_ACK    = 9,
 };
 
 /**
@@ -98,9 +100,10 @@
  * buffers as soon as possible upon receiving the message.
  */
 struct BufferInvalidationMessage {
+    uint32_t messageId;
     /**
      * Buffers from fromBufferId to toBufferId must be invalidated.
-     * Both of fromBufferId and toBufferId are inclusive.
+     * fromBufferId is inclusive, but toBufferId is not inclusive.
      * If fromBufferId > toBufferID, wrap happens. In that case
      * the wrap is based on UINT32_MAX.
      */
diff --git a/neuralnetworks/1.0/vts/OWNERS b/neuralnetworks/1.0/vts/OWNERS
index 87e322b..b5a8e1f 100644
--- a/neuralnetworks/1.0/vts/OWNERS
+++ b/neuralnetworks/1.0/vts/OWNERS
@@ -2,9 +2,14 @@
 butlermichael@google.com
 dgross@google.com
 jeanluc@google.com
+levp@google.com
 miaowang@google.com
 mikie@google.com
+mks@google.com
 pszczepaniak@google.com
+slavash@google.com
+vddang@google.com
+xusongw@google.com
 
 # VTS team
 yim@google.com
diff --git a/neuralnetworks/1.1/vts/OWNERS b/neuralnetworks/1.1/vts/OWNERS
index 87e322b..b5a8e1f 100644
--- a/neuralnetworks/1.1/vts/OWNERS
+++ b/neuralnetworks/1.1/vts/OWNERS
@@ -2,9 +2,14 @@
 butlermichael@google.com
 dgross@google.com
 jeanluc@google.com
+levp@google.com
 miaowang@google.com
 mikie@google.com
+mks@google.com
 pszczepaniak@google.com
+slavash@google.com
+vddang@google.com
+xusongw@google.com
 
 # VTS team
 yim@google.com
diff --git a/neuralnetworks/1.2/IDevice.hal b/neuralnetworks/1.2/IDevice.hal
index 9cc23a2..aff4cf3 100644
--- a/neuralnetworks/1.2/IDevice.hal
+++ b/neuralnetworks/1.2/IDevice.hal
@@ -26,6 +26,36 @@
  */
 interface IDevice extends @1.1::IDevice {
     /**
+     * Get the version string of the driver implementation.
+     *
+     * The version string must be a unique token among the set of version strings of
+     * drivers of a specific device. The token identifies the device driver's
+     * implementation. The token must not be confused with the feature level which is solely
+     * defined by the interface version. This API is opaque to the Android framework, but the
+     * Android framework may use the information for debugging or to pass on to NNAPI applications.
+     *
+     * Application developers sometimes have specific requirements to ensure good user experiences,
+     * and they need more information to make intelligent decisions when the Android framework cannot.
+     * For example, combined with the device name and other information, the token can help
+     * NNAPI applications filter devices based on their needs:
+     *     - An application demands a certain level of performance, but a specific version of
+     *       the driver cannot meet that requirement because of a performance regression.
+     *       The application can blacklist the driver based on the version provided.
+     *     - An application has a minimum precision requirement, but certain versions of
+     *       the driver cannot meet that requirement because of bugs or certain optimizations.
+     *       The application can filter out versions of these drivers.
+     *
+     * @return status Error status returned from querying the version string. Must be:
+     *     - NONE if the query was successful
+     *     - DEVICE_UNAVAILABLE if driver is offline or busy
+     *     - GENERAL_FAILURE if the query resulted in an
+     *       unspecified error
+     * @return version The version string of the device implementation.
+     *     Must have nonzero length
+     */
+    getVersionString() generates (ErrorStatus status, string version);
+
+    /**
      * Gets the supported operations in a model.
      *
      * getSupportedOperations indicates which operations of a model are fully
diff --git a/neuralnetworks/1.2/types.hal b/neuralnetworks/1.2/types.hal
index 4377131..bed1d5c 100644
--- a/neuralnetworks/1.2/types.hal
+++ b/neuralnetworks/1.2/types.hal
@@ -30,7 +30,7 @@
     ARGMAX = 38,
     ARGMIN = 39,
     PAD_V2 = 40,
-    BBOX_TRANSFORM = 41,
+    AXIS_ALIGNED_BBOX_TRANSFORM = 41,
     BIDIRECTIONAL_SEQUENCE_LSTM = 42,
     BIDIRECTIONAL_SEQUENCE_RNN = 43,
     BOX_WITH_NMS_LIMIT = 44,
@@ -76,6 +76,7 @@
     TRANSPOSE_CONV_2D = 84,
     UNIDIRECTIONAL_SEQUENCE_LSTM = 85,
     UNIDIRECTIONAL_SEQUENCE_RNN = 86,
+    ROTATED_BBOX_TRANSFORM = 87,
 };
 
 /**
diff --git a/neuralnetworks/1.2/vts/OWNERS b/neuralnetworks/1.2/vts/OWNERS
index 8f25436..b5a8e1f 100644
--- a/neuralnetworks/1.2/vts/OWNERS
+++ b/neuralnetworks/1.2/vts/OWNERS
@@ -8,6 +8,8 @@
 mks@google.com
 pszczepaniak@google.com
 slavash@google.com
+vddang@google.com
+xusongw@google.com
 
 # VTS team
 yim@google.com
diff --git a/neuralnetworks/1.2/vts/functional/BasicTests.cpp b/neuralnetworks/1.2/vts/functional/BasicTests.cpp
index d2dea1d..eb3ebd3 100644
--- a/neuralnetworks/1.2/vts/functional/BasicTests.cpp
+++ b/neuralnetworks/1.2/vts/functional/BasicTests.cpp
@@ -37,6 +37,14 @@
     EXPECT_EQ(DeviceStatus::AVAILABLE, static_cast<DeviceStatus>(status));
 }
 
+// device version test
+TEST_F(NeuralnetworksHidlTest, GetDeviceVersionStringTest) {
+    Return<void> ret = device->getVersionString([](ErrorStatus status, const hidl_string& version) {
+        EXPECT_EQ(ErrorStatus::NONE, status);
+        EXPECT_LT(0, version.size());
+    });
+    EXPECT_TRUE(ret.isOk());
+}
 }  // namespace functional
 }  // namespace vts
 }  // namespace V1_2
diff --git a/radio/1.3/Android.bp b/radio/1.3/Android.bp
index 5ac38cd..6a9b1d0 100644
--- a/radio/1.3/Android.bp
+++ b/radio/1.3/Android.bp
@@ -20,8 +20,10 @@
     ],
     types: [
         "AccessNetwork",
+        "DataProfileInfo",
         "DataRegStateResult",
         "EmergencyNumber",
+        "EmergencyNumberSource",
         "EmergencyServiceCategory",
         "LteVopsInfo",
     ],
diff --git a/radio/1.3/IRadio.hal b/radio/1.3/IRadio.hal
index 480a61f..dde9d71 100644
--- a/radio/1.3/IRadio.hal
+++ b/radio/1.3/IRadio.hal
@@ -16,7 +16,7 @@
 
 package android.hardware.radio@1.3;
 
-import @1.0::DataProfileInfo;
+import @1.3::DataProfileInfo;
 import @1.0::Dial;
 import @1.2::DataRequestReason;
 import @1.2::IRadio;
@@ -56,13 +56,7 @@
      * @param accessNetwork The access network to setup the data call. If the data connection cannot
      *     be established on the specified access network, the setup request must be failed.
      * @param dataProfileInfo Data profile info.
-     * @param modemCognitive Indicates that the requested profile has previously been provided via
-     *     setDataProfile().
      * @param roamingAllowed Indicates whether or not data roaming is allowed by the user.
-     * @param isRoaming Indicates whether or not the framework has requested this setupDataCall for
-     *     a roaming network. The 'protocol' parameter in the old RIL API must be filled
-     *     accordingly based on the roaming condition. Note this is for backward compatibility with
-     *     the old radio modem. The modem must not use this param for any other reason.
      * @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
@@ -82,40 +76,43 @@
      * Note this API is same as 1.2 version except using the 1.3 AccessNetwork as the input param.
      */
     oneway setupDataCall_1_3(int32_t serial, AccessNetwork accessNetwork,
-            DataProfileInfo dataProfileInfo, bool modemCognitive, bool roamingAllowed,
-            bool isRoaming, DataRequestReason reason, vec<string> addresses, vec<string> dnses);
+            DataProfileInfo dataProfileInfo, bool roamingAllowed,
+            DataRequestReason reason, vec<string> addresses, vec<string> dnses);
 
     /**
-     * Request the current emergency number list.
-     *
-     * Each emergency number (@1.3::EmergencyNumber) in the emergency number list contains a
-     * dialing number, one or more service category(s), and mobile country code.
-     *
-     * Radio must collect all sources of the emergency number to build the response.
-     * For example, network operator signals, sim card information, modem configuration, OEM
-     * configuration (for example, OEM system properties), always-available emergency numbers and
-     * sim-absence emergency numbers, etc.
-     *
-     * 112, 911 are always available. Besides, 000, 08, 110, 999, 118 and 119 should be available
-     * when sim is not present.
-     *
-     * Please refer the document of @1.3::EmergencyNumber to construct each emergency number to be
-     * returned.
-     *
-     * Reference: 3GPP TS 22.101 version 9.1.0 Release 9
+     * Set an apn to initial attach network
      *
      * @param serial Serial number of request.
+     * @param dataProfileInfo data profile containing APN settings
      *
-     * Response function is IRadioResponse.getCurrentEmergencyNumberListResponse()
+     * Response callback is IRadioResponse.setInitialAttachApnResponse()
      */
-    oneway getCurrentEmergencyNumberList(int32_t serial);
+    oneway setInitialAttachApn_1_3(int32_t serial, DataProfileInfo dataProfileInfo);
 
     /**
-     * Initiate emergency voice call, with one or more emergency service category(s).
+     * Send data profiles of the current carrier to the modem.
+     *
+     * @param serial Serial number of request.
+     * @param profiles Array of DataProfile to set.
+     *
+     * Response callback is IRadioResponse.setDataProfileResponse()
+     */
+    oneway setDataProfile_1_3(int32_t serial, vec<DataProfileInfo> profiles);
+
+    /**
+     * Initiate emergency voice call, with zero or more emergency service category(s).
      *
      * Note this API is the same as IRadio.dial except using the
      * @1.3::EmergencyServiceCategory as the input param.
      *
+     * If the dialed emergency number does not have a specified emergency service category, the
+     * 'categories' field is set to @1.3::EmergencyServiceCategory#UNSPECIFIED; iff either the
+     * 'categories' field is set to @1.3::EmergencyServiceCategory#UNSPECIFIED or the underlying
+     * technology used to request emergency services does not support the emergency service
+     * category, the interpretation of the categories is defined by implementation.
+     *
+     * Reference: 3gpp TS 22.101, Section 10 - Emergency Calls
+     *
      * @param serial Serial number of request.
      * @param dialInfo the same @1.0::Dial information used by @1.0::IRadio.dial.
      * @param categories bitfield<@1.3::EmergencyServiceCategory> the Emergency Service Category(s)
diff --git a/radio/1.3/IRadioIndication.hal b/radio/1.3/IRadioIndication.hal
index c80e762..509eef8 100644
--- a/radio/1.3/IRadioIndication.hal
+++ b/radio/1.3/IRadioIndication.hal
@@ -24,29 +24,28 @@
  */
 interface IRadioIndication extends @1.2::IRadioIndication {
     /**
-     * Indicate and update all of the current Emergency Number information known to the radio,
-     * when any of the Emergency Number sources (For example, network operator signals, sim card
-     * information, modem configuration, OEM configuration or system properties, etc.) change the
-     * list of emergency numbers.
+     * Report the current list of emergency numbers
      *
-     * 112, 911 are always available. Besides, 000, 08, 110, 999, 118 and 119 should be available
-     * when sim is not present.
+     * Each emergency number (@1.3::EmergencyNumber) in the emergency number list contains a
+     * dialing number, zero or more service category(s), mobile country code, and source(s) that
+     * indicate where it comes from.
      *
-     * This should be the same information as returned by getCurrentEmergencyNumberList() in
-     * 1.3::IRadio.
+     * Radio must report all the valid emergency numbers with known mobile country code and
+     * emergency service categories from all available sources including network signaling, sim,
+     * modem/oem configuration, and default configuration (112 and 911 must be always available;
+     * additionally, 000, 08, 110, 999, 118 and 119 must be available when sim is not present).
+     * Radio shall not report emergency numbers that are invalid in the current locale. The
+     * reported emergency number list must not have duplicate @1.3::EmergencyNumber entries. Please
+     * refer the documentation of @1.3::EmergencyNumber to construct each emergency number to
+     * report.
      *
-     * The indicated list of emergency numbers should not have duplicate @1.3::EmergencyNumber.
-     * Please refer the document of @1.3::EmergencyNumber to construct each emergency number to be
-     * returned.
+     * Radio must report the complete list of emergency numbers whenever the emergency numbers in
+     * the list are changed or whenever the client and the radio server are connected.
      *
-     * Reference: 3GPP TS 22.101 version 9.1.0 Release 9
+     * Reference: 3gpp 22.101, Section 10 - Emergency Calls
      *
      * @param type Type of radio indication
-     * @param emergencyNumberList List of current Emergency Number information
-     *     (@1.3::EmergencyNumber) known to radio. Radio must collect all sources of the emergency
-     *     numbers to build the indication. For example, network operator signals, sim card
-     *     information, modem configuration, OEM configuration (for example, OEM specific system
-     *     properties), always-available emergency numbers and sim-absence emergency numbers, etc.
+     * @param emergencyNumberList Current list of emergency numbers known to radio.
      */
     oneway currentEmergencyNumberList(RadioIndicationType type,
             vec<EmergencyNumber> emergencyNumberList);
diff --git a/radio/1.3/IRadioResponse.hal b/radio/1.3/IRadioResponse.hal
index 3604953..10e7d63 100644
--- a/radio/1.3/IRadioResponse.hal
+++ b/radio/1.3/IRadioResponse.hal
@@ -25,30 +25,6 @@
 interface IRadioResponse extends @1.2::IRadioResponse {
     /**
      * @param info Response info struct containing response type, serial no. and error
-     * @param emergencyNumberList List of current Emergency Number information known to radio.
-     *
-     * Radio must collect all sources of the emergency number to build the response. For example,
-     * network operator signals, sim card information, modem configuration, OEM configuration (for
-     * example, OEM system properties), always-available emergency numbers and sim-absence
-     * emergency numbers, etc.
-     *
-     * The returned list of emergency numbers must not have duplicate @1.3::EmergencyNumber. Please
-     * refer the document of @1.3::EmergencyNumber to construct each emergency number to be
-     * returned.
-     *
-     * Reference: 3GPP TS 22.101 version 9.1.0 Release 9
-     *
-     * Valid errors returned:
-     *   RadioError:NONE
-     *   RadioError:RADIO_NOT_AVAILABLE
-     *   RadioError:NO_MEMORY
-     *   RadioError:MODEM_ERR
-     */
-    oneway getCurrentEmergencyNumberListResponse(RadioResponseInfo info,
-            vec<EmergencyNumber> emergencyNumberList);
-
-    /**
-     * @param info Response info struct containing response type, serial no. and error
      *
      * Valid errors returned:
      *   RadioError:NONE
diff --git a/radio/1.3/types.hal b/radio/1.3/types.hal
index d472ca7..a41f4b2 100644
--- a/radio/1.3/types.hal
+++ b/radio/1.3/types.hal
@@ -16,6 +16,11 @@
 
 package android.hardware.radio@1.3;
 
+import @1.0::ApnAuthType;
+import @1.0::ApnTypes;
+import @1.0::DataProfileId;
+import @1.0::DataProfileInfoType;
+import @1.0::RadioAccessFamily;
 import @1.0::RegState;
 import @1.2::AccessNetwork;
 import @1.2::CellIdentity;
@@ -29,14 +34,14 @@
 };
 
 /**
- * Emergency number contains information of number, one or more service category(s), and mobile
- * country code (mcc).
+ * Emergency number contains information of number, one or more service category(s), mobile country
+ * code (mcc), and source(s) that indicate where it comes from.
  *
  * If the source of the emergency number is associated with country, field ‘mcc’ must be
  * provided; otherwise the field ‘mcc’ must be an empty string.
  *
- * A unique EmergencyNumber has a unique combination of ‘number’ and ‘mcc’ fields.
- * Multiple @1.3::EmergencyServiceCategory should be merged into the bitfield for the same
+ * A unique EmergencyNumber has a unique combination of ‘number’, ‘mcc’ and 'categories' fields.
+ * Multiple @1.3::EmergencyNumberSource should be merged into the bitfield for the same
  * EmergencyNumber.
  *
  * Reference: 3GPP TS 22.101 version 9.1.0 Release 9
@@ -56,6 +61,11 @@
      * the value of each bit.
      */
     bitfield<EmergencyServiceCategory> categories;
+    /**
+     * The bitfield of @1.3::EmergencyNumberSource(s). See @1.3::EmergencyNumberSource for the
+     * value of each bit.
+     */
+    bitfield<EmergencyNumberSource> sources;
 };
 
 /**
@@ -69,20 +79,55 @@
  * - Manually Initiated eCall (MIeC);
  * - Automatically Initiated eCall (AIeC);
  *
- * Type GENERIC (General emergency call, all categories) is considered to use if the reported type
- * is not any of the other specific types.
+ * Category UNSPECIFIED (General emergency call, all categories) indicates that no specific
+ * services are associated with this emergency number.
  *
- * Reference: 3GPP TS 22.101 version 9.1.0 Release 9
+ * Reference: 3gpp 22.101, Section 10 - Emergency Calls
  */
 enum EmergencyServiceCategory : int32_t {
-    GENERIC = 0, // General emergency call, all categories
+    /**
+     * General emergency call, all categories
+     */
+    UNSPECIFIED = 0,
     POLICE = 1 << 0,
     AMBULANCE = 1 << 1,
     FIRE_BRIGADE = 1 << 2,
     MARINE_GUARD = 1 << 3,
     MOUNTAIN_RESCUE = 1 << 4,
-    MIEC = 1 << 5, // Manually Initiated eCall (MIeC)
-    AIEC = 1 << 6, // Automatically Initiated eCall (AIeC)
+    /**
+     * Manually Initiated eCall (MIeC)
+     */
+    MIEC = 1 << 5,
+    /**
+     * Automatically Initiated eCall (AIeC)
+     */
+    AIEC = 1 << 6,
+};
+
+/**
+ * The source to tell where the corresponding @1.3::EmergencyNumber comes from.
+ *
+ * Reference: 3gpp 22.101, Section 10 - Emergency Calls
+ */
+enum EmergencyNumberSource : int32_t {
+    /**
+     * Indicates the number is from the network signal.
+     */
+    NETWORK_SIGNALING = 1 << 0,
+    /**
+     * Indicates the number is from the sim card.
+     */
+    SIM = 1 << 1,
+    /**
+     * Indicates the number is from the modem config.
+     */
+    MODEM_CONFIG = 1 << 2,
+    /**
+     * Indicates the number is available as default. Per the reference, 112, 911 must always be
+     * available; additionally, 000, 08, 110, 999, 118 and 119 must be available when sim is not
+     * present.
+     */
+    DEFAULT = 1 << 3,
 };
 
 /**
@@ -120,3 +165,71 @@
         LteVopsInfo lteVopsInfo; // LTE network capability
     } vopsInfo;
 };
+
+/**
+ * Overwritten from @1.0::DataProfileInfo in order to deprecate 'mvnoType', 'mvnoMatchData',
+ * 'maxConnsTime', and 'maxConns'. In the future, this must be extended instead of overwritten.
+ * Added 'preferred' and 'persistent' in this version.
+ */
+struct DataProfileInfo {
+    /** id of the data profile */
+    DataProfileId profileId;
+
+    /** The APN name */
+    string apn;
+
+    /**
+     * One of the PDP_type values in TS 27.007 section 10.1.1. For example, "IP", "IPV6", "IPV4V6",
+     * or "PPP".
+     */
+    string protocol;
+
+    /**
+     * one of the PDP_type values in TS 27.007 section 10.1.1 used on roaming network. For example,
+     * "IP", "IPV6", "IPV4V6", or "PPP".
+     */
+    string roamingProtocol;
+
+    /** APN authentication type */
+    ApnAuthType authType;
+
+    /** The username for APN, or empty string */
+    string user;
+
+    /** The password for APN, or empty string */
+    string password;
+
+    /** Data profile technology type */
+    DataProfileInfoType type;
+
+    /**
+     * The required wait time in seconds after a successful UE initiated disconnect of a given PDN
+     * connection before the device can send a new PDN connection request for that given PDN.
+     */
+    int32_t waitTime;
+
+    /** True to enable the profile, false to disable */
+    bool enabled;
+
+    /** Supported APN types bitmap. See ApnTypes for the value of each bit. */
+    bitfield<ApnTypes> supportedApnTypesBitmap;
+
+    /** The bearer bitmap. See RadioAccessFamily for the value of each bit. */
+    bitfield<RadioAccessFamily> bearerBitmap;
+
+    /** Maximum transmission unit (MTU) size in bytes */
+    int32_t mtu;
+
+    /**
+     * True if this data profile was used to bring up the last default (i.e internet) data
+     * connection successfully.
+     */
+    bool preferred;
+
+    /**
+     * If true, modem must persist this data profile and profileId must not be
+     * set to DataProfileId.INVALID. If the same data profile exists, this data profile must
+     * overwrite it.
+     */
+    bool persistent;
+};
diff --git a/sensors/2.0/ISensors.hal b/sensors/2.0/ISensors.hal
index 2a57251..939bf73 100644
--- a/sensors/2.0/ISensors.hal
+++ b/sensors/2.0/ISensors.hal
@@ -27,6 +27,13 @@
 interface ISensors {
     /**
      * Enumerate all available (static) sensors.
+     *
+     * The SensorInfo for each sensor returned by getSensorsList must be stable
+     * from the initial call to getSensorsList after a device boot until the
+     * entire system restarts. The SensorInfo for each sensor must not change
+     * between subsequent calls to getSensorsList, even across restarts of the
+     * HAL and its dependencies (for example, the sensor handle for a given
+     * sensor must not change across HAL restarts).
      */
     getSensorsList() generates (vec<SensorInfo> list);
 
diff --git a/tests/foo/1.0/IFoo.hal b/tests/foo/1.0/IFoo.hal
index 4a930a2..9642e2a 100644
--- a/tests/foo/1.0/IFoo.hal
+++ b/tests/foo/1.0/IFoo.hal
@@ -103,7 +103,6 @@
         union U {
             int8_t number;
             int8_t[1][2] multidimArray;
-            pointer p;
             Fumble anotherStruct;
             bitfield<BitField> bf;
         } u;
diff --git a/wifi/1.3/Android.bp b/wifi/1.3/Android.bp
index 95fbf83..5e87c1c 100644
--- a/wifi/1.3/Android.bp
+++ b/wifi/1.3/Android.bp
@@ -7,7 +7,9 @@
         enabled: true,
     },
     srcs: [
+        "types.hal",
         "IWifi.hal",
+        "IWifiStaIface.hal",
     ],
     interfaces: [
         "android.hardware.wifi@1.0",
@@ -15,6 +17,10 @@
         "android.hardware.wifi@1.2",
         "android.hidl.base@1.0",
     ],
+    types: [
+      "StaLinkLayerRadioStats",
+      "StaLinkLayerStats",
+    ],
     gen_java: true,
 }
 
diff --git a/wifi/1.3/IWifiStaIface.hal b/wifi/1.3/IWifiStaIface.hal
new file mode 100644
index 0000000..0dc6128
--- /dev/null
+++ b/wifi/1.3/IWifiStaIface.hal
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2018 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.wifi@1.3;
+
+import @1.0::WifiStatus;
+import @1.2::IWifiStaIface;
+
+/**
+ * Interface used to represent a single STA iface.
+ *
+ * IWifiChip.createStaIface() may return a @1.3::IWifiStaIface when supported.
+ */
+interface IWifiStaIface extends @1.2::IWifiStaIface {
+    /**
+     * Retrieve the latest link layer stats.
+     * Must fail if |StaIfaceCapabilityMask.LINK_LAYER_STATS| is not set or if
+     * link layer stats collection hasn't been explicitly enabled.
+     *
+     * @return status WifiStatus of the operation.
+     *     Possible status codes:
+     *     |WifiStatusCode.SUCCESS|,
+     *     |WifiStatusCode.ERROR_WIFI_IFACE_INVALID|,
+     *     |WifiStatusCode.ERROR_NOT_SUPPORTED|,
+     *     |WifiStatusCode.ERROR_NOT_STARTED|,
+     *     |WifiStatusCode.ERROR_NOT_AVAILABLE|,
+     *     |WifiStatusCode.ERROR_UNKNOWN|
+     * @return stats Instance of |LinkLayerStats|.
+     */
+    getLinkLayerStats_1_3() generates (WifiStatus status, StaLinkLayerStats stats);
+};
diff --git a/wifi/1.3/default/hidl_struct_util.cpp b/wifi/1.3/default/hidl_struct_util.cpp
index e793236..c88ddaa 100644
--- a/wifi/1.3/default/hidl_struct_util.cpp
+++ b/wifi/1.3/default/hidl_struct_util.cpp
@@ -785,7 +785,7 @@
 
 bool convertLegacyLinkLayerStatsToHidl(
     const legacy_hal::LinkLayerStats& legacy_stats,
-    StaLinkLayerStats* hidl_stats) {
+    V1_3::StaLinkLayerStats* hidl_stats) {
     if (!hidl_stats) {
         return false;
     }
@@ -826,16 +826,26 @@
     hidl_stats->iface.wmeVoPktStats.retries =
         legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].retries;
     // radio legacy_stats conversion.
-    std::vector<StaLinkLayerRadioStats> hidl_radios_stats;
+    std::vector<V1_3::StaLinkLayerRadioStats> hidl_radios_stats;
     for (const auto& legacy_radio_stats : legacy_stats.radios) {
-        StaLinkLayerRadioStats hidl_radio_stats;
-        hidl_radio_stats.onTimeInMs = legacy_radio_stats.stats.on_time;
-        hidl_radio_stats.txTimeInMs = legacy_radio_stats.stats.tx_time;
-        hidl_radio_stats.rxTimeInMs = legacy_radio_stats.stats.rx_time;
-        hidl_radio_stats.onTimeInMsForScan =
+        V1_3::StaLinkLayerRadioStats hidl_radio_stats;
+        hidl_radio_stats.V1_0.onTimeInMs = legacy_radio_stats.stats.on_time;
+        hidl_radio_stats.V1_0.txTimeInMs = legacy_radio_stats.stats.tx_time;
+        hidl_radio_stats.V1_0.rxTimeInMs = legacy_radio_stats.stats.rx_time;
+        hidl_radio_stats.V1_0.onTimeInMsForScan =
             legacy_radio_stats.stats.on_time_scan;
-        hidl_radio_stats.txTimeInMsPerLevel =
+        hidl_radio_stats.V1_0.txTimeInMsPerLevel =
             legacy_radio_stats.tx_time_per_levels;
+        hidl_radio_stats.onTimeInMsForNanScan =
+            legacy_radio_stats.stats.on_time_nbd;
+        hidl_radio_stats.onTimeInMsForBgScan =
+            legacy_radio_stats.stats.on_time_gscan;
+        hidl_radio_stats.onTimeInMsForRoamScan =
+            legacy_radio_stats.stats.on_time_roam_scan;
+        hidl_radio_stats.onTimeInMsForPnoScan =
+            legacy_radio_stats.stats.on_time_pno_scan;
+        hidl_radio_stats.onTimeInMsForHs20Scan =
+            legacy_radio_stats.stats.on_time_hs20;
         hidl_radios_stats.push_back(hidl_radio_stats);
     }
     hidl_stats->radios = hidl_radios_stats;
diff --git a/wifi/1.3/default/hidl_struct_util.h b/wifi/1.3/default/hidl_struct_util.h
index e2ba00c..8df484d 100644
--- a/wifi/1.3/default/hidl_struct_util.h
+++ b/wifi/1.3/default/hidl_struct_util.h
@@ -24,6 +24,7 @@
 #include <android/hardware/wifi/1.2/IWifiChip.h>
 #include <android/hardware/wifi/1.2/IWifiChipEventCallback.h>
 #include <android/hardware/wifi/1.2/types.h>
+#include <android/hardware/wifi/1.3/types.h>
 
 #include "wifi_legacy_hal.h"
 
@@ -89,7 +90,7 @@
     std::vector<StaScanData>* hidl_scan_datas);
 bool convertLegacyLinkLayerStatsToHidl(
     const legacy_hal::LinkLayerStats& legacy_stats,
-    StaLinkLayerStats* hidl_stats);
+    V1_3::StaLinkLayerStats* hidl_stats);
 bool convertLegacyRoamingCapabilitiesToHidl(
     const legacy_hal::wifi_roaming_capabilities& legacy_caps,
     StaRoamingCapabilities* hidl_caps);
diff --git a/wifi/1.3/default/tests/hidl_struct_util_unit_tests.cpp b/wifi/1.3/default/tests/hidl_struct_util_unit_tests.cpp
index 4cd3719..d600a2b 100644
--- a/wifi/1.3/default/tests/hidl_struct_util_unit_tests.cpp
+++ b/wifi/1.3/default/tests/hidl_struct_util_unit_tests.cpp
@@ -126,6 +126,118 @@
     EXPECT_EQ(static_cast<uint32_t>(legacy_iface_info2.channel),
               hidl_iface_info2.channel);
 }
+
+TEST_F(HidlStructUtilTest, canConvertLegacyLinkLayerStatsToHidl) {
+    legacy_hal::LinkLayerStats legacy_stats{};
+    legacy_stats.radios.push_back(legacy_hal::LinkLayerRadioStats{});
+    legacy_stats.radios.push_back(legacy_hal::LinkLayerRadioStats{});
+    legacy_stats.iface.beacon_rx = rand();
+    legacy_stats.iface.rssi_mgmt = rand();
+    legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].rx_mpdu = rand();
+    legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].tx_mpdu = rand();
+    legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].mpdu_lost = rand();
+    legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].retries = rand();
+
+    legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].rx_mpdu = rand();
+    legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].tx_mpdu = rand();
+    legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].mpdu_lost = rand();
+    legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].retries = rand();
+
+    legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].rx_mpdu = rand();
+    legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].tx_mpdu = rand();
+    legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].mpdu_lost = rand();
+    legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].retries = rand();
+
+    legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].rx_mpdu = rand();
+    legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].tx_mpdu = rand();
+    legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].mpdu_lost = rand();
+    legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].retries = rand();
+
+    for (auto& radio : legacy_stats.radios) {
+        radio.stats.on_time = rand();
+        radio.stats.tx_time = rand();
+        radio.stats.rx_time = rand();
+        radio.stats.on_time_scan = rand();
+        radio.stats.on_time_nbd = rand();
+        radio.stats.on_time_gscan = rand();
+        radio.stats.on_time_roam_scan = rand();
+        radio.stats.on_time_pno_scan = rand();
+        radio.stats.on_time_hs20 = rand();
+        for (int i = 0; i < 4; i++) {
+            radio.tx_time_per_levels.push_back(rand());
+        }
+    }
+
+    V1_3::StaLinkLayerStats converted{};
+    hidl_struct_util::convertLegacyLinkLayerStatsToHidl(legacy_stats,
+                                                        &converted);
+    EXPECT_EQ(legacy_stats.iface.beacon_rx, converted.iface.beaconRx);
+    EXPECT_EQ(legacy_stats.iface.rssi_mgmt, converted.iface.avgRssiMgmt);
+    EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].rx_mpdu,
+              converted.iface.wmeBePktStats.rxMpdu);
+    EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].tx_mpdu,
+              converted.iface.wmeBePktStats.txMpdu);
+    EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].mpdu_lost,
+              converted.iface.wmeBePktStats.lostMpdu);
+    EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].retries,
+              converted.iface.wmeBePktStats.retries);
+
+    EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].rx_mpdu,
+              converted.iface.wmeBkPktStats.rxMpdu);
+    EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].tx_mpdu,
+              converted.iface.wmeBkPktStats.txMpdu);
+    EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].mpdu_lost,
+              converted.iface.wmeBkPktStats.lostMpdu);
+    EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].retries,
+              converted.iface.wmeBkPktStats.retries);
+
+    EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].rx_mpdu,
+              converted.iface.wmeViPktStats.rxMpdu);
+    EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].tx_mpdu,
+              converted.iface.wmeViPktStats.txMpdu);
+    EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].mpdu_lost,
+              converted.iface.wmeViPktStats.lostMpdu);
+    EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].retries,
+              converted.iface.wmeViPktStats.retries);
+
+    EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].rx_mpdu,
+              converted.iface.wmeVoPktStats.rxMpdu);
+    EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].tx_mpdu,
+              converted.iface.wmeVoPktStats.txMpdu);
+    EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].mpdu_lost,
+              converted.iface.wmeVoPktStats.lostMpdu);
+    EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].retries,
+              converted.iface.wmeVoPktStats.retries);
+
+    EXPECT_EQ(legacy_stats.radios.size(), converted.radios.size());
+    for (int i = 0; i < legacy_stats.radios.size(); i++) {
+        EXPECT_EQ(legacy_stats.radios[i].stats.on_time,
+                  converted.radios[i].V1_0.onTimeInMs);
+        EXPECT_EQ(legacy_stats.radios[i].stats.tx_time,
+                  converted.radios[i].V1_0.txTimeInMs);
+        EXPECT_EQ(legacy_stats.radios[i].stats.rx_time,
+                  converted.radios[i].V1_0.rxTimeInMs);
+        EXPECT_EQ(legacy_stats.radios[i].stats.on_time_scan,
+                  converted.radios[i].V1_0.onTimeInMsForScan);
+        EXPECT_EQ(legacy_stats.radios[i].tx_time_per_levels.size(),
+                  converted.radios[i].V1_0.txTimeInMsPerLevel.size());
+        for (int j = 0; j < legacy_stats.radios[i].tx_time_per_levels.size();
+             j++) {
+            EXPECT_EQ(legacy_stats.radios[i].tx_time_per_levels[j],
+                      converted.radios[i].V1_0.txTimeInMsPerLevel[j]);
+        }
+        EXPECT_EQ(legacy_stats.radios[i].stats.on_time_nbd,
+                  converted.radios[i].onTimeInMsForNanScan);
+        EXPECT_EQ(legacy_stats.radios[i].stats.on_time_gscan,
+                  converted.radios[i].onTimeInMsForBgScan);
+        EXPECT_EQ(legacy_stats.radios[i].stats.on_time_roam_scan,
+                  converted.radios[i].onTimeInMsForRoamScan);
+        EXPECT_EQ(legacy_stats.radios[i].stats.on_time_pno_scan,
+                  converted.radios[i].onTimeInMsForPnoScan);
+        EXPECT_EQ(legacy_stats.radios[i].stats.on_time_hs20,
+                  converted.radios[i].onTimeInMsForHs20Scan);
+    }
+}
 }  // namespace implementation
 }  // namespace V1_3
 }  // namespace wifi
diff --git a/wifi/1.3/default/tests/wifi_chip_unit_tests.cpp b/wifi/1.3/default/tests/wifi_chip_unit_tests.cpp
index 2d9050d..61060b5 100644
--- a/wifi/1.3/default/tests/wifi_chip_unit_tests.cpp
+++ b/wifi/1.3/default/tests/wifi_chip_unit_tests.cpp
@@ -204,6 +204,19 @@
         }
     }
 
+    bool createRttController() {
+        bool success = false;
+        chip_->createRttController(
+            NULL, [&success](const WifiStatus& status,
+                             const sp<IWifiRttController>& rtt) {
+                if (WifiStatusCode::SUCCESS == status.code) {
+                    ASSERT_NE(rtt.get(), nullptr);
+                    success = true;
+                }
+            });
+        return success;
+    }
+
    public:
     void SetUp() override {
         chip_ = new WifiChip(chip_id_, legacy_hal_, mode_controller_,
@@ -386,6 +399,29 @@
     ASSERT_TRUE(createIface(IfaceType::NAN).empty());
 }
 
+TEST_F(WifiChipV1IfaceCombinationTest, RttControllerFlowStaModeNoSta) {
+    findModeAndConfigureForIfaceType(IfaceType::STA);
+    ASSERT_TRUE(createRttController());
+}
+
+TEST_F(WifiChipV1IfaceCombinationTest, RttControllerFlowStaModeWithSta) {
+    findModeAndConfigureForIfaceType(IfaceType::STA);
+    ASSERT_FALSE(createIface(IfaceType::STA).empty());
+    ASSERT_TRUE(createRttController());
+}
+
+TEST_F(WifiChipV1IfaceCombinationTest, RttControllerFlowApToSta) {
+    findModeAndConfigureForIfaceType(IfaceType::AP);
+    const auto ap_iface_name = createIface(IfaceType::AP);
+    ASSERT_FALSE(ap_iface_name.empty());
+    ASSERT_FALSE(createRttController());
+
+    removeIface(IfaceType::AP, ap_iface_name);
+
+    findModeAndConfigureForIfaceType(IfaceType::STA);
+    ASSERT_TRUE(createRttController());
+}
+
 ////////// V2 + Aware Iface Combinations ////////////
 // Mode 1 - STA + STA/AP
 //        - STA + P2P/NAN
@@ -540,6 +576,24 @@
     ASSERT_NE(sta_iface_name, ap_iface_name);
 }
 
+TEST_F(WifiChipV2_AwareIfaceCombinationTest, RttControllerFlowStaModeNoSta) {
+    findModeAndConfigureForIfaceType(IfaceType::STA);
+    ASSERT_TRUE(createRttController());
+}
+
+TEST_F(WifiChipV2_AwareIfaceCombinationTest, RttControllerFlowStaModeWithSta) {
+    findModeAndConfigureForIfaceType(IfaceType::STA);
+    ASSERT_FALSE(createIface(IfaceType::STA).empty());
+    ASSERT_TRUE(createRttController());
+}
+
+TEST_F(WifiChipV2_AwareIfaceCombinationTest, RttControllerFlow) {
+    findModeAndConfigureForIfaceType(IfaceType::STA);
+    ASSERT_FALSE(createIface(IfaceType::STA).empty());
+    ASSERT_FALSE(createIface(IfaceType::AP).empty());
+    ASSERT_TRUE(createRttController());
+}
+
 ////////// V1 Iface Combinations when AP creation is disabled //////////
 class WifiChipV1_AwareDisabledApIfaceCombinationTest : public WifiChipTest {
    public:
diff --git a/wifi/1.3/default/wifi_chip.cpp b/wifi/1.3/default/wifi_chip.cpp
index cf64e51..faf1862 100644
--- a/wifi/1.3/default/wifi_chip.cpp
+++ b/wifi/1.3/default/wifi_chip.cpp
@@ -930,6 +930,12 @@
 
 std::pair<WifiStatus, sp<IWifiRttController>>
 WifiChip::createRttControllerInternal(const sp<IWifiIface>& bound_iface) {
+    if (sta_ifaces_.size() == 0 &&
+        !canCurrentModeSupportIfaceOfType(IfaceType::STA)) {
+        LOG(ERROR) << "createRttControllerInternal: Chip cannot support STAs "
+                      "(and RTT by extension)";
+        return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}};
+    }
     sp<WifiRttController> rtt =
         new WifiRttController(getWlan0IfaceName(), bound_iface, legacy_hal_);
     rtt_controllers_.emplace_back(rtt);
diff --git a/wifi/1.3/default/wifi_sta_iface.cpp b/wifi/1.3/default/wifi_sta_iface.cpp
index 63341df..b0fa1ae 100644
--- a/wifi/1.3/default/wifi_sta_iface.cpp
+++ b/wifi/1.3/default/wifi_sta_iface.cpp
@@ -152,6 +152,13 @@
                            hidl_status_cb);
 }
 
+Return<void> WifiStaIface::getLinkLayerStats_1_3(
+    getLinkLayerStats_1_3_cb hidl_status_cb) {
+    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+                           &WifiStaIface::getLinkLayerStatsInternal_1_3,
+                           hidl_status_cb);
+}
+
 Return<void> WifiStaIface::startRssiMonitoring(
     uint32_t cmd_id, int32_t max_rssi, int32_t min_rssi,
     startRssiMonitoring_cb hidl_status_cb) {
@@ -445,8 +452,13 @@
     return createWifiStatusFromLegacyError(legacy_status);
 }
 
-std::pair<WifiStatus, StaLinkLayerStats>
+std::pair<WifiStatus, V1_0::StaLinkLayerStats>
 WifiStaIface::getLinkLayerStatsInternal() {
+    return {createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED), {}};
+}
+
+std::pair<WifiStatus, V1_3::StaLinkLayerStats>
+WifiStaIface::getLinkLayerStatsInternal_1_3() {
     legacy_hal::wifi_error legacy_status;
     legacy_hal::LinkLayerStats legacy_stats;
     std::tie(legacy_status, legacy_stats) =
@@ -454,7 +466,7 @@
     if (legacy_status != legacy_hal::WIFI_SUCCESS) {
         return {createWifiStatusFromLegacyError(legacy_status), {}};
     }
-    StaLinkLayerStats hidl_stats;
+    V1_3::StaLinkLayerStats hidl_stats;
     if (!hidl_struct_util::convertLegacyLinkLayerStatsToHidl(legacy_stats,
                                                              &hidl_stats)) {
         return {createWifiStatus(WifiStatusCode::ERROR_UNKNOWN), {}};
diff --git a/wifi/1.3/default/wifi_sta_iface.h b/wifi/1.3/default/wifi_sta_iface.h
index 0fc61e2..bc3090f 100644
--- a/wifi/1.3/default/wifi_sta_iface.h
+++ b/wifi/1.3/default/wifi_sta_iface.h
@@ -19,7 +19,7 @@
 
 #include <android-base/macros.h>
 #include <android/hardware/wifi/1.0/IWifiStaIfaceEventCallback.h>
-#include <android/hardware/wifi/1.2/IWifiStaIface.h>
+#include <android/hardware/wifi/1.3/IWifiStaIface.h>
 
 #include <wifi_system/interface_tool.h>
 
@@ -36,7 +36,7 @@
 /**
  * HIDL interface object used to control a STA Iface instance.
  */
-class WifiStaIface : public V1_2::IWifiStaIface {
+class WifiStaIface : public V1_3::IWifiStaIface {
    public:
     WifiStaIface(const std::string& ifname,
                  const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal);
@@ -75,6 +75,8 @@
         disableLinkLayerStatsCollection_cb hidl_status_cb) override;
     Return<void> getLinkLayerStats(
         getLinkLayerStats_cb hidl_status_cb) override;
+    Return<void> getLinkLayerStats_1_3(
+        getLinkLayerStats_1_3_cb hidl_status_cb) override;
     Return<void> startRssiMonitoring(
         uint32_t cmd_id, int32_t max_rssi, int32_t min_rssi,
         startRssiMonitoring_cb hidl_status_cb) override;
@@ -130,7 +132,9 @@
     WifiStatus stopBackgroundScanInternal(uint32_t cmd_id);
     WifiStatus enableLinkLayerStatsCollectionInternal(bool debug);
     WifiStatus disableLinkLayerStatsCollectionInternal();
-    std::pair<WifiStatus, StaLinkLayerStats> getLinkLayerStatsInternal();
+    std::pair<WifiStatus, V1_0::StaLinkLayerStats> getLinkLayerStatsInternal();
+    std::pair<WifiStatus, V1_3::StaLinkLayerStats>
+    getLinkLayerStatsInternal_1_3();
     WifiStatus startRssiMonitoringInternal(uint32_t cmd_id, int32_t max_rssi,
                                            int32_t min_rssi);
     WifiStatus stopRssiMonitoringInternal(uint32_t cmd_id);
diff --git a/wifi/1.3/types.hal b/wifi/1.3/types.hal
new file mode 100644
index 0000000..4585ff3
--- /dev/null
+++ b/wifi/1.3/types.hal
@@ -0,0 +1,68 @@
+/*
+ * Copyright 2018 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.wifi@1.3;
+
+import @1.0::StaLinkLayerRadioStats;
+import @1.0::StaLinkLayerIfaceStats;
+import @1.0::TimeStampInMs;
+
+struct StaLinkLayerRadioStats {
+    /**
+     * Baseline information as defined in HAL 1.0.
+     */
+    @1.0::StaLinkLayerRadioStats V1_0;
+
+    /**
+     * Total time for which the radio is awake due to NAN scan since boot or crash.
+     */
+    uint32_t onTimeInMsForNanScan;
+
+    /**
+     * Total time for which the radio is awake due to background scan since boot or crash.
+     */
+    uint32_t onTimeInMsForBgScan;
+
+    /**
+     * Total time for which the radio is awake due to roam scan since boot or crash.
+     */
+    uint32_t onTimeInMsForRoamScan;
+
+    /**
+     * Total time for which the radio is awake due to PNO scan since boot or crash.
+     */
+    uint32_t onTimeInMsForPnoScan;
+
+    /**
+     * Total time for which the radio is awake due to Hotspot 2.0 scans and GAS exchange since boot
+     * or crash.
+     */
+    uint32_t onTimeInMsForHs20Scan;
+};
+
+/**
+ * Link layer stats retrieved via |getLinkLayerStats|.
+ */
+struct StaLinkLayerStats {
+    StaLinkLayerIfaceStats iface;
+    vec<StaLinkLayerRadioStats> radios;
+    /**
+     * TimeStamp for each stats sample.
+     * This is the absolute milliseconds from boot when these stats were
+     * sampled.
+     */
+    TimeStampInMs timeStampInMs;
+};
\ No newline at end of file