Merge "Implement Gnss::start() and Gnss::stop()"
diff --git a/audio/2.0/default/service.cpp b/audio/2.0/default/service.cpp
deleted file mode 100644
index 3cf7134..0000000
--- a/audio/2.0/default/service.cpp
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright (C) 2016 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 "audiohalservice"
-
-#include <android/hardware/audio/2.0/IDevicesFactory.h>
-#include <android/hardware/audio/effect/2.0/IEffectsFactory.h>
-#include <android/hardware/soundtrigger/2.0/ISoundTriggerHw.h>
-#include <android/hardware/soundtrigger/2.1/ISoundTriggerHw.h>
-#include <hidl/HidlTransportSupport.h>
-#include <hidl/LegacySupport.h>
-
-using android::hardware::configureRpcThreadpool;
-using android::hardware::joinRpcThreadpool;
-using android::hardware::registerPassthroughServiceImplementation;
-
-using android::hardware::audio::effect::V2_0::IEffectsFactory;
-using android::hardware::audio::V2_0::IDevicesFactory;
-using V2_0_ISoundTriggerHw = android::hardware::soundtrigger::V2_0::ISoundTriggerHw;
-using V2_1_ISoundTriggerHw = android::hardware::soundtrigger::V2_1::ISoundTriggerHw;
-using android::hardware::registerPassthroughServiceImplementation;
-
-using android::OK;
-
-int main(int /* argc */, char* /* argv */ []) {
-    configureRpcThreadpool(16, true /*callerWillJoin*/);
-    android::status_t status;
-    status = registerPassthroughServiceImplementation<IDevicesFactory>();
-    LOG_ALWAYS_FATAL_IF(status != OK, "Error while registering audio service: %d", status);
-    status = registerPassthroughServiceImplementation<IEffectsFactory>();
-    LOG_ALWAYS_FATAL_IF(status != OK, "Error while registering audio effects service: %d", status);
-    // Soundtrigger might be not present.
-    status = registerPassthroughServiceImplementation<V2_1_ISoundTriggerHw>();
-    ALOGW_IF(status != OK, "Registering soundtrigger V2.1 service was unsuccessful: %d", status);
-    status = registerPassthroughServiceImplementation<V2_0_ISoundTriggerHw>();
-    ALOGW_IF(status != OK, "Registering soundtrigger V2.0 service was unsuccessful: %d", status);
-    joinRpcThreadpool();
-    return status;
-}
diff --git a/audio/4.0/IDevice.hal b/audio/4.0/IDevice.hal
index 7eb03c8..1bb5aba 100644
--- a/audio/4.0/IDevice.hal
+++ b/audio/4.0/IDevice.hal
@@ -132,7 +132,6 @@
      * @param device device type and (if needed) address.
      * @param config stream configuration.
      * @param flags additional flags.
-     * @param source source specification.
      * @param sinkMetadata Description of the audio that is suggested by the client.
      *                     May be used by implementations to configure hardware effects.
      * @return retval operation completion status.
diff --git a/audio/4.0/IDevicesFactory.hal b/audio/4.0/IDevicesFactory.hal
index c552c6d..489294e 100644
--- a/audio/4.0/IDevicesFactory.hal
+++ b/audio/4.0/IDevicesFactory.hal
@@ -18,42 +18,53 @@
 
 import android.hardware.audio.common@4.0;
 import IDevice;
+import IPrimaryDevice;
 
+/** This factory allows a HAL implementation to be split in multiple independent
+ *  devices (called module in the pre-treble API).
+ *  Note that this division is arbitrary and implementation are free
+ *  to only have a Primary.
+ *  The framework will query the devices according to audio_policy_configuration.xml
+ *
+ *  Each device name is arbitrary, provided by the vendor's audio_policy_configuration.xml
+ *  and only used to identify a device in this factory.
+ *  The framework must not interpret the name, treating it as a vendor opaque data
+ *  with the following exception:
+ *  - the "r_submix" device that must be present to support policyMixes (Eg: Android projected).
+ *    Note that this Device is included by default in a build derived from AOSP.
+ *
+ *  Note that on AOSP Oreo (including MR1) the "a2dp" module is not using this API
+ *  but is loaded directly from the system partition using the legacy API
+ *  due to limitations with the Bluetooth framework.
+ */
 interface IDevicesFactory {
-    /** Allows a HAL implementation to be split in multiple independent
-     *  devices (called module in the pre-treble API).
-     *  Note that this division is arbitrary and implementation are free
-     *  to only have a Primary.
-     *  The framework will query the devices according to audio_policy_configuration.xml
-     *
-     *  Each Device value is interchangeable with any other and the framework
-     *  does not differentiate between values with the following exceptions:
-     *  - the Primary device must always be present
-     *  - the R_SUBMIX that is used to forward audio of REMOTE_SUBMIX DEVICES
-     */
-    enum Device : int32_t {
-        PRIMARY,
-        A2DP,
-        USB,
-        R_SUBMIX,
-        STUB,
-        CODEC_OFFLOAD,
-        SECONDARY,
-        AUXILIARY,
-        /** Multi Stream Decoder */
-        MSD
-    };
 
     /**
      * Opens an audio device. To close the device, it is necessary to release
      * references to the returned device object.
      *
-     * @param device device type.
+     * @param device device name.
      * @return retval operation completion status. Returns INVALID_ARGUMENTS
      *         if there is no corresponding hardware module found,
      *         NOT_INITIALIZED if an error occured while opening the hardware
      *         module.
      * @return result the interface for the created device.
      */
-    openDevice(Device device) generates (Result retval, IDevice result);
+    openDevice(string device) generates (Result retval, IDevice result);
+
+    /**
+     * Opens the Primary audio device that must be present.
+     * This function is not optional and must return successfully the primary device.
+     *
+     * This device must have the name "primary".
+     *
+     * The telephony stack uses this device to control the audio during a voice call.
+     *
+     * @return retval operation completion status. Must be SUCCESS.
+     *         For debuging, return INVALID_ARGUMENTS if there is no corresponding
+     *         hardware module found, NOT_INITIALIZED if an error occurred
+     *         while opening the hardware module.
+     * @return result the interface for the created device.
+     */
+    openPrimaryDevice() generates (Result retval, IPrimaryDevice result);
 };
diff --git a/audio/4.0/config/audio_policy_configuration.xsd b/audio/4.0/config/audio_policy_configuration.xsd
index 924fb47..e5b4449 100644
--- a/audio/4.0/config/audio_policy_configuration.xsd
+++ b/audio/4.0/config/audio_policy_configuration.xsd
@@ -66,35 +66,6 @@
     <xs:complexType name="globalConfiguration">
         <xs:attribute name="speaker_drc_enabled" type="xs:boolean" use="required"/>
     </xs:complexType>
-    <!-- Enum values of IDevicesFactory::Device
-         TODO: generate from hidl to avoid manual sync. -->
-    <xs:simpleType name="halName">
-        <xs:union>
-            <xs:simpleType>
-                <xs:restriction base="xs:string">
-                    <xs:enumeration value="primary"/>
-                    <xs:enumeration value="a2dp"/>
-                    <xs:enumeration value="usb"/>
-                    <xs:enumeration value="r_submix"/>
-                    <xs:enumeration value="codec_offload"/>
-                    <xs:enumeration value="stub"/>
-                </xs:restriction>
-            </xs:simpleType>
-            <xs:simpleType>
-                <xs:annotation>
-                    <xs:documentation xml:lang="en">
-                        Vendor eXtension names must be in the vx namespace.
-                        Vendor are encouraged to namespace their module names.
-                        Example for an hypothetical Google virtual reality HAL:
-                            <module name="vx_google_vr" halVersion="3.0"/>
-                    </xs:documentation>
-                </xs:annotation>
-                <xs:restriction base="xs:string">
-                    <xs:pattern value="vx_[_a-zA-Z0-9]+"/>
-                </xs:restriction>
-            </xs:simpleType>
-        </xs:union>
-    </xs:simpleType>
     <xs:complexType name="modules">
         <xs:annotation>
             <xs:documentation xml:lang="en">
@@ -133,7 +104,7 @@
                         <xs:element name="devicePorts" type="devicePorts" minOccurs="0"/>
                         <xs:element name="routes" type="routes" minOccurs="0"/>
                     </xs:sequence>
-                    <xs:attribute name="name" type="halName" use="required"/>
+                    <xs:attribute name="name" type="xsd:string" use="required"/>
                     <xs:attribute name="halVersion" type="halVersion" use="required"/>
                 </xs:complexType>
                 <xs:unique name="mixPortNameUniqueness">
diff --git a/audio/common/2.0/default/OWNERS b/audio/common/2.0/default/OWNERS
new file mode 100644
index 0000000..6fdc97c
--- /dev/null
+++ b/audio/common/2.0/default/OWNERS
@@ -0,0 +1,3 @@
+elaurent@google.com
+krocard@google.com
+mnaganov@google.com
diff --git a/audio/common/2.0/default/VersionUtils.h b/audio/common/2.0/default/VersionUtils.h
new file mode 100644
index 0000000..60d1f9c
--- /dev/null
+++ b/audio/common/2.0/default/VersionUtils.h
@@ -0,0 +1,41 @@
+/*
+ * 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_AUDIO_EFFECT_VERSION_UTILS_H
+#define ANDROID_HARDWARE_AUDIO_EFFECT_VERSION_UTILS_H
+
+#include <android/hardware/audio/common/2.0/types.h>
+
+namespace android {
+namespace hardware {
+namespace audio {
+namespace common {
+namespace V2_0 {
+namespace implementation {
+
+typedef common::V2_0::AudioDevice AudioDeviceBitfield;
+typedef common::V2_0::AudioChannelMask AudioChannelBitfield;
+typedef common::V2_0::AudioOutputFlag AudioOutputFlagBitfield;
+typedef common::V2_0::AudioInputFlag AudioInputFlagBitfield;
+
+}  // namespace implementation
+}  // namespace V2_0
+}  // namespace common
+}  // namespace audio
+}  // namespace hardware
+}  // namespace android
+
+#endif  // ANDROID_HARDWARE_AUDIO_EFFECT_VERSION_UTILS_H
diff --git a/audio/common/4.0/default/Android.bp b/audio/common/4.0/default/Android.bp
new file mode 100644
index 0000000..57b2e01
--- /dev/null
+++ b/audio/common/4.0/default/Android.bp
@@ -0,0 +1,47 @@
+//
+// 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.
+
+cc_library_shared {
+    name: "android.hardware.audio.common@4.0-util",
+    defaults: ["hidl_defaults"],
+    vendor_available: true,
+    vndk: {
+        enabled: true,
+    },
+    srcs: [
+        "HidlUtils.cpp",
+    ],
+
+    export_include_dirs: ["."],
+
+    static_libs: [
+    ],
+
+    shared_libs: [
+        "liblog",
+        "libutils",
+        "libhidlbase",
+        "android.hardware.audio.common-util",
+        "android.hardware.audio.common@4.0",
+    ],
+    export_shared_lib_headers: [
+        "android.hardware.audio.common-util"
+    ],
+
+    header_libs: [
+        "libaudio_system_headers",
+        "libhardware_headers",
+    ],
+}
diff --git a/audio/common/4.0/default/HidlUtils.cpp b/audio/common/4.0/default/HidlUtils.cpp
new file mode 100644
index 0000000..b66eff9
--- /dev/null
+++ b/audio/common/4.0/default/HidlUtils.cpp
@@ -0,0 +1,21 @@
+/*
+ * 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.
+ */
+
+#include "HidlUtils.h"
+
+#define AUDIO_HAL_VERSION V4_0
+#include <common/all-versions/default/HidlUtils.impl.h>
+#undef AUDIO_HAL_VERSION
diff --git a/audio/common/4.0/default/HidlUtils.h b/audio/common/4.0/default/HidlUtils.h
new file mode 100644
index 0000000..91e6a9e
--- /dev/null
+++ b/audio/common/4.0/default/HidlUtils.h
@@ -0,0 +1,26 @@
+/*
+ * 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_audio_V4_0_Hidl_Utils_H_
+#define android_hardware_audio_V4_0_Hidl_Utils_H_
+
+#include <android/hardware/audio/common/4.0/types.h>
+
+#define AUDIO_HAL_VERSION V4_0
+#include <common/all-versions/default/HidlUtils.h>
+#undef AUDIO_HAL_VERSION
+
+#endif  // android_hardware_audio_V4_0_Hidl_Utils_H_
diff --git a/audio/common/4.0/default/OWNERS b/audio/common/4.0/default/OWNERS
new file mode 100644
index 0000000..6fdc97c
--- /dev/null
+++ b/audio/common/4.0/default/OWNERS
@@ -0,0 +1,3 @@
+elaurent@google.com
+krocard@google.com
+mnaganov@google.com
diff --git a/audio/common/4.0/default/VersionUtils.h b/audio/common/4.0/default/VersionUtils.h
new file mode 100644
index 0000000..b7f2aec
--- /dev/null
+++ b/audio/common/4.0/default/VersionUtils.h
@@ -0,0 +1,41 @@
+/*
+ * 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_AUDIO_EFFECT_VERSION_UTILS_H
+#define ANDROID_HARDWARE_AUDIO_EFFECT_VERSION_UTILS_H
+
+#include <android/hardware/audio/common/4.0/types.h>
+
+namespace android {
+namespace hardware {
+namespace audio {
+namespace common {
+namespace V4_0 {
+namespace implementation {
+
+typedef hidl_bitfield<common::V4_0::AudioDevice> AudioDeviceBitfield;
+typedef hidl_bitfield<common::V4_0::AudioChannelMask> AudioChannelBitfield;
+typedef hidl_bitfield<common::V4_0::AudioOutputFlag> AudioOutputFlagBitfield;
+typedef hidl_bitfield<common::V4_0::AudioInputFlag> AudioInputFlagBitfield;
+
+}  // namespace implementation
+}  // namespace V4_0
+}  // namespace common
+}  // namespace audio
+}  // namespace hardware
+}  // namespace android
+
+#endif  // ANDROID_HARDWARE_AUDIO_EFFECT_VERSION_UTILS_H
diff --git a/audio/common/4.0/types.hal b/audio/common/4.0/types.hal
index 4efdea3..0adff73 100644
--- a/audio/common/4.0/types.hal
+++ b/audio/common/4.0/types.hal
@@ -104,8 +104,6 @@
     TTS              = 9,  // Transmitted Through Speaker.  Plays over speaker
                            // only, silent on other devices
     ACCESSIBILITY    = 10, // For accessibility talk back prompts
-    REROUTING        = 11, // For dynamic policy output mixes
-    PATCH            = 12, // For internal audio flinger tracks.  Fixed volume
 };
 
 @export(name="audio_source_t", value_prefix="AUDIO_SOURCE_")
@@ -657,6 +655,8 @@
 /** Type of audio generated by an application. */
 @export(name="audio_content_type_t", value_prefix="AUDIO_CONTENT_TYPE_")
 enum AudioContentType : uint32_t {
+    // Do not change these values without updating their counterparts
+    // in frameworks/base/media/java/android/media/AudioAttributes.java
     UNKNOWN      = 0,
     SPEECH       = 1,
     MUSIC        = 2,
diff --git a/audio/common/all-versions/default/Android.bp b/audio/common/all-versions/default/Android.bp
index 8f6b74c..4a27bb7 100644
--- a/audio/common/all-versions/default/Android.bp
+++ b/audio/common/all-versions/default/Android.bp
@@ -33,7 +33,11 @@
     ],
 
     header_libs: [
+        "android.hardware.audio.common.util@all-versions",
         "libaudio_system_headers",
         "libhardware_headers",
     ],
+    export_header_lib_headers: [
+        "android.hardware.audio.common.util@all-versions",
+    ]
 }
diff --git a/audio/common/all-versions/default/include/common/all-versions/default/HidlUtils.h b/audio/common/all-versions/default/include/common/all-versions/default/HidlUtils.h
index 1654ac6..f9a5697 100644
--- a/audio/common/all-versions/default/include/common/all-versions/default/HidlUtils.h
+++ b/audio/common/all-versions/default/include/common/all-versions/default/HidlUtils.h
@@ -47,6 +47,8 @@
                                      struct audio_gain_config* halConfig);
     static void audioGainFromHal(const struct audio_gain& halGain, AudioGain* gain);
     static void audioGainToHal(const AudioGain& gain, struct audio_gain* halGain);
+    static AudioUsage audioUsageFromHal(const audio_usage_t halUsage);
+    static audio_usage_t audioUsageToHal(const AudioUsage usage);
     static void audioOffloadInfoFromHal(const audio_offload_info_t& halOffload,
                                         AudioOffloadInfo* offload);
     static void audioOffloadInfoToHal(const AudioOffloadInfo& offload,
diff --git a/audio/common/all-versions/default/include/common/all-versions/default/HidlUtils.impl.h b/audio/common/all-versions/default/include/common/all-versions/default/HidlUtils.impl.h
index 935f307..8ab7350 100644
--- a/audio/common/all-versions/default/include/common/all-versions/default/HidlUtils.impl.h
+++ b/audio/common/all-versions/default/include/common/all-versions/default/HidlUtils.impl.h
@@ -18,6 +18,7 @@
 #error "AUDIO_HAL_VERSION must be set before including this file."
 #endif
 
+#include <common/all-versions/VersionUtils.h>
 #include <string.h>
 
 using ::android::hardware::audio::common::AUDIO_HAL_VERSION::AudioChannelMask;
@@ -32,6 +33,8 @@
 using ::android::hardware::audio::common::AUDIO_HAL_VERSION::AudioStreamType;
 using ::android::hardware::audio::common::AUDIO_HAL_VERSION::AudioUsage;
 
+using ::android::hardware::audio::common::utils::mkEnumConverter;
+
 namespace android {
 namespace hardware {
 namespace audio {
@@ -40,7 +43,7 @@
 
 void HidlUtils::audioConfigFromHal(const audio_config_t& halConfig, AudioConfig* config) {
     config->sampleRateHz = halConfig.sample_rate;
-    config->channelMask = AudioChannelMask(halConfig.channel_mask);
+    config->channelMask = mkEnumConverter<AudioChannelMask>(halConfig.channel_mask);
     config->format = AudioFormat(halConfig.format);
     audioOffloadInfoFromHal(halConfig.offload_info, &config->offloadInfo);
     config->frameCount = halConfig.frame_count;
@@ -58,8 +61,8 @@
 void HidlUtils::audioGainConfigFromHal(const struct audio_gain_config& halConfig,
                                        AudioGainConfig* config) {
     config->index = halConfig.index;
-    config->mode = AudioGainMode(halConfig.mode);
-    config->channelMask = AudioChannelMask(halConfig.channel_mask);
+    config->mode = mkEnumConverter<AudioGainMode>(halConfig.mode);
+    config->channelMask = mkEnumConverter<AudioChannelMask>(halConfig.channel_mask);
     for (size_t i = 0; i < sizeof(audio_channel_mask_t) * 8; ++i) {
         config->values[i] = halConfig.values[i];
     }
@@ -79,8 +82,8 @@
 }
 
 void HidlUtils::audioGainFromHal(const struct audio_gain& halGain, AudioGain* gain) {
-    gain->mode = AudioGainMode(halGain.mode);
-    gain->channelMask = AudioChannelMask(halGain.channel_mask);
+    gain->mode = mkEnumConverter<AudioGainMode>(halGain.mode);
+    gain->channelMask = mkEnumConverter<AudioChannelMask>(halGain.channel_mask);
     gain->minValue = halGain.min_value;
     gain->maxValue = halGain.max_value;
     gain->defaultValue = halGain.default_value;
@@ -100,10 +103,26 @@
     halGain->max_ramp_ms = gain.maxRampMs;
 }
 
+AudioUsage HidlUtils::audioUsageFromHal(const audio_usage_t halUsage) {
+    switch (halUsage) {
+        case AUDIO_USAGE_NOTIFICATION_COMMUNICATION_REQUEST:
+        case AUDIO_USAGE_NOTIFICATION_COMMUNICATION_INSTANT:
+        case AUDIO_USAGE_NOTIFICATION_COMMUNICATION_DELAYED:
+        case AUDIO_USAGE_NOTIFICATION_EVENT:
+            return AudioUsage::NOTIFICATION;
+        default:
+            return static_cast<AudioUsage>(halUsage);
+    }
+}
+
+audio_usage_t HidlUtils::audioUsageToHal(const AudioUsage usage) {
+    return static_cast<audio_usage_t>(usage);
+}
+
 void HidlUtils::audioOffloadInfoFromHal(const audio_offload_info_t& halOffload,
                                         AudioOffloadInfo* offload) {
     offload->sampleRateHz = halOffload.sample_rate;
-    offload->channelMask = AudioChannelMask(halOffload.channel_mask);
+    offload->channelMask = mkEnumConverter<AudioChannelMask>(halOffload.channel_mask);
     offload->format = AudioFormat(halOffload.format);
     offload->streamType = AudioStreamType(halOffload.stream_type);
     offload->bitRatePerSecond = halOffload.bit_rate;
@@ -112,7 +131,7 @@
     offload->isStreaming = halOffload.is_streaming;
     offload->bitWidth = halOffload.bit_width;
     offload->bufferSize = halOffload.offload_buffer_size;
-    offload->usage = static_cast<AudioUsage>(halOffload.usage);
+    offload->usage = audioUsageFromHal(halOffload.usage);
 }
 
 void HidlUtils::audioOffloadInfoToHal(const AudioOffloadInfo& offload,
@@ -128,7 +147,7 @@
     halOffload->is_streaming = offload.isStreaming;
     halOffload->bit_width = offload.bitWidth;
     halOffload->offload_buffer_size = offload.bufferSize;
-    halOffload->usage = static_cast<audio_usage_t>(offload.usage);
+    halOffload->usage = audioUsageToHal(offload.usage);
 }
 
 void HidlUtils::audioPortConfigFromHal(const struct audio_port_config& halConfig,
@@ -136,9 +155,9 @@
     config->id = halConfig.id;
     config->role = AudioPortRole(halConfig.role);
     config->type = AudioPortType(halConfig.type);
-    config->configMask = AudioPortConfigMask(halConfig.config_mask);
+    config->configMask = mkEnumConverter<AudioPortConfigMask>(halConfig.config_mask);
     config->sampleRateHz = halConfig.sample_rate;
-    config->channelMask = AudioChannelMask(halConfig.channel_mask);
+    config->channelMask = mkEnumConverter<AudioChannelMask>(halConfig.channel_mask);
     config->format = AudioFormat(halConfig.format);
     audioGainConfigFromHal(halConfig.gain, &config->gain);
     switch (halConfig.type) {
@@ -238,7 +257,7 @@
     }
     port->channelMasks.resize(halPort.num_channel_masks);
     for (size_t i = 0; i < halPort.num_channel_masks; ++i) {
-        port->channelMasks[i] = AudioChannelMask(halPort.channel_masks[i]);
+        port->channelMasks[i] = mkEnumConverter<AudioChannelMask>(halPort.channel_masks[i]);
     }
     port->formats.resize(halPort.num_formats);
     for (size_t i = 0; i < halPort.num_formats; ++i) {
@@ -277,8 +296,8 @@
     halPort->id = port.id;
     halPort->role = static_cast<audio_port_role_t>(port.role);
     halPort->type = static_cast<audio_port_type_t>(port.type);
-    memcpy(halPort->name, port.name.c_str(),
-           std::min(port.name.size(), static_cast<size_t>(AUDIO_PORT_MAX_NAME_LEN)));
+    strncpy(halPort->name, port.name.c_str(), AUDIO_PORT_MAX_NAME_LEN);
+    halPort->name[AUDIO_PORT_MAX_NAME_LEN - 1] = '\0';
     halPort->num_sample_rates =
         std::min(port.sampleRates.size(), static_cast<size_t>(AUDIO_PORT_MAX_SAMPLING_RATES));
     for (size_t i = 0; i < halPort->num_sample_rates; ++i) {
diff --git a/audio/2.0/default/Android.mk b/audio/common/all-versions/default/service/Android.mk
similarity index 91%
rename from audio/2.0/default/Android.mk
rename to audio/common/all-versions/default/service/Android.mk
index 12713d3..f502dfd 100644
--- a/audio/2.0/default/Android.mk
+++ b/audio/common/all-versions/default/service/Android.mk
@@ -31,14 +31,18 @@
 LOCAL_CFLAGS := -Wall -Werror
 
 LOCAL_SHARED_LIBRARIES := \
+    libbinder \
     libhidlbase \
     libhidltransport \
     liblog \
     libutils \
     libhardware \
     android.hardware.audio@2.0 \
+    android.hardware.audio@4.0 \
     android.hardware.audio.common@2.0 \
+    android.hardware.audio.common@4.0 \
     android.hardware.audio.effect@2.0 \
+    android.hardware.audio.effect@4.0 \
     android.hardware.soundtrigger@2.0 \
     android.hardware.soundtrigger@2.1
 
diff --git a/audio/2.0/default/android.hardware.audio@2.0-service.rc b/audio/common/all-versions/default/service/android.hardware.audio@2.0-service.rc
similarity index 100%
rename from audio/2.0/default/android.hardware.audio@2.0-service.rc
rename to audio/common/all-versions/default/service/android.hardware.audio@2.0-service.rc
diff --git a/audio/common/all-versions/default/service/service.cpp b/audio/common/all-versions/default/service/service.cpp
new file mode 100644
index 0000000..f6e4353
--- /dev/null
+++ b/audio/common/all-versions/default/service/service.cpp
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2016 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 "audiohalservice"
+
+#include <android/hardware/audio/2.0/IDevicesFactory.h>
+#include <android/hardware/audio/4.0/IDevicesFactory.h>
+#include <android/hardware/audio/effect/2.0/IEffectsFactory.h>
+#include <android/hardware/audio/effect/4.0/IEffectsFactory.h>
+#include <android/hardware/soundtrigger/2.0/ISoundTriggerHw.h>
+#include <android/hardware/soundtrigger/2.1/ISoundTriggerHw.h>
+#include <binder/ProcessState.h>
+#include <hidl/HidlTransportSupport.h>
+#include <hidl/LegacySupport.h>
+
+using namespace android::hardware;
+using android::OK;
+
+int main(int /* argc */, char* /* argv */ []) {
+    android::ProcessState::initWithDriver("/dev/vndbinder");
+    // start a threadpool for vndbinder interactions
+    android::ProcessState::self()->startThreadPool();
+    configureRpcThreadpool(16, true /*callerWillJoin*/);
+
+    bool fail = registerPassthroughServiceImplementation<audio::V4_0::IDevicesFactory>() != OK &&
+                registerPassthroughServiceImplementation<audio::V2_0::IDevicesFactory>() != OK;
+    LOG_ALWAYS_FATAL_IF(fail, "Could not register audio core API 2.0 nor 4.0");
+
+    fail = registerPassthroughServiceImplementation<audio::effect::V4_0::IEffectsFactory>() != OK &&
+           registerPassthroughServiceImplementation<audio::effect::V2_0::IEffectsFactory>() != OK,
+    LOG_ALWAYS_FATAL_IF(fail, "Could not register audio effect API 2.0 nor 4.0");
+
+    fail = registerPassthroughServiceImplementation<soundtrigger::V2_1::ISoundTriggerHw>() != OK &&
+           registerPassthroughServiceImplementation<soundtrigger::V2_0::ISoundTriggerHw>() != OK,
+    ALOGW_IF(fail, "Could not register soundtrigger API 2.0 nor 2.1");
+
+    joinRpcThreadpool();
+}
diff --git a/audio/common/all-versions/util/include/common/all-versions/VersionUtils.h b/audio/common/all-versions/util/include/common/all-versions/VersionUtils.h
new file mode 100644
index 0000000..a998b06
--- /dev/null
+++ b/audio/common/all-versions/util/include/common/all-versions/VersionUtils.h
@@ -0,0 +1,61 @@
+/*
+ * 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_audio_common_VersionUtils_H_
+#define android_hardware_audio_common_VersionUtils_H_
+
+#include <hidl/HidlSupport.h>
+#include <type_traits>
+
+namespace android {
+namespace hardware {
+namespace audio {
+namespace common {
+namespace utils {
+
+/** Similar to static_cast but also casts to hidl_bitfield depending on
+ * return type inference (emulated through user-define conversion).
+ */
+template <class Source, class Destination = Source>
+class EnumConverter {
+   public:
+    static_assert(std::is_enum<Source>::value || std::is_enum<Destination>::value,
+                  "Source or destination should be an enum");
+
+    explicit EnumConverter(Source source) : mSource(source) {}
+
+    operator Destination() const { return static_cast<Destination>(mSource); }
+
+    template <class = std::enable_if_t<std::is_enum<Destination>::value>>
+    operator ::android::hardware::hidl_bitfield<Destination>() {
+        return static_cast<std::underlying_type_t<Destination>>(mSource);
+    }
+
+   private:
+    const Source mSource;
+};
+template <class Destination, class Source>
+auto mkEnumConverter(Source source) {
+    return EnumConverter<Source, Destination>{source};
+}
+
+}  // namespace utils
+}  // namespace common
+}  // namespace audio
+}  // namespace hardware
+}  // namespace android
+
+#endif  // android_hardware_audio_common_VersionUtils_H_
diff --git a/audio/core/2.0/default/Android.bp b/audio/core/2.0/default/Android.bp
index 9847886..625df74 100644
--- a/audio/core/2.0/default/Android.bp
+++ b/audio/core/2.0/default/Android.bp
@@ -14,6 +14,10 @@
         "StreamOut.cpp",
     ],
 
+    cflags: [
+        "-DAUDIO_HAL_VERSION_2_0",
+    ],
+
     defaults: ["hidl_defaults"],
 
     export_include_dirs: ["include"],
diff --git a/audio/core/4.0/default/Android.bp b/audio/core/4.0/default/Android.bp
new file mode 100644
index 0000000..8e41545
--- /dev/null
+++ b/audio/core/4.0/default/Android.bp
@@ -0,0 +1,53 @@
+cc_library_shared {
+    name: "android.hardware.audio@4.0-impl",
+    relative_install_path: "hw",
+    proprietary: true,
+    vendor: true,
+    srcs: [
+        "Conversions.cpp",
+        "Device.cpp",
+        "DevicesFactory.cpp",
+        "ParametersUtil.cpp",
+        "PrimaryDevice.cpp",
+        "Stream.cpp",
+        "StreamIn.cpp",
+        "StreamOut.cpp",
+    ],
+
+    cflags: [
+        "-DAUDIO_HAL_VERSION_4_0",
+    ],
+
+    defaults: ["hidl_defaults"],
+
+    export_include_dirs: ["include"],
+
+    shared_libs: [
+        "libbase",
+        "libcutils",
+        "libfmq",
+        "libhardware",
+        "libhidlbase",
+        "libhidltransport",
+        "liblog",
+        "libutils",
+        "android.hardware.audio@4.0",
+        "android.hardware.audio.common@4.0",
+        "android.hardware.audio.common@4.0-util",
+        "android.hardware.audio.common-util",
+    ],
+
+    header_libs: [
+        "android.hardware.audio.common.util@all-versions",
+        "android.hardware.audio.core@all-versions-impl",
+        "libaudioclient_headers",
+        "libaudio_system_headers",
+        "libhardware_headers",
+        "libmedia_headers",
+    ],
+
+    whole_static_libs: [
+        "libmedia_helper",
+    ],
+
+}
diff --git a/audio/core/4.0/default/Conversions.cpp b/audio/core/4.0/default/Conversions.cpp
new file mode 100644
index 0000000..4f18744
--- /dev/null
+++ b/audio/core/4.0/default/Conversions.cpp
@@ -0,0 +1,21 @@
+/*
+ * 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.
+ */
+
+#include "core/4.0/default/Conversions.h"
+
+#define AUDIO_HAL_VERSION V4_0
+#include <core/all-versions/default/Conversions.impl.h>
+#undef AUDIO_HAL_VERSION
diff --git a/audio/core/4.0/default/Device.cpp b/audio/core/4.0/default/Device.cpp
new file mode 100644
index 0000000..26f9ab4
--- /dev/null
+++ b/audio/core/4.0/default/Device.cpp
@@ -0,0 +1,28 @@
+/*
+ * 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.
+ */
+
+#define LOG_TAG "DeviceHAL"
+
+#include "core/4.0/default/Device.h"
+#include <HidlUtils.h>
+#include "core/4.0/default/Conversions.h"
+#include "core/4.0/default/StreamIn.h"
+#include "core/4.0/default/StreamOut.h"
+#include "core/all-versions/default/Util.h"
+
+#define AUDIO_HAL_VERSION V4_0
+#include <core/all-versions/default/Device.impl.h>
+#undef AUDIO_HAL_VERSION
diff --git a/audio/core/4.0/default/DevicesFactory.cpp b/audio/core/4.0/default/DevicesFactory.cpp
new file mode 100644
index 0000000..cb8a3c3
--- /dev/null
+++ b/audio/core/4.0/default/DevicesFactory.cpp
@@ -0,0 +1,25 @@
+/*
+ * 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.
+ */
+
+#define LOG_TAG "DevicesFactoryHAL"
+
+#include "core/4.0/default/DevicesFactory.h"
+#include "core/4.0/default/Device.h"
+#include "core/4.0/default/PrimaryDevice.h"
+
+#define AUDIO_HAL_VERSION V4_0
+#include <core/all-versions/default/DevicesFactory.impl.h>
+#undef AUDIO_HAL_VERSION
diff --git a/audio/core/4.0/default/OWNERS b/audio/core/4.0/default/OWNERS
new file mode 100644
index 0000000..6fdc97c
--- /dev/null
+++ b/audio/core/4.0/default/OWNERS
@@ -0,0 +1,3 @@
+elaurent@google.com
+krocard@google.com
+mnaganov@google.com
diff --git a/audio/core/4.0/default/ParametersUtil.cpp b/audio/core/4.0/default/ParametersUtil.cpp
new file mode 100644
index 0000000..5c1b1c4
--- /dev/null
+++ b/audio/core/4.0/default/ParametersUtil.cpp
@@ -0,0 +1,21 @@
+/*
+ * 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.
+ */
+
+#include "core/4.0/default/ParametersUtil.h"
+
+#define AUDIO_HAL_VERSION V4_0
+#include <core/all-versions/default/ParametersUtil.impl.h>
+#undef AUDIO_HAL_VERSION
diff --git a/audio/core/4.0/default/PrimaryDevice.cpp b/audio/core/4.0/default/PrimaryDevice.cpp
new file mode 100644
index 0000000..0294b4d
--- /dev/null
+++ b/audio/core/4.0/default/PrimaryDevice.cpp
@@ -0,0 +1,24 @@
+/*
+ * 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.
+ */
+
+#define LOG_TAG "PrimaryDeviceHAL"
+
+#include "core/4.0/default/PrimaryDevice.h"
+#include "core/all-versions/default/Util.h"
+
+#define AUDIO_HAL_VERSION V4_0
+#include <core/all-versions/default/PrimaryDevice.impl.h>
+#undef AUDIO_HAL_VERSION
diff --git a/audio/core/4.0/default/Stream.cpp b/audio/core/4.0/default/Stream.cpp
new file mode 100644
index 0000000..30b3454
--- /dev/null
+++ b/audio/core/4.0/default/Stream.cpp
@@ -0,0 +1,25 @@
+/*
+ * 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.
+ */
+
+#define LOG_TAG "StreamHAL"
+
+#include "core/4.0/default/Stream.h"
+#include "common/all-versions/default/EffectMap.h"
+#include "core/4.0/default/Conversions.h"
+
+#define AUDIO_HAL_VERSION V4_0
+#include <core/all-versions/default/Stream.impl.h>
+#undef AUDIO_HAL_VERSION
diff --git a/audio/core/4.0/default/StreamIn.cpp b/audio/core/4.0/default/StreamIn.cpp
new file mode 100644
index 0000000..18719b5
--- /dev/null
+++ b/audio/core/4.0/default/StreamIn.cpp
@@ -0,0 +1,24 @@
+/*
+ * 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.
+ */
+
+#define LOG_TAG "StreamInHAL"
+
+#include "core/4.0/default/StreamIn.h"
+#include "core/all-versions/default/Util.h"
+
+#define AUDIO_HAL_VERSION V4_0
+#include <core/all-versions/default/StreamIn.impl.h>
+#undef AUDIO_HAL_VERSION
diff --git a/audio/core/4.0/default/StreamOut.cpp b/audio/core/4.0/default/StreamOut.cpp
new file mode 100644
index 0000000..11c8fde
--- /dev/null
+++ b/audio/core/4.0/default/StreamOut.cpp
@@ -0,0 +1,24 @@
+/*
+ * 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.
+ */
+
+#define LOG_TAG "StreamOutHAL"
+
+#include "core/4.0/default/StreamOut.h"
+#include "core/all-versions/default/Util.h"
+
+#define AUDIO_HAL_VERSION V4_0
+#include <core/all-versions/default/StreamOut.impl.h>
+#undef AUDIO_HAL_VERSION
diff --git a/audio/core/4.0/default/include/core/4.0/default/Conversions.h b/audio/core/4.0/default/include/core/4.0/default/Conversions.h
new file mode 100644
index 0000000..32c2f88
--- /dev/null
+++ b/audio/core/4.0/default/include/core/4.0/default/Conversions.h
@@ -0,0 +1,26 @@
+/*
+ * 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.
+ */
+
+#ifndef ANDROID_HARDWARE_AUDIO_V4_0_CONVERSIONS_H_
+#define ANDROID_HARDWARE_AUDIO_V4_0_CONVERSIONS_H_
+
+#include <android/hardware/audio/4.0/types.h>
+
+#define AUDIO_HAL_VERSION V4_0
+#include <core/all-versions/default/Conversions.h>
+#undef AUDIO_HAL_VERSION
+
+#endif  // ANDROID_HARDWARE_AUDIO_V4_0_CONVERSIONS_H_
diff --git a/audio/core/4.0/default/include/core/4.0/default/Device.h b/audio/core/4.0/default/include/core/4.0/default/Device.h
new file mode 100644
index 0000000..770d606
--- /dev/null
+++ b/audio/core/4.0/default/include/core/4.0/default/Device.h
@@ -0,0 +1,28 @@
+/*
+ * 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.
+ */
+
+#ifndef ANDROID_HARDWARE_AUDIO_V4_0_DEVICE_H
+#define ANDROID_HARDWARE_AUDIO_V4_0_DEVICE_H
+
+#include <android/hardware/audio/4.0/IDevice.h>
+
+#include "ParametersUtil.h"
+
+#define AUDIO_HAL_VERSION V4_0
+#include <core/all-versions/default/Device.h>
+#undef AUDIO_HAL_VERSION
+
+#endif  // ANDROID_HARDWARE_AUDIO_V4_0_DEVICE_H
diff --git a/audio/core/4.0/default/include/core/4.0/default/DevicesFactory.h b/audio/core/4.0/default/include/core/4.0/default/DevicesFactory.h
new file mode 100644
index 0000000..200e59d
--- /dev/null
+++ b/audio/core/4.0/default/include/core/4.0/default/DevicesFactory.h
@@ -0,0 +1,26 @@
+/*
+ * 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.
+ */
+
+#ifndef ANDROID_HARDWARE_AUDIO_V4_0_DEVICESFACTORY_H
+#define ANDROID_HARDWARE_AUDIO_V4_0_DEVICESFACTORY_H
+
+#include <android/hardware/audio/4.0/IDevicesFactory.h>
+
+#define AUDIO_HAL_VERSION V4_0
+#include <core/all-versions/default/DevicesFactory.h>
+#undef AUDIO_HAL_VERSION
+
+#endif  // ANDROID_HARDWARE_AUDIO_V4_0_DEVICESFACTORY_H
diff --git a/audio/core/4.0/default/include/core/4.0/default/ParametersUtil.h b/audio/core/4.0/default/include/core/4.0/default/ParametersUtil.h
new file mode 100644
index 0000000..fa31ee9
--- /dev/null
+++ b/audio/core/4.0/default/include/core/4.0/default/ParametersUtil.h
@@ -0,0 +1,26 @@
+/*
+ * 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.
+ */
+
+#ifndef ANDROID_HARDWARE_AUDIO_V4_0_PARAMETERS_UTIL_H_
+#define ANDROID_HARDWARE_AUDIO_V4_0_PARAMETERS_UTIL_H_
+
+#include <android/hardware/audio/4.0/types.h>
+
+#define AUDIO_HAL_VERSION V4_0
+#include <core/all-versions/default/ParametersUtil.h>
+#undef AUDIO_HAL_VERSION
+
+#endif  // ANDROID_HARDWARE_AUDIO_V4_0_PARAMETERS_UTIL_H_
diff --git a/audio/core/4.0/default/include/core/4.0/default/PrimaryDevice.h b/audio/core/4.0/default/include/core/4.0/default/PrimaryDevice.h
new file mode 100644
index 0000000..e7f846b
--- /dev/null
+++ b/audio/core/4.0/default/include/core/4.0/default/PrimaryDevice.h
@@ -0,0 +1,28 @@
+/*
+ * 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.
+ */
+
+#ifndef ANDROID_HARDWARE_AUDIO_V4_0_PRIMARYDEVICE_H
+#define ANDROID_HARDWARE_AUDIO_V4_0_PRIMARYDEVICE_H
+
+#include <android/hardware/audio/4.0/IPrimaryDevice.h>
+
+#include "Device.h"
+
+#define AUDIO_HAL_VERSION V4_0
+#include <core/all-versions/default/PrimaryDevice.h>
+#undef AUDIO_HAL_VERSION
+
+#endif  // ANDROID_HARDWARE_AUDIO_V4_0_PRIMARYDEVICE_H
diff --git a/audio/core/4.0/default/include/core/4.0/default/Stream.h b/audio/core/4.0/default/include/core/4.0/default/Stream.h
new file mode 100644
index 0000000..afad80f
--- /dev/null
+++ b/audio/core/4.0/default/include/core/4.0/default/Stream.h
@@ -0,0 +1,28 @@
+/*
+ * 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.
+ */
+
+#ifndef ANDROID_HARDWARE_AUDIO_V4_0_STREAM_H
+#define ANDROID_HARDWARE_AUDIO_V4_0_STREAM_H
+
+#include <android/hardware/audio/4.0/IStream.h>
+
+#include "ParametersUtil.h"
+
+#define AUDIO_HAL_VERSION V4_0
+#include <core/all-versions/default/Stream.h>
+#undef AUDIO_HAL_VERSION
+
+#endif  // ANDROID_HARDWARE_AUDIO_V4_0_STREAM_H
diff --git a/audio/core/4.0/default/include/core/4.0/default/StreamIn.h b/audio/core/4.0/default/include/core/4.0/default/StreamIn.h
new file mode 100644
index 0000000..151f03f
--- /dev/null
+++ b/audio/core/4.0/default/include/core/4.0/default/StreamIn.h
@@ -0,0 +1,29 @@
+/*
+ * 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.
+ */
+
+#ifndef ANDROID_HARDWARE_AUDIO_V4_0_STREAMIN_H
+#define ANDROID_HARDWARE_AUDIO_V4_0_STREAMIN_H
+
+#include <android/hardware/audio/4.0/IStreamIn.h>
+
+#include "Device.h"
+#include "Stream.h"
+
+#define AUDIO_HAL_VERSION V4_0
+#include <core/all-versions/default/StreamIn.h>
+#undef AUDIO_HAL_VERSION
+
+#endif  // ANDROID_HARDWARE_AUDIO_V4_0_STREAMIN_H
diff --git a/audio/core/4.0/default/include/core/4.0/default/StreamOut.h b/audio/core/4.0/default/include/core/4.0/default/StreamOut.h
new file mode 100644
index 0000000..dbf3bd1
--- /dev/null
+++ b/audio/core/4.0/default/include/core/4.0/default/StreamOut.h
@@ -0,0 +1,29 @@
+/*
+ * 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.
+ */
+
+#ifndef ANDROID_HARDWARE_AUDIO_V4_0_STREAMOUT_H
+#define ANDROID_HARDWARE_AUDIO_V4_0_STREAMOUT_H
+
+#include <android/hardware/audio/4.0/IStreamOut.h>
+
+#include "Device.h"
+#include "Stream.h"
+
+#define AUDIO_HAL_VERSION V4_0
+#include <core/all-versions/default/StreamOut.h>
+#undef AUDIO_HAL_VERSION
+
+#endif  // ANDROID_HARDWARE_AUDIO_V4_0_STREAMOUT_H
diff --git a/audio/core/all-versions/default/Android.bp b/audio/core/all-versions/default/Android.bp
index 214b8d5..bb02863 100644
--- a/audio/core/all-versions/default/Android.bp
+++ b/audio/core/all-versions/default/Android.bp
@@ -1,7 +1,6 @@
 cc_library_headers {
     name: "android.hardware.audio.core@all-versions-impl",
     relative_install_path: "hw",
-    proprietary: true,
     vendor: true,
 
     defaults: ["hidl_defaults"],
diff --git a/audio/core/all-versions/default/include/core/all-versions/default/Device.h b/audio/core/all-versions/default/include/core/all-versions/default/Device.h
index 224823c..eb53b48 100644
--- a/audio/core/all-versions/default/include/core/all-versions/default/Device.h
+++ b/audio/core/all-versions/default/include/core/all-versions/default/Device.h
@@ -25,6 +25,8 @@
 
 #include <hidl/MQDescriptor.h>
 
+#include <VersionUtils.h>
+
 namespace android {
 namespace hardware {
 namespace audio {
@@ -39,6 +41,9 @@
 using ::android::hardware::audio::common::AUDIO_HAL_VERSION::AudioPort;
 using ::android::hardware::audio::common::AUDIO_HAL_VERSION::AudioPortConfig;
 using ::android::hardware::audio::common::AUDIO_HAL_VERSION::AudioSource;
+using ::android::hardware::audio::common::AUDIO_HAL_VERSION::implementation::AudioInputFlagBitfield;
+using ::android::hardware::audio::common::AUDIO_HAL_VERSION::implementation::
+    AudioOutputFlagBitfield;
 using ::android::hardware::audio::AUDIO_HAL_VERSION::DeviceAddress;
 using ::android::hardware::audio::AUDIO_HAL_VERSION::IDevice;
 using ::android::hardware::audio::AUDIO_HAL_VERSION::IStreamIn;
@@ -51,6 +56,11 @@
 using ::android::hardware::hidl_string;
 using ::android::sp;
 
+#ifdef AUDIO_HAL_VERSION_4_0
+using ::android::hardware::audio::AUDIO_HAL_VERSION::SourceMetadata;
+using ::android::hardware::audio::AUDIO_HAL_VERSION::SinkMetadata;
+#endif
+
 struct Device : public IDevice, public ParametersUtil {
     explicit Device(audio_hw_device_t* device);
 
@@ -64,12 +74,26 @@
     Return<void> getMasterMute(getMasterMute_cb _hidl_cb) override;
     Return<void> getInputBufferSize(const AudioConfig& config,
                                     getInputBufferSize_cb _hidl_cb) override;
+
+    // V2 openInputStream is called by V4 input stream thus present in both versions
+    Return<void> openInputStream(int32_t ioHandle, const DeviceAddress& device,
+                                 const AudioConfig& config, AudioInputFlagBitfield flags,
+                                 AudioSource source, openInputStream_cb _hidl_cb);
+#ifdef AUDIO_HAL_VERSION_2_0
     Return<void> openOutputStream(int32_t ioHandle, const DeviceAddress& device,
-                                  const AudioConfig& config, AudioOutputFlag flags,
+                                  const AudioConfig& config, AudioOutputFlagBitfield flags,
+                                  openOutputStream_cb _hidl_cb) override;
+#elif defined(AUDIO_HAL_VERSION_4_0)
+    Return<void> openOutputStream(int32_t ioHandle, const DeviceAddress& device,
+                                  const AudioConfig& config, AudioOutputFlagBitfield flags,
+                                  const SourceMetadata& sourceMetadata,
                                   openOutputStream_cb _hidl_cb) override;
     Return<void> openInputStream(int32_t ioHandle, const DeviceAddress& device,
-                                 const AudioConfig& config, AudioInputFlag flags,
-                                 AudioSource source, openInputStream_cb _hidl_cb) override;
+                                 const AudioConfig& config, AudioInputFlagBitfield flags,
+                                 const SinkMetadata& sinkMetadata,
+                                 openInputStream_cb _hidl_cb) override;
+#endif
+
     Return<bool> supportsAudioPatches() override;
     Return<void> createAudioPatch(const hidl_vec<AudioPortConfig>& sources,
                                   const hidl_vec<AudioPortConfig>& sinks,
@@ -77,12 +101,27 @@
     Return<Result> releaseAudioPatch(int32_t patch) override;
     Return<void> getAudioPort(const AudioPort& port, getAudioPort_cb _hidl_cb) override;
     Return<Result> setAudioPortConfig(const AudioPortConfig& config) override;
-    Return<AudioHwSync> getHwAvSync() override;
+
     Return<Result> setScreenState(bool turnedOn) override;
+
+#ifdef AUDIO_HAL_VERSION_2_0
+    Return<AudioHwSync> getHwAvSync() override;
     Return<void> getParameters(const hidl_vec<hidl_string>& keys,
                                getParameters_cb _hidl_cb) override;
     Return<Result> setParameters(const hidl_vec<ParameterValue>& parameters) override;
     Return<void> debugDump(const hidl_handle& fd) override;
+#elif defined(AUDIO_HAL_VERSION_4_0)
+    Return<void> getHwAvSync(getHwAvSync_cb _hidl_cb) override;
+    Return<void> getParameters(const hidl_vec<ParameterValue>& context,
+                               const hidl_vec<hidl_string>& keys,
+                               getParameters_cb _hidl_cb) override;
+    Return<Result> setParameters(const hidl_vec<ParameterValue>& context,
+                                 const hidl_vec<ParameterValue>& parameters) override;
+    Return<void> getMicrophones(getMicrophones_cb _hidl_cb) override;
+    Return<Result> setConnectedState(const DeviceAddress& address, bool connected) override;
+#endif
+
+    Return<void> debug(const hidl_handle& fd, const hidl_vec<hidl_string>& options) override;
 
     // Utility methods for extending interfaces.
     Result analyzeStatus(const char* funcName, int status);
diff --git a/audio/core/all-versions/default/include/core/all-versions/default/Device.impl.h b/audio/core/all-versions/default/include/core/all-versions/default/Device.impl.h
index b295082..fb4b686 100644
--- a/audio/core/all-versions/default/include/core/all-versions/default/Device.impl.h
+++ b/audio/core/all-versions/default/include/core/all-versions/default/Device.impl.h
@@ -147,7 +147,10 @@
 }
 
 Return<void> Device::openOutputStream(int32_t ioHandle, const DeviceAddress& device,
-                                      const AudioConfig& config, AudioOutputFlag flags,
+                                      const AudioConfig& config, AudioOutputFlagBitfield flags,
+#ifdef AUDIO_HAL_VERSION_4_0
+                                      const SourceMetadata& /* sourceMetadata */,
+#endif
                                       openOutputStream_cb _hidl_cb) {
     audio_config_t halConfig;
     HidlUtils::audioConfigToHal(config, &halConfig);
@@ -174,7 +177,7 @@
 }
 
 Return<void> Device::openInputStream(int32_t ioHandle, const DeviceAddress& device,
-                                     const AudioConfig& config, AudioInputFlag flags,
+                                     const AudioConfig& config, AudioInputFlagBitfield flags,
                                      AudioSource source, openInputStream_cb _hidl_cb) {
     audio_config_t halConfig;
     HidlUtils::audioConfigToHal(config, &halConfig);
@@ -201,6 +204,24 @@
     return Void();
 }
 
+#ifdef AUDIO_HAL_VERSION_4_0
+Return<void> Device::openInputStream(int32_t ioHandle, const DeviceAddress& device,
+                                     const AudioConfig& config, AudioInputFlagBitfield flags,
+                                     const SinkMetadata& sinkMetadata,
+                                     openInputStream_cb _hidl_cb) {
+    if (sinkMetadata.tracks.size() == 0) {
+        // This should never happen, the framework must not create as stream
+        // if there is no client
+        ALOGE("openInputStream called without tracks connected");
+        _hidl_cb(Result::INVALID_ARGUMENTS, nullptr, AudioConfig());
+        return Void();
+    }
+    // Pick the first one as the main until the legacy API is update
+    AudioSource source = sinkMetadata.tracks[0].source;
+    return openInputStream(ioHandle, device, config, flags, source, _hidl_cb);
+}
+#endif
+
 Return<bool> Device::supportsAudioPatches() {
     return version() >= AUDIO_DEVICE_API_VERSION_3_0;
 }
@@ -256,32 +277,72 @@
     return Result::NOT_SUPPORTED;
 }
 
+#ifdef AUDIO_HAL_VERSION_2_0
 Return<AudioHwSync> Device::getHwAvSync() {
     int halHwAvSync;
     Result retval = getParam(AudioParameter::keyHwAvSync, &halHwAvSync);
     return retval == Result::OK ? halHwAvSync : AUDIO_HW_SYNC_INVALID;
 }
+#elif defined(AUDIO_HAL_VERSION_4_0)
+Return<void> Device::getHwAvSync(getHwAvSync_cb _hidl_cb) {
+    int halHwAvSync;
+    Result retval = getParam(AudioParameter::keyHwAvSync, &halHwAvSync);
+    _hidl_cb(retval, halHwAvSync);
+    return Void();
+}
+#endif
 
 Return<Result> Device::setScreenState(bool turnedOn) {
     return setParam(AudioParameter::keyScreenState, turnedOn);
 }
 
+#ifdef AUDIO_HAL_VERSION_2_0
 Return<void> Device::getParameters(const hidl_vec<hidl_string>& keys, getParameters_cb _hidl_cb) {
-    getParametersImpl(keys, _hidl_cb);
+    getParametersImpl({}, keys, _hidl_cb);
     return Void();
 }
 
 Return<Result> Device::setParameters(const hidl_vec<ParameterValue>& parameters) {
-    return setParametersImpl(parameters);
+    return setParametersImpl({} /* context */, parameters);
 }
+#elif defined(AUDIO_HAL_VERSION_4_0)
+Return<void> Device::getParameters(const hidl_vec<ParameterValue>& context,
+                                   const hidl_vec<hidl_string>& keys, getParameters_cb _hidl_cb) {
+    getParametersImpl(context, keys, _hidl_cb);
+    return Void();
+}
+Return<Result> Device::setParameters(const hidl_vec<ParameterValue>& context,
+                                     const hidl_vec<ParameterValue>& parameters) {
+    return setParametersImpl(context, parameters);
+}
+#endif
 
+#ifdef AUDIO_HAL_VERSION_2_0
 Return<void> Device::debugDump(const hidl_handle& fd) {
+    return debug(fd, {});
+}
+#endif
+
+Return<void> Device::debug(const hidl_handle& fd, const hidl_vec<hidl_string>& /* options */) {
     if (fd.getNativeHandle() != nullptr && fd->numFds == 1) {
         analyzeStatus("dump", mDevice->dump(mDevice, fd->data[0]));
     }
     return Void();
 }
 
+#ifdef AUDIO_HAL_VERSION_4_0
+Return<void> Device::getMicrophones(getMicrophones_cb _hidl_cb) {
+    // TODO return device microphones
+    _hidl_cb(Result::NOT_SUPPORTED, {});
+    return Void();
+}
+
+Return<Result> Device::setConnectedState(const DeviceAddress& address, bool connected) {
+    auto key = connected ? AudioParameter::keyStreamConnect : AudioParameter::keyStreamDisconnect;
+    return setParam(key, address);
+}
+#endif
+
 }  // namespace implementation
 }  // namespace AUDIO_HAL_VERSION
 }  // namespace audio
diff --git a/audio/core/all-versions/default/include/core/all-versions/default/DevicesFactory.h b/audio/core/all-versions/default/include/core/all-versions/default/DevicesFactory.h
index 769adaa..1509ad1 100644
--- a/audio/core/all-versions/default/include/core/all-versions/default/DevicesFactory.h
+++ b/audio/core/all-versions/default/include/core/all-versions/default/DevicesFactory.h
@@ -37,11 +37,19 @@
 using ::android::sp;
 
 struct DevicesFactory : public IDevicesFactory {
-    // Methods from ::android::hardware::audio::AUDIO_HAL_VERSION::IDevicesFactory follow.
+#ifdef AUDIO_HAL_VERSION_2_0
     Return<void> openDevice(IDevicesFactory::Device device, openDevice_cb _hidl_cb) override;
+#endif
+#ifdef AUDIO_HAL_VERSION_4_0
+    Return<void> openDevice(const hidl_string& device, openDevice_cb _hidl_cb) override;
+    Return<void> openPrimaryDevice(openPrimaryDevice_cb _hidl_cb) override;
+#endif
 
    private:
-    static const char* deviceToString(IDevicesFactory::Device device);
+    template <class DeviceShim, class Callback>
+    Return<void> openDevice(const char* moduleName, Callback _hidl_cb);
+    Return<void> openDevice(const char* moduleName, openDevice_cb _hidl_cb);
+
     static int loadAudioInterface(const char* if_name, audio_hw_device_t** dev);
 };
 
diff --git a/audio/core/all-versions/default/include/core/all-versions/default/DevicesFactory.impl.h b/audio/core/all-versions/default/include/core/all-versions/default/DevicesFactory.impl.h
index 014b4d8..a9f59fb 100644
--- a/audio/core/all-versions/default/include/core/all-versions/default/DevicesFactory.impl.h
+++ b/audio/core/all-versions/default/include/core/all-versions/default/DevicesFactory.impl.h
@@ -26,21 +26,54 @@
 namespace AUDIO_HAL_VERSION {
 namespace implementation {
 
-// static
-const char* DevicesFactory::deviceToString(IDevicesFactory::Device device) {
+#ifdef AUDIO_HAL_VERSION_2_0
+Return<void> DevicesFactory::openDevice(IDevicesFactory::Device device, openDevice_cb _hidl_cb) {
     switch (device) {
         case IDevicesFactory::Device::PRIMARY:
-            return AUDIO_HARDWARE_MODULE_ID_PRIMARY;
+            return openDevice<PrimaryDevice>(AUDIO_HARDWARE_MODULE_ID_PRIMARY, _hidl_cb);
         case IDevicesFactory::Device::A2DP:
-            return AUDIO_HARDWARE_MODULE_ID_A2DP;
+            return openDevice(AUDIO_HARDWARE_MODULE_ID_A2DP, _hidl_cb);
         case IDevicesFactory::Device::USB:
-            return AUDIO_HARDWARE_MODULE_ID_USB;
+            return openDevice(AUDIO_HARDWARE_MODULE_ID_USB, _hidl_cb);
         case IDevicesFactory::Device::R_SUBMIX:
-            return AUDIO_HARDWARE_MODULE_ID_REMOTE_SUBMIX;
+            return openDevice(AUDIO_HARDWARE_MODULE_ID_REMOTE_SUBMIX, _hidl_cb);
         case IDevicesFactory::Device::STUB:
-            return AUDIO_HARDWARE_MODULE_ID_STUB;
+            return openDevice(AUDIO_HARDWARE_MODULE_ID_STUB, _hidl_cb);
     }
-    return nullptr;
+    _hidl_cb(Result::INVALID_ARGUMENTS, nullptr);
+    return Void();
+}
+#endif
+#ifdef AUDIO_HAL_VERSION_4_0
+Return<void> DevicesFactory::openDevice(const hidl_string& moduleName, openDevice_cb _hidl_cb) {
+    if (moduleName == AUDIO_HARDWARE_MODULE_ID_PRIMARY) {
+        return openDevice<PrimaryDevice>(moduleName.c_str(), _hidl_cb);
+    }
+    return openDevice(moduleName.c_str(), _hidl_cb);
+}
+Return<void> DevicesFactory::openPrimaryDevice(openPrimaryDevice_cb _hidl_cb) {
+    return openDevice<PrimaryDevice>(AUDIO_HARDWARE_MODULE_ID_PRIMARY, _hidl_cb);
+}
+#endif
+
+Return<void> DevicesFactory::openDevice(const char* moduleName, openDevice_cb _hidl_cb) {
+    return openDevice<implementation::Device>(moduleName, _hidl_cb);
+}
+
+template <class DeviceShim, class Callback>
+Return<void> DevicesFactory::openDevice(const char* moduleName, Callback _hidl_cb) {
+    audio_hw_device_t* halDevice;
+    Result retval(Result::INVALID_ARGUMENTS);
+    sp<DeviceShim> result;
+    int halStatus = loadAudioInterface(moduleName, &halDevice);
+    if (halStatus == OK) {
+        result = new DeviceShim(halDevice);
+        retval = Result::OK;
+    } else if (halStatus == -EINVAL) {
+        retval = Result::NOT_INITIALIZED;
+    }
+    _hidl_cb(retval, result);
+    return Void();
 }
 
 // static
@@ -73,32 +106,8 @@
     return rc;
 }
 
-// Methods from ::android::hardware::audio::AUDIO_HAL_VERSION::IDevicesFactory follow.
-Return<void> DevicesFactory::openDevice(IDevicesFactory::Device device, openDevice_cb _hidl_cb) {
-    audio_hw_device_t* halDevice;
-    Result retval(Result::INVALID_ARGUMENTS);
-    sp<IDevice> result;
-    const char* moduleName = deviceToString(device);
-    if (moduleName != nullptr) {
-        int halStatus = loadAudioInterface(moduleName, &halDevice);
-        if (halStatus == OK) {
-            if (device == IDevicesFactory::Device::PRIMARY) {
-                result = new PrimaryDevice(halDevice);
-            } else {
-                result = new ::android::hardware::audio::AUDIO_HAL_VERSION::implementation::Device(
-                    halDevice);
-            }
-            retval = Result::OK;
-        } else if (halStatus == -EINVAL) {
-            retval = Result::NOT_INITIALIZED;
-        }
-    }
-    _hidl_cb(retval, result);
-    return Void();
-}
-
-IDevicesFactory* HIDL_FETCH_IDevicesFactory(const char* /* name */) {
-    return new DevicesFactory();
+IDevicesFactory* HIDL_FETCH_IDevicesFactory(const char* name) {
+    return strcmp(name, "default") == 0 ? new DevicesFactory() : nullptr;
 }
 
 }  // namespace implementation
diff --git a/audio/core/all-versions/default/include/core/all-versions/default/ParametersUtil.h b/audio/core/all-versions/default/include/core/all-versions/default/ParametersUtil.h
index df5adee..a27ac25 100644
--- a/audio/core/all-versions/default/include/core/all-versions/default/ParametersUtil.h
+++ b/audio/core/all-versions/default/include/core/all-versions/default/ParametersUtil.h
@@ -28,6 +28,7 @@
 namespace AUDIO_HAL_VERSION {
 namespace implementation {
 
+using ::android::hardware::audio::AUDIO_HAL_VERSION::DeviceAddress;
 using ::android::hardware::audio::AUDIO_HAL_VERSION::ParameterValue;
 using ::android::hardware::audio::AUDIO_HAL_VERSION::Result;
 using ::android::hardware::hidl_string;
@@ -37,16 +38,18 @@
    public:
     Result getParam(const char* name, bool* value);
     Result getParam(const char* name, int* value);
-    Result getParam(const char* name, String8* value);
+    Result getParam(const char* name, String8* value, AudioParameter context = {});
     void getParametersImpl(
-        const hidl_vec<hidl_string>& keys,
+        const hidl_vec<ParameterValue>& context, const hidl_vec<hidl_string>& keys,
         std::function<void(Result retval, const hidl_vec<ParameterValue>& parameters)> cb);
     std::unique_ptr<AudioParameter> getParams(const AudioParameter& keys);
     Result setParam(const char* name, bool value);
     Result setParam(const char* name, int value);
-    Result setParam(const char* name, const char* value);
-    Result setParametersImpl(const hidl_vec<ParameterValue>& parameters);
+    Result setParam(const char* name, float value);
+    Result setParametersImpl(const hidl_vec<ParameterValue>& context,
+                             const hidl_vec<ParameterValue>& parameters);
     Result setParams(const AudioParameter& param);
+    Result setParam(const char* name, const DeviceAddress& address);
 
    protected:
     virtual ~ParametersUtil() {}
diff --git a/audio/core/all-versions/default/include/core/all-versions/default/ParametersUtil.impl.h b/audio/core/all-versions/default/include/core/all-versions/default/ParametersUtil.impl.h
index a858a48..3907284 100644
--- a/audio/core/all-versions/default/include/core/all-versions/default/ParametersUtil.impl.h
+++ b/audio/core/all-versions/default/include/core/all-versions/default/ParametersUtil.impl.h
@@ -15,6 +15,8 @@
  */
 
 #include <common/all-versions/IncludeGuard.h>
+#include <core/all-versions/default/Conversions.h>
+#include <system/audio.h>
 
 namespace android {
 namespace hardware {
@@ -62,18 +64,20 @@
     return getHalStatusToResult(params->getInt(halName, *value));
 }
 
-Result ParametersUtil::getParam(const char* name, String8* value) {
+Result ParametersUtil::getParam(const char* name, String8* value, AudioParameter context) {
     const String8 halName(name);
-    AudioParameter keys;
-    keys.addKey(halName);
-    std::unique_ptr<AudioParameter> params = getParams(keys);
+    context.addKey(halName);
+    std::unique_ptr<AudioParameter> params = getParams(context);
     return getHalStatusToResult(params->get(halName, *value));
 }
 
 void ParametersUtil::getParametersImpl(
-    const hidl_vec<hidl_string>& keys,
+    const hidl_vec<ParameterValue>& context, const hidl_vec<hidl_string>& keys,
     std::function<void(Result retval, const hidl_vec<ParameterValue>& parameters)> cb) {
     AudioParameter halKeys;
+    for (auto& pair : context) {
+        halKeys.add(String8(pair.key.c_str()), String8(pair.value.c_str()));
+    }
     for (size_t i = 0; i < keys.size(); ++i) {
         halKeys.addKey(String8(keys[i].c_str()));
     }
@@ -120,19 +124,28 @@
     return setParams(param);
 }
 
-Result ParametersUtil::setParam(const char* name, const char* value) {
+Result ParametersUtil::setParam(const char* name, float value) {
     AudioParameter param;
-    param.add(String8(name), String8(value));
+    param.addFloat(String8(name), value);
     return setParams(param);
 }
 
-Result ParametersUtil::setParametersImpl(const hidl_vec<ParameterValue>& parameters) {
+Result ParametersUtil::setParametersImpl(const hidl_vec<ParameterValue>& context,
+                                         const hidl_vec<ParameterValue>& parameters) {
     AudioParameter params;
+    for (auto& pair : context) {
+        params.add(String8(pair.key.c_str()), String8(pair.value.c_str()));
+    }
     for (size_t i = 0; i < parameters.size(); ++i) {
         params.add(String8(parameters[i].key.c_str()), String8(parameters[i].value.c_str()));
     }
     return setParams(params);
 }
+Result ParametersUtil::setParam(const char* name, const DeviceAddress& address) {
+    AudioParameter params(String8(deviceAddressToHal(address).c_str()));
+    params.addInt(String8(name), int(address.device));
+    return setParams(params);
+}
 
 Result ParametersUtil::setParams(const AudioParameter& param) {
     int halStatus = halSetParameters(param.toString().string());
diff --git a/audio/core/all-versions/default/include/core/all-versions/default/PrimaryDevice.h b/audio/core/all-versions/default/include/core/all-versions/default/PrimaryDevice.h
index 240b221..42996d7 100644
--- a/audio/core/all-versions/default/include/core/all-versions/default/PrimaryDevice.h
+++ b/audio/core/all-versions/default/include/core/all-versions/default/PrimaryDevice.h
@@ -59,12 +59,24 @@
     Return<void> getMasterMute(getMasterMute_cb _hidl_cb) override;
     Return<void> getInputBufferSize(const AudioConfig& config,
                                     getInputBufferSize_cb _hidl_cb) override;
+
     Return<void> openOutputStream(int32_t ioHandle, const DeviceAddress& device,
-                                  const AudioConfig& config, AudioOutputFlag flags,
+                                  const AudioConfig& config, AudioOutputFlagBitfield flags,
+#ifdef AUDIO_HAL_VERSION_4_0
+                                  const SourceMetadata& sourceMetadata,
+#endif
                                   openOutputStream_cb _hidl_cb) override;
+
     Return<void> openInputStream(int32_t ioHandle, const DeviceAddress& device,
-                                 const AudioConfig& config, AudioInputFlag flags,
-                                 AudioSource source, openInputStream_cb _hidl_cb) override;
+                                 const AudioConfig& config, AudioInputFlagBitfield flags,
+                                 AudioSource source, openInputStream_cb _hidl_cb);
+#ifdef AUDIO_HAL_VERSION_4_0
+    Return<void> openInputStream(int32_t ioHandle, const DeviceAddress& device,
+                                 const AudioConfig& config, AudioInputFlagBitfield flags,
+                                 const SinkMetadata& sinkMetadata,
+                                 openInputStream_cb _hidl_cb) override;
+#endif
+
     Return<bool> supportsAudioPatches() override;
     Return<void> createAudioPatch(const hidl_vec<AudioPortConfig>& sources,
                                   const hidl_vec<AudioPortConfig>& sinks,
@@ -72,12 +84,27 @@
     Return<Result> releaseAudioPatch(int32_t patch) override;
     Return<void> getAudioPort(const AudioPort& port, getAudioPort_cb _hidl_cb) override;
     Return<Result> setAudioPortConfig(const AudioPortConfig& config) override;
-    Return<AudioHwSync> getHwAvSync() override;
+
     Return<Result> setScreenState(bool turnedOn) override;
+
+#ifdef AUDIO_HAL_VERSION_2_0
+    Return<AudioHwSync> getHwAvSync() override;
     Return<void> getParameters(const hidl_vec<hidl_string>& keys,
                                getParameters_cb _hidl_cb) override;
     Return<Result> setParameters(const hidl_vec<ParameterValue>& parameters) override;
     Return<void> debugDump(const hidl_handle& fd) override;
+#elif defined(AUDIO_HAL_VERSION_4_0)
+    Return<void> getHwAvSync(getHwAvSync_cb _hidl_cb) override;
+    Return<void> getParameters(const hidl_vec<ParameterValue>& context,
+                               const hidl_vec<hidl_string>& keys,
+                               getParameters_cb _hidl_cb) override;
+    Return<Result> setParameters(const hidl_vec<ParameterValue>& context,
+                                 const hidl_vec<ParameterValue>& parameters) override;
+    Return<void> getMicrophones(getMicrophones_cb _hidl_cb) override;
+    Return<Result> setConnectedState(const DeviceAddress& address, bool connected) override;
+#endif
+
+    Return<void> debug(const hidl_handle& fd, const hidl_vec<hidl_string>& options) override;
 
     // Methods from ::android::hardware::audio::AUDIO_HAL_VERSION::IPrimaryDevice follow.
     Return<Result> setVoiceVolume(float volume) override;
@@ -91,6 +118,15 @@
     Return<void> getHacEnabled(getHacEnabled_cb _hidl_cb) override;
     Return<Result> setHacEnabled(bool enabled) override;
 
+#ifdef AUDIO_HAL_VERSION_4_0
+    Return<Result> setBtScoHeadsetDebugName(const hidl_string& name) override;
+    Return<void> getBtHfpEnabled(getBtHfpEnabled_cb _hidl_cb) override;
+    Return<Result> setBtHfpEnabled(bool enabled) override;
+    Return<Result> setBtHfpSampleRate(uint32_t sampleRateHz) override;
+    Return<Result> setBtHfpVolume(float volume) override;
+    Return<Result> updateRotation(IPrimaryDevice::Rotation rotation) override;
+#endif
+
    private:
     sp<Device> mDevice;
 
diff --git a/audio/core/all-versions/default/include/core/all-versions/default/PrimaryDevice.impl.h b/audio/core/all-versions/default/include/core/all-versions/default/PrimaryDevice.impl.h
index 3ce047a..f00cac4 100644
--- a/audio/core/all-versions/default/include/core/all-versions/default/PrimaryDevice.impl.h
+++ b/audio/core/all-versions/default/include/core/all-versions/default/PrimaryDevice.impl.h
@@ -60,17 +60,35 @@
     return mDevice->getInputBufferSize(config, _hidl_cb);
 }
 
+#ifdef AUDIO_HAL_VERSION_2_0
 Return<void> PrimaryDevice::openOutputStream(int32_t ioHandle, const DeviceAddress& device,
-                                             const AudioConfig& config, AudioOutputFlag flags,
+                                             const AudioConfig& config,
+                                             AudioOutputFlagBitfield flags,
                                              openOutputStream_cb _hidl_cb) {
     return mDevice->openOutputStream(ioHandle, device, config, flags, _hidl_cb);
 }
 
 Return<void> PrimaryDevice::openInputStream(int32_t ioHandle, const DeviceAddress& device,
-                                            const AudioConfig& config, AudioInputFlag flags,
+                                            const AudioConfig& config, AudioInputFlagBitfield flags,
                                             AudioSource source, openInputStream_cb _hidl_cb) {
     return mDevice->openInputStream(ioHandle, device, config, flags, source, _hidl_cb);
 }
+#elif defined(AUDIO_HAL_VERSION_4_0)
+Return<void> PrimaryDevice::openOutputStream(int32_t ioHandle, const DeviceAddress& device,
+                                             const AudioConfig& config,
+                                             AudioOutputFlagBitfield flags,
+                                             const SourceMetadata& sourceMetadata,
+                                             openOutputStream_cb _hidl_cb) {
+    return mDevice->openOutputStream(ioHandle, device, config, flags, sourceMetadata, _hidl_cb);
+}
+
+Return<void> PrimaryDevice::openInputStream(int32_t ioHandle, const DeviceAddress& device,
+                                            const AudioConfig& config, AudioInputFlagBitfield flags,
+                                            const SinkMetadata& sinkMetadata,
+                                            openInputStream_cb _hidl_cb) {
+    return mDevice->openInputStream(ioHandle, device, config, flags, sinkMetadata, _hidl_cb);
+}
+#endif
 
 Return<bool> PrimaryDevice::supportsAudioPatches() {
     return mDevice->supportsAudioPatches();
@@ -94,14 +112,15 @@
     return mDevice->setAudioPortConfig(config);
 }
 
-Return<AudioHwSync> PrimaryDevice::getHwAvSync() {
-    return mDevice->getHwAvSync();
-}
-
 Return<Result> PrimaryDevice::setScreenState(bool turnedOn) {
     return mDevice->setScreenState(turnedOn);
 }
 
+#ifdef AUDIO_HAL_VERSION_2_0
+Return<AudioHwSync> PrimaryDevice::getHwAvSync() {
+    return mDevice->getHwAvSync();
+}
+
 Return<void> PrimaryDevice::getParameters(const hidl_vec<hidl_string>& keys,
                                           getParameters_cb _hidl_cb) {
     return mDevice->getParameters(keys, _hidl_cb);
@@ -114,6 +133,26 @@
 Return<void> PrimaryDevice::debugDump(const hidl_handle& fd) {
     return mDevice->debugDump(fd);
 }
+#elif defined(AUDIO_HAL_VERSION_4_0)
+Return<void> PrimaryDevice::getHwAvSync(getHwAvSync_cb _hidl_cb) {
+    return mDevice->getHwAvSync(_hidl_cb);
+}
+Return<void> PrimaryDevice::getParameters(const hidl_vec<ParameterValue>& context,
+                                          const hidl_vec<hidl_string>& keys,
+                                          getParameters_cb _hidl_cb) {
+    return mDevice->getParameters(context, keys, _hidl_cb);
+}
+Return<Result> PrimaryDevice::setParameters(const hidl_vec<ParameterValue>& context,
+                                            const hidl_vec<ParameterValue>& parameters) {
+    return mDevice->setParameters(context, parameters);
+}
+Return<void> PrimaryDevice::getMicrophones(getMicrophones_cb _hidl_cb) {
+    return mDevice->getMicrophones(_hidl_cb);
+}
+Return<Result> PrimaryDevice::setConnectedState(const DeviceAddress& address, bool connected) {
+    return mDevice->setConnectedState(address, connected);
+}
+#endif
 
 // Methods from ::android::hardware::audio::AUDIO_HAL_VERSION::IPrimaryDevice follow.
 Return<Result> PrimaryDevice::setVoiceVolume(float volume) {
@@ -188,6 +227,35 @@
     return mDevice->setParam(AUDIO_PARAMETER_KEY_HAC, enabled);
 }
 
+#ifdef AUDIO_HAL_VERSION_4_0
+Return<Result> PrimaryDevice::setBtScoHeadsetDebugName(const hidl_string& name) {
+    return mDevice->setParam(AUDIO_PARAMETER_KEY_BT_SCO_HEADSET_NAME, name.c_str());
+}
+Return<void> PrimaryDevice::getBtHfpEnabled(getBtHfpEnabled_cb _hidl_cb) {
+    bool enabled;
+    Result retval = mDevice->getParam(AUDIO_PARAMETER_KEY_HFP_ENABLE, &enabled);
+    _hidl_cb(retval, enabled);
+    return Void();
+}
+Return<Result> PrimaryDevice::setBtHfpEnabled(bool enabled) {
+    return mDevice->setParam(AUDIO_PARAMETER_KEY_HFP_ENABLE, enabled);
+}
+Return<Result> PrimaryDevice::setBtHfpSampleRate(uint32_t sampleRateHz) {
+    return mDevice->setParam(AUDIO_PARAMETER_KEY_HFP_SET_SAMPLING_RATE, int(sampleRateHz));
+}
+Return<Result> PrimaryDevice::setBtHfpVolume(float volume) {
+    return mDevice->setParam(AUDIO_PARAMETER_KEY_HFP_VOLUME, volume);
+}
+Return<Result> PrimaryDevice::updateRotation(IPrimaryDevice::Rotation rotation) {
+    // legacy API expects the rotation in degree
+    return mDevice->setParam(AUDIO_PARAMETER_KEY_ROTATION, int(rotation) * 90);
+}
+#endif
+
+Return<void> PrimaryDevice::debug(const hidl_handle& fd, const hidl_vec<hidl_string>& options) {
+    return mDevice->debug(fd, options);
+}
+
 }  // namespace implementation
 }  // namespace AUDIO_HAL_VERSION
 }  // namespace audio
diff --git a/audio/core/all-versions/default/include/core/all-versions/default/Stream.h b/audio/core/all-versions/default/include/core/all-versions/default/Stream.h
index 4196dec..6f79429 100644
--- a/audio/core/all-versions/default/include/core/all-versions/default/Stream.h
+++ b/audio/core/all-versions/default/include/core/all-versions/default/Stream.h
@@ -23,6 +23,8 @@
 
 #include <hidl/MQDescriptor.h>
 
+#include <VersionUtils.h>
+
 namespace android {
 namespace hardware {
 namespace audio {
@@ -32,6 +34,7 @@
 using ::android::hardware::audio::common::AUDIO_HAL_VERSION::AudioChannelMask;
 using ::android::hardware::audio::common::AUDIO_HAL_VERSION::AudioDevice;
 using ::android::hardware::audio::common::AUDIO_HAL_VERSION::AudioFormat;
+using ::android::hardware::audio::common::AUDIO_HAL_VERSION::implementation::AudioChannelBitfield;
 using ::android::hardware::audio::AUDIO_HAL_VERSION::DeviceAddress;
 using ::android::hardware::audio::AUDIO_HAL_VERSION::IStream;
 using ::android::hardware::audio::AUDIO_HAL_VERSION::ParameterValue;
@@ -57,11 +60,15 @@
     Return<uint64_t> getFrameCount() override;
     Return<uint64_t> getBufferSize() override;
     Return<uint32_t> getSampleRate() override;
+#ifdef AUDIO_HAL_VERSION_2_0
     Return<void> getSupportedSampleRates(getSupportedSampleRates_cb _hidl_cb) override;
-    Return<Result> setSampleRate(uint32_t sampleRateHz) override;
-    Return<AudioChannelMask> getChannelMask() override;
     Return<void> getSupportedChannelMasks(getSupportedChannelMasks_cb _hidl_cb) override;
-    Return<Result> setChannelMask(AudioChannelMask mask) override;
+#endif
+    Return<void> getSupportedSampleRates(AudioFormat format, getSupportedSampleRates_cb _hidl_cb);
+    Return<void> getSupportedChannelMasks(AudioFormat format, getSupportedChannelMasks_cb _hidl_cb);
+    Return<Result> setSampleRate(uint32_t sampleRateHz) override;
+    Return<AudioChannelBitfield> getChannelMask() override;
+    Return<Result> setChannelMask(AudioChannelBitfield mask) override;
     Return<AudioFormat> getFormat() override;
     Return<void> getSupportedFormats(getSupportedFormats_cb _hidl_cb) override;
     Return<Result> setFormat(AudioFormat format) override;
@@ -69,20 +76,34 @@
     Return<Result> addEffect(uint64_t effectId) override;
     Return<Result> removeEffect(uint64_t effectId) override;
     Return<Result> standby() override;
+#ifdef AUDIO_HAL_VERSION_2_0
     Return<AudioDevice> getDevice() override;
     Return<Result> setDevice(const DeviceAddress& address) override;
-    Return<Result> setConnectedState(const DeviceAddress& address, bool connected) override;
-    Return<Result> setHwAvSync(uint32_t hwAvSync) override;
     Return<void> getParameters(const hidl_vec<hidl_string>& keys,
                                getParameters_cb _hidl_cb) override;
     Return<Result> setParameters(const hidl_vec<ParameterValue>& parameters) override;
-    Return<void> debugDump(const hidl_handle& fd) override;
+    Return<Result> setConnectedState(const DeviceAddress& address, bool connected) override;
+#elif defined(AUDIO_HAL_VERSION_4_0)
+    Return<void> getDevices(getDevices_cb _hidl_cb) override;
+    Return<Result> setDevices(const hidl_vec<DeviceAddress>& devices) override;
+    Return<void> getParameters(const hidl_vec<ParameterValue>& context,
+                               const hidl_vec<hidl_string>& keys,
+                               getParameters_cb _hidl_cb) override;
+    Return<Result> setParameters(const hidl_vec<ParameterValue>& context,
+                                 const hidl_vec<ParameterValue>& parameters) override;
+#endif
+    Return<Result> setHwAvSync(uint32_t hwAvSync) override;
     Return<Result> start() override;
     Return<Result> stop() override;
     Return<void> createMmapBuffer(int32_t minSizeFrames, createMmapBuffer_cb _hidl_cb) override;
     Return<void> getMmapPosition(getMmapPosition_cb _hidl_cb) override;
     Return<Result> close() override;
 
+    Return<void> debug(const hidl_handle& fd, const hidl_vec<hidl_string>& options) override;
+#ifdef AUDIO_HAL_VERSION_2_0
+    Return<void> debugDump(const hidl_handle& fd) override;
+#endif
+
     // Utility methods for extending interfaces.
     static Result analyzeStatus(const char* funcName, int status);
     static Result analyzeStatus(const char* funcName, int status,
diff --git a/audio/core/all-versions/default/include/core/all-versions/default/Stream.impl.h b/audio/core/all-versions/default/include/core/all-versions/default/Stream.impl.h
index 92cff72..fa0ef45 100644
--- a/audio/core/all-versions/default/include/core/all-versions/default/Stream.impl.h
+++ b/audio/core/all-versions/default/include/core/all-versions/default/Stream.impl.h
@@ -100,9 +100,22 @@
     return mStream->get_sample_rate(mStream);
 }
 
+#ifdef AUDIO_HAL_VERSION_2_0
 Return<void> Stream::getSupportedSampleRates(getSupportedSampleRates_cb _hidl_cb) {
+    return getSupportedSampleRates(getFormat(), _hidl_cb);
+}
+Return<void> Stream::getSupportedChannelMasks(getSupportedChannelMasks_cb _hidl_cb) {
+    return getSupportedChannelMasks(getFormat(), _hidl_cb);
+}
+#endif
+
+Return<void> Stream::getSupportedSampleRates(AudioFormat format,
+                                             getSupportedSampleRates_cb _hidl_cb) {
+    AudioParameter context;
+    context.addInt(String8(AUDIO_PARAMETER_STREAM_FORMAT), int(format));
     String8 halListValue;
-    Result result = getParam(AudioParameter::keyStreamSupportedSamplingRates, &halListValue);
+    Result result =
+        getParam(AudioParameter::keyStreamSupportedSamplingRates, &halListValue, context);
     hidl_vec<uint32_t> sampleRates;
     SortedVector<uint32_t> halSampleRates;
     if (result == Result::OK) {
@@ -110,7 +123,36 @@
             samplingRatesFromString(halListValue.string(), AudioParameter::valueListSeparator);
         sampleRates.setToExternal(halSampleRates.editArray(), halSampleRates.size());
     }
+#ifdef AUDIO_HAL_VERSION_2_0
     _hidl_cb(sampleRates);
+#endif
+#ifdef AUDIO_HAL_VERSION_4_0
+    _hidl_cb(result, sampleRates);
+#endif
+    return Void();
+}
+
+Return<void> Stream::getSupportedChannelMasks(AudioFormat format,
+                                              getSupportedChannelMasks_cb _hidl_cb) {
+    AudioParameter context;
+    context.addInt(String8(AUDIO_PARAMETER_STREAM_FORMAT), int(format));
+    String8 halListValue;
+    Result result = getParam(AudioParameter::keyStreamSupportedChannels, &halListValue, context);
+    hidl_vec<AudioChannelBitfield> channelMasks;
+    SortedVector<audio_channel_mask_t> halChannelMasks;
+    if (result == Result::OK) {
+        halChannelMasks =
+            channelMasksFromString(halListValue.string(), AudioParameter::valueListSeparator);
+        channelMasks.resize(halChannelMasks.size());
+        for (size_t i = 0; i < halChannelMasks.size(); ++i) {
+            channelMasks[i] = AudioChannelBitfield(halChannelMasks[i]);
+        }
+    }
+#ifdef AUDIO_HAL_VERSION_2_0
+    _hidl_cb(channelMasks);
+#elif defined(AUDIO_HAL_VERSION_4_0)
+    _hidl_cb(result, channelMasks);
+#endif
     return Void();
 }
 
@@ -118,28 +160,11 @@
     return setParam(AudioParameter::keySamplingRate, static_cast<int>(sampleRateHz));
 }
 
-Return<AudioChannelMask> Stream::getChannelMask() {
-    return AudioChannelMask(mStream->get_channels(mStream));
+Return<AudioChannelBitfield> Stream::getChannelMask() {
+    return AudioChannelBitfield(mStream->get_channels(mStream));
 }
 
-Return<void> Stream::getSupportedChannelMasks(getSupportedChannelMasks_cb _hidl_cb) {
-    String8 halListValue;
-    Result result = getParam(AudioParameter::keyStreamSupportedChannels, &halListValue);
-    hidl_vec<AudioChannelMask> channelMasks;
-    SortedVector<audio_channel_mask_t> halChannelMasks;
-    if (result == Result::OK) {
-        halChannelMasks =
-            channelMasksFromString(halListValue.string(), AudioParameter::valueListSeparator);
-        channelMasks.resize(halChannelMasks.size());
-        for (size_t i = 0; i < halChannelMasks.size(); ++i) {
-            channelMasks[i] = AudioChannelMask(halChannelMasks[i]);
-        }
-    }
-    _hidl_cb(channelMasks);
-    return Void();
-}
-
-Return<Result> Stream::setChannelMask(AudioChannelMask mask) {
+Return<Result> Stream::setChannelMask(AudioChannelBitfield mask) {
     return setParam(AudioParameter::keyChannels, static_cast<int>(mask));
 }
 
@@ -171,7 +196,7 @@
     uint32_t halSampleRate = mStream->get_sample_rate(mStream);
     audio_channel_mask_t halMask = mStream->get_channels(mStream);
     audio_format_t halFormat = mStream->get_format(mStream);
-    _hidl_cb(halSampleRate, AudioChannelMask(halMask), AudioFormat(halFormat));
+    _hidl_cb(halSampleRate, AudioChannelBitfield(halMask), AudioFormat(halFormat));
     return Void();
 }
 
@@ -200,48 +225,73 @@
     return analyzeStatus("standby", mStream->standby(mStream));
 }
 
+Return<Result> Stream::setHwAvSync(uint32_t hwAvSync) {
+    return setParam(AudioParameter::keyStreamHwAvSync, static_cast<int>(hwAvSync));
+}
+
+#ifdef AUDIO_HAL_VERSION_2_0
 Return<AudioDevice> Stream::getDevice() {
-    int device;
+    int device = 0;
     Result retval = getParam(AudioParameter::keyRouting, &device);
     return retval == Result::OK ? static_cast<AudioDevice>(device) : AudioDevice::NONE;
 }
 
 Return<Result> Stream::setDevice(const DeviceAddress& address) {
-    char* halDeviceAddress = audio_device_address_to_parameter(
-        static_cast<audio_devices_t>(address.device), deviceAddressToHal(address).c_str());
-    AudioParameter params((String8(halDeviceAddress)));
-    free(halDeviceAddress);
-    params.addInt(String8(AudioParameter::keyRouting),
-                  static_cast<audio_devices_t>(address.device));
-    return setParams(params);
+    return setParam(AudioParameter::keyRouting, address);
+}
+
+Return<void> Stream::getParameters(const hidl_vec<hidl_string>& keys, getParameters_cb _hidl_cb) {
+    getParametersImpl({} /* context */, keys, _hidl_cb);
+    return Void();
+}
+
+Return<Result> Stream::setParameters(const hidl_vec<ParameterValue>& parameters) {
+    return setParametersImpl({} /* context */, parameters);
 }
 
 Return<Result> Stream::setConnectedState(const DeviceAddress& address, bool connected) {
     return setParam(
         connected ? AudioParameter::keyStreamConnect : AudioParameter::keyStreamDisconnect,
-        deviceAddressToHal(address).c_str());
+        address);
 }
-
-Return<Result> Stream::setHwAvSync(uint32_t hwAvSync) {
-    return setParam(AudioParameter::keyStreamHwAvSync, static_cast<int>(hwAvSync));
-}
-
-Return<void> Stream::getParameters(const hidl_vec<hidl_string>& keys, getParameters_cb _hidl_cb) {
-    getParametersImpl(keys, _hidl_cb);
-    return Void();
-}
-
-Return<Result> Stream::setParameters(const hidl_vec<ParameterValue>& parameters) {
-    return setParametersImpl(parameters);
-}
-
-Return<void> Stream::debugDump(const hidl_handle& fd) {
-    if (fd.getNativeHandle() != nullptr && fd->numFds == 1) {
-        analyzeStatus("dump", mStream->dump(mStream, fd->data[0]));
+#elif defined(AUDIO_HAL_VERSION_4_0)
+Return<void> Stream::getDevices(getDevices_cb _hidl_cb) {
+    int device = 0;
+    Result retval = getParam(AudioParameter::keyRouting, &device);
+    hidl_vec<DeviceAddress> devices;
+    if (retval == Result::OK) {
+        devices.resize(1);
+        devices[0].device = static_cast<AudioDevice>(device);
     }
+    _hidl_cb(retval, devices);
     return Void();
 }
 
+Return<Result> Stream::setDevices(const hidl_vec<DeviceAddress>& devices) {
+    // FIXME: can the legacy API set multiple device with address ?
+    if (devices.size() > 1) {
+        return Result::NOT_SUPPORTED;
+    }
+    DeviceAddress address;
+    if (devices.size() == 1) {
+        address = devices[0];
+    } else {
+        address.device = AudioDevice::NONE;
+    }
+    return setParam(AudioParameter::keyRouting, address);
+}
+Return<void> Stream::getParameters(const hidl_vec<ParameterValue>& context,
+                                   const hidl_vec<hidl_string>& keys, getParameters_cb _hidl_cb) {
+    getParametersImpl(context, keys, _hidl_cb);
+    return Void();
+}
+
+Return<Result> Stream::setParameters(const hidl_vec<ParameterValue>& context,
+                                     const hidl_vec<ParameterValue>& parameters) {
+    return setParametersImpl(context, parameters);
+}
+#endif
+
 Return<Result> Stream::start() {
     return Result::NOT_SUPPORTED;
 }
@@ -269,6 +319,19 @@
     return Result::NOT_SUPPORTED;
 }
 
+Return<void> Stream::debug(const hidl_handle& fd, const hidl_vec<hidl_string>& /* options */) {
+    if (fd.getNativeHandle() != nullptr && fd->numFds == 1) {
+        analyzeStatus("dump", mStream->dump(mStream, fd->data[0]));
+    }
+    return Void();
+}
+
+#ifdef AUDIO_HAL_VERSION_2_0
+Return<void> Stream::debugDump(const hidl_handle& fd) {
+    return debug(fd, {} /* options */);
+}
+#endif
+
 }  // namespace implementation
 }  // namespace AUDIO_HAL_VERSION
 }  // namespace audio
diff --git a/audio/core/all-versions/default/include/core/all-versions/default/StreamIn.h b/audio/core/all-versions/default/include/core/all-versions/default/StreamIn.h
index 7380dae..f226e63 100644
--- a/audio/core/all-versions/default/include/core/all-versions/default/StreamIn.h
+++ b/audio/core/all-versions/default/include/core/all-versions/default/StreamIn.h
@@ -58,11 +58,15 @@
     Return<uint64_t> getFrameCount() override;
     Return<uint64_t> getBufferSize() override;
     Return<uint32_t> getSampleRate() override;
+#ifdef AUDIO_HAL_VERSION_2_0
     Return<void> getSupportedSampleRates(getSupportedSampleRates_cb _hidl_cb) override;
-    Return<Result> setSampleRate(uint32_t sampleRateHz) override;
-    Return<AudioChannelMask> getChannelMask() override;
     Return<void> getSupportedChannelMasks(getSupportedChannelMasks_cb _hidl_cb) override;
-    Return<Result> setChannelMask(AudioChannelMask mask) override;
+#endif
+    Return<void> getSupportedSampleRates(AudioFormat format, getSupportedSampleRates_cb _hidl_cb);
+    Return<void> getSupportedChannelMasks(AudioFormat format, getSupportedChannelMasks_cb _hidl_cb);
+    Return<Result> setSampleRate(uint32_t sampleRateHz) override;
+    Return<AudioChannelBitfield> getChannelMask() override;
+    Return<Result> setChannelMask(AudioChannelBitfield mask) override;
     Return<AudioFormat> getFormat() override;
     Return<void> getSupportedFormats(getSupportedFormats_cb _hidl_cb) override;
     Return<Result> setFormat(AudioFormat format) override;
@@ -70,16 +74,30 @@
     Return<Result> addEffect(uint64_t effectId) override;
     Return<Result> removeEffect(uint64_t effectId) override;
     Return<Result> standby() override;
+#ifdef AUDIO_HAL_VERSION_2_0
     Return<AudioDevice> getDevice() override;
     Return<Result> setDevice(const DeviceAddress& address) override;
-    Return<Result> setConnectedState(const DeviceAddress& address, bool connected) override;
-    Return<Result> setHwAvSync(uint32_t hwAvSync) override;
     Return<void> getParameters(const hidl_vec<hidl_string>& keys,
                                getParameters_cb _hidl_cb) override;
     Return<Result> setParameters(const hidl_vec<ParameterValue>& parameters) override;
-    Return<void> debugDump(const hidl_handle& fd) override;
+    Return<Result> setConnectedState(const DeviceAddress& address, bool connected) override;
+#elif defined(AUDIO_HAL_VERSION_4_0)
+    Return<void> getDevices(getDevices_cb _hidl_cb) override;
+    Return<Result> setDevices(const hidl_vec<DeviceAddress>& devices) override;
+    Return<void> getParameters(const hidl_vec<ParameterValue>& context,
+                               const hidl_vec<hidl_string>& keys,
+                               getParameters_cb _hidl_cb) override;
+    Return<Result> setParameters(const hidl_vec<ParameterValue>& context,
+                                 const hidl_vec<ParameterValue>& parameters) override;
+#endif
+    Return<Result> setHwAvSync(uint32_t hwAvSync) override;
     Return<Result> close() override;
 
+    Return<void> debug(const hidl_handle& fd, const hidl_vec<hidl_string>& options) override;
+#ifdef AUDIO_HAL_VERSION_2_0
+    Return<void> debugDump(const hidl_handle& fd) override;
+#endif
+
     // Methods from ::android::hardware::audio::AUDIO_HAL_VERSION::IStreamIn follow.
     Return<void> getAudioSource(getAudioSource_cb _hidl_cb) override;
     Return<Result> setGain(float gain) override;
@@ -91,6 +109,10 @@
     Return<Result> stop() override;
     Return<void> createMmapBuffer(int32_t minSizeFrames, createMmapBuffer_cb _hidl_cb) override;
     Return<void> getMmapPosition(getMmapPosition_cb _hidl_cb) override;
+#ifdef AUDIO_HAL_VERSION_4_0
+    Return<void> updateSinkMetadata(const SinkMetadata& sinkMetadata) override;
+    Return<void> getActiveMicrophones(getActiveMicrophones_cb _hidl_cb) override;
+#endif
 
     static Result getCapturePositionImpl(audio_stream_in_t* stream, uint64_t* frames,
                                          uint64_t* time);
diff --git a/audio/core/all-versions/default/include/core/all-versions/default/StreamIn.impl.h b/audio/core/all-versions/default/include/core/all-versions/default/StreamIn.impl.h
index abee225..dcd3df1 100644
--- a/audio/core/all-versions/default/include/core/all-versions/default/StreamIn.impl.h
+++ b/audio/core/all-versions/default/include/core/all-versions/default/StreamIn.impl.h
@@ -179,23 +179,33 @@
     return mStreamCommon->getSampleRate();
 }
 
+#ifdef AUDIO_HAL_VERSION_2_0
+Return<void> StreamIn::getSupportedChannelMasks(getSupportedChannelMasks_cb _hidl_cb) {
+    return mStreamCommon->getSupportedChannelMasks(_hidl_cb);
+}
 Return<void> StreamIn::getSupportedSampleRates(getSupportedSampleRates_cb _hidl_cb) {
     return mStreamCommon->getSupportedSampleRates(_hidl_cb);
 }
+#endif
+
+Return<void> StreamIn::getSupportedChannelMasks(AudioFormat format,
+                                                getSupportedChannelMasks_cb _hidl_cb) {
+    return mStreamCommon->getSupportedChannelMasks(format, _hidl_cb);
+}
+Return<void> StreamIn::getSupportedSampleRates(AudioFormat format,
+                                               getSupportedSampleRates_cb _hidl_cb) {
+    return mStreamCommon->getSupportedSampleRates(format, _hidl_cb);
+}
 
 Return<Result> StreamIn::setSampleRate(uint32_t sampleRateHz) {
     return mStreamCommon->setSampleRate(sampleRateHz);
 }
 
-Return<AudioChannelMask> StreamIn::getChannelMask() {
+Return<AudioChannelBitfield> StreamIn::getChannelMask() {
     return mStreamCommon->getChannelMask();
 }
 
-Return<void> StreamIn::getSupportedChannelMasks(getSupportedChannelMasks_cb _hidl_cb) {
-    return mStreamCommon->getSupportedChannelMasks(_hidl_cb);
-}
-
-Return<Result> StreamIn::setChannelMask(AudioChannelMask mask) {
+Return<Result> StreamIn::setChannelMask(AudioChannelBitfield mask) {
     return mStreamCommon->setChannelMask(mask);
 }
 
@@ -227,6 +237,15 @@
     return mStreamCommon->standby();
 }
 
+Return<Result> StreamIn::setHwAvSync(uint32_t hwAvSync) {
+    return mStreamCommon->setHwAvSync(hwAvSync);
+}
+
+#ifdef AUDIO_HAL_VERSION_2_0
+Return<Result> StreamIn::setConnectedState(const DeviceAddress& address, bool connected) {
+    return mStreamCommon->setConnectedState(address, connected);
+}
+
 Return<AudioDevice> StreamIn::getDevice() {
     return mStreamCommon->getDevice();
 }
@@ -235,14 +254,6 @@
     return mStreamCommon->setDevice(address);
 }
 
-Return<Result> StreamIn::setConnectedState(const DeviceAddress& address, bool connected) {
-    return mStreamCommon->setConnectedState(address, connected);
-}
-
-Return<Result> StreamIn::setHwAvSync(uint32_t hwAvSync) {
-    return mStreamCommon->setHwAvSync(hwAvSync);
-}
-
 Return<void> StreamIn::getParameters(const hidl_vec<hidl_string>& keys, getParameters_cb _hidl_cb) {
     return mStreamCommon->getParameters(keys, _hidl_cb);
 }
@@ -254,6 +265,24 @@
 Return<void> StreamIn::debugDump(const hidl_handle& fd) {
     return mStreamCommon->debugDump(fd);
 }
+#elif defined(AUDIO_HAL_VERSION_4_0)
+Return<void> StreamIn::getDevices(getDevices_cb _hidl_cb) {
+    return mStreamCommon->getDevices(_hidl_cb);
+}
+
+Return<Result> StreamIn::setDevices(const hidl_vec<DeviceAddress>& devices) {
+    return mStreamCommon->setDevices(devices);
+}
+Return<void> StreamIn::getParameters(const hidl_vec<ParameterValue>& context,
+                                     const hidl_vec<hidl_string>& keys, getParameters_cb _hidl_cb) {
+    return mStreamCommon->getParameters(context, keys, _hidl_cb);
+}
+
+Return<Result> StreamIn::setParameters(const hidl_vec<ParameterValue>& context,
+                                       const hidl_vec<ParameterValue>& parameters) {
+    return mStreamCommon->setParameters(context, parameters);
+}
+#endif
 
 Return<Result> StreamIn::start() {
     return mStreamMmap->start();
@@ -415,6 +444,21 @@
     return Void();
 }
 
+Return<void> StreamIn::debug(const hidl_handle& fd, const hidl_vec<hidl_string>& options) {
+    return mStreamCommon->debug(fd, options);
+}
+
+#ifdef AUDIO_HAL_VERSION_4_0
+Return<void> StreamIn::updateSinkMetadata(const SinkMetadata& /*sinkMetadata*/) {
+    return Void();  // TODO: propagate to legacy
+}
+
+Return<void> StreamIn::getActiveMicrophones(getActiveMicrophones_cb _hidl_cb) {
+    _hidl_cb(Result::NOT_SUPPORTED, {});  // TODO: retrieve from legacy
+    return Void();
+}
+#endif
+
 }  // namespace implementation
 }  // namespace AUDIO_HAL_VERSION
 }  // namespace audio
diff --git a/audio/core/all-versions/default/include/core/all-versions/default/StreamOut.h b/audio/core/all-versions/default/include/core/all-versions/default/StreamOut.h
index 4cfe2e3..134d7b9 100644
--- a/audio/core/all-versions/default/include/core/all-versions/default/StreamOut.h
+++ b/audio/core/all-versions/default/include/core/all-versions/default/StreamOut.h
@@ -60,11 +60,15 @@
     Return<uint64_t> getFrameCount() override;
     Return<uint64_t> getBufferSize() override;
     Return<uint32_t> getSampleRate() override;
+#ifdef AUDIO_HAL_VERSION_2_0
     Return<void> getSupportedSampleRates(getSupportedSampleRates_cb _hidl_cb) override;
-    Return<Result> setSampleRate(uint32_t sampleRateHz) override;
-    Return<AudioChannelMask> getChannelMask() override;
     Return<void> getSupportedChannelMasks(getSupportedChannelMasks_cb _hidl_cb) override;
-    Return<Result> setChannelMask(AudioChannelMask mask) override;
+#endif
+    Return<void> getSupportedSampleRates(AudioFormat format, getSupportedSampleRates_cb _hidl_cb);
+    Return<void> getSupportedChannelMasks(AudioFormat format, getSupportedChannelMasks_cb _hidl_cb);
+    Return<Result> setSampleRate(uint32_t sampleRateHz) override;
+    Return<AudioChannelBitfield> getChannelMask() override;
+    Return<Result> setChannelMask(AudioChannelBitfield mask) override;
     Return<AudioFormat> getFormat() override;
     Return<void> getSupportedFormats(getSupportedFormats_cb _hidl_cb) override;
     Return<Result> setFormat(AudioFormat format) override;
@@ -72,16 +76,30 @@
     Return<Result> addEffect(uint64_t effectId) override;
     Return<Result> removeEffect(uint64_t effectId) override;
     Return<Result> standby() override;
+#ifdef AUDIO_HAL_VERSION_2_0
     Return<AudioDevice> getDevice() override;
     Return<Result> setDevice(const DeviceAddress& address) override;
-    Return<Result> setConnectedState(const DeviceAddress& address, bool connected) override;
-    Return<Result> setHwAvSync(uint32_t hwAvSync) override;
     Return<void> getParameters(const hidl_vec<hidl_string>& keys,
                                getParameters_cb _hidl_cb) override;
     Return<Result> setParameters(const hidl_vec<ParameterValue>& parameters) override;
-    Return<void> debugDump(const hidl_handle& fd) override;
+    Return<Result> setConnectedState(const DeviceAddress& address, bool connected) override;
+#elif defined(AUDIO_HAL_VERSION_4_0)
+    Return<void> getDevices(getDevices_cb _hidl_cb) override;
+    Return<Result> setDevices(const hidl_vec<DeviceAddress>& devices) override;
+    Return<void> getParameters(const hidl_vec<ParameterValue>& context,
+                               const hidl_vec<hidl_string>& keys,
+                               getParameters_cb _hidl_cb) override;
+    Return<Result> setParameters(const hidl_vec<ParameterValue>& context,
+                                 const hidl_vec<ParameterValue>& parameters) override;
+#endif
+    Return<Result> setHwAvSync(uint32_t hwAvSync) override;
     Return<Result> close() override;
 
+    Return<void> debug(const hidl_handle& fd, const hidl_vec<hidl_string>& options) override;
+#ifdef AUDIO_HAL_VERSION_2_0
+    Return<void> debugDump(const hidl_handle& fd) override;
+#endif
+
     // Methods from ::android::hardware::audio::AUDIO_HAL_VERSION::IStreamOut follow.
     Return<uint32_t> getLatency() override;
     Return<Result> setVolume(float left, float right) override;
@@ -102,6 +120,10 @@
     Return<Result> stop() override;
     Return<void> createMmapBuffer(int32_t minSizeFrames, createMmapBuffer_cb _hidl_cb) override;
     Return<void> getMmapPosition(getMmapPosition_cb _hidl_cb) override;
+#ifdef AUDIO_HAL_VERSION_4_0
+    Return<void> updateSourceMetadata(const SourceMetadata& sourceMetadata) override;
+    Return<Result> selectPresentation(int32_t presentationId, int32_t programId) override;
+#endif
 
     static Result getPresentationPositionImpl(audio_stream_out_t* stream, uint64_t* frames,
                                               TimeSpec* timeStamp);
diff --git a/audio/core/all-versions/default/include/core/all-versions/default/StreamOut.impl.h b/audio/core/all-versions/default/include/core/all-versions/default/StreamOut.impl.h
index bdbeb38..605b824 100644
--- a/audio/core/all-versions/default/include/core/all-versions/default/StreamOut.impl.h
+++ b/audio/core/all-versions/default/include/core/all-versions/default/StreamOut.impl.h
@@ -183,23 +183,33 @@
     return mStreamCommon->getSampleRate();
 }
 
+#ifdef AUDIO_HAL_VERSION_2_0
+Return<void> StreamOut::getSupportedChannelMasks(getSupportedChannelMasks_cb _hidl_cb) {
+    return mStreamCommon->getSupportedChannelMasks(_hidl_cb);
+}
 Return<void> StreamOut::getSupportedSampleRates(getSupportedSampleRates_cb _hidl_cb) {
     return mStreamCommon->getSupportedSampleRates(_hidl_cb);
 }
+#endif
+
+Return<void> StreamOut::getSupportedChannelMasks(AudioFormat format,
+                                                 getSupportedChannelMasks_cb _hidl_cb) {
+    return mStreamCommon->getSupportedChannelMasks(format, _hidl_cb);
+}
+Return<void> StreamOut::getSupportedSampleRates(AudioFormat format,
+                                                getSupportedSampleRates_cb _hidl_cb) {
+    return mStreamCommon->getSupportedSampleRates(format, _hidl_cb);
+}
 
 Return<Result> StreamOut::setSampleRate(uint32_t sampleRateHz) {
     return mStreamCommon->setSampleRate(sampleRateHz);
 }
 
-Return<AudioChannelMask> StreamOut::getChannelMask() {
+Return<AudioChannelBitfield> StreamOut::getChannelMask() {
     return mStreamCommon->getChannelMask();
 }
 
-Return<void> StreamOut::getSupportedChannelMasks(getSupportedChannelMasks_cb _hidl_cb) {
-    return mStreamCommon->getSupportedChannelMasks(_hidl_cb);
-}
-
-Return<Result> StreamOut::setChannelMask(AudioChannelMask mask) {
+Return<Result> StreamOut::setChannelMask(AudioChannelBitfield mask) {
     return mStreamCommon->setChannelMask(mask);
 }
 
@@ -231,6 +241,15 @@
     return mStreamCommon->standby();
 }
 
+Return<Result> StreamOut::setHwAvSync(uint32_t hwAvSync) {
+    return mStreamCommon->setHwAvSync(hwAvSync);
+}
+
+#ifdef AUDIO_HAL_VERSION_2_0
+Return<Result> StreamOut::setConnectedState(const DeviceAddress& address, bool connected) {
+    return mStreamCommon->setConnectedState(address, connected);
+}
+
 Return<AudioDevice> StreamOut::getDevice() {
     return mStreamCommon->getDevice();
 }
@@ -239,14 +258,6 @@
     return mStreamCommon->setDevice(address);
 }
 
-Return<Result> StreamOut::setConnectedState(const DeviceAddress& address, bool connected) {
-    return mStreamCommon->setConnectedState(address, connected);
-}
-
-Return<Result> StreamOut::setHwAvSync(uint32_t hwAvSync) {
-    return mStreamCommon->setHwAvSync(hwAvSync);
-}
-
 Return<void> StreamOut::getParameters(const hidl_vec<hidl_string>& keys,
                                       getParameters_cb _hidl_cb) {
     return mStreamCommon->getParameters(keys, _hidl_cb);
@@ -259,6 +270,25 @@
 Return<void> StreamOut::debugDump(const hidl_handle& fd) {
     return mStreamCommon->debugDump(fd);
 }
+#elif defined(AUDIO_HAL_VERSION_4_0)
+Return<void> StreamOut::getDevices(getDevices_cb _hidl_cb) {
+    return mStreamCommon->getDevices(_hidl_cb);
+}
+
+Return<Result> StreamOut::setDevices(const hidl_vec<DeviceAddress>& devices) {
+    return mStreamCommon->setDevices(devices);
+}
+Return<void> StreamOut::getParameters(const hidl_vec<ParameterValue>& context,
+                                      const hidl_vec<hidl_string>& keys,
+                                      getParameters_cb _hidl_cb) {
+    return mStreamCommon->getParameters(context, keys, _hidl_cb);
+}
+
+Return<Result> StreamOut::setParameters(const hidl_vec<ParameterValue>& context,
+                                        const hidl_vec<ParameterValue>& parameters) {
+    return mStreamCommon->setParameters(context, parameters);
+}
+#endif
 
 Return<Result> StreamOut::close() {
     if (mIsClosed) return Result::INVALID_STATE;
@@ -512,6 +542,19 @@
     return mStreamMmap->getMmapPosition(_hidl_cb);
 }
 
+Return<void> StreamOut::debug(const hidl_handle& fd, const hidl_vec<hidl_string>& options) {
+    return mStreamCommon->debug(fd, options);
+}
+
+#ifdef AUDIO_HAL_VERSION_4_0
+Return<void> StreamOut::updateSourceMetadata(const SourceMetadata& /*sourceMetadata*/) {
+    return Void();  // TODO: propagate to legacy
+}
+Return<Result> StreamOut::selectPresentation(int32_t /*presentationId*/, int32_t /*programId*/) {
+    return Result::NOT_SUPPORTED;  // TODO: propagate to legacy
+}
+#endif
+
 }  // namespace implementation
 }  // namespace AUDIO_HAL_VERSION
 }  // namespace audio
diff --git a/audio/effect/4.0/default/AcousticEchoCancelerEffect.cpp b/audio/effect/4.0/default/AcousticEchoCancelerEffect.cpp
new file mode 100644
index 0000000..242740e
--- /dev/null
+++ b/audio/effect/4.0/default/AcousticEchoCancelerEffect.cpp
@@ -0,0 +1,23 @@
+/*
+ * 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 "AEC_Effect_HAL"
+
+#include "AcousticEchoCancelerEffect.h"
+
+#define AUDIO_HAL_VERSION V4_0
+#include <effect/all-versions/default/AcousticEchoCancelerEffect.impl.h>
+#undef AUDIO_HAL_VERSION
diff --git a/audio/effect/4.0/default/AcousticEchoCancelerEffect.h b/audio/effect/4.0/default/AcousticEchoCancelerEffect.h
new file mode 100644
index 0000000..0ac0a1e
--- /dev/null
+++ b/audio/effect/4.0/default/AcousticEchoCancelerEffect.h
@@ -0,0 +1,28 @@
+/*
+ * 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_AUDIO_EFFECT_V4_0_ACOUSTICECHOCANCELEREFFECT_H
+#define ANDROID_HARDWARE_AUDIO_EFFECT_V4_0_ACOUSTICECHOCANCELEREFFECT_H
+
+#include <android/hardware/audio/effect/4.0/IAcousticEchoCancelerEffect.h>
+
+#include "Effect.h"
+
+#define AUDIO_HAL_VERSION V4_0
+#include <effect/all-versions/default/AcousticEchoCancelerEffect.h>
+#undef AUDIO_HAL_VERSION
+
+#endif  // ANDROID_HARDWARE_AUDIO_EFFECT_V4_0_ACOUSTICECHOCANCELEREFFECT_H
diff --git a/audio/effect/4.0/default/Android.bp b/audio/effect/4.0/default/Android.bp
new file mode 100644
index 0000000..dcb2269
--- /dev/null
+++ b/audio/effect/4.0/default/Android.bp
@@ -0,0 +1,50 @@
+cc_library_shared {
+    name: "android.hardware.audio.effect@4.0-impl",
+    defaults: ["hidl_defaults"],
+    vendor: true,
+    relative_install_path: "hw",
+    srcs: [
+        "AcousticEchoCancelerEffect.cpp",
+        "AudioBufferManager.cpp",
+        "AutomaticGainControlEffect.cpp",
+        "BassBoostEffect.cpp",
+        "Conversions.cpp",
+        "DownmixEffect.cpp",
+        "Effect.cpp",
+        "EffectsFactory.cpp",
+        "EnvironmentalReverbEffect.cpp",
+        "EqualizerEffect.cpp",
+        "LoudnessEnhancerEffect.cpp",
+        "NoiseSuppressionEffect.cpp",
+        "PresetReverbEffect.cpp",
+        "VirtualizerEffect.cpp",
+        "VisualizerEffect.cpp",
+    ],
+
+    shared_libs: [
+        "libbase",
+        "libcutils",
+        "libeffects",
+        "libfmq",
+        "libhidlbase",
+        "libhidlmemory",
+        "libhidltransport",
+        "liblog",
+        "libutils",
+        "android.hardware.audio.common-util",
+        "android.hardware.audio.common@4.0",
+        "android.hardware.audio.common@4.0-util",
+        "android.hardware.audio.effect@4.0",
+        "android.hidl.memory@1.0",
+    ],
+
+    header_libs: [
+        "android.hardware.audio.common.util@all-versions",
+        "android.hardware.audio.effect@all-versions-impl",
+        "libaudio_system_headers",
+        "libaudioclient_headers",
+        "libeffects_headers",
+        "libhardware_headers",
+        "libmedia_headers",
+    ],
+}
diff --git a/audio/effect/4.0/default/AudioBufferManager.cpp b/audio/effect/4.0/default/AudioBufferManager.cpp
new file mode 100644
index 0000000..2d75f3f
--- /dev/null
+++ b/audio/effect/4.0/default/AudioBufferManager.cpp
@@ -0,0 +1,21 @@
+/*
+ * 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.
+ */
+
+#include "AudioBufferManager.h"
+
+#define AUDIO_HAL_VERSION V4_0
+#include <effect/all-versions/default/AudioBufferManager.impl.h>
+#undef AUDIO_HAL_VERSION
diff --git a/audio/effect/4.0/default/AudioBufferManager.h b/audio/effect/4.0/default/AudioBufferManager.h
new file mode 100644
index 0000000..1f151e6
--- /dev/null
+++ b/audio/effect/4.0/default/AudioBufferManager.h
@@ -0,0 +1,26 @@
+/*
+ * 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_AUDIO_EFFECT_V4_0_AUDIO_BUFFER_MANAGER_H_
+#define ANDROID_HARDWARE_AUDIO_EFFECT_V4_0_AUDIO_BUFFER_MANAGER_H_
+
+#include <android/hardware/audio/effect/4.0/types.h>
+
+#define AUDIO_HAL_VERSION V4_0
+#include <effect/all-versions/default/AudioBufferManager.h>
+#undef AUDIO_HAL_VERSION
+
+#endif  // ANDROID_HARDWARE_AUDIO_EFFECT_V4_0_AUDIO_BUFFER_MANAGER_H_
diff --git a/audio/effect/4.0/default/AutomaticGainControlEffect.cpp b/audio/effect/4.0/default/AutomaticGainControlEffect.cpp
new file mode 100644
index 0000000..9d21c8a
--- /dev/null
+++ b/audio/effect/4.0/default/AutomaticGainControlEffect.cpp
@@ -0,0 +1,23 @@
+/*
+ * 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 "AGC_Effect_HAL"
+
+#include "AutomaticGainControlEffect.h"
+
+#define AUDIO_HAL_VERSION V4_0
+#include <effect/all-versions/default/AutomaticGainControlEffect.impl.h>
+#undef AUDIO_HAL_VERSION
diff --git a/audio/effect/4.0/default/AutomaticGainControlEffect.h b/audio/effect/4.0/default/AutomaticGainControlEffect.h
new file mode 100644
index 0000000..7f12007
--- /dev/null
+++ b/audio/effect/4.0/default/AutomaticGainControlEffect.h
@@ -0,0 +1,28 @@
+/*
+ * 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_AUDIO_EFFECT_V4_0_AUTOMATICGAINCONTROLEFFECT_H
+#define ANDROID_HARDWARE_AUDIO_EFFECT_V4_0_AUTOMATICGAINCONTROLEFFECT_H
+
+#include <android/hardware/audio/effect/4.0/IAutomaticGainControlEffect.h>
+
+#include "Effect.h"
+
+#define AUDIO_HAL_VERSION V4_0
+#include <effect/all-versions/default/AutomaticGainControlEffect.h>
+#undef AUDIO_HAL_VERSION
+
+#endif  // ANDROID_HARDWARE_AUDIO_EFFECT_V4_0_AUTOMATICGAINCONTROLEFFECT_H
diff --git a/audio/effect/4.0/default/BassBoostEffect.cpp b/audio/effect/4.0/default/BassBoostEffect.cpp
new file mode 100644
index 0000000..74a626b
--- /dev/null
+++ b/audio/effect/4.0/default/BassBoostEffect.cpp
@@ -0,0 +1,23 @@
+/*
+ * 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 "BassBoost_HAL"
+
+#include "BassBoostEffect.h"
+
+#define AUDIO_HAL_VERSION V4_0
+#include <effect/all-versions/default/BassBoostEffect.impl.h>
+#undef AUDIO_HAL_VERSION
diff --git a/audio/effect/4.0/default/BassBoostEffect.h b/audio/effect/4.0/default/BassBoostEffect.h
new file mode 100644
index 0000000..206a75f
--- /dev/null
+++ b/audio/effect/4.0/default/BassBoostEffect.h
@@ -0,0 +1,30 @@
+/*
+ * 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_AUDIO_EFFECT_V4_0_BASSBOOSTEFFECT_H
+#define ANDROID_HARDWARE_AUDIO_EFFECT_V4_0_BASSBOOSTEFFECT_H
+
+#include <android/hardware/audio/effect/4.0/IBassBoostEffect.h>
+
+#include <hidl/MQDescriptor.h>
+
+#include "Effect.h"
+
+#define AUDIO_HAL_VERSION V4_0
+#include <effect/all-versions/default/BassBoostEffect.h>
+#undef AUDIO_HAL_VERSION
+
+#endif  // ANDROID_HARDWARE_AUDIO_EFFECT_V4_0_BASSBOOSTEFFECT_H
diff --git a/audio/effect/4.0/default/Conversions.cpp b/audio/effect/4.0/default/Conversions.cpp
new file mode 100644
index 0000000..91285ae
--- /dev/null
+++ b/audio/effect/4.0/default/Conversions.cpp
@@ -0,0 +1,24 @@
+/*
+ * 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.
+ */
+
+#include "Conversions.h"
+#include "HidlUtils.h"
+
+using ::android::hardware::audio::common::V4_0::HidlUtils;
+
+#define AUDIO_HAL_VERSION V4_0
+#include <effect/all-versions/default/Conversions.impl.h>
+#undef AUDIO_HAL_VERSION
diff --git a/audio/effect/4.0/default/Conversions.h b/audio/effect/4.0/default/Conversions.h
new file mode 100644
index 0000000..50e380f
--- /dev/null
+++ b/audio/effect/4.0/default/Conversions.h
@@ -0,0 +1,26 @@
+/*
+ * 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_AUDIO_EFFECT_V4_0_CONVERSIONS_H_
+#define ANDROID_HARDWARE_AUDIO_EFFECT_V4_0_CONVERSIONS_H_
+
+#include <android/hardware/audio/effect/4.0/types.h>
+
+#define AUDIO_HAL_VERSION V4_0
+#include <effect/all-versions/default/Conversions.h>
+#undef AUDIO_HAL_VERSION
+
+#endif  // ANDROID_HARDWARE_AUDIO_EFFECT_V4_0_CONVERSIONS_H_
diff --git a/audio/effect/4.0/default/DownmixEffect.cpp b/audio/effect/4.0/default/DownmixEffect.cpp
new file mode 100644
index 0000000..07fcab2
--- /dev/null
+++ b/audio/effect/4.0/default/DownmixEffect.cpp
@@ -0,0 +1,23 @@
+/*
+ * 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 "Downmix_HAL"
+
+#include "DownmixEffect.h"
+
+#define AUDIO_HAL_VERSION V4_0
+#include <effect/all-versions/default/DownmixEffect.impl.h>
+#undef AUDIO_HAL_VERSION
diff --git a/audio/effect/4.0/default/DownmixEffect.h b/audio/effect/4.0/default/DownmixEffect.h
new file mode 100644
index 0000000..5ae820b
--- /dev/null
+++ b/audio/effect/4.0/default/DownmixEffect.h
@@ -0,0 +1,28 @@
+/*
+ * 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_AUDIO_EFFECT_V4_0_DOWNMIXEFFECT_H
+#define ANDROID_HARDWARE_AUDIO_EFFECT_V4_0_DOWNMIXEFFECT_H
+
+#include <android/hardware/audio/effect/4.0/IDownmixEffect.h>
+
+#include "Effect.h"
+
+#define AUDIO_HAL_VERSION V4_0
+#include <effect/all-versions/default/DownmixEffect.h>
+#undef AUDIO_HAL_VERSION
+
+#endif  // ANDROID_HARDWARE_AUDIO_EFFECT_V4_0_DOWNMIXEFFECT_H
diff --git a/audio/effect/4.0/default/Effect.cpp b/audio/effect/4.0/default/Effect.cpp
new file mode 100644
index 0000000..707044b
--- /dev/null
+++ b/audio/effect/4.0/default/Effect.cpp
@@ -0,0 +1,28 @@
+/*
+ * 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.
+ */
+
+#include <memory.h>
+
+#define LOG_TAG "EffectHAL"
+#define ATRACE_TAG ATRACE_TAG_AUDIO
+
+#include "Conversions.h"
+#include "Effect.h"
+#include "common/all-versions/default/EffectMap.h"
+
+#define AUDIO_HAL_VERSION V4_0
+#include <effect/all-versions/default/Effect.impl.h>
+#undef AUDIO_HAL_VERSION
diff --git a/audio/effect/4.0/default/Effect.h b/audio/effect/4.0/default/Effect.h
new file mode 100644
index 0000000..9ca79c4
--- /dev/null
+++ b/audio/effect/4.0/default/Effect.h
@@ -0,0 +1,28 @@
+/*
+ * 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_AUDIO_EFFECT_V4_0_EFFECT_H
+#define ANDROID_HARDWARE_AUDIO_EFFECT_V4_0_EFFECT_H
+
+#include <android/hardware/audio/effect/4.0/IEffect.h>
+
+#include "AudioBufferManager.h"
+
+#define AUDIO_HAL_VERSION V4_0
+#include <effect/all-versions/default/Effect.h>
+#undef AUDIO_HAL_VERSION
+
+#endif  // ANDROID_HARDWARE_AUDIO_EFFECT_V4_0_EFFECT_H
diff --git a/audio/effect/4.0/default/EffectsFactory.cpp b/audio/effect/4.0/default/EffectsFactory.cpp
new file mode 100644
index 0000000..ee0413d
--- /dev/null
+++ b/audio/effect/4.0/default/EffectsFactory.cpp
@@ -0,0 +1,39 @@
+/*
+ * 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 "EffectFactoryHAL"
+#include "EffectsFactory.h"
+#include "AcousticEchoCancelerEffect.h"
+#include "AutomaticGainControlEffect.h"
+#include "BassBoostEffect.h"
+#include "Conversions.h"
+#include "DownmixEffect.h"
+#include "Effect.h"
+#include "EnvironmentalReverbEffect.h"
+#include "EqualizerEffect.h"
+#include "HidlUtils.h"
+#include "LoudnessEnhancerEffect.h"
+#include "NoiseSuppressionEffect.h"
+#include "PresetReverbEffect.h"
+#include "VirtualizerEffect.h"
+#include "VisualizerEffect.h"
+#include "common/all-versions/default/EffectMap.h"
+
+using ::android::hardware::audio::common::V4_0::HidlUtils;
+
+#define AUDIO_HAL_VERSION V4_0
+#include <effect/all-versions/default/EffectsFactory.impl.h>
+#undef AUDIO_HAL_VERSION
diff --git a/audio/effect/4.0/default/EffectsFactory.h b/audio/effect/4.0/default/EffectsFactory.h
new file mode 100644
index 0000000..48e4b4c
--- /dev/null
+++ b/audio/effect/4.0/default/EffectsFactory.h
@@ -0,0 +1,29 @@
+/*
+ * 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_AUDIO_EFFECT_V4_0_EFFECTSFACTORY_H
+#define ANDROID_HARDWARE_AUDIO_EFFECT_V4_0_EFFECTSFACTORY_H
+
+#include <system/audio_effect.h>
+
+#include <android/hardware/audio/effect/4.0/IEffectsFactory.h>
+
+#include <hidl/MQDescriptor.h>
+#define AUDIO_HAL_VERSION V4_0
+#include <effect/all-versions/default/EffectsFactory.h>
+#undef AUDIO_HAL_VERSION
+
+#endif  // ANDROID_HARDWARE_AUDIO_EFFECT_V4_0_EFFECTSFACTORY_H
diff --git a/audio/effect/4.0/default/EnvironmentalReverbEffect.cpp b/audio/effect/4.0/default/EnvironmentalReverbEffect.cpp
new file mode 100644
index 0000000..cc3102d
--- /dev/null
+++ b/audio/effect/4.0/default/EnvironmentalReverbEffect.cpp
@@ -0,0 +1,24 @@
+/*
+ * 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 "EnvReverb_HAL"
+#include <android/log.h>
+
+#include "EnvironmentalReverbEffect.h"
+
+#define AUDIO_HAL_VERSION V4_0
+#include <effect/all-versions/default/EnvironmentalReverbEffect.impl.h>
+#undef AUDIO_HAL_VERSION
diff --git a/audio/effect/4.0/default/EnvironmentalReverbEffect.h b/audio/effect/4.0/default/EnvironmentalReverbEffect.h
new file mode 100644
index 0000000..c0fb25c
--- /dev/null
+++ b/audio/effect/4.0/default/EnvironmentalReverbEffect.h
@@ -0,0 +1,30 @@
+/*
+ * 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_AUDIO_EFFECT_V4_0_ENVIRONMENTALREVERBEFFECT_H
+#define ANDROID_HARDWARE_AUDIO_EFFECT_V4_0_ENVIRONMENTALREVERBEFFECT_H
+
+#include <system/audio_effects/effect_environmentalreverb.h>
+
+#include <android/hardware/audio/effect/4.0/IEnvironmentalReverbEffect.h>
+
+#include "Effect.h"
+
+#define AUDIO_HAL_VERSION V4_0
+#include <effect/all-versions/default/EnvironmentalReverbEffect.h>
+#undef AUDIO_HAL_VERSION
+
+#endif  // ANDROID_HARDWARE_AUDIO_EFFECT_V4_0_ENVIRONMENTALREVERBEFFECT_H
diff --git a/audio/effect/4.0/default/EqualizerEffect.cpp b/audio/effect/4.0/default/EqualizerEffect.cpp
new file mode 100644
index 0000000..d0a40bc
--- /dev/null
+++ b/audio/effect/4.0/default/EqualizerEffect.cpp
@@ -0,0 +1,23 @@
+/*
+ * 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 "Equalizer_HAL"
+
+#include "EqualizerEffect.h"
+
+#define AUDIO_HAL_VERSION V4_0
+#include <effect/all-versions/default/EqualizerEffect.impl.h>
+#undef AUDIO_HAL_VERSION
diff --git a/audio/effect/4.0/default/EqualizerEffect.h b/audio/effect/4.0/default/EqualizerEffect.h
new file mode 100644
index 0000000..7c9463b
--- /dev/null
+++ b/audio/effect/4.0/default/EqualizerEffect.h
@@ -0,0 +1,28 @@
+/*
+ * 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_AUDIO_EFFECT_V4_0_EQUALIZEREFFECT_H
+#define ANDROID_HARDWARE_AUDIO_EFFECT_V4_0_EQUALIZEREFFECT_H
+
+#include <android/hardware/audio/effect/4.0/IEqualizerEffect.h>
+
+#include "Effect.h"
+
+#define AUDIO_HAL_VERSION V4_0
+#include <effect/all-versions/default/EqualizerEffect.h>
+#undef AUDIO_HAL_VERSION
+
+#endif  // ANDROID_HARDWARE_AUDIO_EFFECT_V4_0_EQUALIZEREFFECT_H
diff --git a/audio/effect/4.0/default/LoudnessEnhancerEffect.cpp b/audio/effect/4.0/default/LoudnessEnhancerEffect.cpp
new file mode 100644
index 0000000..e3c5184
--- /dev/null
+++ b/audio/effect/4.0/default/LoudnessEnhancerEffect.cpp
@@ -0,0 +1,23 @@
+/*
+ * 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 "LoudnessEnhancer_HAL"
+
+#include "LoudnessEnhancerEffect.h"
+
+#define AUDIO_HAL_VERSION V4_0
+#include <effect/all-versions/default/LoudnessEnhancerEffect.impl.h>
+#undef AUDIO_HAL_VERSION
diff --git a/audio/effect/4.0/default/LoudnessEnhancerEffect.h b/audio/effect/4.0/default/LoudnessEnhancerEffect.h
new file mode 100644
index 0000000..64fa26a
--- /dev/null
+++ b/audio/effect/4.0/default/LoudnessEnhancerEffect.h
@@ -0,0 +1,28 @@
+/*
+ * 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_AUDIO_EFFECT_V4_0_LOUDNESSENHANCEREFFECT_H
+#define ANDROID_HARDWARE_AUDIO_EFFECT_V4_0_LOUDNESSENHANCEREFFECT_H
+
+#include <android/hardware/audio/effect/4.0/ILoudnessEnhancerEffect.h>
+
+#include "Effect.h"
+
+#define AUDIO_HAL_VERSION V4_0
+#include <effect/all-versions/default/LoudnessEnhancerEffect.h>
+#undef AUDIO_HAL_VERSION
+
+#endif  // ANDROID_HARDWARE_AUDIO_EFFECT_V4_0_LOUDNESSENHANCEREFFECT_H
diff --git a/audio/effect/4.0/default/NoiseSuppressionEffect.cpp b/audio/effect/4.0/default/NoiseSuppressionEffect.cpp
new file mode 100644
index 0000000..e83a8e3
--- /dev/null
+++ b/audio/effect/4.0/default/NoiseSuppressionEffect.cpp
@@ -0,0 +1,23 @@
+/*
+ * 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 "NS_Effect_HAL"
+
+#include "NoiseSuppressionEffect.h"
+
+#define AUDIO_HAL_VERSION V4_0
+#include <effect/all-versions/default/NoiseSuppressionEffect.impl.h>
+#undef AUDIO_HAL_VERSION
diff --git a/audio/effect/4.0/default/NoiseSuppressionEffect.h b/audio/effect/4.0/default/NoiseSuppressionEffect.h
new file mode 100644
index 0000000..36d45af
--- /dev/null
+++ b/audio/effect/4.0/default/NoiseSuppressionEffect.h
@@ -0,0 +1,28 @@
+/*
+ * 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_AUDIO_EFFECT_V4_0_NOISESUPPRESSIONEFFECT_H
+#define ANDROID_HARDWARE_AUDIO_EFFECT_V4_0_NOISESUPPRESSIONEFFECT_H
+
+#include <android/hardware/audio/effect/4.0/INoiseSuppressionEffect.h>
+
+#include "Effect.h"
+
+#define AUDIO_HAL_VERSION V4_0
+#include <effect/all-versions/default/NoiseSuppressionEffect.h>
+#undef AUDIO_HAL_VERSION
+
+#endif  // ANDROID_HARDWARE_AUDIO_EFFECT_V4_0_NOISESUPPRESSIONEFFECT_H
diff --git a/audio/effect/4.0/default/OWNERS b/audio/effect/4.0/default/OWNERS
new file mode 100644
index 0000000..6fdc97c
--- /dev/null
+++ b/audio/effect/4.0/default/OWNERS
@@ -0,0 +1,3 @@
+elaurent@google.com
+krocard@google.com
+mnaganov@google.com
diff --git a/audio/effect/4.0/default/PresetReverbEffect.cpp b/audio/effect/4.0/default/PresetReverbEffect.cpp
new file mode 100644
index 0000000..0c23be7
--- /dev/null
+++ b/audio/effect/4.0/default/PresetReverbEffect.cpp
@@ -0,0 +1,23 @@
+/*
+ * 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 "PresetReverb_HAL"
+
+#include "PresetReverbEffect.h"
+
+#define AUDIO_HAL_VERSION V4_0
+#include <effect/all-versions/default/PresetReverbEffect.impl.h>
+#undef AUDIO_HAL_VERSION
diff --git a/audio/effect/4.0/default/PresetReverbEffect.h b/audio/effect/4.0/default/PresetReverbEffect.h
new file mode 100644
index 0000000..3eeae0a
--- /dev/null
+++ b/audio/effect/4.0/default/PresetReverbEffect.h
@@ -0,0 +1,28 @@
+/*
+ * 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_AUDIO_EFFECT_V4_0_PRESETREVERBEFFECT_H
+#define ANDROID_HARDWARE_AUDIO_EFFECT_V4_0_PRESETREVERBEFFECT_H
+
+#include <android/hardware/audio/effect/4.0/IPresetReverbEffect.h>
+
+#include "Effect.h"
+
+#define AUDIO_HAL_VERSION V4_0
+#include <effect/all-versions/default/PresetReverbEffect.h>
+#undef AUDIO_HAL_VERSION
+
+#endif  // ANDROID_HARDWARE_AUDIO_EFFECT_V4_0_PRESETREVERBEFFECT_H
diff --git a/audio/effect/4.0/default/VirtualizerEffect.cpp b/audio/effect/4.0/default/VirtualizerEffect.cpp
new file mode 100644
index 0000000..f50e8ad
--- /dev/null
+++ b/audio/effect/4.0/default/VirtualizerEffect.cpp
@@ -0,0 +1,23 @@
+/*
+ * 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 "Virtualizer_HAL"
+
+#include "VirtualizerEffect.h"
+
+#define AUDIO_HAL_VERSION V4_0
+#include <effect/all-versions/default/VirtualizerEffect.impl.h>
+#undef AUDIO_HAL_VERSION
diff --git a/audio/effect/4.0/default/VirtualizerEffect.h b/audio/effect/4.0/default/VirtualizerEffect.h
new file mode 100644
index 0000000..8e7114e
--- /dev/null
+++ b/audio/effect/4.0/default/VirtualizerEffect.h
@@ -0,0 +1,28 @@
+/*
+ * 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_AUDIO_EFFECT_V4_0_VIRTUALIZEREFFECT_H
+#define ANDROID_HARDWARE_AUDIO_EFFECT_V4_0_VIRTUALIZEREFFECT_H
+
+#include <android/hardware/audio/effect/4.0/IVirtualizerEffect.h>
+
+#include "Effect.h"
+
+#define AUDIO_HAL_VERSION V4_0
+#include <effect/all-versions/default/VirtualizerEffect.h>
+#undef AUDIO_HAL_VERSION
+
+#endif  // ANDROID_HARDWARE_AUDIO_EFFECT_V4_0_VIRTUALIZEREFFECT_H
diff --git a/audio/effect/4.0/default/VisualizerEffect.cpp b/audio/effect/4.0/default/VisualizerEffect.cpp
new file mode 100644
index 0000000..8d4f100
--- /dev/null
+++ b/audio/effect/4.0/default/VisualizerEffect.cpp
@@ -0,0 +1,23 @@
+/*
+ * 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 "Visualizer_HAL"
+
+#include "VisualizerEffect.h"
+
+#define AUDIO_HAL_VERSION V4_0
+#include <effect/all-versions/default/VisualizerEffect.impl.h>
+#undef AUDIO_HAL_VERSION
diff --git a/audio/effect/4.0/default/VisualizerEffect.h b/audio/effect/4.0/default/VisualizerEffect.h
new file mode 100644
index 0000000..6b5ab9c
--- /dev/null
+++ b/audio/effect/4.0/default/VisualizerEffect.h
@@ -0,0 +1,28 @@
+/*
+ * 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_AUDIO_EFFECT_V4_0_VISUALIZEREFFECT_H
+#define ANDROID_HARDWARE_AUDIO_EFFECT_V4_0_VISUALIZEREFFECT_H
+
+#include <android/hardware/audio/effect/4.0/IVisualizerEffect.h>
+
+#include "Effect.h"
+
+#define AUDIO_HAL_VERSION V4_0
+#include <effect/all-versions/default/VisualizerEffect.h>
+#undef AUDIO_HAL_VERSION
+
+#endif  // ANDROID_HARDWARE_AUDIO_EFFECT_V4_0_VISUALIZEREFFECT_H
diff --git a/audio/effect/all-versions/default/include/effect/all-versions/default/AcousticEchoCancelerEffect.h b/audio/effect/all-versions/default/include/effect/all-versions/default/AcousticEchoCancelerEffect.h
index b63f2fb..852cb3f 100644
--- a/audio/effect/all-versions/default/include/effect/all-versions/default/AcousticEchoCancelerEffect.h
+++ b/audio/effect/all-versions/default/include/effect/all-versions/default/AcousticEchoCancelerEffect.h
@@ -20,6 +20,8 @@
 
 #include <hidl/MQDescriptor.h>
 
+#include "VersionUtils.h"
+
 namespace android {
 namespace hardware {
 namespace audio {
@@ -46,7 +48,7 @@
     Return<Result> reset() override;
     Return<Result> enable() override;
     Return<Result> disable() override;
-    Return<Result> setDevice(AudioDevice device) override;
+    Return<Result> setDevice(AudioDeviceBitfield device) override;
     Return<void> setAndGetVolume(const hidl_vec<uint32_t>& volumes,
                                  setAndGetVolume_cb _hidl_cb) override;
     Return<Result> volumeChangeNotification(const hidl_vec<uint32_t>& volumes) override;
@@ -54,7 +56,7 @@
     Return<Result> setConfigReverse(
         const EffectConfig& config, const sp<IEffectBufferProviderCallback>& inputBufferProvider,
         const sp<IEffectBufferProviderCallback>& outputBufferProvider) override;
-    Return<Result> setInputDevice(AudioDevice device) override;
+    Return<Result> setInputDevice(AudioDeviceBitfield device) override;
     Return<void> getConfig(getConfig_cb _hidl_cb) override;
     Return<void> getConfigReverse(getConfigReverse_cb _hidl_cb) override;
     Return<void> getSupportedAuxChannelsConfigs(
diff --git a/audio/effect/all-versions/default/include/effect/all-versions/default/AcousticEchoCancelerEffect.impl.h b/audio/effect/all-versions/default/include/effect/all-versions/default/AcousticEchoCancelerEffect.impl.h
index bee3607..8ad80a2 100644
--- a/audio/effect/all-versions/default/include/effect/all-versions/default/AcousticEchoCancelerEffect.impl.h
+++ b/audio/effect/all-versions/default/include/effect/all-versions/default/AcousticEchoCancelerEffect.impl.h
@@ -19,6 +19,8 @@
 #include <android/log.h>
 #include <system/audio_effects/effect_aec.h>
 
+#include "VersionUtils.h"
+
 namespace android {
 namespace hardware {
 namespace audio {
@@ -54,7 +56,7 @@
     return mEffect->disable();
 }
 
-Return<Result> AcousticEchoCancelerEffect::setDevice(AudioDevice device) {
+Return<Result> AcousticEchoCancelerEffect::setDevice(AudioDeviceBitfield device) {
     return mEffect->setDevice(device);
 }
 
@@ -78,7 +80,7 @@
     return mEffect->setConfigReverse(config, inputBufferProvider, outputBufferProvider);
 }
 
-Return<Result> AcousticEchoCancelerEffect::setInputDevice(AudioDevice device) {
+Return<Result> AcousticEchoCancelerEffect::setInputDevice(AudioDeviceBitfield device) {
     return mEffect->setInputDevice(device);
 }
 
diff --git a/audio/effect/all-versions/default/include/effect/all-versions/default/AutomaticGainControlEffect.h b/audio/effect/all-versions/default/include/effect/all-versions/default/AutomaticGainControlEffect.h
index 941f45d..5ac43eb 100644
--- a/audio/effect/all-versions/default/include/effect/all-versions/default/AutomaticGainControlEffect.h
+++ b/audio/effect/all-versions/default/include/effect/all-versions/default/AutomaticGainControlEffect.h
@@ -22,6 +22,8 @@
 
 #include <hidl/MQDescriptor.h>
 
+#include "VersionUtils.h"
+
 namespace android {
 namespace hardware {
 namespace audio {
@@ -48,7 +50,7 @@
     Return<Result> reset() override;
     Return<Result> enable() override;
     Return<Result> disable() override;
-    Return<Result> setDevice(AudioDevice device) override;
+    Return<Result> setDevice(AudioDeviceBitfield device) override;
     Return<void> setAndGetVolume(const hidl_vec<uint32_t>& volumes,
                                  setAndGetVolume_cb _hidl_cb) override;
     Return<Result> volumeChangeNotification(const hidl_vec<uint32_t>& volumes) override;
@@ -56,7 +58,7 @@
     Return<Result> setConfigReverse(
         const EffectConfig& config, const sp<IEffectBufferProviderCallback>& inputBufferProvider,
         const sp<IEffectBufferProviderCallback>& outputBufferProvider) override;
-    Return<Result> setInputDevice(AudioDevice device) override;
+    Return<Result> setInputDevice(AudioDeviceBitfield device) override;
     Return<void> getConfig(getConfig_cb _hidl_cb) override;
     Return<void> getConfigReverse(getConfigReverse_cb _hidl_cb) override;
     Return<void> getSupportedAuxChannelsConfigs(
diff --git a/audio/effect/all-versions/default/include/effect/all-versions/default/AutomaticGainControlEffect.impl.h b/audio/effect/all-versions/default/include/effect/all-versions/default/AutomaticGainControlEffect.impl.h
index af05d9b..e2e751e 100644
--- a/audio/effect/all-versions/default/include/effect/all-versions/default/AutomaticGainControlEffect.impl.h
+++ b/audio/effect/all-versions/default/include/effect/all-versions/default/AutomaticGainControlEffect.impl.h
@@ -18,6 +18,8 @@
 
 #include <android/log.h>
 
+#include "VersionUtils.h"
+
 namespace android {
 namespace hardware {
 namespace audio {
@@ -67,7 +69,7 @@
     return mEffect->disable();
 }
 
-Return<Result> AutomaticGainControlEffect::setDevice(AudioDevice device) {
+Return<Result> AutomaticGainControlEffect::setDevice(AudioDeviceBitfield device) {
     return mEffect->setDevice(device);
 }
 
@@ -91,7 +93,7 @@
     return mEffect->setConfigReverse(config, inputBufferProvider, outputBufferProvider);
 }
 
-Return<Result> AutomaticGainControlEffect::setInputDevice(AudioDevice device) {
+Return<Result> AutomaticGainControlEffect::setInputDevice(AudioDeviceBitfield device) {
     return mEffect->setInputDevice(device);
 }
 
diff --git a/audio/effect/all-versions/default/include/effect/all-versions/default/BassBoostEffect.h b/audio/effect/all-versions/default/include/effect/all-versions/default/BassBoostEffect.h
index 0092621..29173dd 100644
--- a/audio/effect/all-versions/default/include/effect/all-versions/default/BassBoostEffect.h
+++ b/audio/effect/all-versions/default/include/effect/all-versions/default/BassBoostEffect.h
@@ -20,6 +20,8 @@
 
 #include <hidl/MQDescriptor.h>
 
+#include "VersionUtils.h"
+
 namespace android {
 namespace hardware {
 namespace audio {
@@ -46,7 +48,7 @@
     Return<Result> reset() override;
     Return<Result> enable() override;
     Return<Result> disable() override;
-    Return<Result> setDevice(AudioDevice device) override;
+    Return<Result> setDevice(AudioDeviceBitfield device) override;
     Return<void> setAndGetVolume(const hidl_vec<uint32_t>& volumes,
                                  setAndGetVolume_cb _hidl_cb) override;
     Return<Result> volumeChangeNotification(const hidl_vec<uint32_t>& volumes) override;
@@ -54,7 +56,7 @@
     Return<Result> setConfigReverse(
         const EffectConfig& config, const sp<IEffectBufferProviderCallback>& inputBufferProvider,
         const sp<IEffectBufferProviderCallback>& outputBufferProvider) override;
-    Return<Result> setInputDevice(AudioDevice device) override;
+    Return<Result> setInputDevice(AudioDeviceBitfield device) override;
     Return<void> getConfig(getConfig_cb _hidl_cb) override;
     Return<void> getConfigReverse(getConfigReverse_cb _hidl_cb) override;
     Return<void> getSupportedAuxChannelsConfigs(
diff --git a/audio/effect/all-versions/default/include/effect/all-versions/default/BassBoostEffect.impl.h b/audio/effect/all-versions/default/include/effect/all-versions/default/BassBoostEffect.impl.h
index 1fc8d1b..7bcb4a3 100644
--- a/audio/effect/all-versions/default/include/effect/all-versions/default/BassBoostEffect.impl.h
+++ b/audio/effect/all-versions/default/include/effect/all-versions/default/BassBoostEffect.impl.h
@@ -19,6 +19,8 @@
 #include <android/log.h>
 #include <system/audio_effects/effect_bassboost.h>
 
+#include "VersionUtils.h"
+
 namespace android {
 namespace hardware {
 namespace audio {
@@ -53,7 +55,7 @@
     return mEffect->disable();
 }
 
-Return<Result> BassBoostEffect::setDevice(AudioDevice device) {
+Return<Result> BassBoostEffect::setDevice(AudioDeviceBitfield device) {
     return mEffect->setDevice(device);
 }
 
@@ -76,7 +78,7 @@
     return mEffect->setConfigReverse(config, inputBufferProvider, outputBufferProvider);
 }
 
-Return<Result> BassBoostEffect::setInputDevice(AudioDevice device) {
+Return<Result> BassBoostEffect::setInputDevice(AudioDeviceBitfield device) {
     return mEffect->setInputDevice(device);
 }
 
diff --git a/audio/effect/all-versions/default/include/effect/all-versions/default/DownmixEffect.h b/audio/effect/all-versions/default/include/effect/all-versions/default/DownmixEffect.h
index e461ca8..3e3aa78 100644
--- a/audio/effect/all-versions/default/include/effect/all-versions/default/DownmixEffect.h
+++ b/audio/effect/all-versions/default/include/effect/all-versions/default/DownmixEffect.h
@@ -20,6 +20,8 @@
 
 #include <hidl/MQDescriptor.h>
 
+#include "VersionUtils.h"
+
 namespace android {
 namespace hardware {
 namespace audio {
@@ -46,7 +48,7 @@
     Return<Result> reset() override;
     Return<Result> enable() override;
     Return<Result> disable() override;
-    Return<Result> setDevice(AudioDevice device) override;
+    Return<Result> setDevice(AudioDeviceBitfield device) override;
     Return<void> setAndGetVolume(const hidl_vec<uint32_t>& volumes,
                                  setAndGetVolume_cb _hidl_cb) override;
     Return<Result> volumeChangeNotification(const hidl_vec<uint32_t>& volumes) override;
@@ -54,7 +56,7 @@
     Return<Result> setConfigReverse(
         const EffectConfig& config, const sp<IEffectBufferProviderCallback>& inputBufferProvider,
         const sp<IEffectBufferProviderCallback>& outputBufferProvider) override;
-    Return<Result> setInputDevice(AudioDevice device) override;
+    Return<Result> setInputDevice(AudioDeviceBitfield device) override;
     Return<void> getConfig(getConfig_cb _hidl_cb) override;
     Return<void> getConfigReverse(getConfigReverse_cb _hidl_cb) override;
     Return<void> getSupportedAuxChannelsConfigs(
diff --git a/audio/effect/all-versions/default/include/effect/all-versions/default/DownmixEffect.impl.h b/audio/effect/all-versions/default/include/effect/all-versions/default/DownmixEffect.impl.h
index 98710f8..abef10e 100644
--- a/audio/effect/all-versions/default/include/effect/all-versions/default/DownmixEffect.impl.h
+++ b/audio/effect/all-versions/default/include/effect/all-versions/default/DownmixEffect.impl.h
@@ -19,6 +19,8 @@
 #include <android/log.h>
 #include <system/audio_effects/effect_downmix.h>
 
+#include "VersionUtils.h"
+
 namespace android {
 namespace hardware {
 namespace audio {
@@ -53,7 +55,7 @@
     return mEffect->disable();
 }
 
-Return<Result> DownmixEffect::setDevice(AudioDevice device) {
+Return<Result> DownmixEffect::setDevice(AudioDeviceBitfield device) {
     return mEffect->setDevice(device);
 }
 
@@ -76,7 +78,7 @@
     return mEffect->setConfigReverse(config, inputBufferProvider, outputBufferProvider);
 }
 
-Return<Result> DownmixEffect::setInputDevice(AudioDevice device) {
+Return<Result> DownmixEffect::setInputDevice(AudioDeviceBitfield device) {
     return mEffect->setInputDevice(device);
 }
 
diff --git a/audio/effect/all-versions/default/include/effect/all-versions/default/Effect.h b/audio/effect/all-versions/default/include/effect/all-versions/default/Effect.h
index 81b0b24..b546e0e 100644
--- a/audio/effect/all-versions/default/include/effect/all-versions/default/Effect.h
+++ b/audio/effect/all-versions/default/include/effect/all-versions/default/Effect.h
@@ -28,6 +28,8 @@
 
 #include <hardware/audio_effect.h>
 
+#include "VersionUtils.h"
+
 namespace android {
 namespace hardware {
 namespace audio {
@@ -39,6 +41,7 @@
 using ::android::hardware::audio::common::AUDIO_HAL_VERSION::AudioMode;
 using ::android::hardware::audio::common::AUDIO_HAL_VERSION::AudioSource;
 using ::android::hardware::audio::common::AUDIO_HAL_VERSION::Uuid;
+using ::android::hardware::audio::common::AUDIO_HAL_VERSION::implementation::AudioDeviceBitfield;
 using ::android::hardware::audio::effect::AUDIO_HAL_VERSION::AudioBuffer;
 using ::android::hardware::audio::effect::AUDIO_HAL_VERSION::EffectAuxChannelsConfig;
 using ::android::hardware::audio::effect::AUDIO_HAL_VERSION::EffectConfig;
@@ -69,7 +72,7 @@
     Return<Result> reset() override;
     Return<Result> enable() override;
     Return<Result> disable() override;
-    Return<Result> setDevice(AudioDevice device) override;
+    Return<Result> setDevice(AudioDeviceBitfield device) override;
     Return<void> setAndGetVolume(const hidl_vec<uint32_t>& volumes,
                                  setAndGetVolume_cb _hidl_cb) override;
     Return<Result> volumeChangeNotification(const hidl_vec<uint32_t>& volumes) override;
@@ -77,7 +80,7 @@
     Return<Result> setConfigReverse(
         const EffectConfig& config, const sp<IEffectBufferProviderCallback>& inputBufferProvider,
         const sp<IEffectBufferProviderCallback>& outputBufferProvider) override;
-    Return<Result> setInputDevice(AudioDevice device) override;
+    Return<Result> setInputDevice(AudioDeviceBitfield device) override;
     Return<void> getConfig(getConfig_cb _hidl_cb) override;
     Return<void> getConfigReverse(getConfigReverse_cb _hidl_cb) override;
     Return<void> getSupportedAuxChannelsConfigs(
diff --git a/audio/effect/all-versions/default/include/effect/all-versions/default/Effect.impl.h b/audio/effect/all-versions/default/include/effect/all-versions/default/Effect.impl.h
index d376146..61c9805 100644
--- a/audio/effect/all-versions/default/include/effect/all-versions/default/Effect.impl.h
+++ b/audio/effect/all-versions/default/include/effect/all-versions/default/Effect.impl.h
@@ -24,6 +24,8 @@
 #include <media/EffectsFactoryApi.h>
 #include <utils/Trace.h>
 
+#include "VersionUtils.h"
+
 namespace android {
 namespace hardware {
 namespace audio {
@@ -33,6 +35,7 @@
 
 using ::android::hardware::audio::common::AUDIO_HAL_VERSION::AudioChannelMask;
 using ::android::hardware::audio::common::AUDIO_HAL_VERSION::AudioFormat;
+using ::android::hardware::audio::common::AUDIO_HAL_VERSION::implementation::AudioChannelBitfield;
 using ::android::hardware::audio::effect::AUDIO_HAL_VERSION::MessageQueueFlagBits;
 
 namespace {
@@ -174,8 +177,8 @@
 // static
 void Effect::effectAuxChannelsConfigFromHal(const channel_config_t& halConfig,
                                             EffectAuxChannelsConfig* config) {
-    config->mainChannels = AudioChannelMask(halConfig.main_channels);
-    config->auxChannels = AudioChannelMask(halConfig.aux_channels);
+    config->mainChannels = AudioChannelBitfield(halConfig.main_channels);
+    config->auxChannels = AudioChannelBitfield(halConfig.aux_channels);
 }
 
 // static
@@ -191,10 +194,10 @@
     config->buffer.id = 0;
     config->buffer.frameCount = 0;
     config->samplingRateHz = halConfig.samplingRate;
-    config->channels = AudioChannelMask(halConfig.channels);
+    config->channels = AudioChannelBitfield(halConfig.channels);
     config->format = AudioFormat(halConfig.format);
     config->accessMode = EffectBufferAccess(halConfig.accessMode);
-    config->mask = EffectConfigParameters(halConfig.mask);
+    config->mask = static_cast<decltype(config->mask)>(halConfig.mask);
 }
 
 // static
@@ -500,7 +503,7 @@
     return sendCommandReturningStatus(EFFECT_CMD_DISABLE, "DISABLE");
 }
 
-Return<Result> Effect::setDevice(AudioDevice device) {
+Return<Result> Effect::setDevice(AudioDeviceBitfield device) {
     uint32_t halDevice = static_cast<uint32_t>(device);
     return sendCommand(EFFECT_CMD_SET_DEVICE, "SET_DEVICE", sizeof(uint32_t), &halDevice);
 }
@@ -539,7 +542,7 @@
                          inputBufferProvider, outputBufferProvider);
 }
 
-Return<Result> Effect::setInputDevice(AudioDevice device) {
+Return<Result> Effect::setInputDevice(AudioDeviceBitfield device) {
     uint32_t halDevice = static_cast<uint32_t>(device);
     return sendCommand(EFFECT_CMD_SET_INPUT_DEVICE, "SET_INPUT_DEVICE", sizeof(uint32_t),
                        &halDevice);
diff --git a/audio/effect/all-versions/default/include/effect/all-versions/default/EffectsFactory.h b/audio/effect/all-versions/default/include/effect/all-versions/default/EffectsFactory.h
index e586abb..313c8c2 100644
--- a/audio/effect/all-versions/default/include/effect/all-versions/default/EffectsFactory.h
+++ b/audio/effect/all-versions/default/include/effect/all-versions/default/EffectsFactory.h
@@ -46,7 +46,7 @@
     Return<void> getDescriptor(const Uuid& uid, getDescriptor_cb _hidl_cb) override;
     Return<void> createEffect(const Uuid& uid, int32_t session, int32_t ioHandle,
                               createEffect_cb _hidl_cb) override;
-    Return<void> debugDump(const hidl_handle& fd) override;
+    Return<void> debugDump(const hidl_handle& fd);
 
    private:
     static sp<IEffect> dispatchEffectInstanceCreation(const effect_descriptor_t& halDescriptor,
diff --git a/audio/effect/all-versions/default/include/effect/all-versions/default/EffectsFactory.impl.h b/audio/effect/all-versions/default/include/effect/all-versions/default/EffectsFactory.impl.h
index b2a36a9..066a6a6 100644
--- a/audio/effect/all-versions/default/include/effect/all-versions/default/EffectsFactory.impl.h
+++ b/audio/effect/all-versions/default/include/effect/all-versions/default/EffectsFactory.impl.h
@@ -178,8 +178,8 @@
     return Void();
 }
 
-IEffectsFactory* HIDL_FETCH_IEffectsFactory(const char* /* name */) {
-    return new EffectsFactory();
+IEffectsFactory* HIDL_FETCH_IEffectsFactory(const char* name) {
+    return strcmp(name, "default") == 0 ? new EffectsFactory() : nullptr;
 }
 
 }  // namespace implementation
diff --git a/audio/effect/all-versions/default/include/effect/all-versions/default/EnvironmentalReverbEffect.h b/audio/effect/all-versions/default/include/effect/all-versions/default/EnvironmentalReverbEffect.h
index 8351e55..d2f8cc3 100644
--- a/audio/effect/all-versions/default/include/effect/all-versions/default/EnvironmentalReverbEffect.h
+++ b/audio/effect/all-versions/default/include/effect/all-versions/default/EnvironmentalReverbEffect.h
@@ -22,6 +22,8 @@
 
 #include <hidl/MQDescriptor.h>
 
+#include "VersionUtils.h"
+
 namespace android {
 namespace hardware {
 namespace audio {
@@ -58,7 +60,7 @@
     Return<Result> reset() override;
     Return<Result> enable() override;
     Return<Result> disable() override;
-    Return<Result> setDevice(AudioDevice device) override;
+    Return<Result> setDevice(AudioDeviceBitfield device) override;
     Return<void> setAndGetVolume(const hidl_vec<uint32_t>& volumes,
                                  setAndGetVolume_cb _hidl_cb) override;
     Return<Result> volumeChangeNotification(const hidl_vec<uint32_t>& volumes) override;
@@ -66,7 +68,7 @@
     Return<Result> setConfigReverse(
         const EffectConfig& config, const sp<IEffectBufferProviderCallback>& inputBufferProvider,
         const sp<IEffectBufferProviderCallback>& outputBufferProvider) override;
-    Return<Result> setInputDevice(AudioDevice device) override;
+    Return<Result> setInputDevice(AudioDeviceBitfield device) override;
     Return<void> getConfig(getConfig_cb _hidl_cb) override;
     Return<void> getConfigReverse(getConfigReverse_cb _hidl_cb) override;
     Return<void> getSupportedAuxChannelsConfigs(
diff --git a/audio/effect/all-versions/default/include/effect/all-versions/default/EnvironmentalReverbEffect.impl.h b/audio/effect/all-versions/default/include/effect/all-versions/default/EnvironmentalReverbEffect.impl.h
index 9090b8a..39a4092 100644
--- a/audio/effect/all-versions/default/include/effect/all-versions/default/EnvironmentalReverbEffect.impl.h
+++ b/audio/effect/all-versions/default/include/effect/all-versions/default/EnvironmentalReverbEffect.impl.h
@@ -18,6 +18,8 @@
 
 #include <android/log.h>
 
+#include "VersionUtils.h"
+
 namespace android {
 namespace hardware {
 namespace audio {
@@ -81,7 +83,7 @@
     return mEffect->disable();
 }
 
-Return<Result> EnvironmentalReverbEffect::setDevice(AudioDevice device) {
+Return<Result> EnvironmentalReverbEffect::setDevice(AudioDeviceBitfield device) {
     return mEffect->setDevice(device);
 }
 
@@ -105,7 +107,7 @@
     return mEffect->setConfigReverse(config, inputBufferProvider, outputBufferProvider);
 }
 
-Return<Result> EnvironmentalReverbEffect::setInputDevice(AudioDevice device) {
+Return<Result> EnvironmentalReverbEffect::setInputDevice(AudioDeviceBitfield device) {
     return mEffect->setInputDevice(device);
 }
 
diff --git a/audio/effect/all-versions/default/include/effect/all-versions/default/EqualizerEffect.h b/audio/effect/all-versions/default/include/effect/all-versions/default/EqualizerEffect.h
index c2b8ef8..de52052 100644
--- a/audio/effect/all-versions/default/include/effect/all-versions/default/EqualizerEffect.h
+++ b/audio/effect/all-versions/default/include/effect/all-versions/default/EqualizerEffect.h
@@ -24,6 +24,8 @@
 
 #include <hidl/MQDescriptor.h>
 
+#include "VersionUtils.h"
+
 namespace android {
 namespace hardware {
 namespace audio {
@@ -60,7 +62,7 @@
     Return<Result> reset() override;
     Return<Result> enable() override;
     Return<Result> disable() override;
-    Return<Result> setDevice(AudioDevice device) override;
+    Return<Result> setDevice(AudioDeviceBitfield device) override;
     Return<void> setAndGetVolume(const hidl_vec<uint32_t>& volumes,
                                  setAndGetVolume_cb _hidl_cb) override;
     Return<Result> volumeChangeNotification(const hidl_vec<uint32_t>& volumes) override;
@@ -68,7 +70,7 @@
     Return<Result> setConfigReverse(
         const EffectConfig& config, const sp<IEffectBufferProviderCallback>& inputBufferProvider,
         const sp<IEffectBufferProviderCallback>& outputBufferProvider) override;
-    Return<Result> setInputDevice(AudioDevice device) override;
+    Return<Result> setInputDevice(AudioDeviceBitfield device) override;
     Return<void> getConfig(getConfig_cb _hidl_cb) override;
     Return<void> getConfigReverse(getConfigReverse_cb _hidl_cb) override;
     Return<void> getSupportedAuxChannelsConfigs(
diff --git a/audio/effect/all-versions/default/include/effect/all-versions/default/EqualizerEffect.impl.h b/audio/effect/all-versions/default/include/effect/all-versions/default/EqualizerEffect.impl.h
index 78485e4..db6bed8 100644
--- a/audio/effect/all-versions/default/include/effect/all-versions/default/EqualizerEffect.impl.h
+++ b/audio/effect/all-versions/default/include/effect/all-versions/default/EqualizerEffect.impl.h
@@ -20,6 +20,8 @@
 
 #include <android/log.h>
 
+#include "VersionUtils.h"
+
 namespace android {
 namespace hardware {
 namespace audio {
@@ -76,7 +78,7 @@
     return mEffect->disable();
 }
 
-Return<Result> EqualizerEffect::setDevice(AudioDevice device) {
+Return<Result> EqualizerEffect::setDevice(AudioDeviceBitfield device) {
     return mEffect->setDevice(device);
 }
 
@@ -99,7 +101,7 @@
     return mEffect->setConfigReverse(config, inputBufferProvider, outputBufferProvider);
 }
 
-Return<Result> EqualizerEffect::setInputDevice(AudioDevice device) {
+Return<Result> EqualizerEffect::setInputDevice(AudioDeviceBitfield device) {
     return mEffect->setInputDevice(device);
 }
 
diff --git a/audio/effect/all-versions/default/include/effect/all-versions/default/LoudnessEnhancerEffect.h b/audio/effect/all-versions/default/include/effect/all-versions/default/LoudnessEnhancerEffect.h
index e4f1bd5..b59b077 100644
--- a/audio/effect/all-versions/default/include/effect/all-versions/default/LoudnessEnhancerEffect.h
+++ b/audio/effect/all-versions/default/include/effect/all-versions/default/LoudnessEnhancerEffect.h
@@ -20,6 +20,8 @@
 
 #include <hidl/MQDescriptor.h>
 
+#include "VersionUtils.h"
+
 namespace android {
 namespace hardware {
 namespace audio {
@@ -56,7 +58,7 @@
     Return<Result> reset() override;
     Return<Result> enable() override;
     Return<Result> disable() override;
-    Return<Result> setDevice(AudioDevice device) override;
+    Return<Result> setDevice(AudioDeviceBitfield device) override;
     Return<void> setAndGetVolume(const hidl_vec<uint32_t>& volumes,
                                  setAndGetVolume_cb _hidl_cb) override;
     Return<Result> volumeChangeNotification(const hidl_vec<uint32_t>& volumes) override;
@@ -64,7 +66,7 @@
     Return<Result> setConfigReverse(
         const EffectConfig& config, const sp<IEffectBufferProviderCallback>& inputBufferProvider,
         const sp<IEffectBufferProviderCallback>& outputBufferProvider) override;
-    Return<Result> setInputDevice(AudioDevice device) override;
+    Return<Result> setInputDevice(AudioDeviceBitfield device) override;
     Return<void> getConfig(getConfig_cb _hidl_cb) override;
     Return<void> getConfigReverse(getConfigReverse_cb _hidl_cb) override;
     Return<void> getSupportedAuxChannelsConfigs(
diff --git a/audio/effect/all-versions/default/include/effect/all-versions/default/LoudnessEnhancerEffect.impl.h b/audio/effect/all-versions/default/include/effect/all-versions/default/LoudnessEnhancerEffect.impl.h
index 3f4f379..88210e9 100644
--- a/audio/effect/all-versions/default/include/effect/all-versions/default/LoudnessEnhancerEffect.impl.h
+++ b/audio/effect/all-versions/default/include/effect/all-versions/default/LoudnessEnhancerEffect.impl.h
@@ -21,6 +21,8 @@
 #include <android/log.h>
 #include <system/audio_effects/effect_aec.h>
 
+#include "VersionUtils.h"
+
 namespace android {
 namespace hardware {
 namespace audio {
@@ -56,7 +58,7 @@
     return mEffect->disable();
 }
 
-Return<Result> LoudnessEnhancerEffect::setDevice(AudioDevice device) {
+Return<Result> LoudnessEnhancerEffect::setDevice(AudioDeviceBitfield device) {
     return mEffect->setDevice(device);
 }
 
@@ -79,7 +81,7 @@
     return mEffect->setConfigReverse(config, inputBufferProvider, outputBufferProvider);
 }
 
-Return<Result> LoudnessEnhancerEffect::setInputDevice(AudioDevice device) {
+Return<Result> LoudnessEnhancerEffect::setInputDevice(AudioDeviceBitfield device) {
     return mEffect->setInputDevice(device);
 }
 
diff --git a/audio/effect/all-versions/default/include/effect/all-versions/default/NoiseSuppressionEffect.h b/audio/effect/all-versions/default/include/effect/all-versions/default/NoiseSuppressionEffect.h
index 7b64ba0..af1635b 100644
--- a/audio/effect/all-versions/default/include/effect/all-versions/default/NoiseSuppressionEffect.h
+++ b/audio/effect/all-versions/default/include/effect/all-versions/default/NoiseSuppressionEffect.h
@@ -22,6 +22,8 @@
 
 #include <hidl/MQDescriptor.h>
 
+#include "VersionUtils.h"
+
 namespace android {
 namespace hardware {
 namespace audio {
@@ -58,7 +60,7 @@
     Return<Result> reset() override;
     Return<Result> enable() override;
     Return<Result> disable() override;
-    Return<Result> setDevice(AudioDevice device) override;
+    Return<Result> setDevice(AudioDeviceBitfield device) override;
     Return<void> setAndGetVolume(const hidl_vec<uint32_t>& volumes,
                                  setAndGetVolume_cb _hidl_cb) override;
     Return<Result> volumeChangeNotification(const hidl_vec<uint32_t>& volumes) override;
@@ -66,7 +68,7 @@
     Return<Result> setConfigReverse(
         const EffectConfig& config, const sp<IEffectBufferProviderCallback>& inputBufferProvider,
         const sp<IEffectBufferProviderCallback>& outputBufferProvider) override;
-    Return<Result> setInputDevice(AudioDevice device) override;
+    Return<Result> setInputDevice(AudioDeviceBitfield device) override;
     Return<void> getConfig(getConfig_cb _hidl_cb) override;
     Return<void> getConfigReverse(getConfigReverse_cb _hidl_cb) override;
     Return<void> getSupportedAuxChannelsConfigs(
diff --git a/audio/effect/all-versions/default/include/effect/all-versions/default/NoiseSuppressionEffect.impl.h b/audio/effect/all-versions/default/include/effect/all-versions/default/NoiseSuppressionEffect.impl.h
index e5fc454..f32399c 100644
--- a/audio/effect/all-versions/default/include/effect/all-versions/default/NoiseSuppressionEffect.impl.h
+++ b/audio/effect/all-versions/default/include/effect/all-versions/default/NoiseSuppressionEffect.impl.h
@@ -18,6 +18,8 @@
 
 #include <android/log.h>
 
+#include "VersionUtils.h"
+
 namespace android {
 namespace hardware {
 namespace audio {
@@ -65,7 +67,7 @@
     return mEffect->disable();
 }
 
-Return<Result> NoiseSuppressionEffect::setDevice(AudioDevice device) {
+Return<Result> NoiseSuppressionEffect::setDevice(AudioDeviceBitfield device) {
     return mEffect->setDevice(device);
 }
 
@@ -88,7 +90,7 @@
     return mEffect->setConfigReverse(config, inputBufferProvider, outputBufferProvider);
 }
 
-Return<Result> NoiseSuppressionEffect::setInputDevice(AudioDevice device) {
+Return<Result> NoiseSuppressionEffect::setInputDevice(AudioDeviceBitfield device) {
     return mEffect->setInputDevice(device);
 }
 
diff --git a/audio/effect/all-versions/default/include/effect/all-versions/default/PresetReverbEffect.h b/audio/effect/all-versions/default/include/effect/all-versions/default/PresetReverbEffect.h
index 3114acd..1a91ab4 100644
--- a/audio/effect/all-versions/default/include/effect/all-versions/default/PresetReverbEffect.h
+++ b/audio/effect/all-versions/default/include/effect/all-versions/default/PresetReverbEffect.h
@@ -20,6 +20,8 @@
 
 #include <hidl/MQDescriptor.h>
 
+#include "VersionUtils.h"
+
 namespace android {
 namespace hardware {
 namespace audio {
@@ -56,7 +58,7 @@
     Return<Result> reset() override;
     Return<Result> enable() override;
     Return<Result> disable() override;
-    Return<Result> setDevice(AudioDevice device) override;
+    Return<Result> setDevice(AudioDeviceBitfield device) override;
     Return<void> setAndGetVolume(const hidl_vec<uint32_t>& volumes,
                                  setAndGetVolume_cb _hidl_cb) override;
     Return<Result> volumeChangeNotification(const hidl_vec<uint32_t>& volumes) override;
@@ -64,7 +66,7 @@
     Return<Result> setConfigReverse(
         const EffectConfig& config, const sp<IEffectBufferProviderCallback>& inputBufferProvider,
         const sp<IEffectBufferProviderCallback>& outputBufferProvider) override;
-    Return<Result> setInputDevice(AudioDevice device) override;
+    Return<Result> setInputDevice(AudioDeviceBitfield device) override;
     Return<void> getConfig(getConfig_cb _hidl_cb) override;
     Return<void> getConfigReverse(getConfigReverse_cb _hidl_cb) override;
     Return<void> getSupportedAuxChannelsConfigs(
diff --git a/audio/effect/all-versions/default/include/effect/all-versions/default/PresetReverbEffect.impl.h b/audio/effect/all-versions/default/include/effect/all-versions/default/PresetReverbEffect.impl.h
index 32198d5..eab68fb 100644
--- a/audio/effect/all-versions/default/include/effect/all-versions/default/PresetReverbEffect.impl.h
+++ b/audio/effect/all-versions/default/include/effect/all-versions/default/PresetReverbEffect.impl.h
@@ -19,6 +19,8 @@
 #include <android/log.h>
 #include <system/audio_effects/effect_presetreverb.h>
 
+#include "VersionUtils.h"
+
 namespace android {
 namespace hardware {
 namespace audio {
@@ -53,7 +55,7 @@
     return mEffect->disable();
 }
 
-Return<Result> PresetReverbEffect::setDevice(AudioDevice device) {
+Return<Result> PresetReverbEffect::setDevice(AudioDeviceBitfield device) {
     return mEffect->setDevice(device);
 }
 
@@ -76,7 +78,7 @@
     return mEffect->setConfigReverse(config, inputBufferProvider, outputBufferProvider);
 }
 
-Return<Result> PresetReverbEffect::setInputDevice(AudioDevice device) {
+Return<Result> PresetReverbEffect::setInputDevice(AudioDeviceBitfield device) {
     return mEffect->setInputDevice(device);
 }
 
diff --git a/audio/effect/all-versions/default/include/effect/all-versions/default/VirtualizerEffect.h b/audio/effect/all-versions/default/include/effect/all-versions/default/VirtualizerEffect.h
index 3715894..c0d5a00 100644
--- a/audio/effect/all-versions/default/include/effect/all-versions/default/VirtualizerEffect.h
+++ b/audio/effect/all-versions/default/include/effect/all-versions/default/VirtualizerEffect.h
@@ -20,6 +20,8 @@
 
 #include <hidl/MQDescriptor.h>
 
+#include "VersionUtils.h"
+
 namespace android {
 namespace hardware {
 namespace audio {
@@ -31,6 +33,7 @@
 using ::android::hardware::audio::common::AUDIO_HAL_VERSION::AudioDevice;
 using ::android::hardware::audio::common::AUDIO_HAL_VERSION::AudioMode;
 using ::android::hardware::audio::common::AUDIO_HAL_VERSION::AudioSource;
+using ::android::hardware::audio::common::AUDIO_HAL_VERSION::implementation::AudioChannelBitfield;
 using ::android::hardware::audio::effect::AUDIO_HAL_VERSION::AudioBuffer;
 using ::android::hardware::audio::effect::AUDIO_HAL_VERSION::EffectAuxChannelsConfig;
 using ::android::hardware::audio::effect::AUDIO_HAL_VERSION::EffectConfig;
@@ -57,7 +60,7 @@
     Return<Result> reset() override;
     Return<Result> enable() override;
     Return<Result> disable() override;
-    Return<Result> setDevice(AudioDevice device) override;
+    Return<Result> setDevice(AudioDeviceBitfield device) override;
     Return<void> setAndGetVolume(const hidl_vec<uint32_t>& volumes,
                                  setAndGetVolume_cb _hidl_cb) override;
     Return<Result> volumeChangeNotification(const hidl_vec<uint32_t>& volumes) override;
@@ -65,7 +68,7 @@
     Return<Result> setConfigReverse(
         const EffectConfig& config, const sp<IEffectBufferProviderCallback>& inputBufferProvider,
         const sp<IEffectBufferProviderCallback>& outputBufferProvider) override;
-    Return<Result> setInputDevice(AudioDevice device) override;
+    Return<Result> setInputDevice(AudioDeviceBitfield device) override;
     Return<void> getConfig(getConfig_cb _hidl_cb) override;
     Return<void> getConfigReverse(getConfigReverse_cb _hidl_cb) override;
     Return<void> getSupportedAuxChannelsConfigs(
@@ -98,7 +101,7 @@
     Return<bool> isStrengthSupported() override;
     Return<Result> setStrength(uint16_t strength) override;
     Return<void> getStrength(getStrength_cb _hidl_cb) override;
-    Return<void> getVirtualSpeakerAngles(AudioChannelMask mask, AudioDevice device,
+    Return<void> getVirtualSpeakerAngles(AudioChannelBitfield mask, AudioDevice device,
                                          getVirtualSpeakerAngles_cb _hidl_cb) override;
     Return<Result> forceVirtualizationMode(AudioDevice device) override;
     Return<void> getVirtualizationMode(getVirtualizationMode_cb _hidl_cb) override;
diff --git a/audio/effect/all-versions/default/include/effect/all-versions/default/VirtualizerEffect.impl.h b/audio/effect/all-versions/default/include/effect/all-versions/default/VirtualizerEffect.impl.h
index 6fb8005..23b09a89 100644
--- a/audio/effect/all-versions/default/include/effect/all-versions/default/VirtualizerEffect.impl.h
+++ b/audio/effect/all-versions/default/include/effect/all-versions/default/VirtualizerEffect.impl.h
@@ -21,6 +21,8 @@
 #include <android/log.h>
 #include <system/audio_effects/effect_virtualizer.h>
 
+#include "VersionUtils.h"
+
 namespace android {
 namespace hardware {
 namespace audio {
@@ -36,7 +38,7 @@
                                              hidl_vec<SpeakerAngle>& speakerAngles) {
     speakerAngles.resize(channelCount);
     for (uint32_t i = 0; i < channelCount; ++i) {
-        speakerAngles[i].mask = AudioChannelMask(*halAngles++);
+        speakerAngles[i].mask = AudioChannelBitfield(*halAngles++);
         speakerAngles[i].azimuth = *halAngles++;
         speakerAngles[i].elevation = *halAngles++;
     }
@@ -65,7 +67,7 @@
     return mEffect->disable();
 }
 
-Return<Result> VirtualizerEffect::setDevice(AudioDevice device) {
+Return<Result> VirtualizerEffect::setDevice(AudioDeviceBitfield device) {
     return mEffect->setDevice(device);
 }
 
@@ -88,7 +90,7 @@
     return mEffect->setConfigReverse(config, inputBufferProvider, outputBufferProvider);
 }
 
-Return<Result> VirtualizerEffect::setInputDevice(AudioDevice device) {
+Return<Result> VirtualizerEffect::setInputDevice(AudioDeviceBitfield device) {
     return mEffect->setInputDevice(device);
 }
 
@@ -184,7 +186,8 @@
     return mEffect->getIntegerParam(VIRTUALIZER_PARAM_STRENGTH, _hidl_cb);
 }
 
-Return<void> VirtualizerEffect::getVirtualSpeakerAngles(AudioChannelMask mask, AudioDevice device,
+Return<void> VirtualizerEffect::getVirtualSpeakerAngles(AudioChannelBitfield mask,
+                                                        AudioDevice device,
                                                         getVirtualSpeakerAngles_cb _hidl_cb) {
     uint32_t channelCount =
         audio_channel_count_from_out_mask(static_cast<audio_channel_mask_t>(mask));
diff --git a/audio/effect/all-versions/default/include/effect/all-versions/default/VisualizerEffect.h b/audio/effect/all-versions/default/include/effect/all-versions/default/VisualizerEffect.h
index 8050221..114d3b7 100644
--- a/audio/effect/all-versions/default/include/effect/all-versions/default/VisualizerEffect.h
+++ b/audio/effect/all-versions/default/include/effect/all-versions/default/VisualizerEffect.h
@@ -20,6 +20,8 @@
 
 #include <hidl/MQDescriptor.h>
 
+#include "VersionUtils.h"
+
 namespace android {
 namespace hardware {
 namespace audio {
@@ -56,7 +58,7 @@
     Return<Result> reset() override;
     Return<Result> enable() override;
     Return<Result> disable() override;
-    Return<Result> setDevice(AudioDevice device) override;
+    Return<Result> setDevice(AudioDeviceBitfield device) override;
     Return<void> setAndGetVolume(const hidl_vec<uint32_t>& volumes,
                                  setAndGetVolume_cb _hidl_cb) override;
     Return<Result> volumeChangeNotification(const hidl_vec<uint32_t>& volumes) override;
@@ -64,7 +66,7 @@
     Return<Result> setConfigReverse(
         const EffectConfig& config, const sp<IEffectBufferProviderCallback>& inputBufferProvider,
         const sp<IEffectBufferProviderCallback>& outputBufferProvider) override;
-    Return<Result> setInputDevice(AudioDevice device) override;
+    Return<Result> setInputDevice(AudioDeviceBitfield device) override;
     Return<void> getConfig(getConfig_cb _hidl_cb) override;
     Return<void> getConfigReverse(getConfigReverse_cb _hidl_cb) override;
     Return<void> getSupportedAuxChannelsConfigs(
diff --git a/audio/effect/all-versions/default/include/effect/all-versions/default/VisualizerEffect.impl.h b/audio/effect/all-versions/default/include/effect/all-versions/default/VisualizerEffect.impl.h
index 0351453..9f2195b 100644
--- a/audio/effect/all-versions/default/include/effect/all-versions/default/VisualizerEffect.impl.h
+++ b/audio/effect/all-versions/default/include/effect/all-versions/default/VisualizerEffect.impl.h
@@ -19,6 +19,8 @@
 #include <android/log.h>
 #include <system/audio_effects/effect_visualizer.h>
 
+#include "VersionUtils.h"
+
 namespace android {
 namespace hardware {
 namespace audio {
@@ -54,7 +56,7 @@
     return mEffect->disable();
 }
 
-Return<Result> VisualizerEffect::setDevice(AudioDevice device) {
+Return<Result> VisualizerEffect::setDevice(AudioDeviceBitfield device) {
     return mEffect->setDevice(device);
 }
 
@@ -77,7 +79,7 @@
     return mEffect->setConfigReverse(config, inputBufferProvider, outputBufferProvider);
 }
 
-Return<Result> VisualizerEffect::setInputDevice(AudioDevice device) {
+Return<Result> VisualizerEffect::setInputDevice(AudioDeviceBitfield device) {
     return mEffect->setInputDevice(device);
 }
 
diff --git a/authsecret/1.0/vts/functional/VtsHalAuthSecretV1_0TargetTest.cpp b/authsecret/1.0/vts/functional/VtsHalAuthSecretV1_0TargetTest.cpp
index a610a75..255d4de 100644
--- a/authsecret/1.0/vts/functional/VtsHalAuthSecretV1_0TargetTest.cpp
+++ b/authsecret/1.0/vts/functional/VtsHalAuthSecretV1_0TargetTest.cpp
@@ -17,18 +17,35 @@
 #include <android/hardware/authsecret/1.0/IAuthSecret.h>
 
 #include <VtsHalHidlTargetTestBase.h>
+#include <VtsHalHidlTargetTestEnvBase.h>
 
 using ::android::hardware::hidl_vec;
 using ::android::hardware::authsecret::V1_0::IAuthSecret;
 using ::android::sp;
 
+// Test environment for Boot HIDL HAL.
+class AuthSecretHidlEnvironment : public ::testing::VtsHalHidlTargetTestEnvBase {
+   public:
+    // get the test environment singleton
+    static AuthSecretHidlEnvironment* Instance() {
+        static AuthSecretHidlEnvironment* instance = new AuthSecretHidlEnvironment;
+        return instance;
+    }
+
+    virtual void registerTestServices() override { registerTestService<IAuthSecret>(); }
+
+   private:
+    AuthSecretHidlEnvironment() {}
+};
+
 /**
  * There is no expected behaviour that can be tested so these tests check the
  * HAL doesn't crash with different execution orders.
  */
 struct AuthSecretHidlTest : public ::testing::VtsHalHidlTargetTestBase {
     virtual void SetUp() override {
-        authsecret = ::testing::VtsHalHidlTargetTestBase::getService<IAuthSecret>();
+        authsecret = ::testing::VtsHalHidlTargetTestBase::getService<IAuthSecret>(
+            AuthSecretHidlEnvironment::Instance()->getServiceName<IAuthSecret>());
         ASSERT_NE(authsecret, nullptr);
 
         // All tests must enroll the correct secret first as this cannot be changed
@@ -69,3 +86,12 @@
     // Secret provisioned by SetUp()
     authsecret->primaryUserCredential(WRONG_SECRET);
 }
+
+int main(int argc, char** argv) {
+    ::testing::AddGlobalTestEnvironment(AuthSecretHidlEnvironment::Instance());
+    ::testing::InitGoogleTest(&argc, argv);
+    AuthSecretHidlEnvironment::Instance()->init(&argc, argv);
+    int status = RUN_ALL_TESTS();
+    ALOGI("Test result = %d", status);
+    return status;
+}
diff --git a/bluetooth/1.0/vts/functional/VtsHalBluetoothV1_0TargetTest.cpp b/bluetooth/1.0/vts/functional/VtsHalBluetoothV1_0TargetTest.cpp
index b9f505d..bf8b547 100644
--- a/bluetooth/1.0/vts/functional/VtsHalBluetoothV1_0TargetTest.cpp
+++ b/bluetooth/1.0/vts/functional/VtsHalBluetoothV1_0TargetTest.cpp
@@ -90,13 +90,15 @@
 #define EVENT_NUMBER_OF_COMPLETED_PACKETS_NUM_HANDLES 2
 
 #define ACL_BROADCAST_FLAG_OFFSET 6
-#define ACL_BROADCAST_FLAG_ACTIVE_SLAVE 0x1
-#define ACL_BROADCAST_ACTIVE_SLAVE (ACL_BROADCAST_FLAG_ACTIVE_SLAVE << ACL_BROADCAST_FLAG_OFFSET)
+#define ACL_BROADCAST_FLAG_POINT_TO_POINT 0x0
+#define ACL_BROADCAST_POINT_TO_POINT \
+  (ACL_BROADCAST_FLAG_POINT_TO_POINT << ACL_BROADCAST_FLAG_OFFSET)
 
 #define ACL_PACKET_BOUNDARY_FLAG_OFFSET 4
-#define ACL_PACKET_BOUNDARY_FLAG_COMPLETE 0x3
-#define ACL_PACKET_BOUNDARY_COMPLETE \
-    (ACL_PACKET_BOUNDARY_FLAG_COMPLETE << ACL_PACKET_BOUNDARY_FLAG_OFFSET)
+#define ACL_PACKET_BOUNDARY_FLAG_FIRST_AUTO_FLUSHABLE 0x2
+#define ACL_PACKET_BOUNDARY_FIRST_AUTO_FLUSHABLE \
+  (ACL_PACKET_BOUNDARY_FLAG_FIRST_AUTO_FLUSHABLE \
+   << ACL_PACKET_BOUNDARY_FLAG_OFFSET)
 
 constexpr char kCallbackNameAclEventReceived[] = "aclDataReceived";
 constexpr char kCallbackNameHciEventReceived[] = "hciEventReceived";
@@ -189,6 +191,7 @@
 
   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());
@@ -204,6 +207,8 @@
   // Helper functions to try to get a handle on verbosity
   void enterLoopbackMode(std::vector<uint16_t>& sco_handles,
                          std::vector<uint16_t>& acl_handles);
+  void handle_no_ops();
+  void wait_for_event(bool timeout_is_error);
   void wait_for_command_complete_event(hidl_vec<uint8_t> cmd);
   int wait_for_completed_packets_event(uint16_t handle);
 
@@ -269,31 +274,50 @@
   int max_sco_data_packets;
 };
 
-// Receive and check status events until a COMMAND_COMPLETE is received.
-void BluetoothHidlTest::wait_for_command_complete_event(hidl_vec<uint8_t> cmd) {
-  // Allow intermediate COMMAND_STATUS events
-  int status_event_count = 0;
+// Discard NO-OPs from the event queue.
+void BluetoothHidlTest::handle_no_ops() {
+  while (event_queue.size() > 0) {
+    hidl_vec<uint8_t> event = event_queue.front();
+    EXPECT_GE(event.size(),
+              static_cast<size_t>(EVENT_COMMAND_COMPLETE_STATUS_BYTE));
+    bool event_is_no_op =
+        (event[EVENT_CODE_BYTE] == EVENT_COMMAND_COMPLETE) &&
+        (event[EVENT_COMMAND_COMPLETE_OPCODE_LSBYTE] == 0x00) &&
+        (event[EVENT_COMMAND_COMPLETE_OPCODE_LSBYTE + 1] == 0x00);
+    event_is_no_op |= (event[EVENT_CODE_BYTE] == EVENT_COMMAND_STATUS) &&
+                      (event[EVENT_COMMAND_STATUS_OPCODE_LSBYTE] == 0x00) &&
+                      (event[EVENT_COMMAND_STATUS_OPCODE_LSBYTE + 1] == 0x00);
+    if (event_is_no_op) {
+      event_queue.pop();
+    } else {
+      return;
+    }
+  }
+}
+
+// Receive an event, discarding NO-OPs.
+void BluetoothHidlTest::wait_for_event(bool timeout_is_error = true) {
   hidl_vec<uint8_t> event;
   do {
-      EXPECT_TRUE(bluetooth_cb->WaitForCallback(kCallbackNameHciEventReceived)
-                      .no_timeout);
+    bool no_timeout =
+        bluetooth_cb->WaitForCallback(kCallbackNameHciEventReceived).no_timeout;
+    EXPECT_TRUE(no_timeout || !timeout_is_error);
+    if (no_timeout && timeout_is_error) {
       EXPECT_LT(static_cast<size_t>(0), event_queue.size());
-      if (event_queue.size() == 0) {
-          event.resize(0);
-          break;
     }
-    event = event_queue.front();
-    event_queue.pop();
-    EXPECT_GT(event.size(),
-              static_cast<size_t>(EVENT_COMMAND_STATUS_OPCODE_LSBYTE + 1));
-    if (event[EVENT_CODE_BYTE] == EVENT_COMMAND_STATUS) {
-      EXPECT_EQ(EVENT_COMMAND_STATUS_LENGTH, event[EVENT_LENGTH_BYTE]);
-      EXPECT_EQ(cmd[0], event[EVENT_COMMAND_STATUS_OPCODE_LSBYTE]);
-      EXPECT_EQ(cmd[1], event[EVENT_COMMAND_STATUS_OPCODE_LSBYTE + 1]);
-      EXPECT_EQ(event[EVENT_COMMAND_STATUS_STATUS_BYTE], HCI_STATUS_SUCCESS);
-      status_event_count++;
+    if (event_queue.size() == 0) {
+      // WaitForCallback timed out.
+      return;
     }
-  } while (event.size() > 0 && event[EVENT_CODE_BYTE] == EVENT_COMMAND_STATUS);
+    handle_no_ops();
+  } while (event_queue.size() == 0);
+}
+
+// Wait until a COMMAND_COMPLETE is received.
+void BluetoothHidlTest::wait_for_command_complete_event(hidl_vec<uint8_t> cmd) {
+  wait_for_event();
+  hidl_vec<uint8_t> event = event_queue.front();
+  event_queue.pop();
 
   EXPECT_GT(event.size(),
             static_cast<size_t>(EVENT_COMMAND_COMPLETE_STATUS_BYTE));
@@ -308,10 +332,7 @@
   hidl_vec<uint8_t> cmd = COMMAND_HCI_READ_BUFFER_SIZE;
   bluetooth->sendHciCommand(cmd);
 
-  EXPECT_TRUE(
-      bluetooth_cb->WaitForCallback(kCallbackNameHciEventReceived).no_timeout);
-
-  EXPECT_LT(static_cast<size_t>(0), event_queue.size());
+  wait_for_event();
   if (event_queue.size() == 0) return;
 
   hidl_vec<uint8_t> event = event_queue.front();
@@ -341,6 +362,7 @@
 // Send an HCI command (in Loopback mode) and check the response.
 void BluetoothHidlTest::sendAndCheckHCI(int num_packets) {
   ThroughputLogger logger = {__func__};
+  int command_size = 0;
   for (int n = 0; n < num_packets; n++) {
     // Send an HCI packet
     std::vector<uint8_t> write_name = COMMAND_HCI_WRITE_LOCAL_NAME;
@@ -350,11 +372,9 @@
     for (size_t i = 0; i < new_name_length; i++)
       write_name.push_back(static_cast<uint8_t>(new_name[i]));
     // And the packet number
-    {
-      size_t i = new_name_length - 1;
-      for (int digits = n; digits > 0; digits = digits / 10, i--)
-        write_name[i] = static_cast<uint8_t>('0' + digits % 10);
-    }
+    size_t i = new_name_length - 1;
+    for (int digits = n; digits > 0; digits = digits / 10, i--)
+      write_name[i] = static_cast<uint8_t>('0' + digits % 10);
     // And padding
     for (size_t i = 0; i < 248 - new_name_length; i++)
       write_name.push_back(static_cast<uint8_t>(0));
@@ -363,8 +383,9 @@
     bluetooth->sendHciCommand(cmd);
 
     // Check the loopback of the HCI packet
-    EXPECT_TRUE(bluetooth_cb->WaitForCallback(kCallbackNameHciEventReceived)
-                    .no_timeout);
+    wait_for_event();
+    if (event_queue.size() == 0) return;
+
     hidl_vec<uint8_t> event = event_queue.front();
     event_queue.pop();
     size_t compare_length =
@@ -374,11 +395,21 @@
 
     EXPECT_EQ(EVENT_LOOPBACK_COMMAND, event[EVENT_CODE_BYTE]);
     EXPECT_EQ(compare_length, event[EVENT_LENGTH_BYTE]);
-    if (n == 0) logger.setTotalBytes(cmd.size() * num_packets * 2);
+
+    // Don't compare past the end of the event.
+    if (compare_length + EVENT_FIRST_PAYLOAD_BYTE > event.size()) {
+      compare_length = event.size() - EVENT_FIRST_PAYLOAD_BYTE;
+      ALOGE("Only comparing %d bytes", static_cast<int>(compare_length));
+    }
+
+    if (n == num_packets - 1) {
+      command_size = cmd.size();
+    }
 
     for (size_t i = 0; i < compare_length; i++)
       EXPECT_EQ(cmd[i], event[EVENT_FIRST_PAYLOAD_BYTE + i]);
   }
+  logger.setTotalBytes(command_size * num_packets * 2);
 }
 
 // Send a SCO data packet (in Loopback mode) and check the response.
@@ -408,8 +439,6 @@
     EXPECT_EQ(sco_packet.size(), sco_loopback.size());
     size_t successful_bytes = 0;
 
-    if (n == 0) logger.setTotalBytes(num_packets * size * 2);
-
     for (size_t i = 0; i < sco_packet.size(); i++) {
       if (sco_packet[i] == sco_loopback[i]) {
         successful_bytes = i;
@@ -423,6 +452,7 @@
     }
     EXPECT_EQ(sco_packet.size(), successful_bytes + 1);
   }
+  logger.setTotalBytes(num_packets * size * 2);
 }
 
 // Send an ACL data packet (in Loopback mode) and check the response.
@@ -435,8 +465,8 @@
     std::vector<uint8_t> acl_vector;
     acl_vector.push_back(static_cast<uint8_t>(handle & 0xff));
     acl_vector.push_back(static_cast<uint8_t>((handle & 0x0f00) >> 8) |
-                         ACL_BROADCAST_ACTIVE_SLAVE |
-                         ACL_PACKET_BOUNDARY_COMPLETE);
+                         ACL_BROADCAST_POINT_TO_POINT |
+                         ACL_PACKET_BOUNDARY_FIRST_AUTO_FLUSHABLE);
     acl_vector.push_back(static_cast<uint8_t>(size & 0xff));
     acl_vector.push_back(static_cast<uint8_t>((size & 0xff00) >> 8));
     for (size_t i = 0; i < size; i++) {
@@ -454,8 +484,6 @@
     EXPECT_EQ(acl_packet.size(), acl_loopback.size());
     size_t successful_bytes = 0;
 
-    if (n == 0) logger.setTotalBytes(num_packets * size * 2);
-
     for (size_t i = 0; i < acl_packet.size(); i++) {
       if (acl_packet[i] == acl_loopback[i]) {
         successful_bytes = i;
@@ -469,25 +497,28 @@
     }
     EXPECT_EQ(acl_packet.size(), successful_bytes + 1);
   }
+  logger.setTotalBytes(num_packets * size * 2);
 }
 
 // Return the number of completed packets reported by the controller.
 int BluetoothHidlTest::wait_for_completed_packets_event(uint16_t handle) {
-    if (!bluetooth_cb->WaitForCallback(kCallbackNameHciEventReceived).no_timeout) {
-        ALOGW("%s: WaitForCallback timed out.", __func__);
-    }
-    int packets_processed = 0;
-    while (event_queue.size() > 0) {
-        hidl_vec<uint8_t> event = event_queue.front();
-        event_queue.pop();
+  int packets_processed = 0;
+  wait_for_event(false);
+  if (event_queue.size() == 0) {
+    ALOGW("%s: WaitForCallback timed out.", __func__);
+    return packets_processed;
+  }
+  while (event_queue.size() > 0) {
+    hidl_vec<uint8_t> event = event_queue.front();
+    event_queue.pop();
 
-        EXPECT_EQ(EVENT_NUMBER_OF_COMPLETED_PACKETS, event[EVENT_CODE_BYTE]);
-        EXPECT_EQ(1, event[EVENT_NUMBER_OF_COMPLETED_PACKETS_NUM_HANDLES]);
+    EXPECT_EQ(EVENT_NUMBER_OF_COMPLETED_PACKETS, event[EVENT_CODE_BYTE]);
+    EXPECT_EQ(1, event[EVENT_NUMBER_OF_COMPLETED_PACKETS_NUM_HANDLES]);
 
-        uint16_t event_handle = event[3] + (event[4] << 8);
-        EXPECT_EQ(handle, event_handle);
+    uint16_t event_handle = event[3] + (event[4] << 8);
+    EXPECT_EQ(handle, event_handle);
 
-        packets_processed += event[5] + (event[6] << 8);
+    packets_processed += event[5] + (event[6] << 8);
   }
   return packets_processed;
 }
@@ -500,45 +531,48 @@
 
   // Receive connection complete events with data channels
   int connection_event_count = 0;
-  hidl_vec<uint8_t> event;
-  do {
-      EXPECT_TRUE(bluetooth_cb->WaitForCallback(kCallbackNameHciEventReceived)
-                      .no_timeout);
-      event = event_queue.front();
-      event_queue.pop();
-      EXPECT_GT(event.size(),
-                static_cast<size_t>(EVENT_COMMAND_COMPLETE_STATUS_BYTE));
-      if (event[EVENT_CODE_BYTE] == EVENT_CONNECTION_COMPLETE) {
-          EXPECT_GT(event.size(),
-                    static_cast<size_t>(EVENT_CONNECTION_COMPLETE_TYPE));
-          EXPECT_EQ(event[EVENT_LENGTH_BYTE],
-                    EVENT_CONNECTION_COMPLETE_PARAM_LENGTH);
-          uint8_t connection_type = event[EVENT_CONNECTION_COMPLETE_TYPE];
-
-          EXPECT_TRUE(connection_type == EVENT_CONNECTION_COMPLETE_TYPE_SCO ||
-                      connection_type == EVENT_CONNECTION_COMPLETE_TYPE_ACL);
-
-          // Save handles
-          uint16_t handle = event[EVENT_CONNECTION_COMPLETE_HANDLE_LSBYTE] |
-                            event[EVENT_CONNECTION_COMPLETE_HANDLE_LSBYTE + 1]
-                                << 8;
-          if (connection_type == EVENT_CONNECTION_COMPLETE_TYPE_SCO)
-              sco_handles.push_back(handle);
-          else
-              acl_handles.push_back(handle);
-
-          ALOGD("Connect complete type = %d handle = %d",
-                event[EVENT_CONNECTION_COMPLETE_TYPE], handle);
-          connection_event_count++;
+  bool command_complete_received = false;
+  while (true) {
+    wait_for_event(false);
+    if (event_queue.size() == 0) {
+      // Fail if there was no event received or no connections completed.
+      EXPECT_TRUE(command_complete_received);
+      EXPECT_LT(0, connection_event_count);
+      return;
     }
-  } while (event[EVENT_CODE_BYTE] == EVENT_CONNECTION_COMPLETE);
+    hidl_vec<uint8_t> event = event_queue.front();
+    event_queue.pop();
+    EXPECT_GT(event.size(),
+              static_cast<size_t>(EVENT_COMMAND_COMPLETE_STATUS_BYTE));
+    if (event[EVENT_CODE_BYTE] == EVENT_CONNECTION_COMPLETE) {
+      EXPECT_GT(event.size(),
+                static_cast<size_t>(EVENT_CONNECTION_COMPLETE_TYPE));
+      EXPECT_EQ(event[EVENT_LENGTH_BYTE],
+                EVENT_CONNECTION_COMPLETE_PARAM_LENGTH);
+      uint8_t connection_type = event[EVENT_CONNECTION_COMPLETE_TYPE];
 
-  EXPECT_GT(connection_event_count, 0);
+      EXPECT_TRUE(connection_type == EVENT_CONNECTION_COMPLETE_TYPE_SCO ||
+                  connection_type == EVENT_CONNECTION_COMPLETE_TYPE_ACL);
 
-  EXPECT_EQ(EVENT_COMMAND_COMPLETE, event[EVENT_CODE_BYTE]);
-  EXPECT_EQ(cmd[0], event[EVENT_COMMAND_COMPLETE_OPCODE_LSBYTE]);
-  EXPECT_EQ(cmd[1], event[EVENT_COMMAND_COMPLETE_OPCODE_LSBYTE + 1]);
-  EXPECT_EQ(HCI_STATUS_SUCCESS, event[EVENT_COMMAND_COMPLETE_STATUS_BYTE]);
+      // Save handles
+      uint16_t handle = event[EVENT_CONNECTION_COMPLETE_HANDLE_LSBYTE] |
+                        event[EVENT_CONNECTION_COMPLETE_HANDLE_LSBYTE + 1] << 8;
+      if (connection_type == EVENT_CONNECTION_COMPLETE_TYPE_SCO)
+        sco_handles.push_back(handle);
+      else
+        acl_handles.push_back(handle);
+
+      ALOGD("Connect complete type = %d handle = %d",
+            event[EVENT_CONNECTION_COMPLETE_TYPE], handle);
+      connection_event_count++;
+    } else {
+      EXPECT_EQ(EVENT_COMMAND_COMPLETE, event[EVENT_CODE_BYTE]);
+      EXPECT_EQ(cmd[0], event[EVENT_COMMAND_COMPLETE_OPCODE_LSBYTE]);
+      EXPECT_EQ(cmd[1], event[EVENT_COMMAND_COMPLETE_OPCODE_LSBYTE + 1]);
+      EXPECT_EQ(HCI_STATUS_SUCCESS, event[EVENT_COMMAND_COMPLETE_STATUS_BYTE]);
+      command_complete_received = true;
+    }
+  }
 }
 
 // Empty test: Initialize()/Close() are called in SetUp()/TearDown().
@@ -557,8 +591,8 @@
   hidl_vec<uint8_t> cmd = COMMAND_HCI_READ_LOCAL_VERSION_INFORMATION;
   bluetooth->sendHciCommand(cmd);
 
-  EXPECT_TRUE(
-      bluetooth_cb->WaitForCallback(kCallbackNameHciEventReceived).no_timeout);
+  wait_for_event();
+  if (event_queue.size() == 0) return;
 
   hidl_vec<uint8_t> event = event_queue.front();
   event_queue.pop();
@@ -578,19 +612,26 @@
   hidl_vec<uint8_t> cmd = COMMAND_HCI_SHOULD_BE_UNKNOWN;
   bluetooth->sendHciCommand(cmd);
 
-  EXPECT_TRUE(
-      bluetooth_cb->WaitForCallback(kCallbackNameHciEventReceived).no_timeout);
+  wait_for_event();
+  if (event_queue.size() == 0) return;
 
   hidl_vec<uint8_t> event = event_queue.front();
   event_queue.pop();
-  EXPECT_GT(event.size(),
-            static_cast<size_t>(EVENT_COMMAND_STATUS_OPCODE_LSBYTE + 1));
 
-  EXPECT_EQ(EVENT_COMMAND_COMPLETE, event[EVENT_CODE_BYTE]);
-  EXPECT_EQ(cmd[0], event[EVENT_COMMAND_COMPLETE_OPCODE_LSBYTE]);
-  EXPECT_EQ(cmd[1], event[EVENT_COMMAND_COMPLETE_OPCODE_LSBYTE + 1]);
-  EXPECT_EQ(HCI_STATUS_UNKNOWN_HCI_COMMAND,
-            event[EVENT_COMMAND_COMPLETE_STATUS_BYTE]);
+  EXPECT_GT(event.size(),
+            static_cast<size_t>(EVENT_COMMAND_COMPLETE_STATUS_BYTE));
+  if (event[EVENT_CODE_BYTE] == EVENT_COMMAND_COMPLETE) {
+    EXPECT_EQ(cmd[0], event[EVENT_COMMAND_COMPLETE_OPCODE_LSBYTE]);
+    EXPECT_EQ(cmd[1], event[EVENT_COMMAND_COMPLETE_OPCODE_LSBYTE + 1]);
+    EXPECT_EQ(HCI_STATUS_UNKNOWN_HCI_COMMAND,
+              event[EVENT_COMMAND_COMPLETE_STATUS_BYTE]);
+  } else {
+    EXPECT_EQ(EVENT_COMMAND_STATUS, event[EVENT_CODE_BYTE]);
+    EXPECT_EQ(cmd[0], event[EVENT_COMMAND_STATUS_OPCODE_LSBYTE]);
+    EXPECT_EQ(cmd[1], event[EVENT_COMMAND_STATUS_OPCODE_LSBYTE + 1]);
+    EXPECT_EQ(HCI_STATUS_UNKNOWN_HCI_COMMAND,
+              event[EVENT_COMMAND_STATUS_STATUS_BYTE]);
+  }
 }
 
 // Enter loopback mode, but don't send any packets.
@@ -603,8 +644,6 @@
 // Enter loopback mode and send single packets.
 TEST_F(BluetoothHidlTest, LoopbackModeSinglePackets) {
   setBufferSizes();
-  EXPECT_LT(0, max_sco_data_packet_length);
-  EXPECT_LT(0, max_acl_data_packet_length);
 
   std::vector<uint16_t> sco_connection_handles;
   std::vector<uint16_t> acl_connection_handles;
@@ -615,6 +654,7 @@
   // This should work, but breaks on some current platforms.  Figure out how to
   // grandfather older devices but test new ones.
   if (0 && sco_connection_handles.size() > 0) {
+    EXPECT_LT(0, max_sco_data_packet_length);
     sendAndCheckSCO(1, max_sco_data_packet_length, sco_connection_handles[0]);
     int sco_packets_sent = 1;
     int completed_packets = wait_for_completed_packets_event(sco_connection_handles[0]);
@@ -625,6 +665,7 @@
   }
 
   if (acl_connection_handles.size() > 0) {
+    EXPECT_LT(0, max_acl_data_packet_length);
     sendAndCheckACL(1, max_acl_data_packet_length, acl_connection_handles[0]);
     int acl_packets_sent = 1;
     int completed_packets = wait_for_completed_packets_event(acl_connection_handles[0]);
@@ -648,6 +689,7 @@
   // This should work, but breaks on some current platforms.  Figure out how to
   // grandfather older devices but test new ones.
   if (0 && sco_connection_handles.size() > 0) {
+    EXPECT_LT(0, max_sco_data_packet_length);
     sendAndCheckSCO(NUM_SCO_PACKETS_BANDWIDTH, max_sco_data_packet_length,
                     sco_connection_handles[0]);
     int sco_packets_sent = NUM_SCO_PACKETS_BANDWIDTH;
@@ -659,6 +701,7 @@
   }
 
   if (acl_connection_handles.size() > 0) {
+    EXPECT_LT(0, max_acl_data_packet_length);
     sendAndCheckACL(NUM_ACL_PACKETS_BANDWIDTH, max_acl_data_packet_length,
                     acl_connection_handles[0]);
     int acl_packets_sent = NUM_ACL_PACKETS_BANDWIDTH;
diff --git a/camera/common/1.0/default/VendorTagDescriptor.cpp b/camera/common/1.0/default/VendorTagDescriptor.cpp
index bc18270..1f53857 100644
--- a/camera/common/1.0/default/VendorTagDescriptor.cpp
+++ b/camera/common/1.0/default/VendorTagDescriptor.cpp
@@ -116,11 +116,11 @@
 }
 
 int VendorTagDescriptor::getTagType(uint32_t tag) const {
-    ssize_t index = mTagToNameMap.indexOfKey(tag);
-    if (index < 0) {
+    auto iter = mTagToTypeMap.find(tag);
+    if (iter == mTagToTypeMap.end()) {
         return VENDOR_TAG_TYPE_ERR;
     }
-    return mTagToTypeMap.valueFor(tag);
+    return iter->second;
 }
 
 const SortedVector<String8>* VendorTagDescriptor::getAllSectionNames() const {
@@ -167,7 +167,7 @@
         String8 name = mTagToNameMap.valueAt(i);
         uint32_t sectionId = mTagToSectionMap.valueFor(tag);
         String8 sectionName = mSections[sectionId];
-        int type = mTagToTypeMap.valueFor(tag);
+        int type = mTagToTypeMap.at(tag);
         const char* typeName = (type >= 0 && type < NUM_TYPES) ?
                 camera_metadata_type_names[type] : "UNKNOWN";
         dprintf(fd, "%*s0x%x (%s) with type %d (%s) defined in section %s\n", indentation + 2,
@@ -251,7 +251,7 @@
             ALOGE("%s: tag type %d from vendor ops does not exist.", __FUNCTION__, tagType);
             return BAD_VALUE;
         }
-        desc->mTagToTypeMap.add(tag, tagType);
+        desc->mTagToTypeMap.insert(std::make_pair(tag, tagType));
     }
 
     desc->mSections = sections;
diff --git a/camera/common/1.0/default/include/VendorTagDescriptor.h b/camera/common/1.0/default/include/VendorTagDescriptor.h
index 8d8ded9..a040540 100644
--- a/camera/common/1.0/default/include/VendorTagDescriptor.h
+++ b/camera/common/1.0/default/include/VendorTagDescriptor.h
@@ -24,6 +24,7 @@
 #include <system/camera_vendor_tags.h>
 
 #include <stdint.h>
+#include <unordered_map>
 
 namespace android {
 namespace hardware {
@@ -94,7 +95,8 @@
         KeyedVector<String8, KeyedVector<String8, uint32_t>*> mReverseMapping;
         KeyedVector<uint32_t, String8> mTagToNameMap;
         KeyedVector<uint32_t, uint32_t> mTagToSectionMap; // Value is offset in mSections
-        KeyedVector<uint32_t, int32_t> mTagToTypeMap;
+
+        std::unordered_map<uint32_t, int32_t> mTagToTypeMap;
         SortedVector<String8> mSections;
         // must be int32_t to be compatible with Parcel::writeInt32
         int32_t mTagCount;
diff --git a/camera/device/3.4/default/CameraDeviceSession.cpp b/camera/device/3.4/default/CameraDeviceSession.cpp
index bb4886d..b032357 100644
--- a/camera/device/3.4/default/CameraDeviceSession.cpp
+++ b/camera/device/3.4/default/CameraDeviceSession.cpp
@@ -107,7 +107,6 @@
 
     const camera_metadata_t *paramBuffer = nullptr;
     if (0 < requestedConfiguration.sessionParams.size()) {
-        ::android::hardware::camera::common::V1_0::helper::CameraMetadata sessionParams;
         V3_2::implementation::convertFromHidl(requestedConfiguration.sessionParams, &paramBuffer);
     }
 
diff --git a/camera/device/3.4/default/ExternalCameraDevice.cpp b/camera/device/3.4/default/ExternalCameraDevice.cpp
index 14f82bc..9a02ce8 100644
--- a/camera/device/3.4/default/ExternalCameraDevice.cpp
+++ b/camera/device/3.4/default/ExternalCameraDevice.cpp
@@ -638,12 +638,6 @@
         }
     }
 
-    // The document in aeAvailableTargetFpsRanges section says the minFps should
-    // not be larger than 15.
-    // We cannot support fixed 30fps but Android requires (min, max) and
-    // (max, max) ranges.
-    // TODO: populate more, right now this does not support 30,30 if the device
-    //       has higher than 30 fps modes
     std::vector<int32_t> fpsRanges;
     // Variable range
     fpsRanges.push_back(minFps);
@@ -693,7 +687,7 @@
 #undef UPDATE
 
 void ExternalCameraDevice::getFrameRateList(
-        int fd, float fpsUpperBound, SupportedV4L2Format* format) {
+        int fd, double fpsUpperBound, SupportedV4L2Format* format) {
     format->frameRates.clear();
 
     v4l2_frmivalenum frameInterval {
@@ -715,7 +709,7 @@
                 if (framerate > fpsUpperBound) {
                     continue;
                 }
-                ALOGI("index:%d, format:%c%c%c%c, w %d, h %d, framerate %f",
+                ALOGV("index:%d, format:%c%c%c%c, w %d, h %d, framerate %f",
                     frameInterval.index,
                     frameInterval.pixel_format & 0xFF,
                     (frameInterval.pixel_format >> 8) & 0xFF,
@@ -738,71 +732,68 @@
     }
 }
 
-CroppingType ExternalCameraDevice::initCroppingType(
-        /*inout*/std::vector<SupportedV4L2Format>* pSortedFmts) {
-    std::vector<SupportedV4L2Format>& sortedFmts = *pSortedFmts;
+void ExternalCameraDevice::trimSupportedFormats(
+        CroppingType cropType,
+        /*inout*/std::vector<SupportedV4L2Format>* pFmts) {
+    std::vector<SupportedV4L2Format>& sortedFmts = *pFmts;
+    if (cropType == VERTICAL) {
+        std::sort(sortedFmts.begin(), sortedFmts.end(),
+                [](const SupportedV4L2Format& a, const SupportedV4L2Format& b) -> bool {
+                    if (a.width == b.width) {
+                        return a.height < b.height;
+                    }
+                    return a.width < b.width;
+                });
+    } else {
+        std::sort(sortedFmts.begin(), sortedFmts.end(),
+                [](const SupportedV4L2Format& a, const SupportedV4L2Format& b) -> bool {
+                    if (a.height == b.height) {
+                        return a.width < b.width;
+                    }
+                    return a.height < b.height;
+                });
+    }
+
+    if (sortedFmts.size() == 0) {
+        ALOGE("%s: input format list is empty!", __FUNCTION__);
+        return;
+    }
+
     const auto& maxSize = sortedFmts[sortedFmts.size() - 1];
     float maxSizeAr = ASPECT_RATIO(maxSize);
-    float minAr = kMaxAspectRatio;
-    float maxAr = kMinAspectRatio;
+
+    // Remove formats that has aspect ratio not croppable from largest size
+    std::vector<SupportedV4L2Format> out;
     for (const auto& fmt : sortedFmts) {
         float ar = ASPECT_RATIO(fmt);
-        if (ar < minAr) {
-            minAr = ar;
-        }
-        if (ar > maxAr) {
-            maxAr = ar;
-        }
-    }
-
-    CroppingType ct = VERTICAL;
-    if (isAspectRatioClose(maxSizeAr, maxAr)) {
-        // Ex: 16:9 sensor, cropping horizontally to get to 4:3
-        ct = HORIZONTAL;
-    } else if (isAspectRatioClose(maxSizeAr, minAr)) {
-        // Ex: 4:3 sensor, cropping vertically to get to 16:9
-        ct = VERTICAL;
-    } else {
-        ALOGI("%s: camera maxSizeAr %f is not close to minAr %f or maxAr %f",
-                __FUNCTION__, maxSizeAr, minAr, maxAr);
-        if ((maxSizeAr - minAr) < (maxAr - maxSizeAr)) {
-            ct = VERTICAL;
+        if (isAspectRatioClose(ar, maxSizeAr)) {
+            out.push_back(fmt);
+        } else if (cropType == HORIZONTAL && ar < maxSizeAr) {
+            out.push_back(fmt);
+        } else if (cropType == VERTICAL && ar > maxSizeAr) {
+            out.push_back(fmt);
         } else {
-            ct = HORIZONTAL;
+            ALOGV("%s: size (%d,%d) is removed due to unable to crop %s from (%d,%d)",
+                __FUNCTION__, fmt.width, fmt.height,
+                cropType == VERTICAL ? "vertically" : "horizontally",
+                maxSize.width, maxSize.height);
         }
-
-        // Remove formats that has aspect ratio not croppable from largest size
-        std::vector<SupportedV4L2Format> out;
-        for (const auto& fmt : sortedFmts) {
-            float ar = ASPECT_RATIO(fmt);
-            if (isAspectRatioClose(ar, maxSizeAr)) {
-                out.push_back(fmt);
-            } else if (ct == HORIZONTAL && ar < maxSizeAr) {
-                out.push_back(fmt);
-            } else if (ct == VERTICAL && ar > maxSizeAr) {
-                out.push_back(fmt);
-            } else {
-                ALOGD("%s: size (%d,%d) is removed due to unable to crop %s from (%d,%d)",
-                    __FUNCTION__, fmt.width, fmt.height,
-                    ct == VERTICAL ? "vertically" : "horizontally",
-                    maxSize.width, maxSize.height);
-            }
-        }
-        sortedFmts = out;
     }
-    ALOGI("%s: camera croppingType is %s", __FUNCTION__,
-            ct == VERTICAL ? "VERTICAL" : "HORIZONTAL");
-    return ct;
+    sortedFmts = out;
 }
 
-void ExternalCameraDevice::initSupportedFormatsLocked(int fd) {
+std::vector<SupportedV4L2Format>
+ExternalCameraDevice::getCandidateSupportedFormatsLocked(
+        int fd, CroppingType cropType,
+        const std::vector<ExternalCameraConfig::FpsLimitation>& fpsLimits) {
+    std::vector<SupportedV4L2Format> outFmts;
     struct v4l2_fmtdesc fmtdesc {
         .index = 0,
         .type = V4L2_BUF_TYPE_VIDEO_CAPTURE};
     int ret = 0;
     while (ret == 0) {
         ret = TEMP_FAILURE_RETRY(ioctl(fd, VIDIOC_ENUM_FMT, &fmtdesc));
-        ALOGD("index:%d,ret:%d, format:%c%c%c%c", fmtdesc.index, ret,
+        ALOGV("index:%d,ret:%d, format:%c%c%c%c", fmtdesc.index, ret,
                 fmtdesc.pixelformat & 0xFF,
                 (fmtdesc.pixelformat >> 8) & 0xFF,
                 (fmtdesc.pixelformat >> 16) & 0xFF,
@@ -835,13 +826,20 @@
                             .fourcc = fmtdesc.pixelformat
                         };
 
-                        float fpsUpperBound = -1.0;
-                        for (const auto& limit : mCfg.fpsLimits) {
-                            if (format.width <= limit.size.width &&
-                                    format.height <= limit.size.height) {
-                                fpsUpperBound = limit.fpsUpperBound;
-                                break;
+                        double fpsUpperBound = -1.0;
+                        for (const auto& limit : fpsLimits) {
+                            if (cropType == VERTICAL) {
+                                if (format.width <= limit.size.width) {
+                                    fpsUpperBound = limit.fpsUpperBound;
+                                    break;
+                                }
+                            } else { // HORIZONTAL
+                                if (format.height <= limit.size.height) {
+                                    fpsUpperBound = limit.fpsUpperBound;
+                                    break;
+                                }
                             }
+
                         }
                         if (fpsUpperBound < 0.f) {
                             continue;
@@ -849,7 +847,7 @@
 
                         getFrameRateList(fd, fpsUpperBound, &format);
                         if (!format.frameRates.empty()) {
-                            mSupportedFormats.push_back(format);
+                            outFmts.push_back(format);
                         }
                     }
                 }
@@ -857,16 +855,66 @@
         }
         fmtdesc.index++;
     }
+    trimSupportedFormats(cropType, &outFmts);
+    return outFmts;
+}
 
-    std::sort(mSupportedFormats.begin(), mSupportedFormats.end(),
-            [](const SupportedV4L2Format& a, const SupportedV4L2Format& b) -> bool {
-                if (a.width == b.width) {
-                    return a.height < b.height;
-                }
-                return a.width < b.width;
-            });
+void ExternalCameraDevice::initSupportedFormatsLocked(int fd) {
 
-    mCroppingType = initCroppingType(&mSupportedFormats);
+    std::vector<SupportedV4L2Format> horizontalFmts =
+            getCandidateSupportedFormatsLocked(fd, HORIZONTAL, mCfg.fpsLimits);
+    std::vector<SupportedV4L2Format> verticalFmts =
+            getCandidateSupportedFormatsLocked(fd, VERTICAL, mCfg.fpsLimits);
+
+    size_t horiSize = horizontalFmts.size();
+    size_t vertSize = verticalFmts.size();
+
+    if (horiSize == 0 && vertSize == 0) {
+        ALOGE("%s: cannot find suitable cropping type!", __FUNCTION__);
+        return;
+    }
+
+    if (horiSize == 0) {
+        mSupportedFormats = verticalFmts;
+        mCroppingType = VERTICAL;
+        return;
+    } else if (vertSize == 0) {
+        mSupportedFormats = horizontalFmts;
+        mCroppingType = HORIZONTAL;
+        return;
+    }
+
+    const auto& maxHoriSize = horizontalFmts[horizontalFmts.size() - 1];
+    const auto& maxVertSize = verticalFmts[verticalFmts.size() - 1];
+
+    // Try to keep largest possible output size
+    // When they are the same or ambiguous, pick the one support more sizes
+    if (maxHoriSize.width == maxVertSize.width &&
+            maxHoriSize.height == maxVertSize.height) {
+        if (horiSize > vertSize) {
+            mSupportedFormats = horizontalFmts;
+            mCroppingType = HORIZONTAL;
+        } else {
+            mSupportedFormats = verticalFmts;
+            mCroppingType = VERTICAL;
+        }
+    } else if (maxHoriSize.width >= maxVertSize.width &&
+            maxHoriSize.height >= maxVertSize.height) {
+        mSupportedFormats = horizontalFmts;
+        mCroppingType = HORIZONTAL;
+    } else if (maxHoriSize.width <= maxVertSize.width &&
+            maxHoriSize.height <= maxVertSize.height) {
+        mSupportedFormats = verticalFmts;
+        mCroppingType = VERTICAL;
+    } else {
+        if (horiSize > vertSize) {
+            mSupportedFormats = horizontalFmts;
+            mCroppingType = HORIZONTAL;
+        } else {
+            mSupportedFormats = verticalFmts;
+            mCroppingType = VERTICAL;
+        }
+    }
 }
 
 }  // namespace implementation
diff --git a/camera/device/3.4/default/ExternalCameraDeviceSession.cpp b/camera/device/3.4/default/ExternalCameraDeviceSession.cpp
index 5346f80..5569439 100644
--- a/camera/device/3.4/default/ExternalCameraDeviceSession.cpp
+++ b/camera/device/3.4/default/ExternalCameraDeviceSession.cpp
@@ -15,6 +15,7 @@
  */
 #define LOG_TAG "ExtCamDevSsn@3.4"
 //#define LOG_NDEBUG 0
+#define ATRACE_TAG ATRACE_TAG_CAMERA
 #include <log/log.h>
 
 #include <inttypes.h>
@@ -22,6 +23,7 @@
 
 #include "android-base/macros.h"
 #include <utils/Timers.h>
+#include <utils/Trace.h>
 #include <linux/videodev2.h>
 #include <sync/sync.h>
 
@@ -160,7 +162,6 @@
     SupportedV4L2Format streamingFmt;
     std::unordered_set<uint32_t>  inflightFrames;
     {
-        Mutex::Autolock _l(mLock);
         bool sessionLocked = tryLock(mLock);
         if (!sessionLocked) {
             dprintf(fd, "!! ExternalCameraDeviceSession mLock may be deadlocked !!\n");
@@ -180,12 +181,13 @@
             streaming ? "streaming" : "not streaming");
     if (streaming) {
         // TODO: dump fps later
-        dprintf(fd, "Current V4L2 format %c%c%c%c %dx%d\n",
+        dprintf(fd, "Current V4L2 format %c%c%c%c %dx%d @ %ffps\n",
                 streamingFmt.fourcc & 0xFF,
                 (streamingFmt.fourcc >> 8) & 0xFF,
                 (streamingFmt.fourcc >> 16) & 0xFF,
                 (streamingFmt.fourcc >> 24) & 0xFF,
-                streamingFmt.width, streamingFmt.height);
+                streamingFmt.width, streamingFmt.height,
+                mV4l2StreamingFps);
 
         size_t numDequeuedV4l2Buffers = 0;
         {
@@ -291,7 +293,6 @@
         config_v32.streams[i] = requestedConfiguration.streams[i].v3_2;
     }
 
-    // Ignore requestedConfiguration.sessionParams. External camera does not support it
     Status status = configureStreams(config_v32, &outStreams_v33);
 
     V3_4::HalStreamConfiguration outStreams;
@@ -358,6 +359,7 @@
 }
 
 Return<Status> ExternalCameraDeviceSession::flush() {
+    ATRACE_CALL();
     Mutex::Autolock _il(mInterfaceLock);
     Status status = initStatus();
     if (status != Status::OK) {
@@ -451,7 +453,25 @@
     }
 }
 
+int ExternalCameraDeviceSession::waitForV4L2BufferReturnLocked(std::unique_lock<std::mutex>& lk) {
+    std::chrono::seconds timeout = std::chrono::seconds(kBufferWaitTimeoutSec);
+    mLock.unlock();
+    auto st = mV4L2BufferReturned.wait_for(lk, timeout);
+    // Here we introduce a order where mV4l2BufferLock is acquired before mLock, while
+    // the normal lock acquisition order is reversed. This is fine because in most of
+    // cases we are protected by mInterfaceLock. The only thread that can cause deadlock
+    // is the OutputThread, where we do need to make sure we don't acquire mLock then
+    // mV4l2BufferLock
+    mLock.lock();
+    if (st == std::cv_status::timeout) {
+        ALOGE("%s: wait for V4L2 buffer return timeout!", __FUNCTION__);
+        return -1;
+    }
+    return 0;
+}
+
 Status ExternalCameraDeviceSession::processOneCaptureRequest(const CaptureRequest& request)  {
+    ATRACE_CALL();
     Status status = initStatus();
     if (status != Status::OK) {
         return status;
@@ -510,15 +530,59 @@
         return Status::ILLEGAL_ARGUMENT;
     }
 
+    camera_metadata_entry fpsRange = mLatestReqSetting.find(ANDROID_CONTROL_AE_TARGET_FPS_RANGE);
+    if (fpsRange.count == 2) {
+        double requestFpsMax = fpsRange.data.i32[1];
+        double closestFps = 0.0;
+        double fpsError = 1000.0;
+        bool fpsSupported = false;
+        for (const auto& fr : mV4l2StreamingFmt.frameRates) {
+            double f = fr.getDouble();
+            if (std::fabs(requestFpsMax - f) < 1.0) {
+                fpsSupported = true;
+                break;
+            }
+            if (std::fabs(requestFpsMax - f) < fpsError) {
+                fpsError = std::fabs(requestFpsMax - f);
+                closestFps = f;
+            }
+        }
+        if (!fpsSupported) {
+            /* This can happen in a few scenarios:
+             * 1. The application is sending a FPS range not supported by the configured outputs.
+             * 2. The application is sending a valid FPS range for all cofigured outputs, but
+             *    the selected V4L2 size can only run at slower speed. This should be very rare
+             *    though: for this to happen a sensor needs to support at least 3 different aspect
+             *    ratio outputs, and when (at least) two outputs are both not the main aspect ratio
+             *    of the webcam, a third size that's larger might be picked and runs into this
+             *    issue.
+             */
+            ALOGW("%s: cannot reach fps %d! Will do %f instead",
+                    __FUNCTION__, fpsRange.data.i32[1], closestFps);
+            requestFpsMax = closestFps;
+        }
+
+        if (requestFpsMax != mV4l2StreamingFps) {
+            {
+                std::unique_lock<std::mutex> lk(mV4l2BufferLock);
+                while (mNumDequeuedV4l2Buffers != 0) {
+                    // Wait until pipeline is idle before reconfigure stream
+                    int waitRet = waitForV4L2BufferReturnLocked(lk);
+                    if (waitRet != 0) {
+                        ALOGE("%s: wait for pipeline idle failed!", __FUNCTION__);
+                        return Status::INTERNAL_ERROR;
+                    }
+                }
+            }
+            configureV4l2StreamLocked(mV4l2StreamingFmt, requestFpsMax);
+        }
+    }
+
     status = importRequest(request, allBufPtrs, allFences);
     if (status != Status::OK) {
         return status;
     }
 
-    // TODO: program fps range per capture request here
-    //       or limit the set of availableFpsRange
-
-
     nsecs_t shutterTs = 0;
     sp<V4L2Frame> frameIn = dequeueV4l2FrameLocked(&shutterTs);
     if ( frameIn == nullptr) {
@@ -573,6 +637,7 @@
 //TODO: refactor with processCaptureResult
 Status ExternalCameraDeviceSession::processCaptureRequestError(
         const std::shared_ptr<HalRequest>& req) {
+    ATRACE_CALL();
     // Return V4L2 buffer to V4L2 buffer queue
     enqueueV4l2Frame(req->frameIn);
 
@@ -613,6 +678,7 @@
 }
 
 Status ExternalCameraDeviceSession::processCaptureResult(std::shared_ptr<HalRequest>& req) {
+    ATRACE_CALL();
     // Return V4L2 buffer to V4L2 buffer queue
     enqueueV4l2Frame(req->frameIn);
 
@@ -1389,6 +1455,7 @@
         HalStreamBuffer &halBuf,
         const std::shared_ptr<HalRequest>& req)
 {
+    ATRACE_CALL();
     int ret;
     auto lfail = [&](auto... args) {
         ALOGE(args...);
@@ -1596,8 +1663,8 @@
     uint8_t* inData;
     size_t inDataSize;
     req->frameIn->map(&inData, &inDataSize);
-    // TODO: profile
     // TODO: in some special case maybe we can decode jpg directly to gralloc output?
+    ATRACE_BEGIN("MJPGtoI420");
     int res = libyuv::MJPGToI420(
             inData, inDataSize,
             static_cast<uint8_t*>(mYu12FrameLayout.y),
@@ -1608,6 +1675,7 @@
             mYu12FrameLayout.cStride,
             mYu12Frame->mWidth, mYu12Frame->mHeight,
             mYu12Frame->mWidth, mYu12Frame->mHeight);
+    ATRACE_END();
 
     if (res != 0) {
         // For some webcam, the first few V4L2 frames might be malformed...
@@ -1669,17 +1737,21 @@
                         (outputFourcc >> 24) & 0xFF);
 
                 YCbCrLayout cropAndScaled;
+                ATRACE_BEGIN("cropAndScaleLocked");
                 int ret = cropAndScaleLocked(
                         mYu12Frame,
                         Size { halBuf.width, halBuf.height },
                         &cropAndScaled);
+                ATRACE_END();
                 if (ret != 0) {
                     lk.unlock();
                     return onDeviceError("%s: crop and scale failed!", __FUNCTION__);
                 }
 
                 Size sz {halBuf.width, halBuf.height};
+                ATRACE_BEGIN("formatConvertLocked");
                 ret = formatConvertLocked(cropAndScaled, outLayout, sz, outputFourcc);
+                ATRACE_END();
                 if (ret != 0) {
                     lk.unlock();
                     return onDeviceError("%s: format coversion failed!", __FUNCTION__);
@@ -1790,6 +1862,7 @@
 }
 
 void ExternalCameraDeviceSession::OutputThread::flush() {
+    ATRACE_CALL();
     auto parent = mParent.promote();
     if (parent == nullptr) {
        ALOGE("%s: session has been disconnected!", __FUNCTION__);
@@ -1807,6 +1880,7 @@
         }
     }
 
+    ALOGV("%s: flusing inflight requests", __FUNCTION__);
     lk.unlock();
     for (const auto& req : reqs) {
         parent->processCaptureRequestError(req);
@@ -1815,6 +1889,7 @@
 
 void ExternalCameraDeviceSession::OutputThread::waitForNextRequest(
         std::shared_ptr<HalRequest>* out) {
+    ATRACE_CALL();
     if (out == nullptr) {
         ALOGE("%s: out is null", __FUNCTION__);
         return;
@@ -1979,7 +2054,47 @@
     return OK;
 }
 
-int ExternalCameraDeviceSession::configureV4l2StreamLocked(const SupportedV4L2Format& v4l2Fmt) {
+int ExternalCameraDeviceSession::setV4l2FpsLocked(double fps) {
+    // VIDIOC_G_PARM/VIDIOC_S_PARM: set fps
+    v4l2_streamparm streamparm = { .type = V4L2_BUF_TYPE_VIDEO_CAPTURE };
+    // The following line checks that the driver knows about framerate get/set.
+    int ret = TEMP_FAILURE_RETRY(ioctl(mV4l2Fd.get(), VIDIOC_G_PARM, &streamparm));
+    if (ret != 0) {
+        if (errno == -EINVAL) {
+            ALOGW("%s: device does not support VIDIOC_G_PARM", __FUNCTION__);
+        }
+        return -errno;
+    }
+    // Now check if the device is able to accept a capture framerate set.
+    if (!(streamparm.parm.capture.capability & V4L2_CAP_TIMEPERFRAME)) {
+        ALOGW("%s: device does not support V4L2_CAP_TIMEPERFRAME", __FUNCTION__);
+        return -EINVAL;
+    }
+
+    // fps is float, approximate by a fraction.
+    const int kFrameRatePrecision = 10000;
+    streamparm.parm.capture.timeperframe.numerator = kFrameRatePrecision;
+    streamparm.parm.capture.timeperframe.denominator =
+        (fps * kFrameRatePrecision);
+
+    if (TEMP_FAILURE_RETRY(ioctl(mV4l2Fd.get(), VIDIOC_S_PARM, &streamparm)) < 0) {
+        ALOGE("%s: failed to set framerate to %f: %s", __FUNCTION__, fps, strerror(errno));
+        return -1;
+    }
+
+    double retFps = streamparm.parm.capture.timeperframe.denominator /
+            static_cast<double>(streamparm.parm.capture.timeperframe.numerator);
+    if (std::fabs(fps - retFps) > 1.0) {
+        ALOGE("%s: expect fps %f, got %f instead", __FUNCTION__, fps, retFps);
+        return -1;
+    }
+    mV4l2StreamingFps = fps;
+    return 0;
+}
+
+int ExternalCameraDeviceSession::configureV4l2StreamLocked(
+        const SupportedV4L2Format& v4l2Fmt, double requestFps) {
+    ATRACE_CALL();
     int ret = v4l2StreamOffLocked();
     if (ret != OK) {
         ALOGE("%s: stop v4l2 streaming failed: ret %d", __FUNCTION__, ret);
@@ -2016,46 +2131,31 @@
     uint32_t bufferSize = fmt.fmt.pix.sizeimage;
     ALOGI("%s: V4L2 buffer size is %d", __FUNCTION__, bufferSize);
 
-    float maxFps = -1.f;
-    float fps = 1000.f;
-    const float kDefaultFps = 30.f;
-    // Try to pick the slowest fps that is at least 30
-    for (const auto& fr : v4l2Fmt.frameRates) {
-        double f = fr.getDouble();
-        if (maxFps < f) {
-            maxFps = f;
-        }
-        if (f >= kDefaultFps && f < fps) {
-            fps = f;
-        }
-    }
-    if (fps == 1000.f) {
-        fps = maxFps;
-    }
-
-    // VIDIOC_G_PARM/VIDIOC_S_PARM: set fps
-    v4l2_streamparm streamparm = { .type = V4L2_BUF_TYPE_VIDEO_CAPTURE };
-    // The following line checks that the driver knows about framerate get/set.
-    if (TEMP_FAILURE_RETRY(ioctl(mV4l2Fd.get(), VIDIOC_G_PARM, &streamparm)) >= 0) {
-        // Now check if the device is able to accept a capture framerate set.
-        if (streamparm.parm.capture.capability & V4L2_CAP_TIMEPERFRAME) {
-            // |frame_rate| is float, approximate by a fraction.
-            const int kFrameRatePrecision = 10000;
-            streamparm.parm.capture.timeperframe.numerator = kFrameRatePrecision;
-            streamparm.parm.capture.timeperframe.denominator =
-                (fps * kFrameRatePrecision);
-
-            if (TEMP_FAILURE_RETRY(ioctl(mV4l2Fd.get(), VIDIOC_S_PARM, &streamparm)) < 0) {
-                ALOGE("%s: failed to set framerate to %f", __FUNCTION__, fps);
-                return UNKNOWN_ERROR;
+    const double kDefaultFps = 30.0;
+    double fps = 1000.0;
+    if (requestFps != 0.0) {
+        fps = requestFps;
+    } else {
+        double maxFps = -1.0;
+        // Try to pick the slowest fps that is at least 30
+        for (const auto& fr : v4l2Fmt.frameRates) {
+            double f = fr.getDouble();
+            if (maxFps < f) {
+                maxFps = f;
+            }
+            if (f >= kDefaultFps && f < fps) {
+                fps = f;
             }
         }
+        if (fps == 1000.0) {
+            fps = maxFps;
+        }
     }
-    float retFps = streamparm.parm.capture.timeperframe.denominator /
-                streamparm.parm.capture.timeperframe.numerator;
-    if (std::fabs(fps - retFps) > std::numeric_limits<float>::epsilon()) {
-        ALOGE("%s: expect fps %f, got %f instead", __FUNCTION__, fps, retFps);
-        return BAD_VALUE;
+
+    int fpsRet = setV4l2FpsLocked(fps);
+    if (fpsRet != 0 && fpsRet != -EINVAL) {
+        ALOGE("%s: set fps failed: %s", __FUNCTION__, strerror(fpsRet));
+        return fpsRet;
     }
 
     uint32_t v4lBufferCount = (fps >= kDefaultFps) ?
@@ -2126,6 +2226,7 @@
 }
 
 sp<V4L2Frame> ExternalCameraDeviceSession::dequeueV4l2FrameLocked(/*out*/nsecs_t* shutterTs) {
+    ATRACE_CALL();
     sp<V4L2Frame> ret = nullptr;
 
     if (shutterTs == nullptr) {
@@ -2136,17 +2237,8 @@
     {
         std::unique_lock<std::mutex> lk(mV4l2BufferLock);
         if (mNumDequeuedV4l2Buffers == mV4L2BufferCount) {
-            std::chrono::seconds timeout = std::chrono::seconds(kBufferWaitTimeoutSec);
-            mLock.unlock();
-            auto st = mV4L2BufferReturned.wait_for(lk, timeout);
-            // Here we introduce a case where mV4l2BufferLock is acquired before mLock, while
-            // the normal lock acquisition order is reversed, but this is fine because in most of
-            // cases we are protected by mInterfaceLock. The only thread that can compete these
-            // locks are the OutputThread, where we do need to make sure we don't acquire mLock then
-            // mV4l2BufferLock
-            mLock.lock();
-            if (st == std::cv_status::timeout) {
-                ALOGE("%s: wait for V4L2 buffer return timeout!", __FUNCTION__);
+            int waitRet = waitForV4L2BufferReturnLocked(lk);
+            if (waitRet != 0) {
                 return ret;
             }
         }
@@ -2189,6 +2281,7 @@
 }
 
 void ExternalCameraDeviceSession::enqueueV4l2Frame(const sp<V4L2Frame>& frame) {
+    ATRACE_CALL();
     {
         // Release mLock before acquiring mV4l2BufferLock to avoid potential
         // deadlock
@@ -2214,6 +2307,7 @@
 
 Status ExternalCameraDeviceSession::configureStreams(
         const V3_2::StreamConfiguration& config, V3_3::HalStreamConfiguration* out) {
+    ATRACE_CALL();
     if (config.operationMode != StreamConfigurationMode::NORMAL_MODE) {
         ALOGE("%s: unsupported operation mode: %d", __FUNCTION__, config.operationMode);
         return Status::ILLEGAL_ARGUMENT;
diff --git a/camera/device/3.4/default/include/ext_device_v3_4_impl/ExternalCameraDeviceSession.h b/camera/device/3.4/default/include/ext_device_v3_4_impl/ExternalCameraDeviceSession.h
index 9c0ad7f..5315097 100644
--- a/camera/device/3.4/default/include/ext_device_v3_4_impl/ExternalCameraDeviceSession.h
+++ b/camera/device/3.4/default/include/ext_device_v3_4_impl/ExternalCameraDeviceSession.h
@@ -177,8 +177,11 @@
     status_t initDefaultRequests();
     status_t fillCaptureResult(common::V1_0::helper::CameraMetadata& md, nsecs_t timestamp);
     Status configureStreams(const V3_2::StreamConfiguration&, V3_3::HalStreamConfiguration* out);
-    int configureV4l2StreamLocked(const SupportedV4L2Format& fmt);
+    // fps = 0.0 means default, which is
+    // slowest fps that is at least 30, or fastest fps if 30 is not supported
+    int configureV4l2StreamLocked(const SupportedV4L2Format& fmt, double fps = 0.0);
     int v4l2StreamOffLocked();
+    int setV4l2FpsLocked(double fps);
 
     // TODO: change to unique_ptr for better tracking
     sp<V4L2Frame> dequeueV4l2FrameLocked(/*out*/nsecs_t* shutterTs); // Called with mLock hold
@@ -212,6 +215,8 @@
 
     ssize_t getJpegBufferSize(uint32_t width, uint32_t height) const;
 
+    int waitForV4L2BufferReturnLocked(std::unique_lock<std::mutex>& lk);
+
     class OutputThread : public android::Thread {
     public:
         OutputThread(wp<ExternalCameraDeviceSession> parent, CroppingType);
@@ -307,6 +312,7 @@
 
     bool mV4l2Streaming = false;
     SupportedV4L2Format mV4l2StreamingFmt;
+    double mV4l2StreamingFps = 0.0;
     size_t mV4L2BufferCount = 0;
 
     static const int kBufferWaitTimeoutSec = 3; // TODO: handle long exposure (or not allowing)
diff --git a/camera/device/3.4/default/include/ext_device_v3_4_impl/ExternalCameraDevice_3_4.h b/camera/device/3.4/default/include/ext_device_v3_4_impl/ExternalCameraDevice_3_4.h
index 5880469..a52f0e4 100644
--- a/camera/device/3.4/default/include/ext_device_v3_4_impl/ExternalCameraDevice_3_4.h
+++ b/camera/device/3.4/default/include/ext_device_v3_4_impl/ExternalCameraDevice_3_4.h
@@ -78,7 +78,6 @@
     /* End of Methods from ::android::hardware::camera::device::V3_2::ICameraDevice */
 
 protected:
-    void getFrameRateList(int fd, float fpsUpperBound, SupportedV4L2Format* format);
     // Init supported w/h/format/fps in mSupportedFormats. Caller still owns fd
     void initSupportedFormatsLocked(int fd);
 
@@ -92,7 +91,15 @@
     status_t initOutputCharsKeys(int fd,
             ::android::hardware::camera::common::V1_0::helper::CameraMetadata*);
 
-    static CroppingType initCroppingType(/*inout*/std::vector<SupportedV4L2Format>*);
+    static void getFrameRateList(int fd, double fpsUpperBound, SupportedV4L2Format* format);
+
+    // Get candidate supported formats list of input cropping type.
+    static std::vector<SupportedV4L2Format> getCandidateSupportedFormatsLocked(
+            int fd, CroppingType cropType,
+            const std::vector<ExternalCameraConfig::FpsLimitation>& fpsLimits);
+    // Trim supported format list by the cropping type. Also sort output formats by width/height
+    static void trimSupportedFormats(CroppingType cropType,
+            /*inout*/std::vector<SupportedV4L2Format>* pFmts);
 
     Mutex mLock;
     bool mInitFailed = false;
diff --git a/compatibility_matrices/compatibility_matrix.current.xml b/compatibility_matrices/compatibility_matrix.current.xml
index 002ff31..930c763 100644
--- a/compatibility_matrices/compatibility_matrix.current.xml
+++ b/compatibility_matrices/compatibility_matrix.current.xml
@@ -2,6 +2,7 @@
     <hal format="hidl" optional="false">
         <name>android.hardware.audio</name>
         <version>2.0</version>
+        <version>4.0</version>
         <interface>
             <name>IDevicesFactory</name>
             <instance>default</instance>
@@ -10,6 +11,7 @@
     <hal format="hidl" optional="false">
         <name>android.hardware.audio.effect</name>
         <version>2.0</version>
+        <version>4.0</version>
         <interface>
             <name>IEffectsFactory</name>
             <instance>default</instance>
@@ -178,9 +180,11 @@
     <hal format="hidl" optional="false">
         <name>android.hardware.keymaster</name>
         <version>3.0</version>
+        <version>4.0</version>
         <interface>
             <name>IKeymasterDevice</name>
             <instance>default</instance>
+	    <!-- TODO: strongbox here? -->
         </interface>
     </hal>
     <hal format="hidl" optional="true">
diff --git a/configstore/1.0/default/surfaceflinger.mk b/configstore/1.0/default/surfaceflinger.mk
index 3ce768a..f7487d5 100644
--- a/configstore/1.0/default/surfaceflinger.mk
+++ b/configstore/1.0/default/surfaceflinger.mk
@@ -17,6 +17,10 @@
     LOCAL_CFLAGS += -DUSE_CONTEXT_PRIORITY=1
 endif
 
+ifeq ($(TARGET_USE_CONTEXT_PRIORITY),true)
+    LOCAL_CFLAGS += -DUSE_CONTEXT_PRIORITY=1
+endif
+
 ifeq ($(TARGET_HAS_WIDE_COLOR_DISPLAY),true)
     LOCAL_CFLAGS += -DHAS_WIDE_COLOR_DISPLAY
 endif
diff --git a/current.txt b/current.txt
index 05660a8..24321cc 100644
--- a/current.txt
+++ b/current.txt
@@ -256,5 +256,5 @@
 fb92e2b40f8e9d494e8fd3b4ac18499a3216342e7cff160714c3bbf3660b6e79 android.hardware.gnss@1.0::IGnssConfiguration
 251594ea9b27447bfa005ebd806e58fb0ae4aad84a69938129c9800ec0c64eda android.hardware.gnss@1.0::IGnssMeasurementCallback
 4e7169919d24fbe5573e5bcd683d0bd7abf553a4e6c34c41f9dfc1e12050db07 android.hardware.gnss@1.0::IGnssNavigationMessageCallback
-0e6e80ddd5c312726e20b003af438325a2d7c305a60a8c8d8e229df2306d50df android.hardware.radio@1.0::types
+d4840db8efabdf1e4b344fc981cd36e5fe81a39aff6e199f6d06c1c8da413efd android.hardware.radio@1.0::types
 b280c4704dfcc548a9bf127b59b7c3578f460c50cce70a06b66fe0df8b27cff0 android.hardware.wifi@1.0::types
diff --git a/keymaster/4.0/vts/functional/keymaster_hidl_hal_test.cpp b/keymaster/4.0/vts/functional/keymaster_hidl_hal_test.cpp
index dbf5ece..602355b 100644
--- a/keymaster/4.0/vts/functional/keymaster_hidl_hal_test.cpp
+++ b/keymaster/4.0/vts/functional/keymaster_hidl_hal_test.cpp
@@ -664,7 +664,7 @@
  */
 TEST_F(SigningOperationsTest, RsaSuccess) {
     ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
-                                             .RsaSigningKey(1024, 3)
+                                             .RsaSigningKey(1024, 65537)
                                              .Digest(Digest::NONE)
                                              .Padding(PaddingMode::NONE)
                                              .Authorization(TAG_NO_AUTH_REQUIRED)));
@@ -680,7 +680,7 @@
  */
 TEST_F(SigningOperationsTest, RsaPssSha256Success) {
     ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
-                                             .RsaSigningKey(1024, 3)
+                                             .RsaSigningKey(1024, 65537)
                                              .Digest(Digest::SHA_2_256)
                                              .Padding(PaddingMode::RSA_PSS)
                                              .Authorization(TAG_NO_AUTH_REQUIRED)));
@@ -698,7 +698,7 @@
  */
 TEST_F(SigningOperationsTest, RsaPaddingNoneDoesNotAllowOther) {
     ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
-                                             .RsaSigningKey(1024, 3)
+                                             .RsaSigningKey(1024, 65537)
                                              .Digest(Digest::NONE)
                                              .Authorization(TAG_NO_AUTH_REQUIRED)
                                              .Padding(PaddingMode::NONE)));
@@ -720,7 +720,7 @@
  */
 TEST_F(SigningOperationsTest, NoUserConfirmation) {
     ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
-                                             .RsaSigningKey(1024, 3)
+                                             .RsaSigningKey(1024, 65537)
                                              .Digest(Digest::NONE)
                                              .Padding(PaddingMode::NONE)
                                              .Authorization(TAG_NO_AUTH_REQUIRED)
@@ -741,7 +741,7 @@
  */
 TEST_F(SigningOperationsTest, RsaPkcs1Sha256Success) {
     ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
-                                             .RsaSigningKey(1024, 3)
+                                             .RsaSigningKey(1024, 65537)
                                              .Digest(Digest::SHA_2_256)
                                              .Authorization(TAG_NO_AUTH_REQUIRED)
                                              .Padding(PaddingMode::RSA_PKCS1_1_5_SIGN)));
@@ -758,7 +758,7 @@
  */
 TEST_F(SigningOperationsTest, RsaPkcs1NoDigestSuccess) {
     ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
-                                             .RsaSigningKey(1024, 3)
+                                             .RsaSigningKey(1024, 65537)
                                              .Digest(Digest::NONE)
                                              .Authorization(TAG_NO_AUTH_REQUIRED)
                                              .Padding(PaddingMode::RSA_PKCS1_1_5_SIGN)));
@@ -776,7 +776,7 @@
  */
 TEST_F(SigningOperationsTest, RsaPkcs1NoDigestTooLong) {
     ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
-                                             .RsaSigningKey(1024, 3)
+                                             .RsaSigningKey(1024, 65537)
                                              .Digest(Digest::NONE)
                                              .Authorization(TAG_NO_AUTH_REQUIRED)
                                              .Padding(PaddingMode::RSA_PKCS1_1_5_SIGN)));
@@ -804,7 +804,7 @@
  */
 TEST_F(SigningOperationsTest, RsaPssSha512TooSmallKey) {
     ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
-                                             .RsaSigningKey(1024, 3)
+                                             .RsaSigningKey(1024, 65537)
                                              .Digest(Digest::SHA_2_512)
                                              .Authorization(TAG_NO_AUTH_REQUIRED)
                                              .Padding(PaddingMode::RSA_PSS)));
@@ -822,7 +822,7 @@
  */
 TEST_F(SigningOperationsTest, RsaNoPaddingTooLong) {
     ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
-                                             .RsaSigningKey(1024, 3)
+                                             .RsaSigningKey(1024, 65537)
                                              .Digest(Digest::NONE)
                                              .Authorization(TAG_NO_AUTH_REQUIRED)
                                              .Padding(PaddingMode::RSA_PKCS1_1_5_SIGN)));
@@ -856,7 +856,7 @@
  */
 TEST_F(SigningOperationsTest, RsaAbort) {
     ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
-                                             .RsaSigningKey(1024, 3)
+                                             .RsaSigningKey(1024, 65537)
                                              .Digest(Digest::NONE)
                                              .Authorization(TAG_NO_AUTH_REQUIRED)
                                              .Padding(PaddingMode::NONE)));
@@ -881,7 +881,7 @@
  */
 TEST_F(SigningOperationsTest, RsaUnsupportedPadding) {
     ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
-                                             .RsaSigningKey(1024, 3)
+                                             .RsaSigningKey(1024, 65537)
                                              .Authorization(TAG_NO_AUTH_REQUIRED)
                                              .Digest(Digest::SHA_2_256 /* supported digest */)
                                              .Padding(PaddingMode::PKCS7)));
@@ -898,7 +898,7 @@
  */
 TEST_F(SigningOperationsTest, RsaNoDigest) {
     ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
-                                             .RsaSigningKey(1024, 3)
+                                             .RsaSigningKey(1024, 65537)
                                              .Authorization(TAG_NO_AUTH_REQUIRED)
                                              .Digest(Digest::NONE)
                                              .Padding(PaddingMode::RSA_PSS)));
@@ -919,7 +919,7 @@
 TEST_F(SigningOperationsTest, RsaNoPadding) {
     // Padding must be specified
     ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
-                                             .RsaKey(1024, 3)
+                                             .RsaKey(1024, 65537)
                                              .Authorization(TAG_NO_AUTH_REQUIRED)
                                              .SigningKey()
                                              .Digest(Digest::NONE)));
@@ -935,7 +935,7 @@
 TEST_F(SigningOperationsTest, RsaTooShortMessage) {
     ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
                                              .Authorization(TAG_NO_AUTH_REQUIRED)
-                                             .RsaSigningKey(1024, 3)
+                                             .RsaSigningKey(1024, 65537)
                                              .Digest(Digest::NONE)
                                              .Padding(PaddingMode::NONE)));
 
@@ -956,7 +956,7 @@
 TEST_F(SigningOperationsTest, RsaSignWithEncryptionKey) {
     ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
                                              .Authorization(TAG_NO_AUTH_REQUIRED)
-                                             .RsaEncryptionKey(1024, 3)
+                                             .RsaEncryptionKey(1024, 65537)
                                              .Digest(Digest::NONE)
                                              .Padding(PaddingMode::NONE)));
     ASSERT_EQ(ErrorCode::INCOMPATIBLE_PURPOSE,
@@ -973,7 +973,7 @@
 TEST_F(SigningOperationsTest, RsaSignTooLargeMessage) {
     ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
                                              .Authorization(TAG_NO_AUTH_REQUIRED)
-                                             .RsaSigningKey(1024, 3)
+                                             .RsaSigningKey(1024, 65537)
                                              .Digest(Digest::NONE)
                                              .Padding(PaddingMode::NONE)));
 
@@ -1044,9 +1044,9 @@
 TEST_F(SigningOperationsTest, EcdsaNoDigestHugeData) {
     ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
                                              .Authorization(TAG_NO_AUTH_REQUIRED)
-                                             .EcdsaSigningKey(224)
+                                             .EcdsaSigningKey(256)
                                              .Digest(Digest::NONE)));
-    string message(2 * 1024, 'a');
+    string message(1 * 1024, 'a');
     SignMessage(message, AuthorizationSetBuilder().Digest(Digest::NONE));
 }
 
@@ -1291,7 +1291,7 @@
 TEST_F(VerificationOperationsTest, RsaSuccess) {
     ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
                                              .Authorization(TAG_NO_AUTH_REQUIRED)
-                                             .RsaSigningKey(1024, 3)
+                                             .RsaSigningKey(1024, 65537)
                                              .Digest(Digest::NONE)
                                              .Padding(PaddingMode::NONE)));
     string message = "12345678901234567890123456789012";
@@ -1310,7 +1310,7 @@
     ASSERT_EQ(ErrorCode::OK,
               GenerateKey(AuthorizationSetBuilder()
                               .Authorization(TAG_NO_AUTH_REQUIRED)
-                              .RsaSigningKey(2048, 3)
+                              .RsaSigningKey(2048, 65537)
                               .Digest(Digest::NONE, Digest::MD5, Digest::SHA1, Digest::SHA_2_224,
                                       Digest::SHA_2_256, Digest::SHA_2_384, Digest::SHA_2_512)
                               .Padding(PaddingMode::NONE)
@@ -1534,7 +1534,7 @@
  */
 TEST_F(ExportKeyTest, RsaUnsupportedKeyFormat) {
     ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
-                                             .RsaSigningKey(1024, 3)
+                                             .RsaSigningKey(1024, 65537)
                                              .Digest(Digest::NONE)
                                              .Padding(PaddingMode::NONE)));
     HidlBuf export_data;
@@ -1550,7 +1550,7 @@
 TEST_F(ExportKeyTest, RsaCorruptedKeyBlob) {
     ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
                                              .Authorization(TAG_NO_AUTH_REQUIRED)
-                                             .RsaSigningKey(1024, 3)
+                                             .RsaSigningKey(1024, 65537)
                                              .Digest(Digest::NONE)
                                              .Padding(PaddingMode::NONE)));
     for (size_t i = 0; i < key_blob_.size(); ++i) {
@@ -1939,7 +1939,7 @@
 TEST_F(EncryptionOperationsTest, RsaNoPaddingSuccess) {
     ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
                                              .Authorization(TAG_NO_AUTH_REQUIRED)
-                                             .RsaEncryptionKey(1024, 3)
+                                             .RsaEncryptionKey(1024, 65537)
                                              .Padding(PaddingMode::NONE)));
 
     string message = string(1024 / 8, 'a');
@@ -1962,7 +1962,7 @@
 TEST_F(EncryptionOperationsTest, RsaNoPaddingShortMessage) {
     ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
                                              .Authorization(TAG_NO_AUTH_REQUIRED)
-                                             .RsaEncryptionKey(1024, 3)
+                                             .RsaEncryptionKey(1024, 65537)
                                              .Padding(PaddingMode::NONE)));
 
     string message = "1";
@@ -1991,7 +1991,7 @@
 TEST_F(EncryptionOperationsTest, RsaNoPaddingTooLong) {
     ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
                                              .Authorization(TAG_NO_AUTH_REQUIRED)
-                                             .RsaEncryptionKey(1024, 3)
+                                             .RsaEncryptionKey(1024, 65537)
                                              .Padding(PaddingMode::NONE)));
 
     string message(1024 / 8 + 1, 'a');
@@ -2011,7 +2011,7 @@
 TEST_F(EncryptionOperationsTest, RsaNoPaddingTooLarge) {
     ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
                                              .Authorization(TAG_NO_AUTH_REQUIRED)
-                                             .RsaEncryptionKey(1024, 3)
+                                             .RsaEncryptionKey(1024, 65537)
                                              .Padding(PaddingMode::NONE)));
 
     HidlBuf exported;
@@ -2057,7 +2057,7 @@
     size_t key_size = 2048;  // Need largish key for SHA-512 test.
     ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
                                              .Authorization(TAG_NO_AUTH_REQUIRED)
-                                             .RsaEncryptionKey(key_size, 3)
+                                             .RsaEncryptionKey(key_size, 65537)
                                              .Padding(PaddingMode::RSA_OAEP)
                                              .Digest(digests)));
 
@@ -2105,7 +2105,7 @@
 TEST_F(EncryptionOperationsTest, RsaOaepInvalidDigest) {
     ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
                                              .Authorization(TAG_NO_AUTH_REQUIRED)
-                                             .RsaEncryptionKey(1024, 3)
+                                             .RsaEncryptionKey(1024, 65537)
                                              .Padding(PaddingMode::RSA_OAEP)
                                              .Digest(Digest::NONE)));
     string message = "Hello World!";
@@ -2123,7 +2123,7 @@
 TEST_F(EncryptionOperationsTest, RsaOaepDecryptWithWrongDigest) {
     ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
                                              .Authorization(TAG_NO_AUTH_REQUIRED)
-                                             .RsaEncryptionKey(1024, 3)
+                                             .RsaEncryptionKey(1024, 65537)
                                              .Padding(PaddingMode::RSA_OAEP)
                                              .Digest(Digest::SHA_2_256, Digest::SHA_2_224)));
     string message = "Hello World!";
@@ -2149,7 +2149,7 @@
 TEST_F(EncryptionOperationsTest, RsaOaepTooLarge) {
     ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
                                              .Authorization(TAG_NO_AUTH_REQUIRED)
-                                             .RsaEncryptionKey(1024, 3)
+                                             .RsaEncryptionKey(1024, 65537)
                                              .Padding(PaddingMode::RSA_OAEP)
                                              .Digest(Digest::SHA1)));
     constexpr size_t digest_size = 160 /* SHA1 */ / 8;
@@ -2171,7 +2171,7 @@
 TEST_F(EncryptionOperationsTest, RsaPkcs1Success) {
     ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
                                              .Authorization(TAG_NO_AUTH_REQUIRED)
-                                             .RsaEncryptionKey(1024, 3)
+                                             .RsaEncryptionKey(1024, 65537)
                                              .Padding(PaddingMode::RSA_PKCS1_1_5_ENCRYPT)));
 
     string message = "Hello World!";
@@ -2210,7 +2210,7 @@
 TEST_F(EncryptionOperationsTest, RsaPkcs1TooLarge) {
     ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
                                              .Authorization(TAG_NO_AUTH_REQUIRED)
-                                             .RsaEncryptionKey(1024, 3)
+                                             .RsaEncryptionKey(1024, 65537)
                                              .Padding(PaddingMode::RSA_PKCS1_1_5_ENCRYPT)));
     string message(1024 / 8 - 10, 'a');
 
@@ -3229,7 +3229,7 @@
     std::cout << "Hello" << std::endl;
 
     auto auths = AuthorizationSetBuilder()
-                     .TripleDesEncryptionKey(112)
+                     .TripleDesEncryptionKey(168)
                      .BlockMode(BlockMode::ECB)
                      .Padding(PaddingMode::NONE);
 
@@ -3257,7 +3257,7 @@
  */
 TEST_F(EncryptionOperationsTest, TripleDesEcbNotAuthorized) {
     ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
-                                             .TripleDesEncryptionKey(112)
+                                             .TripleDesEncryptionKey(168)
                                              .BlockMode(BlockMode::CBC)
                                              .Padding(PaddingMode::NONE)));
 
@@ -3272,7 +3272,7 @@
  */
 TEST_F(EncryptionOperationsTest, TripleDesEcbPkcs7Padding) {
     ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
-                                             .TripleDesEncryptionKey(112)
+                                             .TripleDesEncryptionKey(168)
                                              .BlockMode(BlockMode::ECB)
                                              .Padding(PaddingMode::PKCS7)));
 
@@ -3294,7 +3294,7 @@
  */
 TEST_F(EncryptionOperationsTest, TripleDesEcbNoPaddingKeyWithPkcs7Padding) {
     ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
-                                             .TripleDesEncryptionKey(112)
+                                             .TripleDesEncryptionKey(168)
                                              .BlockMode(BlockMode::ECB)
                                              .Padding(PaddingMode::NONE)));
     for (size_t i = 0; i < 32; ++i) {
@@ -3311,7 +3311,7 @@
  */
 TEST_F(EncryptionOperationsTest, TripleDesEcbPkcs7PaddingCorrupted) {
     ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
-                                             .TripleDesEncryptionKey(112)
+                                             .TripleDesEncryptionKey(168)
                                              .BlockMode(BlockMode::ECB)
                                              .Padding(PaddingMode::PKCS7)));
 
@@ -3347,49 +3347,6 @@
 // the NIST vectors are multiples of the block size.
 static const TripleDesTestVector kTripleDesTestVectors[] = {
     {
-        "TECBMMT2 Encrypt 0", KeyPurpose::ENCRYPT, BlockMode::ECB, PaddingMode::NONE,
-        "ad192fd064b5579e7a4fb3c8f794f22a",  // key
-        "",                                  // IV
-        "13bad542f3652d67",                  // input
-        "908e543cf2cb254f",                  // output
-    },
-    {
-        "TECBMMT2 Encrypt 0 PKCS7", KeyPurpose::ENCRYPT, BlockMode::ECB, PaddingMode::PKCS7,
-        "ad192fd064b5579e7a4fb3c8f794f22a",  // key
-        "",                                  // IV
-        "13bad542f3652d6700",                // input
-        "908e543cf2cb254fc40165289a89008c",  // output
-    },
-    {
-        "TECBMMT2 Encrypt 0 PKCS7 decrypted", KeyPurpose::DECRYPT, BlockMode::ECB,
-        PaddingMode::PKCS7,
-        "ad192fd064b5579e7a4fb3c8f794f22a",  // key
-        "",                                  // IV
-        "908e543cf2cb254fc40165289a89008c",  // input
-        "13bad542f3652d6700",                // output
-    },
-    {
-        "TECBMMT2 Encrypt 1", KeyPurpose::ENCRYPT, BlockMode::ECB, PaddingMode::NONE,
-        "259df16e7af804fe83b90e9bf7c7e557",  // key
-        "",                                  // IV
-        "a4619c433bbd6787c07c81728f9ac9fa",  // input
-        "9e06de155c483c6bcfd834dbc8bd5830",  // output
-    },
-    {
-        "TECBMMT2 Decrypt 0", KeyPurpose::DECRYPT, BlockMode::ECB, PaddingMode::NONE,
-        "b32ff42092024adf2076b9d3d9f19e6d",  // key
-        "",                                  // IV
-        "2f3f2a49bba807a5",                  // input
-        "2249973fa135fb52",                  // output
-    },
-    {
-        "TECBMMT2 Decrypt 1", KeyPurpose::DECRYPT, BlockMode::ECB, PaddingMode::NONE,
-        "023dfbe6621aa17cc219eae9cdecd923",  // key
-        "",                                  // IV
-        "54045dc71d8d565b227ec19f06fef912",  // input
-        "9b071622181e6412de6066429401410d",  // output
-    },
-    {
         "TECBMMT3 Encrypt 0", KeyPurpose::ENCRYPT, BlockMode::ECB, PaddingMode::NONE,
         "a2b5bc67da13dc92cd9d344aa238544a0e1fa79ef76810cd",  // key
         "",                                                  // IV
@@ -3418,34 +3375,6 @@
         "9b2ae9d998efe62f1b592e7e1df8ff38",                  // output
     },
     {
-        "TCBCMMT2 Encrypt 0", KeyPurpose::ENCRYPT, BlockMode::CBC, PaddingMode::NONE,
-        "34a41a8c293176c1b30732ecfe38ae8a",  // key
-        "f55b4855228bd0b4",                  // IV
-        "7dd880d2a9ab411c",                  // input
-        "c91892948b6cadb4",                  // output
-    },
-    {
-        "TCBCMMT2 Encrypt 1", KeyPurpose::ENCRYPT, BlockMode::CBC, PaddingMode::NONE,
-        "70a88fa1dfb9942fa77f40157ffef2ad",  // key
-        "ece08ce2fdc6ce80",                  // IV
-        "bc225304d5a3a5c9918fc5006cbc40cc",  // input
-        "27f67dc87af7ddb4b68f63fa7c2d454a",  // output
-    },
-    {
-        "TCBCMMT2 Decrypt 0", KeyPurpose::DECRYPT, BlockMode::CBC, PaddingMode::NONE,
-        "4ff47fda89209bda8c85f7fe80192007",  // key
-        "d5bc4891dabe48b9",                  // IV
-        "7e154b28c353adef",                  // input
-        "712b961ea9a1d0af",                  // output
-    },
-    {
-        "TCBCMMT2 Decrypt 1", KeyPurpose::DECRYPT, BlockMode::CBC, PaddingMode::NONE,
-        "464092cdbf736d38fb1fe6a12a94ae0e",  // key
-        "5423455f00023b01",                  // IV
-        "3f6050b74ed64416bc23d53b0469ed7a",  // input
-        "9cbe7d1b5cdd1864c3095ba810575960",  // output
-    },
-    {
         "TCBCMMT3 Encrypt 0", KeyPurpose::ENCRYPT, BlockMode::CBC, PaddingMode::NONE,
         "b5cb1504802326c73df186e3e352a20de643b0d63ee30e37",  // key
         "43f791134c5647ba",                                  // IV
@@ -3512,7 +3441,7 @@
  */
 TEST_F(EncryptionOperationsTest, TripleDesCbcRoundTripSuccess) {
     ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
-                                             .TripleDesEncryptionKey(112)
+                                             .TripleDesEncryptionKey(168)
                                              .BlockMode(BlockMode::CBC)
                                              .Padding(PaddingMode::NONE)));
     // Two-block message.
@@ -3540,7 +3469,7 @@
  */
 TEST_F(EncryptionOperationsTest, TripleDesCallerIv) {
     ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
-                                             .TripleDesEncryptionKey(112)
+                                             .TripleDesEncryptionKey(168)
                                              .BlockMode(BlockMode::CBC)
                                              .Authorization(TAG_CALLER_NONCE)
                                              .Padding(PaddingMode::NONE)));
@@ -3574,7 +3503,7 @@
  */
 TEST_F(EncryptionOperationsTest, TripleDesCallerNonceProhibited) {
     ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
-                                             .TripleDesEncryptionKey(112)
+                                             .TripleDesEncryptionKey(168)
                                              .BlockMode(BlockMode::CBC)
                                              .Padding(PaddingMode::NONE)));
 
@@ -3605,7 +3534,7 @@
  */
 TEST_F(EncryptionOperationsTest, TripleDesCbcNotAuthorized) {
     ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
-                                             .TripleDesEncryptionKey(112)
+                                             .TripleDesEncryptionKey(168)
                                              .BlockMode(BlockMode::ECB)
                                              .Padding(PaddingMode::NONE)));
     // Two-block message.
@@ -3622,7 +3551,7 @@
  */
 TEST_F(EncryptionOperationsTest, TripleDesCbcNoPaddingWrongInputSize) {
     ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
-                                             .TripleDesEncryptionKey(112)
+                                             .TripleDesEncryptionKey(168)
                                              .BlockMode(BlockMode::CBC)
                                              .Padding(PaddingMode::NONE)));
     // Message is slightly shorter than two blocks.
@@ -3643,7 +3572,7 @@
  */
 TEST_F(EncryptionOperationsTest, TripleDesCbcPkcs7Padding) {
     ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
-                                             .TripleDesEncryptionKey(112)
+                                             .TripleDesEncryptionKey(168)
                                              .BlockMode(BlockMode::CBC)
                                              .Padding(PaddingMode::PKCS7)));
 
@@ -3665,7 +3594,7 @@
  */
 TEST_F(EncryptionOperationsTest, TripleDesCbcNoPaddingKeyWithPkcs7Padding) {
     ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
-                                             .TripleDesEncryptionKey(112)
+                                             .TripleDesEncryptionKey(168)
                                              .BlockMode(BlockMode::CBC)
                                              .Padding(PaddingMode::NONE)));
 
@@ -3684,7 +3613,7 @@
  */
 TEST_F(EncryptionOperationsTest, TripleDesCbcPkcs7PaddingCorrupted) {
     ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
-                                             .TripleDesEncryptionKey(112)
+                                             .TripleDesEncryptionKey(168)
                                              .BlockMode(BlockMode::CBC)
                                              .Padding(PaddingMode::PKCS7)));
 
@@ -3714,7 +3643,7 @@
  */
 TEST_F(EncryptionOperationsTest, TripleDesCbcIncrementalNoPadding) {
     ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
-                                             .TripleDesEncryptionKey(112)
+                                             .TripleDesEncryptionKey(168)
                                              .BlockMode(BlockMode::CBC)
                                              .Padding(PaddingMode::NONE)));
 
@@ -3784,7 +3713,7 @@
 TEST_F(MaxOperationsTest, TestLimitRsa) {
     ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
                                              .Authorization(TAG_NO_AUTH_REQUIRED)
-                                             .RsaSigningKey(1024, 3)
+                                             .RsaSigningKey(1024, 65537)
                                              .NoDigestOrPadding()
                                              .Authorization(TAG_MAX_USES_PER_BOOT, 3)));
 
@@ -3840,7 +3769,7 @@
 TEST_F(AttestationTest, RsaAttestation) {
     ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
                                              .Authorization(TAG_NO_AUTH_REQUIRED)
-                                             .RsaSigningKey(1024, 3)
+                                             .RsaSigningKey(1024, 65537)
                                              .Digest(Digest::NONE)
                                              .Padding(PaddingMode::NONE)
                                              .Authorization(TAG_INCLUDE_UNIQUE_ID)));
@@ -3867,7 +3796,7 @@
 TEST_F(AttestationTest, RsaAttestationRequiresAppId) {
     ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
                                              .Authorization(TAG_NO_AUTH_REQUIRED)
-                                             .RsaSigningKey(1024, 3)
+                                             .RsaSigningKey(1024, 65537)
                                              .Digest(Digest::NONE)
                                              .Padding(PaddingMode::NONE)
                                              .Authorization(TAG_INCLUDE_UNIQUE_ID)));
@@ -3978,7 +3907,7 @@
  */
 TEST_F(KeyDeletionTest, DeleteKey) {
     ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
-                                             .RsaSigningKey(1024, 3)
+                                             .RsaSigningKey(1024, 65537)
                                              .Digest(Digest::NONE)
                                              .Padding(PaddingMode::NONE)
                                              .Authorization(TAG_NO_AUTH_REQUIRED)));
@@ -4022,7 +3951,7 @@
 TEST_F(KeyDeletionTest, DeleteInvalidKey) {
     // Generate key just to check if rollback protection is implemented
     ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
-                                             .RsaSigningKey(1024, 3)
+                                             .RsaSigningKey(1024, 65537)
                                              .Digest(Digest::NONE)
                                              .Padding(PaddingMode::NONE)
                                              .Authorization(TAG_NO_AUTH_REQUIRED)));
@@ -4061,7 +3990,7 @@
 TEST_F(KeyDeletionTest, DeleteAllKeys) {
     if (!arm_deleteAllKeys) return;
     ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
-                                             .RsaSigningKey(1024, 3)
+                                             .RsaSigningKey(1024, 65537)
                                              .Digest(Digest::NONE)
                                              .Padding(PaddingMode::NONE)
                                              .Authorization(TAG_NO_AUTH_REQUIRED)));
diff --git a/neuralnetworks/1.1/vts/functional/Android.bp b/neuralnetworks/1.1/vts/functional/Android.bp
index 623b441..947ca2c 100644
--- a/neuralnetworks/1.1/vts/functional/Android.bp
+++ b/neuralnetworks/1.1/vts/functional/Android.bp
@@ -36,4 +36,13 @@
         "libneuralnetworks_generated_test_harness_headers",
         "libneuralnetworks_generated_tests",
     ],
+    // Bug: http://b/74200014 - Disable arm32 asan since it triggers internal
+    // error in ld.gold.
+    arch: {
+        arm: {
+            sanitize: {
+                never: true,
+            },
+        },
+    },
 }
diff --git a/radio/1.0/types.hal b/radio/1.0/types.hal
index 6787a82..ab1834b 100644
--- a/radio/1.0/types.hal
+++ b/radio/1.0/types.hal
@@ -1237,9 +1237,9 @@
 };
 
 struct WcdmaSignalStrength{
-    int32_t signalStrength;               // Valid values are (0-96, 99) as defined in
-                                          // TS 27.007 8.69
-    int32_t bitErrorRate;                 // bit error rate (0-49, 99) as defined in TS 27.007 8.69
+    int32_t signalStrength;               // Valid values are (0-31, 99) as defined in
+                                          // TS 27.007 8.5
+    int32_t bitErrorRate;                 // bit error rate (0-7, 99) as defined in TS 27.007 8.5
 };
 
 struct CdmaSignalStrength {
diff --git a/radio/1.2/types.hal b/radio/1.2/types.hal
index b68895e..5e72b3b 100644
--- a/radio/1.2/types.hal
+++ b/radio/1.2/types.hal
@@ -439,12 +439,12 @@
 struct TdscdmaSignalStrength {
     /**
      * UTRA carrier RSSI as defined in TS 25.225 5.1.4
-     * Valid values are (0-96, 99) as defined in TS 27.007 8.69
+     * Valid values are (0-31, 99) as defined in TS 27.007 8.5
      */
     uint32_t signalStrength;
     /**
      * Transport Channel BER as defined in TS 25.225 5.2.5
-     * Valid values are (0-49, 99) as defined in TS 27.007 8.69
+     * Valid values are (0-7, 99) as defined in TS 27.007 8.5
      */
     uint32_t bitErrorRate;
     /**
diff --git a/radio/1.2/vts/functional/radio_hidl_hal_api.cpp b/radio/1.2/vts/functional/radio_hidl_hal_api.cpp
index 7e4c64d..34a87e1 100644
--- a/radio/1.2/vts/functional/radio_hidl_hal_api.cpp
+++ b/radio/1.2/vts/functional/radio_hidl_hal_api.cpp
@@ -567,3 +567,109 @@
           toString(radioRsp_v1_2->rspInfo.error).c_str());
     ASSERT_TRUE(CheckAnyOfErrors(radioRsp_v1_2->rspInfo.error, {RadioError::NONE}));
 }
+
+/*
+ * Test IRadio.setupDataCall_1_2() for the response returned.
+ */
+TEST_F(RadioHidlTest_v1_2, setupDataCall_1_2) {
+    const int serial = GetRandomSerialNumber();
+
+    V1_2::AccessNetwork accessNetwork = V1_2::AccessNetwork::EUTRAN;
+
+    DataProfileInfo dataProfileInfo;
+    memset(&dataProfileInfo, 0, sizeof(dataProfileInfo));
+    dataProfileInfo.profileId = DataProfileId::IMS;
+    dataProfileInfo.apn = hidl_string("VZWIMS");
+    dataProfileInfo.protocol = hidl_string("IPV4V6");
+    dataProfileInfo.roamingProtocol = hidl_string("IPV6");
+    dataProfileInfo.authType = ApnAuthType::NO_PAP_NO_CHAP;
+    dataProfileInfo.user = "";
+    dataProfileInfo.password = "";
+    dataProfileInfo.type = DataProfileInfoType::THREE_GPP2;
+    dataProfileInfo.maxConnsTime = 300;
+    dataProfileInfo.maxConns = 20;
+    dataProfileInfo.waitTime = 0;
+    dataProfileInfo.enabled = true;
+    dataProfileInfo.supportedApnTypesBitmap = 320;
+    dataProfileInfo.bearerBitmap = 161543;
+    dataProfileInfo.mtu = 0;
+    dataProfileInfo.mvnoType = MvnoType::NONE;
+    dataProfileInfo.mvnoMatchData = hidl_string();
+
+    bool modemCognitive = false;
+    bool roamingAllowed = false;
+    bool isRoaming = false;
+
+    V1_2::DataRequestReason reason = V1_2::DataRequestReason::NORMAL;
+    std::vector<hidl_string> addresses = {""};
+    std::vector<hidl_string> dnses = {""};
+
+    Return<void> res = radio_v1_2->setupDataCall_1_2(serial, accessNetwork, dataProfileInfo,
+                                                     modemCognitive, roamingAllowed, isRoaming,
+                                                     reason, addresses, dnses);
+    ASSERT_OK(res);
+
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_2->rspInfo.type);
+    EXPECT_EQ(serial, radioRsp_v1_2->rspInfo.serial);
+
+    if (cardStatus.cardState == CardState::ABSENT) {
+        ASSERT_TRUE(CheckAnyOfErrors(
+            radioRsp_v1_2->rspInfo.error,
+            {RadioError::SIM_ABSENT, RadioError::RADIO_NOT_AVAILABLE, RadioError::INVALID_ARGUMENTS,
+             RadioError::OP_NOT_ALLOWED_BEFORE_REG_TO_NW, RadioError::REQUEST_NOT_SUPPORTED}));
+    } else if (cardStatus.cardState == CardState::PRESENT) {
+        ASSERT_TRUE(CheckAnyOfErrors(
+            radioRsp_v1_2->rspInfo.error,
+            {RadioError::NONE, RadioError::RADIO_NOT_AVAILABLE, RadioError::INVALID_ARGUMENTS,
+             RadioError::OP_NOT_ALLOWED_BEFORE_REG_TO_NW, RadioError::REQUEST_NOT_SUPPORTED}));
+    }
+}
+
+/*
+ * Test IRadio.deactivateDataCall_1_2() for the response returned.
+ */
+TEST_F(RadioHidlTest_v1_2, deactivateDataCall_1_2) {
+    const int serial = GetRandomSerialNumber();
+    int cid = 1;
+    V1_2::DataRequestReason reason = V1_2::DataRequestReason::NORMAL;
+
+    Return<void> res = radio_v1_2->deactivateDataCall_1_2(serial, cid, reason);
+    ASSERT_OK(res);
+
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_2->rspInfo.type);
+    EXPECT_EQ(serial, radioRsp_v1_2->rspInfo.serial);
+
+    if (cardStatus.cardState == CardState::ABSENT) {
+        ASSERT_TRUE(CheckAnyOfErrors(
+            radioRsp_v1_2->rspInfo.error,
+            {RadioError::NONE, RadioError::RADIO_NOT_AVAILABLE, RadioError::INVALID_CALL_ID,
+             RadioError::INVALID_STATE, RadioError::INVALID_ARGUMENTS,
+             RadioError::REQUEST_NOT_SUPPORTED, RadioError::CANCELLED, RadioError::SIM_ABSENT}));
+    } else if (cardStatus.cardState == CardState::PRESENT) {
+        ASSERT_TRUE(CheckAnyOfErrors(
+            radioRsp_v1_2->rspInfo.error,
+            {RadioError::NONE, RadioError::RADIO_NOT_AVAILABLE, RadioError::INVALID_CALL_ID,
+             RadioError::INVALID_STATE, RadioError::INVALID_ARGUMENTS,
+             RadioError::REQUEST_NOT_SUPPORTED, RadioError::CANCELLED}));
+    }
+}
+
+/*
+ * Test IRadio.getCellInfoList() for the response returned.
+ */
+TEST_F(RadioHidlTest_v1_2, getCellInfoList_1_2) {
+    int serial = GetRandomSerialNumber();
+
+    Return<void> res = radio_v1_2->getCellInfoList(serial);
+    ASSERT_OK(res);
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_2->rspInfo.type);
+    EXPECT_EQ(serial, radioRsp_v1_2->rspInfo.serial);
+
+    ALOGI("getCellInfoList_1_2, rspInfo.error = %s\n",
+          toString(radioRsp_v1_2->rspInfo.error).c_str());
+    ASSERT_TRUE(CheckAnyOfErrors(radioRsp_v1_2->rspInfo.error,
+                                 {RadioError::NONE, RadioError::NO_NETWORK_FOUND}));
+}
diff --git a/radio/1.2/vts/functional/radio_hidl_hal_utils_v1_2.h b/radio/1.2/vts/functional/radio_hidl_hal_utils_v1_2.h
index f9919a2..66d8ca4 100644
--- a/radio/1.2/vts/functional/radio_hidl_hal_utils_v1_2.h
+++ b/radio/1.2/vts/functional/radio_hidl_hal_utils_v1_2.h
@@ -405,6 +405,18 @@
     Return<void> setSignalStrengthReportingCriteriaResponse(const RadioResponseInfo& info);
 
     Return<void> setLinkCapacityReportingCriteriaResponse(const RadioResponseInfo& info);
+
+    Return<void> getIccCardStatusResponse_1_2(const RadioResponseInfo& info,
+                                              const CardStatus& card_status);
+
+    Return<void> getCurrentCallsResponse_1_2(const RadioResponseInfo& info,
+                                             const ::android::hardware::hidl_vec<Call>& calls);
+
+    Return<void> getSignalStrengthResponse_1_2(const RadioResponseInfo& info,
+                                               const SignalStrength& sig_strength);
+
+    Return<void> getCellInfoListResponse_1_2(
+        const RadioResponseInfo& info, const ::android::hardware::hidl_vec<CellInfo>& cellInfo);
 };
 
 /* Callback class for radio indication */
diff --git a/radio/1.2/vts/functional/radio_response.cpp b/radio/1.2/vts/functional/radio_response.cpp
index 3079b9e..d96f76b 100644
--- a/radio/1.2/vts/functional/radio_response.cpp
+++ b/radio/1.2/vts/functional/radio_response.cpp
@@ -21,11 +21,8 @@
 RadioResponse_v1_2::RadioResponse_v1_2(RadioHidlTest_v1_2& parent) : parent_v1_2(parent) {}
 
 /* 1.0 Apis */
-Return<void> RadioResponse_v1_2::getIccCardStatusResponse(const RadioResponseInfo& info,
-                                                          const CardStatus& card_status) {
-    rspInfo = info;
-    cardStatus = card_status;
-    parent_v1_2.notify();
+Return<void> RadioResponse_v1_2::getIccCardStatusResponse(const RadioResponseInfo& /*info*/,
+                                                          const CardStatus& /*card_status*/) {
     return Void();
 }
 
@@ -150,8 +147,10 @@
     return Void();
 }
 
-Return<void> RadioResponse_v1_2::setupDataCallResponse(const RadioResponseInfo& /*info*/,
+Return<void> RadioResponse_v1_2::setupDataCallResponse(const RadioResponseInfo& info,
                                                        const SetupDataCallResult& /*dcResponse*/) {
+    rspInfo = info;
+    parent_v1_2.notify();
     return Void();
 }
 
@@ -205,7 +204,9 @@
     return Void();
 }
 
-Return<void> RadioResponse_v1_2::deactivateDataCallResponse(const RadioResponseInfo& /*info*/) {
+Return<void> RadioResponse_v1_2::deactivateDataCallResponse(const RadioResponseInfo& info) {
+    rspInfo = info;
+    parent_v1_2.notify();
     return Void();
 }
 
@@ -702,3 +703,32 @@
     parent_v1_2.notify();
     return Void();
 }
+
+Return<void> RadioResponse_v1_2::getIccCardStatusResponse_1_2(const RadioResponseInfo& info,
+                                                              const CardStatus& card_status) {
+    rspInfo = info;
+    cardStatus = card_status;
+    parent_v1_2.notify();
+    return Void();
+}
+
+Return<void> RadioResponse_v1_2::getCurrentCallsResponse_1_2(
+    const RadioResponseInfo& info, const ::android::hardware::hidl_vec<Call>& /*calls*/) {
+    rspInfo = info;
+    parent_v1_2.notify();
+    return Void();
+}
+
+Return<void> RadioResponse_v1_2::getSignalStrengthResponse_1_2(
+    const RadioResponseInfo& info, const SignalStrength& /*sig_strength*/) {
+    rspInfo = info;
+    parent_v1_2.notify();
+    return Void();
+}
+
+Return<void> RadioResponse_v1_2::getCellInfoListResponse_1_2(
+    const RadioResponseInfo& info, const ::android::hardware::hidl_vec<CellInfo>& /*cellInfo*/) {
+    rspInfo = info;
+    parent_v1_2.notify();
+    return Void();
+}
\ No newline at end of file
diff --git a/vibrator/1.2/vts/functional/VtsHalVibratorV1_2TargetTest.cpp b/vibrator/1.2/vts/functional/VtsHalVibratorV1_2TargetTest.cpp
index d8df18b..3ed689a 100644
--- a/vibrator/1.2/vts/functional/VtsHalVibratorV1_2TargetTest.cpp
+++ b/vibrator/1.2/vts/functional/VtsHalVibratorV1_2TargetTest.cpp
@@ -33,6 +33,8 @@
 using ::android::hardware::Void;
 using ::android::sp;
 
+#define EXPECT_OK(ret) ASSERT_TRUE((ret).isOk())
+
 // Test environment for Vibrator HIDL HAL.
 class VibratorHidlEnvironment : public ::testing::VtsHalHidlTargetTestEnvBase {
    public:
@@ -65,22 +67,70 @@
 static void validatePerformEffect(Status status, uint32_t lengthMs) {
     ASSERT_TRUE(status == Status::OK || status == Status::UNSUPPORTED_OPERATION);
     if (status == Status::OK) {
-        ASSERT_GT(lengthMs, static_cast<uint32_t>(0))
-            << "Effects that return OK must return a non-zero duration";
+        ASSERT_LT(static_cast<uint32_t>(0), lengthMs)
+            << "Effects that return OK must return a positive duration";
     } else {
-        ASSERT_EQ(lengthMs, static_cast<uint32_t>(0))
+        ASSERT_EQ(static_cast<uint32_t>(0), lengthMs)
             << "Effects that return UNSUPPORTED_OPERATION must have a duration of zero";
     }
 }
 
+static void validatePerformEffectBadInput(Status status, uint32_t lengthMs) {
+    ASSERT_EQ(Status::UNSUPPORTED_OPERATION, status);
+    ASSERT_EQ(static_cast<uint32_t>(0), lengthMs)
+        << "Effects that return UNSUPPORTED_OPERATION must have a duration of zero";
+}
+
+/*
+ * Test to make sure effects within the valid range return are either supported and return OK with
+ * a valid duration, or are unsupported and return UNSUPPORTED_OPERATION with a duration of 0.
+ */
 TEST_F(VibratorHidlTest_1_2, PerformEffect_1_2) {
     for (const auto& effect : hidl_enum_iterator<Effect>()) {
         for (const auto& strength : hidl_enum_iterator<EffectStrength>()) {
-            vibrator->perform_1_2(effect, strength, validatePerformEffect);
+            EXPECT_OK(vibrator->perform_1_2(effect, strength, validatePerformEffect));
         }
     }
 }
 
+/*
+ * Test to make sure effect values above the valid range are rejected.
+ */
+TEST_F(VibratorHidlTest_1_2, PerformEffect_1_2_BadEffects_AboveValidRange) {
+    Effect effect = *std::prev(hidl_enum_iterator<Effect>().end());
+    Effect badEffect = static_cast<Effect>(static_cast<int32_t>(effect) + 1);
+    EXPECT_OK(
+        vibrator->perform_1_2(badEffect, EffectStrength::LIGHT, validatePerformEffectBadInput));
+}
+
+/*
+ * Test to make sure effect values below the valid range are rejected.
+ */
+TEST_F(VibratorHidlTest_1_2, PerformEffect_1_2_BadEffects_BelowValidRange) {
+    Effect effect = *hidl_enum_iterator<Effect>().begin();
+    Effect badEffect = static_cast<Effect>(static_cast<int32_t>(effect) - 1);
+    EXPECT_OK(
+        vibrator->perform_1_2(badEffect, EffectStrength::LIGHT, validatePerformEffectBadInput));
+}
+
+/*
+ * Test to make sure strength values above the valid range are rejected.
+ */
+TEST_F(VibratorHidlTest_1_2, PerformEffect_1_2_BadStrength_AboveValidRange) {
+    EffectStrength strength = *std::prev(hidl_enum_iterator<EffectStrength>().end());
+    EffectStrength badStrength = static_cast<EffectStrength>(static_cast<int32_t>(strength) + 1);
+    EXPECT_OK(vibrator->perform_1_2(Effect::THUD, badStrength, validatePerformEffectBadInput));
+}
+
+/*
+ * Test to make sure strength values below the valid range are rejected.
+ */
+TEST_F(VibratorHidlTest_1_2, PerformEffect_1_2_BadStrength_BelowValidRange) {
+    EffectStrength strength = *hidl_enum_iterator<EffectStrength>().begin();
+    EffectStrength badStrength = static_cast<EffectStrength>(static_cast<int32_t>(strength) - 1);
+    EXPECT_OK(vibrator->perform_1_2(Effect::THUD, badStrength, validatePerformEffectBadInput));
+}
+
 int main(int argc, char** argv) {
     ::testing::AddGlobalTestEnvironment(VibratorHidlEnvironment::Instance());
     ::testing::InitGoogleTest(&argc, argv);
diff --git a/wifi/1.2/Android.bp b/wifi/1.2/Android.bp
index f41324e..c144f22 100644
--- a/wifi/1.2/Android.bp
+++ b/wifi/1.2/Android.bp
@@ -13,6 +13,7 @@
         "IWifiChipEventCallback.hal",
         "IWifiNanIface.hal",
         "IWifiNanIfaceEventCallback.hal",
+        "IWifiStaIface.hal",
     ],
     interfaces: [
         "android.hardware.wifi@1.0",
diff --git a/wifi/1.2/IWifiStaIface.hal b/wifi/1.2/IWifiStaIface.hal
new file mode 100644
index 0000000..be4e537
--- /dev/null
+++ b/wifi/1.2/IWifiStaIface.hal
@@ -0,0 +1,54 @@
+/*
+ * 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.2;
+
+import @1.0::WifiStatus;
+import @1.0::IWifiStaIface;
+
+/**
+ * Interface used to represent a single STA iface.
+ *
+ * IWifiChip.createStaIface() may return a @1.2::IWifiStaIface when supported.
+ */
+interface IWifiStaIface extends @1.0::IWifiStaIface {
+    /**
+     * Fetches a consistent snapshot of the entire APF program and working
+     * memory buffer and returns it to the host. The returned buffer contains
+     * both code and data. Its length must match the most recently returned
+     * |StaApfPacketFilterCapabilities.maxLength|.
+     *
+     * While the snapshot is being fetched, the APF intepreter must not execute
+     * and all incoming packets must be passed to the host as if there was no
+     * APF program installed.
+     *
+     * Must fail with |WifiStatusCode.ERROR_NOT_SUPPORTED| if
+     * |StaIfaceCapabilityMask.APF| is not set.
+     *
+     * @return status WifiStatus of the operation.
+     *         Possible status codes:
+     *         |WifiStatusCode.SUCCESS|,
+     *         |WifiStatusCode.ERROR_WIFI_IFACE_INVALID|,
+     *         |WifiStatusCode.ERROR_NOT_SUPPORTED|,
+     *         |WifiStatusCode.ERROR_NOT_AVAILABLE|,
+     *         |WifiStatusCode.ERROR_UNKNOWN|
+     * @return data The entire APF working memory buffer when status is
+     *         |WifiStatusCode.SUCCESS|, empty otherwise.
+     * @see getApfPacketFilterCapabilities()
+     * @see installApfPacketFilter()
+     */
+    readApfPacketFilterData() generates (WifiStatus status, vec<uint8_t> data);
+};
diff --git a/wifi/1.2/default/tests/mock_wifi_legacy_hal.h b/wifi/1.2/default/tests/mock_wifi_legacy_hal.h
index 8e1696e..43370b4 100644
--- a/wifi/1.2/default/tests/mock_wifi_legacy_hal.h
+++ b/wifi/1.2/default/tests/mock_wifi_legacy_hal.h
@@ -36,6 +36,9 @@
     MOCK_METHOD2(stop, wifi_error(std::unique_lock<std::recursive_mutex>*,
                                   const std::function<void()>&));
     MOCK_METHOD2(setDfsFlag, wifi_error(const std::string&, bool));
+    MOCK_METHOD2(registerRadioModeChangeCallbackHandler,
+                 wifi_error(const std::string&,
+                            const on_radio_mode_change_callback&));
     MOCK_METHOD2(nanRegisterCallbackHandlers,
                  wifi_error(const std::string&, const NanCallbackHandlers&));
     MOCK_METHOD2(nanDisableRequest,
diff --git a/wifi/1.2/default/tests/wifi_chip_unit_tests.cpp b/wifi/1.2/default/tests/wifi_chip_unit_tests.cpp
index 1b082d0..27c8d60 100644
--- a/wifi/1.2/default/tests/wifi_chip_unit_tests.cpp
+++ b/wifi/1.2/default/tests/wifi_chip_unit_tests.cpp
@@ -395,10 +395,10 @@
     ASSERT_FALSE(createIface(IfaceType::AP).empty());
 }
 
-TEST_F(WifiChipV2_AwareIfaceCombinationTest, CreateStaSta_ShouldSucceed) {
+TEST_F(WifiChipV2_AwareIfaceCombinationTest, CreateStaSta_ShouldFail) {
     findModeAndConfigureForIfaceType(IfaceType::AP);
     ASSERT_FALSE(createIface(IfaceType::STA).empty());
-    ASSERT_FALSE(createIface(IfaceType::STA).empty());
+    ASSERT_TRUE(createIface(IfaceType::STA).empty());
 }
 
 TEST_F(WifiChipV2_AwareIfaceCombinationTest, CreateStaAp_ShouldSucceed) {
@@ -407,35 +407,18 @@
     ASSERT_FALSE(createIface(IfaceType::STA).empty());
 }
 
-TEST_F(WifiChipV2_AwareIfaceCombinationTest, CreateStaStaAp_ShouldFail) {
-    findModeAndConfigureForIfaceType(IfaceType::AP);
-    ASSERT_FALSE(createIface(IfaceType::STA).empty());
-    ASSERT_FALSE(createIface(IfaceType::STA).empty());
-    ASSERT_TRUE(createIface(IfaceType::AP).empty());
-}
-
 TEST_F(WifiChipV2_AwareIfaceCombinationTest,
-       CreateStaAp_AfterStaRemove_ShouldSucceed) {
+       CreateSta_AfterStaApRemove_ShouldSucceed) {
     findModeAndConfigureForIfaceType(IfaceType::STA);
-    ASSERT_FALSE(createIface(IfaceType::STA).empty());
     const auto sta_iface_name = createIface(IfaceType::STA);
     ASSERT_FALSE(sta_iface_name.empty());
-    ASSERT_TRUE(createIface(IfaceType::AP).empty());
-
-    // After removing STA iface, AP iface creation should succeed.
-    removeIface(IfaceType::STA, sta_iface_name);
-    ASSERT_FALSE(createIface(IfaceType::AP).empty());
-}
-
-TEST_F(WifiChipV2_AwareIfaceCombinationTest,
-       CreateStaSta_AfterApRemove_ShouldSucceed) {
-    findModeAndConfigureForIfaceType(IfaceType::STA);
-    ASSERT_FALSE(createIface(IfaceType::STA).empty());
     const auto ap_iface_name = createIface(IfaceType::AP);
     ASSERT_FALSE(ap_iface_name.empty());
+
     ASSERT_TRUE(createIface(IfaceType::STA).empty());
 
-    // After removing AP  iface, STA iface creation should succeed.
+    // After removing AP & STA iface, STA iface creation should succeed.
+    removeIface(IfaceType::STA, sta_iface_name);
     removeIface(IfaceType::AP, ap_iface_name);
     ASSERT_FALSE(createIface(IfaceType::STA).empty());
 }
@@ -524,16 +507,6 @@
 }
 
 TEST_F(WifiChipV2_AwareIfaceCombinationTest,
-       CreateStaSta_EnsureDifferentIfaceNames) {
-    findModeAndConfigureForIfaceType(IfaceType::AP);
-    const auto sta1_iface_name = createIface(IfaceType::STA);
-    const auto sta2_iface_name = createIface(IfaceType::STA);
-    ASSERT_FALSE(sta1_iface_name.empty());
-    ASSERT_FALSE(sta2_iface_name.empty());
-    ASSERT_NE(sta1_iface_name, sta2_iface_name);
-}
-
-TEST_F(WifiChipV2_AwareIfaceCombinationTest,
        CreateStaAp_EnsureDifferentIfaceNames) {
     findModeAndConfigureForIfaceType(IfaceType::AP);
     const auto sta_iface_name = createIface(IfaceType::STA);
diff --git a/wifi/1.2/default/wifi_chip.cpp b/wifi/1.2/default/wifi_chip.cpp
index 201b8e4..dcd0a3c 100644
--- a/wifi/1.2/default/wifi_chip.cpp
+++ b/wifi/1.2/default/wifi_chip.cpp
@@ -1171,7 +1171,7 @@
     // (conditional on isDualInterfaceSupported()):
     //    Interface Combination 1: Will support 1 STA and 1 P2P or NAN(optional)
     //                             concurrent iface operations.
-    //    Interface Combination 2: Will support 1 STA and 1 STA or AP concurrent
+    //    Interface Combination 2: Will support 1 STA and 1 AP concurrent
     //                             iface operations.
     // If Aware is enabled (conditional on isAwareSupported()), the iface
     // combination will be modified to support either P2P or NAN in place of
@@ -1181,8 +1181,7 @@
         const IWifiChip::ChipIfaceCombinationLimit
             chip_iface_combination_limit_1 = {{IfaceType::STA}, 1};
         const IWifiChip::ChipIfaceCombinationLimit
-            chip_iface_combination_limit_2 = {{IfaceType::STA, IfaceType::AP},
-                                              1};
+            chip_iface_combination_limit_2 = {{IfaceType::AP}, 1};
         IWifiChip::ChipIfaceCombinationLimit chip_iface_combination_limit_3;
         if (feature_flags_.lock()->isAwareSupported()) {
             chip_iface_combination_limit_3 = {{IfaceType::P2P, IfaceType::NAN},
diff --git a/wifi/1.2/default/wifi_legacy_hal.cpp b/wifi/1.2/default/wifi_legacy_hal.cpp
index 5f40d50..84af9c4 100644
--- a/wifi/1.2/default/wifi_legacy_hal.cpp
+++ b/wifi/1.2/default/wifi_legacy_hal.cpp
@@ -360,12 +360,18 @@
         LOG(DEBUG) << "Legacy HAL already started";
         return WIFI_SUCCESS;
     }
+    LOG(DEBUG) << "Waiting for the driver ready";
+    wifi_error status = global_func_table_.wifi_wait_for_driver_ready();
+    if (status == WIFI_ERROR_TIMED_OUT) {
+        LOG(ERROR) << "Timed out awaiting driver ready";
+        return status;
+    }
     LOG(DEBUG) << "Starting legacy HAL";
     if (!iface_tool_.SetWifiUpState(true)) {
         LOG(ERROR) << "Failed to set WiFi interface up";
         return WIFI_ERROR_UNKNOWN;
     }
-    wifi_error status = global_func_table_.wifi_initialize(&global_handle_);
+    status = global_func_table_.wifi_initialize(&global_handle_);
     if (status != WIFI_SUCCESS || !global_handle_) {
         LOG(ERROR) << "Failed to retrieve global handle";
         return status;
diff --git a/wifi/1.2/default/wifi_legacy_hal.h b/wifi/1.2/default/wifi_legacy_hal.h
index bd68bcd..dedbbf8 100644
--- a/wifi/1.2/default/wifi_legacy_hal.h
+++ b/wifi/1.2/default/wifi_legacy_hal.h
@@ -274,7 +274,7 @@
     wifi_error deregisterErrorAlertCallbackHandler(
         const std::string& iface_name);
     // Radio mode functions.
-    wifi_error registerRadioModeChangeCallbackHandler(
+    virtual wifi_error registerRadioModeChangeCallbackHandler(
         const std::string& iface_name,
         const on_radio_mode_change_callback& on_user_change_callback);
     // RTT functions.
diff --git a/wifi/1.2/default/wifi_legacy_hal_stubs.cpp b/wifi/1.2/default/wifi_legacy_hal_stubs.cpp
index 2ee2aa2..24aaf15 100644
--- a/wifi/1.2/default/wifi_legacy_hal_stubs.cpp
+++ b/wifi/1.2/default/wifi_legacy_hal_stubs.cpp
@@ -45,6 +45,7 @@
         return false;
     }
     populateStubFor(&hal_fn->wifi_initialize);
+    populateStubFor(&hal_fn->wifi_wait_for_driver_ready);
     populateStubFor(&hal_fn->wifi_cleanup);
     populateStubFor(&hal_fn->wifi_event_loop);
     populateStubFor(&hal_fn->wifi_get_error_info);
diff --git a/wifi/1.2/vts/OWNERS b/wifi/1.2/vts/OWNERS
new file mode 100644
index 0000000..811c857
--- /dev/null
+++ b/wifi/1.2/vts/OWNERS
@@ -0,0 +1,4 @@
+rpius@google.com
+quiche@google.com
+arabawy@google.com
+yim@google.com
\ No newline at end of file
diff --git a/wifi/1.2/vts/functional/Android.bp b/wifi/1.2/vts/functional/Android.bp
new file mode 100644
index 0000000..d85d42e
--- /dev/null
+++ b/wifi/1.2/vts/functional/Android.bp
@@ -0,0 +1,30 @@
+//
+// 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.
+//
+
+cc_test {
+    name: "VtsHalWifiV1_2TargetTest",
+    defaults: ["VtsHalTargetTestDefaults"],
+    srcs: [
+        "VtsHalWifiV1_2TargetTest.cpp",
+        "wifi_chip_hidl_test.cpp",
+    ],
+    static_libs: [
+        "VtsHalWifiV1_0TargetTestUtil",
+        "android.hardware.wifi@1.0",
+        "android.hardware.wifi@1.1",
+        "android.hardware.wifi@1.2",
+    ],
+}
diff --git a/wifi/1.2/vts/functional/VtsHalWifiV1_2TargetTest.cpp b/wifi/1.2/vts/functional/VtsHalWifiV1_2TargetTest.cpp
new file mode 100644
index 0000000..cfad208
--- /dev/null
+++ b/wifi/1.2/vts/functional/VtsHalWifiV1_2TargetTest.cpp
@@ -0,0 +1,50 @@
+/*
+ * 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.
+ */
+
+#include <android-base/logging.h>
+#include <android/hardware/wifi/1.2/IWifi.h>
+
+#include <VtsHalHidlTargetTestEnvBase.h>
+
+#include "wifi_hidl_test_utils.h"
+
+using ::android::hardware::wifi::V1_2::IWifi;
+
+// Test environment for Wifi HIDL HAL.
+class WifiHidlEnvironment_1_2 : public ::testing::VtsHalHidlTargetTestEnvBase {
+   public:
+    // get the test environment singleton
+    static WifiHidlEnvironment_1_2* Instance() {
+        static WifiHidlEnvironment_1_2* instance = new WifiHidlEnvironment_1_2;
+        return instance;
+    }
+
+    virtual void registerTestServices() override { registerTestService<IWifi>(); }
+
+   private:
+    WifiHidlEnvironment_1_2() {}
+};
+
+WifiHidlEnvironment_1_2* gEnv = WifiHidlEnvironment_1_2::Instance();
+
+int main(int argc, char** argv) {
+  ::testing::AddGlobalTestEnvironment(gEnv);
+  ::testing::InitGoogleTest(&argc, argv);
+  gEnv->init(&argc, argv);
+  int status = RUN_ALL_TESTS();
+  LOG(INFO) << "Test result = " << status;
+  return status;
+}
diff --git a/wifi/1.2/vts/functional/wifi_chip_hidl_test.cpp b/wifi/1.2/vts/functional/wifi_chip_hidl_test.cpp
new file mode 100644
index 0000000..a5457b7
--- /dev/null
+++ b/wifi/1.2/vts/functional/wifi_chip_hidl_test.cpp
@@ -0,0 +1,162 @@
+/*
+ * 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.
+ */
+
+#include <android-base/logging.h>
+
+#include <android/hardware/wifi/1.2/IWifiChip.h>
+#include <android/hardware/wifi/1.2/IWifiChipEventCallback.h>
+
+#include <VtsHalHidlTargetCallbackBase.h>
+#include <VtsHalHidlTargetTestBase.h>
+
+#include "wifi_hidl_call_util.h"
+#include "wifi_hidl_test_utils.h"
+
+using ::android::hardware::hidl_string;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::Return;
+using ::android::hardware::wifi::V1_0::ChipModeId;
+using ::android::hardware::wifi::V1_0::IfaceType;
+using ::android::hardware::wifi::V1_0::WifiStatus;
+using ::android::hardware::wifi::V1_0::WifiDebugRingBufferStatus;
+using ::android::hardware::wifi::V1_0::WifiStatusCode;
+using ::android::hardware::wifi::V1_2::IWifiChip;
+using ::android::hardware::wifi::V1_2::IWifiChipEventCallback;
+using ::android::hardware::Void;
+using ::android::sp;
+
+namespace {
+constexpr IWifiChip::TxPowerScenario kPowerScenarioBody =
+    IWifiChip::TxPowerScenario::ON_BODY_CELL_OFF;
+
+constexpr IWifiChip::TxPowerScenario kPowerScenarioVoiceCall =
+    IWifiChip::TxPowerScenario::VOICE_CALL;
+};  // namespace
+
+/**
+ * Fixture to use for all Wifi chip HIDL interface tests.
+ */
+class WifiChipHidlTest : public ::testing::VtsHalHidlTargetTestBase {
+ public:
+  virtual void SetUp() override {
+    wifi_chip_ = IWifiChip::castFrom(getWifiChip());
+    ASSERT_NE(nullptr, wifi_chip_.get());
+  }
+
+  virtual void TearDown() override { stopWifi(); }
+
+  // A simple test implementation of WifiChipEventCallback.
+  class WifiChipEventCallback
+      : public ::testing::VtsHalHidlTargetCallbackBase<WifiChipHidlTest>,
+        public IWifiChipEventCallback {
+
+   public:
+    WifiChipEventCallback() {};
+
+    virtual ~WifiChipEventCallback() = default;
+
+    Return<void> onChipReconfigured(uint32_t modeId __unused) {
+      return Void();
+    };
+
+    Return<void> onChipReconfigureFailure(const WifiStatus& status __unused) {
+      return Void();
+    };
+
+    Return<void> onIfaceAdded(IfaceType type __unused, const hidl_string& name __unused) {
+      return Void();
+    };
+
+    Return<void> onIfaceRemoved(IfaceType type __unused, const hidl_string& name __unused) {
+      return Void();
+    };
+
+    Return<void> onDebugRingBufferDataAvailable(const WifiDebugRingBufferStatus& status __unused,
+        const hidl_vec<uint8_t>& data __unused) {
+      return Void();
+    };
+
+    Return<void> onDebugErrorAlert(int32_t errorCode __unused,
+        const hidl_vec<uint8_t>& debugData __unused) {
+      return Void();
+    };
+
+    Return<void> onRadioModeChange(const hidl_vec<RadioModeInfo>& radioModeInfos __unused) {
+      return Void();
+    };
+  };
+
+ protected:
+  uint32_t configureChipForStaIfaceAndGetCapabilities() {
+    ChipModeId mode_id;
+    EXPECT_TRUE(
+        configureChipToSupportIfaceType(wifi_chip_, IfaceType::STA, &mode_id));
+    const auto& status_and_caps = HIDL_INVOKE(wifi_chip_, getCapabilities);
+    EXPECT_EQ(WifiStatusCode::SUCCESS, status_and_caps.first.code);
+    return status_and_caps.second;
+  }
+
+  sp<IWifiChip> wifi_chip_;
+};
+
+/*
+ * SelectTxPowerScenario_1_2_body
+ * This test case tests the selectTxPowerScenario_1_2() API with SAR scenarios
+ * newly defined in 1.2
+ */
+TEST_F(WifiChipHidlTest, SelectTxPowerScenario_1_2_body) {
+  uint32_t caps = configureChipForStaIfaceAndGetCapabilities();
+  const auto& status =
+      HIDL_INVOKE(wifi_chip_, selectTxPowerScenario_1_2, kPowerScenarioBody);
+  if (caps & (IWifiChip::ChipCapabilityMask::SET_TX_POWER_LIMIT |
+              IWifiChip::ChipCapabilityMask::USE_BODY_HEAD_SAR)) {
+    EXPECT_EQ(WifiStatusCode::SUCCESS, status.code);
+  } else {
+    EXPECT_EQ(WifiStatusCode::ERROR_NOT_SUPPORTED, status.code);
+  }
+}
+
+/*
+ * SelectTxPowerScenario_1_2_voiceCall
+ * This test case tests the selectTxPowerScenario_1_2() API with previously
+ * defined SAR scenarios
+ */
+TEST_F(WifiChipHidlTest, SelectTxPowerScenario_1_2_voiceCall) {
+  uint32_t caps = configureChipForStaIfaceAndGetCapabilities();
+  const auto& status =
+      HIDL_INVOKE(wifi_chip_, selectTxPowerScenario_1_2, kPowerScenarioVoiceCall);
+  if (caps & (IWifiChip::ChipCapabilityMask::SET_TX_POWER_LIMIT)) {
+    EXPECT_EQ(WifiStatusCode::SUCCESS, status.code);
+  } else {
+    EXPECT_EQ(WifiStatusCode::ERROR_NOT_SUPPORTED, status.code);
+  }
+}
+
+/*
+ * registerEventCallback_1_2
+ * This test case tests the registerEventCallback_1_2() API which registers
+ * a call back function with the hal implementation
+ *
+ * Note: it is not feasible to test the invocation of the call back function
+ * since event is triggered internally in the HAL implementation, and can not be
+ * triggered from the test case
+ */
+TEST_F(WifiChipHidlTest, registerEventCallback_1_2) {
+    sp<WifiChipEventCallback> wifiChipEventCallback = new WifiChipEventCallback();
+    const auto& status =
+        HIDL_INVOKE(wifi_chip_, registerEventCallback_1_2, wifiChipEventCallback);
+    EXPECT_EQ(WifiStatusCode::SUCCESS, status.code);
+}
diff --git a/wifi/hostapd/1.0/vts/functional/hostapd_hidl_test.cpp b/wifi/hostapd/1.0/vts/functional/hostapd_hidl_test.cpp
index 5f51cfb..504f4c8 100644
--- a/wifi/hostapd/1.0/vts/functional/hostapd_hidl_test.cpp
+++ b/wifi/hostapd/1.0/vts/functional/hostapd_hidl_test.cpp
@@ -220,3 +220,11 @@
                     getInvalidPskNwParams());
     EXPECT_NE(HostapdStatusCode::SUCCESS, status.code);
 }
+
+/*
+ * Terminate
+ * This terminates the service.
+ */
+TEST_F(HostapdHidlTest, Terminate) {
+    hostapd_->terminate();
+}
diff --git a/wifi/supplicant/1.1/vts/functional/supplicant_hidl_test.cpp b/wifi/supplicant/1.1/vts/functional/supplicant_hidl_test.cpp
index c29fd0a..7e773d6 100644
--- a/wifi/supplicant/1.1/vts/functional/supplicant_hidl_test.cpp
+++ b/wifi/supplicant/1.1/vts/functional/supplicant_hidl_test.cpp
@@ -137,3 +137,11 @@
             EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
         });
 }
+
+/*
+ * Terminate
+ * This terminates the service.
+ */
+TEST_F(SupplicantHidlTest, Terminate) {
+    supplicant_->terminate();
+}