Merge "Add the new RIL requests to start/stop network scan"
diff --git a/audio/2.0/default/Device.cpp b/audio/2.0/default/Device.cpp
index da79238..280d320 100644
--- a/audio/2.0/default/Device.cpp
+++ b/audio/2.0/default/Device.cpp
@@ -1,18 +1,18 @@
- /*
- * 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.
- */
+/*
+* 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 "DeviceHAL"
 //#define LOG_NDEBUG 0
@@ -30,6 +30,7 @@
 #include "HidlUtils.h"
 #include "StreamIn.h"
 #include "StreamOut.h"
+#include "Util.h"
 
 namespace android {
 namespace hardware {
@@ -92,7 +93,8 @@
 
 Device::~Device() {
     int status = audio_hw_device_close(mDevice);
-    ALOGW_IF(status, "Error closing audio hw device %p: %s", mDevice, strerror(-status));
+    ALOGW_IF(status, "Error closing audio hw device %p: %s", mDevice,
+             strerror(-status));
     mDevice = nullptr;
 }
 
@@ -101,12 +103,18 @@
         ALOGW("Device %p %s: %s", mDevice, funcName, strerror(-status));
     }
     switch (status) {
-        case 0: return Result::OK;
-        case -EINVAL: return Result::INVALID_ARGUMENTS;
-        case -ENODATA: return Result::INVALID_STATE;
-        case -ENODEV: return Result::NOT_INITIALIZED;
-        case -ENOSYS: return Result::NOT_SUPPORTED;
-        default: return Result::INVALID_STATE;
+        case 0:
+            return Result::OK;
+        case -EINVAL:
+            return Result::INVALID_ARGUMENTS;
+        case -ENODATA:
+            return Result::INVALID_STATE;
+        case -ENODEV:
+            return Result::NOT_INITIALIZED;
+        case -ENOSYS:
+            return Result::NOT_SUPPORTED;
+        default:
+            return Result::INVALID_STATE;
     }
 }
 
@@ -129,59 +137,67 @@
 }
 
 // Methods from ::android::hardware::audio::V2_0::IDevice follow.
-Return<Result> Device::initCheck()  {
+Return<Result> Device::initCheck() {
     return analyzeStatus("init_check", mDevice->init_check(mDevice));
 }
 
-Return<Result> Device::setMasterVolume(float volume)  {
-    Result retval(Result::NOT_SUPPORTED);
-    if (mDevice->set_master_volume != NULL) {
-        retval = analyzeStatus("set_master_volume", mDevice->set_master_volume(mDevice, volume));
+Return<Result> Device::setMasterVolume(float volume) {
+    if (mDevice->set_master_volume == NULL) {
+        return Result::NOT_SUPPORTED;
     }
-    return retval;
+    if (!isGainNormalized(volume)) {
+        ALOGW("Can not set a master volume (%f) outside [0,1]", volume);
+        return Result::INVALID_ARGUMENTS;
+    }
+    return analyzeStatus("set_master_volume",
+                         mDevice->set_master_volume(mDevice, volume));
 }
 
-Return<void> Device::getMasterVolume(getMasterVolume_cb _hidl_cb)  {
+Return<void> Device::getMasterVolume(getMasterVolume_cb _hidl_cb) {
     Result retval(Result::NOT_SUPPORTED);
     float volume = 0;
     if (mDevice->get_master_volume != NULL) {
-        retval = analyzeStatus("get_master_volume", mDevice->get_master_volume(mDevice, &volume));
+        retval = analyzeStatus("get_master_volume",
+                               mDevice->get_master_volume(mDevice, &volume));
     }
     _hidl_cb(retval, volume);
     return Void();
 }
 
-Return<Result> Device::setMicMute(bool mute)  {
+Return<Result> Device::setMicMute(bool mute) {
     return analyzeStatus("set_mic_mute", mDevice->set_mic_mute(mDevice, mute));
 }
 
-Return<void> Device::getMicMute(getMicMute_cb _hidl_cb)  {
+Return<void> Device::getMicMute(getMicMute_cb _hidl_cb) {
     bool mute = false;
-    Result retval = analyzeStatus("get_mic_mute", mDevice->get_mic_mute(mDevice, &mute));
+    Result retval =
+        analyzeStatus("get_mic_mute", mDevice->get_mic_mute(mDevice, &mute));
     _hidl_cb(retval, mute);
     return Void();
 }
 
-Return<Result> Device::setMasterMute(bool mute)  {
+Return<Result> Device::setMasterMute(bool mute) {
     Result retval(Result::NOT_SUPPORTED);
     if (mDevice->set_master_mute != NULL) {
-        retval = analyzeStatus("set_master_mute", mDevice->set_master_mute(mDevice, mute));
+        retval = analyzeStatus("set_master_mute",
+                               mDevice->set_master_mute(mDevice, mute));
     }
     return retval;
 }
 
-Return<void> Device::getMasterMute(getMasterMute_cb _hidl_cb)  {
+Return<void> Device::getMasterMute(getMasterMute_cb _hidl_cb) {
     Result retval(Result::NOT_SUPPORTED);
     bool mute = false;
     if (mDevice->get_master_mute != NULL) {
-        retval = analyzeStatus("get_master_mute", mDevice->get_master_mute(mDevice, &mute));
+        retval = analyzeStatus("get_master_mute",
+                               mDevice->get_master_mute(mDevice, &mute));
     }
     _hidl_cb(retval, mute);
     return Void();
 }
 
-Return<void> Device::getInputBufferSize(
-        const AudioConfig& config, getInputBufferSize_cb _hidl_cb)  {
+Return<void> Device::getInputBufferSize(const AudioConfig& config,
+                                        getInputBufferSize_cb _hidl_cb) {
     audio_config_t halConfig;
     HidlUtils::audioConfigToHal(config, &halConfig);
     size_t halBufferSize = mDevice->get_input_buffer_size(mDevice, &halConfig);
@@ -195,29 +211,25 @@
     return Void();
 }
 
-Return<void> Device::openOutputStream(
-        int32_t ioHandle,
-        const DeviceAddress& device,
-        const AudioConfig& config,
-        AudioOutputFlag flags,
-        openOutputStream_cb _hidl_cb)  {
+Return<void> Device::openOutputStream(int32_t ioHandle,
+                                      const DeviceAddress& device,
+                                      const AudioConfig& config,
+                                      AudioOutputFlag flags,
+                                      openOutputStream_cb _hidl_cb) {
     audio_config_t halConfig;
     HidlUtils::audioConfigToHal(config, &halConfig);
-    audio_stream_out_t *halStream;
-    ALOGV("open_output_stream handle: %d devices: %x flags: %#x "
-            "srate: %d format %#x channels %x address %s",
-            ioHandle,
-            static_cast<audio_devices_t>(device.device), static_cast<audio_output_flags_t>(flags),
-            halConfig.sample_rate, halConfig.format, halConfig.channel_mask,
-            deviceAddressToHal(device).c_str());
+    audio_stream_out_t* halStream;
+    ALOGV(
+        "open_output_stream handle: %d devices: %x flags: %#x "
+        "srate: %d format %#x channels %x address %s",
+        ioHandle, static_cast<audio_devices_t>(device.device),
+        static_cast<audio_output_flags_t>(flags), halConfig.sample_rate,
+        halConfig.format, halConfig.channel_mask,
+        deviceAddressToHal(device).c_str());
     int status = mDevice->open_output_stream(
-            mDevice,
-            ioHandle,
-            static_cast<audio_devices_t>(device.device),
-            static_cast<audio_output_flags_t>(flags),
-            &halConfig,
-            &halStream,
-            deviceAddressToHal(device).c_str());
+        mDevice, ioHandle, static_cast<audio_devices_t>(device.device),
+        static_cast<audio_output_flags_t>(flags), &halConfig, &halStream,
+        deviceAddressToHal(device).c_str());
     ALOGV("open_output_stream status %d stream %p", status, halStream);
     sp<IStreamOut> streamOut;
     if (status == OK) {
@@ -225,35 +237,32 @@
     }
     AudioConfig suggestedConfig;
     HidlUtils::audioConfigFromHal(halConfig, &suggestedConfig);
-    _hidl_cb(analyzeStatus("open_output_stream", status), streamOut, suggestedConfig);
+    _hidl_cb(analyzeStatus("open_output_stream", status), streamOut,
+             suggestedConfig);
     return Void();
 }
 
-Return<void> Device::openInputStream(
-        int32_t ioHandle,
-        const DeviceAddress& device,
-        const AudioConfig& config,
-        AudioInputFlag flags,
-        AudioSource source,
-        openInputStream_cb _hidl_cb)  {
+Return<void> Device::openInputStream(int32_t ioHandle,
+                                     const DeviceAddress& device,
+                                     const AudioConfig& config,
+                                     AudioInputFlag flags, AudioSource source,
+                                     openInputStream_cb _hidl_cb) {
     audio_config_t halConfig;
     HidlUtils::audioConfigToHal(config, &halConfig);
-    audio_stream_in_t *halStream;
-    ALOGV("open_input_stream handle: %d devices: %x flags: %#x "
-            "srate: %d format %#x channels %x address %s source %d",
-            ioHandle,
-            static_cast<audio_devices_t>(device.device), static_cast<audio_input_flags_t>(flags),
-            halConfig.sample_rate, halConfig.format, halConfig.channel_mask,
-            deviceAddressToHal(device).c_str(), static_cast<audio_source_t>(source));
+    audio_stream_in_t* halStream;
+    ALOGV(
+        "open_input_stream handle: %d devices: %x flags: %#x "
+        "srate: %d format %#x channels %x address %s source %d",
+        ioHandle, static_cast<audio_devices_t>(device.device),
+        static_cast<audio_input_flags_t>(flags), halConfig.sample_rate,
+        halConfig.format, halConfig.channel_mask,
+        deviceAddressToHal(device).c_str(),
+        static_cast<audio_source_t>(source));
     int status = mDevice->open_input_stream(
-            mDevice,
-            ioHandle,
-            static_cast<audio_devices_t>(device.device),
-            &halConfig,
-            &halStream,
-            static_cast<audio_input_flags_t>(flags),
-            deviceAddressToHal(device).c_str(),
-            static_cast<audio_source_t>(source));
+        mDevice, ioHandle, static_cast<audio_devices_t>(device.device),
+        &halConfig, &halStream, static_cast<audio_input_flags_t>(flags),
+        deviceAddressToHal(device).c_str(),
+        static_cast<audio_source_t>(source));
     ALOGV("open_input_stream status %d stream %p", status, halStream);
     sp<IStreamIn> streamIn;
     if (status == OK) {
@@ -261,7 +270,8 @@
     }
     AudioConfig suggestedConfig;
     HidlUtils::audioConfigFromHal(halConfig, &suggestedConfig);
-    _hidl_cb(analyzeStatus("open_input_stream", status), streamIn, suggestedConfig);
+    _hidl_cb(analyzeStatus("open_input_stream", status), streamIn,
+             suggestedConfig);
     return Void();
 }
 
@@ -269,23 +279,21 @@
     return version() >= AUDIO_DEVICE_API_VERSION_3_0;
 }
 
-Return<void> Device::createAudioPatch(
-        const hidl_vec<AudioPortConfig>& sources,
-        const hidl_vec<AudioPortConfig>& sinks,
-        createAudioPatch_cb _hidl_cb)  {
+Return<void> Device::createAudioPatch(const hidl_vec<AudioPortConfig>& sources,
+                                      const hidl_vec<AudioPortConfig>& sinks,
+                                      createAudioPatch_cb _hidl_cb) {
     Result retval(Result::NOT_SUPPORTED);
     AudioPatchHandle patch = 0;
     if (version() >= AUDIO_DEVICE_API_VERSION_3_0) {
-        std::unique_ptr<audio_port_config[]> halSources(HidlUtils::audioPortConfigsToHal(sources));
-        std::unique_ptr<audio_port_config[]> halSinks(HidlUtils::audioPortConfigsToHal(sinks));
+        std::unique_ptr<audio_port_config[]> halSources(
+            HidlUtils::audioPortConfigsToHal(sources));
+        std::unique_ptr<audio_port_config[]> halSinks(
+            HidlUtils::audioPortConfigsToHal(sinks));
         audio_patch_handle_t halPatch = AUDIO_PATCH_HANDLE_NONE;
         retval = analyzeStatus(
-                "create_audio_patch",
-                mDevice->create_audio_patch(
-                        mDevice,
-                        sources.size(), &halSources[0],
-                        sinks.size(), &halSinks[0],
-                        &halPatch));
+            "create_audio_patch",
+            mDevice->create_audio_patch(mDevice, sources.size(), &halSources[0],
+                                        sinks.size(), &halSinks[0], &halPatch));
         if (retval == Result::OK) {
             patch = static_cast<AudioPatchHandle>(halPatch);
         }
@@ -294,19 +302,22 @@
     return Void();
 }
 
-Return<Result> Device::releaseAudioPatch(int32_t patch)  {
+Return<Result> Device::releaseAudioPatch(int32_t patch) {
     if (version() >= AUDIO_DEVICE_API_VERSION_3_0) {
         return analyzeStatus(
-                "release_audio_patch",
-                mDevice->release_audio_patch(mDevice, static_cast<audio_patch_handle_t>(patch)));
+            "release_audio_patch",
+            mDevice->release_audio_patch(
+                mDevice, static_cast<audio_patch_handle_t>(patch)));
     }
     return Result::NOT_SUPPORTED;
 }
 
-Return<void> Device::getAudioPort(const AudioPort& port, getAudioPort_cb _hidl_cb)  {
+Return<void> Device::getAudioPort(const AudioPort& port,
+                                  getAudioPort_cb _hidl_cb) {
     audio_port halPort;
     HidlUtils::audioPortToHal(port, &halPort);
-    Result retval = analyzeStatus("get_audio_port", mDevice->get_audio_port(mDevice, &halPort));
+    Result retval = analyzeStatus("get_audio_port",
+                                  mDevice->get_audio_port(mDevice, &halPort));
     AudioPort resultPort = port;
     if (retval == Result::OK) {
         HidlUtils::audioPortFromHal(halPort, &resultPort);
@@ -315,36 +326,39 @@
     return Void();
 }
 
-Return<Result> Device::setAudioPortConfig(const AudioPortConfig& config)  {
+Return<Result> Device::setAudioPortConfig(const AudioPortConfig& config) {
     if (version() >= AUDIO_DEVICE_API_VERSION_3_0) {
         struct audio_port_config halPortConfig;
         HidlUtils::audioPortConfigToHal(config, &halPortConfig);
         return analyzeStatus(
-                "set_audio_port_config", mDevice->set_audio_port_config(mDevice, &halPortConfig));
+            "set_audio_port_config",
+            mDevice->set_audio_port_config(mDevice, &halPortConfig));
     }
     return Result::NOT_SUPPORTED;
 }
 
-Return<AudioHwSync> Device::getHwAvSync()  {
+Return<AudioHwSync> Device::getHwAvSync() {
     int halHwAvSync;
     Result retval = getParam(AudioParameter::keyHwAvSync, &halHwAvSync);
     return retval == Result::OK ? halHwAvSync : AUDIO_HW_SYNC_INVALID;
 }
 
-Return<Result> Device::setScreenState(bool turnedOn)  {
+Return<Result> Device::setScreenState(bool turnedOn) {
     return setParam(AudioParameter::keyScreenState, turnedOn);
 }
 
-Return<void> Device::getParameters(const hidl_vec<hidl_string>& keys, getParameters_cb _hidl_cb)  {
+Return<void> Device::getParameters(const hidl_vec<hidl_string>& keys,
+                                   getParameters_cb _hidl_cb) {
     getParametersImpl(keys, _hidl_cb);
     return Void();
 }
 
-Return<Result> Device::setParameters(const hidl_vec<ParameterValue>& parameters)  {
+Return<Result> Device::setParameters(
+    const hidl_vec<ParameterValue>& parameters) {
     return setParametersImpl(parameters);
 }
 
-Return<void> Device::debugDump(const hidl_handle& fd)  {
+Return<void> Device::debugDump(const hidl_handle& fd) {
     if (fd.getNativeHandle() != nullptr && fd->numFds == 1) {
         analyzeStatus("dump", mDevice->dump(mDevice, fd->data[0]));
     }
diff --git a/audio/2.0/default/ParametersUtil.cpp b/audio/2.0/default/ParametersUtil.cpp
index 75a60b9..5cc60db 100644
--- a/audio/2.0/default/ParametersUtil.cpp
+++ b/audio/2.0/default/ParametersUtil.cpp
@@ -22,11 +22,31 @@
 namespace V2_0 {
 namespace implementation {
 
+// Static method and not private method to avoid leaking status_t dependency
+static Result getHalStatusToResult(status_t status) {
+    switch (status) {
+        case OK:
+            return Result::OK;
+        case BAD_VALUE:  // Nothing was returned, probably because the HAL does
+                         // not handle it
+            return Result::NOT_SUPPORTED;
+        case INVALID_OPERATION:  // Conversion from string to the requested type
+                                 // failed
+            return Result::INVALID_ARGUMENTS;
+        default:  // Should not happen
+            ALOGW("Unexpected status returned by getParam: %u", status);
+            return Result::INVALID_ARGUMENTS;
+    }
+}
+
 Result ParametersUtil::getParam(const char* name, bool* value) {
     String8 halValue;
     Result retval = getParam(name, &halValue);
     *value = false;
     if (retval == Result::OK) {
+        if (halValue.empty()) {
+            return Result::NOT_SUPPORTED;
+        }
         *value = !(halValue == AudioParameter::valueOff);
     }
     return retval;
@@ -37,8 +57,7 @@
     AudioParameter keys;
     keys.addKey(halName);
     std::unique_ptr<AudioParameter> params = getParams(keys);
-    status_t halStatus = params->getInt(halName, *value);
-    return halStatus == OK ? Result::OK : Result::INVALID_ARGUMENTS;
+    return getHalStatusToResult(params->getInt(halName, *value));
 }
 
 Result ParametersUtil::getParam(const char* name, String8* value) {
@@ -46,42 +65,41 @@
     AudioParameter keys;
     keys.addKey(halName);
     std::unique_ptr<AudioParameter> params = getParams(keys);
-    status_t halStatus = params->get(halName, *value);
-    return halStatus == OK ? Result::OK : Result::INVALID_ARGUMENTS;
+    return getHalStatusToResult(params->get(halName, *value));
 }
 
 void ParametersUtil::getParametersImpl(
-        const hidl_vec<hidl_string>& keys,
-        std::function<void(Result retval, const hidl_vec<ParameterValue>& parameters)> cb)  {
+    const hidl_vec<hidl_string>& keys,
+    std::function<void(Result retval,
+                       const hidl_vec<ParameterValue>& parameters)>
+        cb) {
     AudioParameter halKeys;
     for (size_t i = 0; i < keys.size(); ++i) {
         halKeys.addKey(String8(keys[i].c_str()));
     }
     std::unique_ptr<AudioParameter> halValues = getParams(halKeys);
-    Result retval(Result::INVALID_ARGUMENTS);
+    Result retval =
+        halValues->size() == keys.size() ? Result::OK : Result::NOT_SUPPORTED;
     hidl_vec<ParameterValue> result;
-    if (halValues->size() > 0) {
-        result.resize(halValues->size());
-        String8 halKey, halValue;
-        for (size_t i = 0; i < halValues->size(); ++i) {
-            status_t status = halValues->getAt(i, halKey, halValue);
-            if (status != OK) {
-                result.resize(0);
-                break;
-            }
-            result[i].key = halKey.string();
-            result[i].value = halValue.string();
+    result.resize(halValues->size());
+    String8 halKey, halValue;
+    for (size_t i = 0; i < halValues->size(); ++i) {
+        status_t status = halValues->getAt(i, halKey, halValue);
+        if (status != OK) {
+            result.resize(0);
+            retval = getHalStatusToResult(status);
+            break;
         }
-        if (result.size() != 0) {
-            retval = Result::OK;
-        }
+        result[i].key = halKey.string();
+        result[i].value = halValue.string();
     }
     cb(retval, result);
 }
 
-std::unique_ptr<AudioParameter> ParametersUtil::getParams(const AudioParameter& keys) {
+std::unique_ptr<AudioParameter> ParametersUtil::getParams(
+    const AudioParameter& keys) {
     String8 paramsAndValues;
-    char *halValues = halGetParameters(keys.keysToString().string());
+    char* halValues = halGetParameters(keys.keysToString().string());
     if (halValues != NULL) {
         paramsAndValues.setTo(halValues);
         free(halValues);
@@ -93,7 +111,8 @@
 
 Result ParametersUtil::setParam(const char* name, bool value) {
     AudioParameter param;
-    param.add(String8(name), String8(value ? AudioParameter::valueOn : AudioParameter::valueOff));
+    param.add(String8(name), String8(value ? AudioParameter::valueOn
+                                           : AudioParameter::valueOff));
     return setParams(param);
 }
 
@@ -109,10 +128,12 @@
     return setParams(param);
 }
 
-Result ParametersUtil::setParametersImpl(const hidl_vec<ParameterValue>& parameters)  {
+Result ParametersUtil::setParametersImpl(
+    const hidl_vec<ParameterValue>& parameters) {
     AudioParameter params;
     for (size_t i = 0; i < parameters.size(); ++i) {
-        params.add(String8(parameters[i].key.c_str()), String8(parameters[i].value.c_str()));
+        params.add(String8(parameters[i].key.c_str()),
+                   String8(parameters[i].value.c_str()));
     }
     return setParams(params);
 }
diff --git a/audio/2.0/default/PrimaryDevice.cpp b/audio/2.0/default/PrimaryDevice.cpp
index af0b249..4e8f30f 100644
--- a/audio/2.0/default/PrimaryDevice.cpp
+++ b/audio/2.0/default/PrimaryDevice.cpp
@@ -30,56 +30,52 @@
 PrimaryDevice::~PrimaryDevice() {}
 
 // Methods from ::android::hardware::audio::V2_0::IDevice follow.
-Return<Result> PrimaryDevice::initCheck()  {
+Return<Result> PrimaryDevice::initCheck() {
     return mDevice->initCheck();
 }
 
-Return<Result> PrimaryDevice::setMasterVolume(float volume)  {
+Return<Result> PrimaryDevice::setMasterVolume(float volume) {
     return mDevice->setMasterVolume(volume);
 }
 
-Return<void> PrimaryDevice::getMasterVolume(getMasterVolume_cb _hidl_cb)  {
+Return<void> PrimaryDevice::getMasterVolume(getMasterVolume_cb _hidl_cb) {
     return mDevice->getMasterVolume(_hidl_cb);
 }
 
-Return<Result> PrimaryDevice::setMicMute(bool mute)  {
+Return<Result> PrimaryDevice::setMicMute(bool mute) {
     return mDevice->setMicMute(mute);
 }
 
-Return<void> PrimaryDevice::getMicMute(getMicMute_cb _hidl_cb)  {
+Return<void> PrimaryDevice::getMicMute(getMicMute_cb _hidl_cb) {
     return mDevice->getMicMute(_hidl_cb);
 }
 
-Return<Result> PrimaryDevice::setMasterMute(bool mute)  {
+Return<Result> PrimaryDevice::setMasterMute(bool mute) {
     return mDevice->setMasterMute(mute);
 }
 
-Return<void> PrimaryDevice::getMasterMute(getMasterMute_cb _hidl_cb)  {
+Return<void> PrimaryDevice::getMasterMute(getMasterMute_cb _hidl_cb) {
     return mDevice->getMasterMute(_hidl_cb);
 }
 
-Return<void> PrimaryDevice::getInputBufferSize(
-        const AudioConfig& config, getInputBufferSize_cb _hidl_cb)  {
+Return<void> PrimaryDevice::getInputBufferSize(const AudioConfig& config,
+                                               getInputBufferSize_cb _hidl_cb) {
     return mDevice->getInputBufferSize(config, _hidl_cb);
 }
 
-Return<void> PrimaryDevice::openOutputStream(
-        int32_t ioHandle,
-        const DeviceAddress& device,
-        const AudioConfig& config,
-        AudioOutputFlag flags,
-        openOutputStream_cb _hidl_cb)  {
+Return<void> PrimaryDevice::openOutputStream(int32_t ioHandle,
+                                             const DeviceAddress& device,
+                                             const AudioConfig& config,
+                                             AudioOutputFlag 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,
-        AudioSource source,
-        openInputStream_cb _hidl_cb)  {
-    return mDevice->openInputStream(ioHandle, device, config, flags, source, _hidl_cb);
+    int32_t ioHandle, const DeviceAddress& device, const AudioConfig& config,
+    AudioInputFlag flags, AudioSource source, openInputStream_cb _hidl_cb) {
+    return mDevice->openInputStream(ioHandle, device, config, flags, source,
+                                    _hidl_cb);
 }
 
 Return<bool> PrimaryDevice::supportsAudioPatches() {
@@ -87,82 +83,97 @@
 }
 
 Return<void> PrimaryDevice::createAudioPatch(
-        const hidl_vec<AudioPortConfig>& sources,
-        const hidl_vec<AudioPortConfig>& sinks,
-        createAudioPatch_cb _hidl_cb)  {
+    const hidl_vec<AudioPortConfig>& sources,
+    const hidl_vec<AudioPortConfig>& sinks, createAudioPatch_cb _hidl_cb) {
     return mDevice->createAudioPatch(sources, sinks, _hidl_cb);
 }
 
-Return<Result> PrimaryDevice::releaseAudioPatch(int32_t patch)  {
+Return<Result> PrimaryDevice::releaseAudioPatch(int32_t patch) {
     return mDevice->releaseAudioPatch(patch);
 }
 
-Return<void> PrimaryDevice::getAudioPort(const AudioPort& port, getAudioPort_cb _hidl_cb)  {
+Return<void> PrimaryDevice::getAudioPort(const AudioPort& port,
+                                         getAudioPort_cb _hidl_cb) {
     return mDevice->getAudioPort(port, _hidl_cb);
 }
 
-Return<Result> PrimaryDevice::setAudioPortConfig(const AudioPortConfig& config)  {
+Return<Result> PrimaryDevice::setAudioPortConfig(
+    const AudioPortConfig& config) {
     return mDevice->setAudioPortConfig(config);
 }
 
-Return<AudioHwSync> PrimaryDevice::getHwAvSync()  {
+Return<AudioHwSync> PrimaryDevice::getHwAvSync() {
     return mDevice->getHwAvSync();
 }
 
-Return<Result> PrimaryDevice::setScreenState(bool turnedOn)  {
+Return<Result> PrimaryDevice::setScreenState(bool turnedOn) {
     return mDevice->setScreenState(turnedOn);
 }
 
-Return<void> PrimaryDevice::getParameters(
-        const hidl_vec<hidl_string>& keys, getParameters_cb _hidl_cb)  {
+Return<void> PrimaryDevice::getParameters(const hidl_vec<hidl_string>& keys,
+                                          getParameters_cb _hidl_cb) {
     return mDevice->getParameters(keys, _hidl_cb);
 }
 
-Return<Result> PrimaryDevice::setParameters(const hidl_vec<ParameterValue>& parameters)  {
+Return<Result> PrimaryDevice::setParameters(
+    const hidl_vec<ParameterValue>& parameters) {
     return mDevice->setParameters(parameters);
 }
 
-Return<void> PrimaryDevice::debugDump(const hidl_handle& fd)  {
+Return<void> PrimaryDevice::debugDump(const hidl_handle& fd) {
     return mDevice->debugDump(fd);
 }
 
-
 // Methods from ::android::hardware::audio::V2_0::IPrimaryDevice follow.
-Return<Result> PrimaryDevice::setVoiceVolume(float volume)  {
+Return<Result> PrimaryDevice::setVoiceVolume(float volume) {
     return mDevice->analyzeStatus(
-            "set_voice_volume",
-            mDevice->device()->set_voice_volume(mDevice->device(), volume));
+        "set_voice_volume",
+        mDevice->device()->set_voice_volume(mDevice->device(), volume));
 }
 
-Return<Result> PrimaryDevice::setMode(AudioMode mode)  {
+Return<Result> PrimaryDevice::setMode(AudioMode mode) {
+    // INVALID, CURRENT, CNT, MAX are reserved for internal use.
+    // TODO: remove the values from the HIDL interface
+    switch (mode) {
+        case AudioMode::NORMAL:
+        case AudioMode::RINGTONE:
+        case AudioMode::IN_CALL:
+        case AudioMode::IN_COMMUNICATION:
+            break;  // Valid values
+        default:
+            return Result::INVALID_ARGUMENTS;
+    };
+
     return mDevice->analyzeStatus(
-            "set_mode",
-            mDevice->device()->set_mode(mDevice->device(), static_cast<audio_mode_t>(mode)));
+        "set_mode", mDevice->device()->set_mode(
+                        mDevice->device(), static_cast<audio_mode_t>(mode)));
 }
 
-Return<void> PrimaryDevice::getBtScoNrecEnabled(getBtScoNrecEnabled_cb _hidl_cb)  {
+Return<void> PrimaryDevice::getBtScoNrecEnabled(
+    getBtScoNrecEnabled_cb _hidl_cb) {
     bool enabled;
     Result retval = mDevice->getParam(AudioParameter::keyBtNrec, &enabled);
     _hidl_cb(retval, enabled);
     return Void();
 }
 
-Return<Result> PrimaryDevice::setBtScoNrecEnabled(bool enabled)  {
+Return<Result> PrimaryDevice::setBtScoNrecEnabled(bool enabled) {
     return mDevice->setParam(AudioParameter::keyBtNrec, enabled);
 }
 
-Return<void> PrimaryDevice::getBtScoWidebandEnabled(getBtScoWidebandEnabled_cb _hidl_cb)  {
+Return<void> PrimaryDevice::getBtScoWidebandEnabled(
+    getBtScoWidebandEnabled_cb _hidl_cb) {
     bool enabled;
     Result retval = mDevice->getParam(AUDIO_PARAMETER_KEY_BT_SCO_WB, &enabled);
     _hidl_cb(retval, enabled);
     return Void();
 }
 
-Return<Result> PrimaryDevice::setBtScoWidebandEnabled(bool enabled)  {
+Return<Result> PrimaryDevice::setBtScoWidebandEnabled(bool enabled) {
     return mDevice->setParam(AUDIO_PARAMETER_KEY_BT_SCO_WB, enabled);
 }
 
-Return<void> PrimaryDevice::getTtyMode(getTtyMode_cb _hidl_cb)  {
+Return<void> PrimaryDevice::getTtyMode(getTtyMode_cb _hidl_cb) {
     int halMode;
     Result retval = mDevice->getParam(AUDIO_PARAMETER_KEY_TTY_MODE, &halMode);
     TtyMode mode = retval == Result::OK ? TtyMode(halMode) : TtyMode::OFF;
@@ -170,18 +181,19 @@
     return Void();
 }
 
-Return<Result> PrimaryDevice::setTtyMode(IPrimaryDevice::TtyMode mode)  {
-    return mDevice->setParam(AUDIO_PARAMETER_KEY_TTY_MODE, static_cast<int>(mode));
+Return<Result> PrimaryDevice::setTtyMode(IPrimaryDevice::TtyMode mode) {
+    return mDevice->setParam(AUDIO_PARAMETER_KEY_TTY_MODE,
+                             static_cast<int>(mode));
 }
 
-Return<void> PrimaryDevice::getHacEnabled(getHacEnabled_cb _hidl_cb)  {
+Return<void> PrimaryDevice::getHacEnabled(getHacEnabled_cb _hidl_cb) {
     bool enabled;
     Result retval = mDevice->getParam(AUDIO_PARAMETER_KEY_HAC, &enabled);
     _hidl_cb(retval, enabled);
     return Void();
 }
 
-Return<Result> PrimaryDevice::setHacEnabled(bool enabled)  {
+Return<Result> PrimaryDevice::setHacEnabled(bool enabled) {
     return mDevice->setParam(AUDIO_PARAMETER_KEY_HAC, enabled);
 }
 
diff --git a/audio/2.0/default/StreamIn.cpp b/audio/2.0/default/StreamIn.cpp
index e5a1a55..abd0497 100644
--- a/audio/2.0/default/StreamIn.cpp
+++ b/audio/2.0/default/StreamIn.cpp
@@ -20,10 +20,11 @@
 
 #include <android/log.h>
 #include <hardware/audio.h>
-#include <memory>
 #include <utils/Trace.h>
+#include <memory>
 
 #include "StreamIn.h"
+#include "Util.h"
 
 using ::android::hardware::audio::V2_0::MessageQueueFlagBits;
 
@@ -38,30 +39,26 @@
 namespace {
 
 class ReadThread : public Thread {
-  public:
+   public:
     // ReadThread's lifespan never exceeds StreamIn's lifespan.
-    ReadThread(std::atomic<bool>* stop,
-            audio_stream_in_t* stream,
-            StreamIn::CommandMQ* commandMQ,
-            StreamIn::DataMQ* dataMQ,
-            StreamIn::StatusMQ* statusMQ,
-            EventFlag* efGroup)
-            : Thread(false /*canCallJava*/),
-              mStop(stop),
-              mStream(stream),
-              mCommandMQ(commandMQ),
-              mDataMQ(dataMQ),
-              mStatusMQ(statusMQ),
-              mEfGroup(efGroup),
-              mBuffer(nullptr) {
-    }
+    ReadThread(std::atomic<bool>* stop, audio_stream_in_t* stream,
+               StreamIn::CommandMQ* commandMQ, StreamIn::DataMQ* dataMQ,
+               StreamIn::StatusMQ* statusMQ, EventFlag* efGroup)
+        : Thread(false /*canCallJava*/),
+          mStop(stop),
+          mStream(stream),
+          mCommandMQ(commandMQ),
+          mDataMQ(dataMQ),
+          mStatusMQ(statusMQ),
+          mEfGroup(efGroup),
+          mBuffer(nullptr) {}
     bool init() {
-        mBuffer.reset(new(std::nothrow) uint8_t[mDataMQ->getQuantumCount()]);
+        mBuffer.reset(new (std::nothrow) uint8_t[mDataMQ->getQuantumCount()]);
         return mBuffer != nullptr;
     }
     virtual ~ReadThread() {}
 
-  private:
+   private:
     std::atomic<bool>* mStop;
     audio_stream_in_t* mStream;
     StreamIn::CommandMQ* mCommandMQ;
@@ -82,8 +79,10 @@
     size_t availableToWrite = mDataMQ->availableToWrite();
     size_t requestedToRead = mParameters.params.read;
     if (requestedToRead > availableToWrite) {
-        ALOGW("truncating read data from %d to %d due to insufficient data queue space",
-                (int32_t)requestedToRead, (int32_t)availableToWrite);
+        ALOGW(
+            "truncating read data from %d to %d due to insufficient data queue "
+            "space",
+            (int32_t)requestedToRead, (int32_t)availableToWrite);
         requestedToRead = availableToWrite;
     }
     ssize_t readResult = mStream->read(mStream, &mBuffer[0], requestedToRead);
@@ -101,16 +100,20 @@
 
 void ReadThread::doGetCapturePosition() {
     mStatus.retval = StreamIn::getCapturePositionImpl(
-            mStream, &mStatus.reply.capturePosition.frames, &mStatus.reply.capturePosition.time);
+        mStream, &mStatus.reply.capturePosition.frames,
+        &mStatus.reply.capturePosition.time);
 }
 
 bool ReadThread::threadLoop() {
-    // This implementation doesn't return control back to the Thread until it decides to stop,
+    // This implementation doesn't return control back to the Thread until it
+    // decides to stop,
     // as the Thread uses mutexes, and this can lead to priority inversion.
-    while(!std::atomic_load_explicit(mStop, std::memory_order_acquire)) {
+    while (!std::atomic_load_explicit(mStop, std::memory_order_acquire)) {
         uint32_t efState = 0;
-        mEfGroup->wait(static_cast<uint32_t>(MessageQueueFlagBits::NOT_FULL), &efState);
-        if (!(efState & static_cast<uint32_t>(MessageQueueFlagBits::NOT_FULL))) {
+        mEfGroup->wait(static_cast<uint32_t>(MessageQueueFlagBits::NOT_FULL),
+                       &efState);
+        if (!(efState &
+              static_cast<uint32_t>(MessageQueueFlagBits::NOT_FULL))) {
             continue;  // Nothing to do.
         }
         if (!mCommandMQ->read(&mParameters)) {
@@ -125,7 +128,8 @@
                 doGetCapturePosition();
                 break;
             default:
-                ALOGE("Unknown read thread command code %d", mParameters.command);
+                ALOGE("Unknown read thread command code %d",
+                      mParameters.command);
                 mStatus.retval = Result::NOT_SUPPORTED;
                 break;
         }
@@ -141,11 +145,13 @@
 }  // namespace
 
 StreamIn::StreamIn(const sp<Device>& device, audio_stream_in_t* stream)
-        : mIsClosed(false), mDevice(device), mStream(stream),
-          mStreamCommon(new Stream(&stream->common)),
-          mStreamMmap(new StreamMmap<audio_stream_in_t>(stream)),
-          mEfGroup(nullptr), mStopReadThread(false) {
-}
+    : mIsClosed(false),
+      mDevice(device),
+      mStream(stream),
+      mStreamCommon(new Stream(&stream->common)),
+      mStreamMmap(new StreamMmap<audio_stream_in_t>(stream)),
+      mEfGroup(nullptr),
+      mStopReadThread(false) {}
 
 StreamIn::~StreamIn() {
     ATRACE_CALL();
@@ -157,102 +163,108 @@
     }
     if (mEfGroup) {
         status_t status = EventFlag::deleteEventFlag(&mEfGroup);
-        ALOGE_IF(status, "read MQ event flag deletion error: %s", strerror(-status));
+        ALOGE_IF(status, "read MQ event flag deletion error: %s",
+                 strerror(-status));
     }
     mDevice->closeInputStream(mStream);
     mStream = nullptr;
 }
 
 // Methods from ::android::hardware::audio::V2_0::IStream follow.
-Return<uint64_t> StreamIn::getFrameSize()  {
+Return<uint64_t> StreamIn::getFrameSize() {
     return audio_stream_in_frame_size(mStream);
 }
 
-Return<uint64_t> StreamIn::getFrameCount()  {
+Return<uint64_t> StreamIn::getFrameCount() {
     return mStreamCommon->getFrameCount();
 }
 
-Return<uint64_t> StreamIn::getBufferSize()  {
+Return<uint64_t> StreamIn::getBufferSize() {
     return mStreamCommon->getBufferSize();
 }
 
-Return<uint32_t> StreamIn::getSampleRate()  {
+Return<uint32_t> StreamIn::getSampleRate() {
     return mStreamCommon->getSampleRate();
 }
 
-Return<void> StreamIn::getSupportedSampleRates(getSupportedSampleRates_cb _hidl_cb)  {
+Return<void> StreamIn::getSupportedSampleRates(
+    getSupportedSampleRates_cb _hidl_cb) {
     return mStreamCommon->getSupportedSampleRates(_hidl_cb);
 }
 
-Return<Result> StreamIn::setSampleRate(uint32_t sampleRateHz)  {
+Return<Result> StreamIn::setSampleRate(uint32_t sampleRateHz) {
     return mStreamCommon->setSampleRate(sampleRateHz);
 }
 
-Return<AudioChannelMask> StreamIn::getChannelMask()  {
+Return<AudioChannelMask> StreamIn::getChannelMask() {
     return mStreamCommon->getChannelMask();
 }
 
-Return<void> StreamIn::getSupportedChannelMasks(getSupportedChannelMasks_cb _hidl_cb)  {
+Return<void> StreamIn::getSupportedChannelMasks(
+    getSupportedChannelMasks_cb _hidl_cb) {
     return mStreamCommon->getSupportedChannelMasks(_hidl_cb);
 }
 
-Return<Result> StreamIn::setChannelMask(AudioChannelMask mask)  {
+Return<Result> StreamIn::setChannelMask(AudioChannelMask mask) {
     return mStreamCommon->setChannelMask(mask);
 }
 
-Return<AudioFormat> StreamIn::getFormat()  {
+Return<AudioFormat> StreamIn::getFormat() {
     return mStreamCommon->getFormat();
 }
 
-Return<void> StreamIn::getSupportedFormats(getSupportedFormats_cb _hidl_cb)  {
+Return<void> StreamIn::getSupportedFormats(getSupportedFormats_cb _hidl_cb) {
     return mStreamCommon->getSupportedFormats(_hidl_cb);
 }
 
-Return<Result> StreamIn::setFormat(AudioFormat format)  {
+Return<Result> StreamIn::setFormat(AudioFormat format) {
     return mStreamCommon->setFormat(format);
 }
 
-Return<void> StreamIn::getAudioProperties(getAudioProperties_cb _hidl_cb)  {
+Return<void> StreamIn::getAudioProperties(getAudioProperties_cb _hidl_cb) {
     return mStreamCommon->getAudioProperties(_hidl_cb);
 }
 
-Return<Result> StreamIn::addEffect(uint64_t effectId)  {
+Return<Result> StreamIn::addEffect(uint64_t effectId) {
     return mStreamCommon->addEffect(effectId);
 }
 
-Return<Result> StreamIn::removeEffect(uint64_t effectId)  {
+Return<Result> StreamIn::removeEffect(uint64_t effectId) {
     return mStreamCommon->removeEffect(effectId);
 }
 
-Return<Result> StreamIn::standby()  {
+Return<Result> StreamIn::standby() {
     return mStreamCommon->standby();
 }
 
-Return<AudioDevice> StreamIn::getDevice()  {
+Return<AudioDevice> StreamIn::getDevice() {
     return mStreamCommon->getDevice();
 }
 
-Return<Result> StreamIn::setDevice(const DeviceAddress& address)  {
+Return<Result> StreamIn::setDevice(const DeviceAddress& address) {
     return mStreamCommon->setDevice(address);
 }
 
-Return<Result> StreamIn::setConnectedState(const DeviceAddress& address, bool connected)  {
+Return<Result> StreamIn::setConnectedState(const DeviceAddress& address,
+                                           bool connected) {
     return mStreamCommon->setConnectedState(address, connected);
 }
 
-Return<Result> StreamIn::setHwAvSync(uint32_t hwAvSync)  {
+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<void> StreamIn::getParameters(const hidl_vec<hidl_string>& keys,
+                                     getParameters_cb _hidl_cb) {
     return mStreamCommon->getParameters(keys, _hidl_cb);
 }
 
-Return<Result> StreamIn::setParameters(const hidl_vec<ParameterValue>& parameters)  {
+Return<Result> StreamIn::setParameters(
+    const hidl_vec<ParameterValue>& parameters) {
     return mStreamCommon->setParameters(parameters);
 }
 
-Return<void> StreamIn::debugDump(const hidl_handle& fd)  {
+Return<void> StreamIn::debugDump(const hidl_handle& fd) {
     return mStreamCommon->debugDump(fd);
 }
 
@@ -264,16 +276,17 @@
     return mStreamMmap->stop();
 }
 
-Return<void> StreamIn::createMmapBuffer(int32_t minSizeFrames, createMmapBuffer_cb _hidl_cb) {
+Return<void> StreamIn::createMmapBuffer(int32_t minSizeFrames,
+                                        createMmapBuffer_cb _hidl_cb) {
     return mStreamMmap->createMmapBuffer(
-            minSizeFrames, audio_stream_in_frame_size(mStream), _hidl_cb);
+        minSizeFrames, audio_stream_in_frame_size(mStream), _hidl_cb);
 }
 
 Return<void> StreamIn::getMmapPosition(getMmapPosition_cb _hidl_cb) {
     return mStreamMmap->getMmapPosition(_hidl_cb);
 }
 
-Return<Result> StreamIn::close()  {
+Return<Result> StreamIn::close() {
     if (mIsClosed) return Result::INVALID_STATE;
     mIsClosed = true;
     if (mReadThread.get()) {
@@ -286,9 +299,10 @@
 }
 
 // Methods from ::android::hardware::audio::V2_0::IStreamIn follow.
-Return<void> StreamIn::getAudioSource(getAudioSource_cb _hidl_cb)  {
+Return<void> StreamIn::getAudioSource(getAudioSource_cb _hidl_cb) {
     int halSource;
-    Result retval = mStreamCommon->getParam(AudioParameter::keyInputSource, &halSource);
+    Result retval =
+        mStreamCommon->getParam(AudioParameter::keyInputSource, &halSource);
     AudioSource source(AudioSource::DEFAULT);
     if (retval == Result::OK) {
         source = AudioSource(halSource);
@@ -297,68 +311,89 @@
     return Void();
 }
 
-Return<Result> StreamIn::setGain(float gain)  {
+Return<Result> StreamIn::setGain(float gain) {
+    if (!isGainNormalized(gain)) {
+        ALOGW("Can not set a stream input gain (%f) outside [0,1]", gain);
+        return Result::INVALID_ARGUMENTS;
+    }
     return Stream::analyzeStatus("set_gain", mStream->set_gain(mStream, gain));
 }
 
-Return<void> StreamIn::prepareForReading(
-        uint32_t frameSize, uint32_t framesCount, prepareForReading_cb _hidl_cb)  {
+Return<void> StreamIn::prepareForReading(uint32_t frameSize,
+                                         uint32_t framesCount,
+                                         prepareForReading_cb _hidl_cb) {
     status_t status;
-    ThreadInfo threadInfo = { 0, 0 };
+    ThreadInfo threadInfo = {0, 0};
+
+    // Wrap the _hidl_cb to return an error
+    auto sendError = [this, &threadInfo, &_hidl_cb](Result result) {
+        _hidl_cb(result, CommandMQ::Descriptor(), DataMQ::Descriptor(),
+                 StatusMQ::Descriptor(), threadInfo);
+
+    };
+
     // Create message queues.
     if (mDataMQ) {
         ALOGE("the client attempts to call prepareForReading twice");
-        _hidl_cb(Result::INVALID_STATE,
-                CommandMQ::Descriptor(), DataMQ::Descriptor(), StatusMQ::Descriptor(), threadInfo);
+        sendError(Result::INVALID_STATE);
         return Void();
     }
     std::unique_ptr<CommandMQ> tempCommandMQ(new CommandMQ(1));
-    if (frameSize > std::numeric_limits<size_t>::max() / framesCount) {
-        ALOGE("Requested buffer is too big, %d*%d can not fit in size_t", frameSize, framesCount);
-        _hidl_cb(Result::INVALID_ARGUMENTS,
-                CommandMQ::Descriptor(), DataMQ::Descriptor(), StatusMQ::Descriptor(), threadInfo);
+
+    // Check frameSize and framesCount
+    if (frameSize == 0 || framesCount == 0) {
+        ALOGE("Null frameSize (%u) or framesCount (%u)", frameSize,
+              framesCount);
+        sendError(Result::INVALID_ARGUMENTS);
         return Void();
     }
-    std::unique_ptr<DataMQ> tempDataMQ(new DataMQ(frameSize * framesCount, true /* EventFlag */));
+    // A message queue asserts if it can not handle the requested buffer,
+    // thus the client has to guess the maximum size it can handle
+    // Choose an arbitrary margin for the overhead of a message queue
+    size_t metadataOverhead = 100000;
+    if (frameSize >
+        (std::numeric_limits<size_t>::max() - metadataOverhead) / framesCount) {
+        ALOGE("Buffer too big: %u*%u bytes can not fit in a message queue",
+              frameSize, framesCount);
+        sendError(Result::INVALID_ARGUMENTS);
+        return Void();
+    }
+    std::unique_ptr<DataMQ> tempDataMQ(
+        new DataMQ(frameSize * framesCount, true /* EventFlag */));
 
     std::unique_ptr<StatusMQ> tempStatusMQ(new StatusMQ(1));
-    if (!tempCommandMQ->isValid() || !tempDataMQ->isValid() || !tempStatusMQ->isValid()) {
+    if (!tempCommandMQ->isValid() || !tempDataMQ->isValid() ||
+        !tempStatusMQ->isValid()) {
         ALOGE_IF(!tempCommandMQ->isValid(), "command MQ is invalid");
         ALOGE_IF(!tempDataMQ->isValid(), "data MQ is invalid");
         ALOGE_IF(!tempStatusMQ->isValid(), "status MQ is invalid");
-        _hidl_cb(Result::INVALID_ARGUMENTS,
-                CommandMQ::Descriptor(), DataMQ::Descriptor(), StatusMQ::Descriptor(), threadInfo);
+        sendError(Result::INVALID_ARGUMENTS);
         return Void();
     }
     EventFlag* tempRawEfGroup{};
-    status = EventFlag::createEventFlag(tempDataMQ->getEventFlagWord(), &tempRawEfGroup);
-    std::unique_ptr<EventFlag, void(*)(EventFlag*)> tempElfGroup(tempRawEfGroup, [](auto *ef) {
-            EventFlag::deleteEventFlag(&ef); });
+    status = EventFlag::createEventFlag(tempDataMQ->getEventFlagWord(),
+                                        &tempRawEfGroup);
+    std::unique_ptr<EventFlag, void (*)(EventFlag*)> tempElfGroup(
+        tempRawEfGroup, [](auto* ef) { EventFlag::deleteEventFlag(&ef); });
     if (status != OK || !tempElfGroup) {
         ALOGE("failed creating event flag for data MQ: %s", strerror(-status));
-        _hidl_cb(Result::INVALID_ARGUMENTS,
-                CommandMQ::Descriptor(), DataMQ::Descriptor(), StatusMQ::Descriptor(), threadInfo);
+        sendError(Result::INVALID_ARGUMENTS);
         return Void();
     }
 
     // Create and launch the thread.
     auto tempReadThread = std::make_unique<ReadThread>(
-            &mStopReadThread,
-            mStream,
-            tempCommandMQ.get(),
-            tempDataMQ.get(),
-            tempStatusMQ.get(),
-            tempElfGroup.get());
+        &mStopReadThread, mStream, tempCommandMQ.get(), tempDataMQ.get(),
+        tempStatusMQ.get(), tempElfGroup.get());
     if (!tempReadThread->init()) {
-        _hidl_cb(Result::INVALID_ARGUMENTS,
-                CommandMQ::Descriptor(), DataMQ::Descriptor(), StatusMQ::Descriptor(), threadInfo);
+        ALOGW("failed to start reader thread: %s", strerror(-status));
+        sendError(Result::INVALID_ARGUMENTS);
         return Void();
     }
     status = tempReadThread->run("reader", PRIORITY_URGENT_AUDIO);
     if (status != OK) {
         ALOGW("failed to start reader thread: %s", strerror(-status));
-        _hidl_cb(Result::INVALID_ARGUMENTS,
-                CommandMQ::Descriptor(), DataMQ::Descriptor(), StatusMQ::Descriptor(), threadInfo);
+        sendError(Result::INVALID_ARGUMENTS);
         return Void();
     }
 
@@ -369,28 +404,27 @@
     mEfGroup = tempElfGroup.release();
     threadInfo.pid = getpid();
     threadInfo.tid = mReadThread->getTid();
-    _hidl_cb(Result::OK,
-            *mCommandMQ->getDesc(), *mDataMQ->getDesc(), *mStatusMQ->getDesc(),
-            threadInfo);
+    _hidl_cb(Result::OK, *mCommandMQ->getDesc(), *mDataMQ->getDesc(),
+             *mStatusMQ->getDesc(), threadInfo);
     return Void();
 }
 
-Return<uint32_t> StreamIn::getInputFramesLost()  {
+Return<uint32_t> StreamIn::getInputFramesLost() {
     return mStream->get_input_frames_lost(mStream);
 }
 
 // static
-Result StreamIn::getCapturePositionImpl(
-        audio_stream_in_t *stream, uint64_t *frames, uint64_t *time) {
+Result StreamIn::getCapturePositionImpl(audio_stream_in_t* stream,
+                                        uint64_t* frames, uint64_t* time) {
     Result retval(Result::NOT_SUPPORTED);
     if (stream->get_capture_position != NULL) return retval;
     int64_t halFrames, halTime;
     retval = Stream::analyzeStatus(
-            "get_capture_position",
-            stream->get_capture_position(stream, &halFrames, &halTime),
-            // HAL may have a stub function, always returning ENOSYS, don't
-            // spam the log in this case.
-            ENOSYS);
+        "get_capture_position",
+        stream->get_capture_position(stream, &halFrames, &halTime),
+        // HAL may have a stub function, always returning ENOSYS, don't
+        // spam the log in this case.
+        ENOSYS);
     if (retval == Result::OK) {
         *frames = halFrames;
         *time = halTime;
@@ -398,14 +432,14 @@
     return retval;
 };
 
-Return<void> StreamIn::getCapturePosition(getCapturePosition_cb _hidl_cb)  {
+Return<void> StreamIn::getCapturePosition(getCapturePosition_cb _hidl_cb) {
     uint64_t frames = 0, time = 0;
     Result retval = getCapturePositionImpl(mStream, &frames, &time);
     _hidl_cb(retval, frames, time);
     return Void();
 }
 
-} // namespace implementation
+}  // namespace implementation
 }  // namespace V2_0
 }  // namespace audio
 }  // namespace hardware
diff --git a/audio/2.0/default/StreamOut.cpp b/audio/2.0/default/StreamOut.cpp
index 3339b63..e48497f 100644
--- a/audio/2.0/default/StreamOut.cpp
+++ b/audio/2.0/default/StreamOut.cpp
@@ -25,6 +25,7 @@
 #include <utils/Trace.h>
 
 #include "StreamOut.h"
+#include "Util.h"
 
 namespace android {
 namespace hardware {
@@ -37,30 +38,26 @@
 namespace {
 
 class WriteThread : public Thread {
-  public:
+   public:
     // WriteThread's lifespan never exceeds StreamOut's lifespan.
-    WriteThread(std::atomic<bool>* stop,
-            audio_stream_out_t* stream,
-            StreamOut::CommandMQ* commandMQ,
-            StreamOut::DataMQ* dataMQ,
-            StreamOut::StatusMQ* statusMQ,
-            EventFlag* efGroup)
-            : Thread(false /*canCallJava*/),
-              mStop(stop),
-              mStream(stream),
-              mCommandMQ(commandMQ),
-              mDataMQ(dataMQ),
-              mStatusMQ(statusMQ),
-              mEfGroup(efGroup),
-              mBuffer(nullptr) {
-    }
+    WriteThread(std::atomic<bool>* stop, audio_stream_out_t* stream,
+                StreamOut::CommandMQ* commandMQ, StreamOut::DataMQ* dataMQ,
+                StreamOut::StatusMQ* statusMQ, EventFlag* efGroup)
+        : Thread(false /*canCallJava*/),
+          mStop(stop),
+          mStream(stream),
+          mCommandMQ(commandMQ),
+          mDataMQ(dataMQ),
+          mStatusMQ(statusMQ),
+          mEfGroup(efGroup),
+          mBuffer(nullptr) {}
     bool init() {
-        mBuffer.reset(new(std::nothrow) uint8_t[mDataMQ->getQuantumCount()]);
+        mBuffer.reset(new (std::nothrow) uint8_t[mDataMQ->getQuantumCount()]);
         return mBuffer != nullptr;
     }
     virtual ~WriteThread() {}
 
-  private:
+   private:
     std::atomic<bool>* mStop;
     audio_stream_out_t* mStream;
     StreamOut::CommandMQ* mCommandMQ;
@@ -93,9 +90,8 @@
 
 void WriteThread::doGetPresentationPosition() {
     mStatus.retval = StreamOut::getPresentationPositionImpl(
-            mStream,
-            &mStatus.reply.presentationPosition.frames,
-            &mStatus.reply.presentationPosition.timeStamp);
+        mStream, &mStatus.reply.presentationPosition.frames,
+        &mStatus.reply.presentationPosition.timeStamp);
 }
 
 void WriteThread::doGetLatency() {
@@ -104,12 +100,15 @@
 }
 
 bool WriteThread::threadLoop() {
-    // This implementation doesn't return control back to the Thread until it decides to stop,
+    // This implementation doesn't return control back to the Thread until it
+    // decides to stop,
     // as the Thread uses mutexes, and this can lead to priority inversion.
-    while(!std::atomic_load_explicit(mStop, std::memory_order_acquire)) {
+    while (!std::atomic_load_explicit(mStop, std::memory_order_acquire)) {
         uint32_t efState = 0;
-        mEfGroup->wait(static_cast<uint32_t>(MessageQueueFlagBits::NOT_EMPTY), &efState);
-        if (!(efState & static_cast<uint32_t>(MessageQueueFlagBits::NOT_EMPTY))) {
+        mEfGroup->wait(static_cast<uint32_t>(MessageQueueFlagBits::NOT_EMPTY),
+                       &efState);
+        if (!(efState &
+              static_cast<uint32_t>(MessageQueueFlagBits::NOT_EMPTY))) {
             continue;  // Nothing to do.
         }
         if (!mCommandMQ->read(&mStatus.replyTo)) {
@@ -142,11 +141,13 @@
 }  // namespace
 
 StreamOut::StreamOut(const sp<Device>& device, audio_stream_out_t* stream)
-        : mIsClosed(false), mDevice(device), mStream(stream),
-          mStreamCommon(new Stream(&stream->common)),
-          mStreamMmap(new StreamMmap<audio_stream_out_t>(stream)),
-          mEfGroup(nullptr), mStopWriteThread(false) {
-}
+    : mIsClosed(false),
+      mDevice(device),
+      mStream(stream),
+      mStreamCommon(new Stream(&stream->common)),
+      mStreamMmap(new StreamMmap<audio_stream_out_t>(stream)),
+      mEfGroup(nullptr),
+      mStopWriteThread(false) {}
 
 StreamOut::~StreamOut() {
     ATRACE_CALL();
@@ -158,7 +159,8 @@
     }
     if (mEfGroup) {
         status_t status = EventFlag::deleteEventFlag(&mEfGroup);
-        ALOGE_IF(status, "write MQ event flag deletion error: %s", strerror(-status));
+        ALOGE_IF(status, "write MQ event flag deletion error: %s",
+                 strerror(-status));
     }
     mCallback.clear();
     mDevice->closeOutputStream(mStream);
@@ -166,100 +168,104 @@
 }
 
 // Methods from ::android::hardware::audio::V2_0::IStream follow.
-Return<uint64_t> StreamOut::getFrameSize()  {
+Return<uint64_t> StreamOut::getFrameSize() {
     return audio_stream_out_frame_size(mStream);
 }
 
-Return<uint64_t> StreamOut::getFrameCount()  {
+Return<uint64_t> StreamOut::getFrameCount() {
     return mStreamCommon->getFrameCount();
 }
 
-Return<uint64_t> StreamOut::getBufferSize()  {
+Return<uint64_t> StreamOut::getBufferSize() {
     return mStreamCommon->getBufferSize();
 }
 
-Return<uint32_t> StreamOut::getSampleRate()  {
+Return<uint32_t> StreamOut::getSampleRate() {
     return mStreamCommon->getSampleRate();
 }
 
-Return<void> StreamOut::getSupportedSampleRates(getSupportedSampleRates_cb _hidl_cb)  {
+Return<void> StreamOut::getSupportedSampleRates(
+    getSupportedSampleRates_cb _hidl_cb) {
     return mStreamCommon->getSupportedSampleRates(_hidl_cb);
 }
 
-Return<Result> StreamOut::setSampleRate(uint32_t sampleRateHz)  {
+Return<Result> StreamOut::setSampleRate(uint32_t sampleRateHz) {
     return mStreamCommon->setSampleRate(sampleRateHz);
 }
 
-Return<AudioChannelMask> StreamOut::getChannelMask()  {
+Return<AudioChannelMask> StreamOut::getChannelMask() {
     return mStreamCommon->getChannelMask();
 }
 
-Return<void> StreamOut::getSupportedChannelMasks(getSupportedChannelMasks_cb _hidl_cb)  {
+Return<void> StreamOut::getSupportedChannelMasks(
+    getSupportedChannelMasks_cb _hidl_cb) {
     return mStreamCommon->getSupportedChannelMasks(_hidl_cb);
 }
 
-Return<Result> StreamOut::setChannelMask(AudioChannelMask mask)  {
+Return<Result> StreamOut::setChannelMask(AudioChannelMask mask) {
     return mStreamCommon->setChannelMask(mask);
 }
 
-Return<AudioFormat> StreamOut::getFormat()  {
+Return<AudioFormat> StreamOut::getFormat() {
     return mStreamCommon->getFormat();
 }
 
-Return<void> StreamOut::getSupportedFormats(getSupportedFormats_cb _hidl_cb)  {
+Return<void> StreamOut::getSupportedFormats(getSupportedFormats_cb _hidl_cb) {
     return mStreamCommon->getSupportedFormats(_hidl_cb);
 }
 
-Return<Result> StreamOut::setFormat(AudioFormat format)  {
+Return<Result> StreamOut::setFormat(AudioFormat format) {
     return mStreamCommon->setFormat(format);
 }
 
-Return<void> StreamOut::getAudioProperties(getAudioProperties_cb _hidl_cb)  {
+Return<void> StreamOut::getAudioProperties(getAudioProperties_cb _hidl_cb) {
     return mStreamCommon->getAudioProperties(_hidl_cb);
 }
 
-Return<Result> StreamOut::addEffect(uint64_t effectId)  {
+Return<Result> StreamOut::addEffect(uint64_t effectId) {
     return mStreamCommon->addEffect(effectId);
 }
 
-Return<Result> StreamOut::removeEffect(uint64_t effectId)  {
+Return<Result> StreamOut::removeEffect(uint64_t effectId) {
     return mStreamCommon->removeEffect(effectId);
 }
 
-Return<Result> StreamOut::standby()  {
+Return<Result> StreamOut::standby() {
     return mStreamCommon->standby();
 }
 
-Return<AudioDevice> StreamOut::getDevice()  {
+Return<AudioDevice> StreamOut::getDevice() {
     return mStreamCommon->getDevice();
 }
 
-Return<Result> StreamOut::setDevice(const DeviceAddress& address)  {
+Return<Result> StreamOut::setDevice(const DeviceAddress& address) {
     return mStreamCommon->setDevice(address);
 }
 
-Return<Result> StreamOut::setConnectedState(const DeviceAddress& address, bool connected)  {
+Return<Result> StreamOut::setConnectedState(const DeviceAddress& address,
+                                            bool connected) {
     return mStreamCommon->setConnectedState(address, connected);
 }
 
-Return<Result> StreamOut::setHwAvSync(uint32_t hwAvSync)  {
+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<void> StreamOut::getParameters(const hidl_vec<hidl_string>& keys,
+                                      getParameters_cb _hidl_cb) {
     return mStreamCommon->getParameters(keys, _hidl_cb);
 }
 
-Return<Result> StreamOut::setParameters(const hidl_vec<ParameterValue>& parameters)  {
+Return<Result> StreamOut::setParameters(
+    const hidl_vec<ParameterValue>& parameters) {
     return mStreamCommon->setParameters(parameters);
 }
 
-Return<void> StreamOut::debugDump(const hidl_handle& fd)  {
+Return<void> StreamOut::debugDump(const hidl_handle& fd) {
     return mStreamCommon->debugDump(fd);
 }
 
-Return<Result> StreamOut::close()  {
+Return<Result> StreamOut::close() {
     if (mIsClosed) return Result::INVALID_STATE;
     mIsClosed = true;
     if (mWriteThread.get()) {
@@ -272,78 +278,98 @@
 }
 
 // Methods from ::android::hardware::audio::V2_0::IStreamOut follow.
-Return<uint32_t> StreamOut::getLatency()  {
+Return<uint32_t> StreamOut::getLatency() {
     return mStream->get_latency(mStream);
 }
 
-Return<Result> StreamOut::setVolume(float left, float right)  {
-    Result retval(Result::NOT_SUPPORTED);
-    if (mStream->set_volume != NULL) {
-        retval = Stream::analyzeStatus(
-                "set_volume", mStream->set_volume(mStream, left, right));
+Return<Result> StreamOut::setVolume(float left, float right) {
+    if (mStream->set_volume == NULL) {
+        return Result::NOT_SUPPORTED;
     }
-    return retval;
+    if (!isGainNormalized(left)) {
+        ALOGW("Can not set a stream output volume {%f, %f} outside [0,1]", left,
+              right);
+        return Result::INVALID_ARGUMENTS;
+    }
+    return Stream::analyzeStatus("set_volume",
+                                 mStream->set_volume(mStream, left, right));
 }
 
-Return<void> StreamOut::prepareForWriting(
-        uint32_t frameSize, uint32_t framesCount, prepareForWriting_cb _hidl_cb)  {
+Return<void> StreamOut::prepareForWriting(uint32_t frameSize,
+                                          uint32_t framesCount,
+                                          prepareForWriting_cb _hidl_cb) {
     status_t status;
-    ThreadInfo threadInfo = { 0, 0 };
+    ThreadInfo threadInfo = {0, 0};
+
+    // Wrap the _hidl_cb to return an error
+    auto sendError = [this, &threadInfo, &_hidl_cb](Result result) {
+        _hidl_cb(result, CommandMQ::Descriptor(), DataMQ::Descriptor(),
+                 StatusMQ::Descriptor(), threadInfo);
+
+    };
+
     // Create message queues.
     if (mDataMQ) {
         ALOGE("the client attempts to call prepareForWriting twice");
-        _hidl_cb(Result::INVALID_STATE,
-                CommandMQ::Descriptor(), DataMQ::Descriptor(), StatusMQ::Descriptor(), threadInfo);
+        sendError(Result::INVALID_STATE);
         return Void();
     }
     std::unique_ptr<CommandMQ> tempCommandMQ(new CommandMQ(1));
 
-    if (frameSize > std::numeric_limits<size_t>::max() / framesCount) {
-        ALOGE("Requested buffer is too big, %d*%d can not fit in size_t", frameSize, framesCount);
-        _hidl_cb(Result::INVALID_ARGUMENTS,
-                CommandMQ::Descriptor(), DataMQ::Descriptor(), StatusMQ::Descriptor(), threadInfo);
+    // Check frameSize and framesCount
+    if (frameSize == 0 || framesCount == 0) {
+        ALOGE("Null frameSize (%u) or framesCount (%u)", frameSize,
+              framesCount);
+        sendError(Result::INVALID_ARGUMENTS);
         return Void();
     }
-    std::unique_ptr<DataMQ> tempDataMQ(new DataMQ(frameSize * framesCount, true /* EventFlag */));
+    // A message queue asserts if it can not handle the requested buffer,
+    // thus the client has to guess the maximum size it can handle
+    size_t metadataOverhead =
+        100000;  // Arbitrary margin for the overhead of a message queue
+    if (frameSize >
+        (std::numeric_limits<size_t>::max() - metadataOverhead) / framesCount) {
+        ALOGE("Buffer too big: %u*%u bytes can not fit in a message queue",
+              frameSize, framesCount);
+        sendError(Result::INVALID_ARGUMENTS);
+        return Void();
+    }
+    std::unique_ptr<DataMQ> tempDataMQ(
+        new DataMQ(frameSize * framesCount, true /* EventFlag */));
 
     std::unique_ptr<StatusMQ> tempStatusMQ(new StatusMQ(1));
-    if (!tempCommandMQ->isValid() || !tempDataMQ->isValid() || !tempStatusMQ->isValid()) {
+    if (!tempCommandMQ->isValid() || !tempDataMQ->isValid() ||
+        !tempStatusMQ->isValid()) {
         ALOGE_IF(!tempCommandMQ->isValid(), "command MQ is invalid");
         ALOGE_IF(!tempDataMQ->isValid(), "data MQ is invalid");
         ALOGE_IF(!tempStatusMQ->isValid(), "status MQ is invalid");
-        _hidl_cb(Result::INVALID_ARGUMENTS,
-                CommandMQ::Descriptor(), DataMQ::Descriptor(), StatusMQ::Descriptor(), threadInfo);
+        sendError(Result::INVALID_ARGUMENTS);
         return Void();
     }
     EventFlag* tempRawEfGroup{};
-    status = EventFlag::createEventFlag(tempDataMQ->getEventFlagWord(), &tempRawEfGroup);
-    std::unique_ptr<EventFlag, void(*)(EventFlag*)> tempElfGroup(tempRawEfGroup,[](auto *ef) {
-            EventFlag::deleteEventFlag(&ef); });
+    status = EventFlag::createEventFlag(tempDataMQ->getEventFlagWord(),
+                                        &tempRawEfGroup);
+    std::unique_ptr<EventFlag, void (*)(EventFlag*)> tempElfGroup(
+        tempRawEfGroup, [](auto* ef) { EventFlag::deleteEventFlag(&ef); });
     if (status != OK || !tempElfGroup) {
         ALOGE("failed creating event flag for data MQ: %s", strerror(-status));
-        _hidl_cb(Result::INVALID_ARGUMENTS,
-                CommandMQ::Descriptor(), DataMQ::Descriptor(), StatusMQ::Descriptor(), threadInfo);
+        sendError(Result::INVALID_ARGUMENTS);
         return Void();
     }
 
     // Create and launch the thread.
     auto tempWriteThread = std::make_unique<WriteThread>(
-            &mStopWriteThread,
-            mStream,
-            tempCommandMQ.get(),
-            tempDataMQ.get(),
-            tempStatusMQ.get(),
-            tempElfGroup.get());
+        &mStopWriteThread, mStream, tempCommandMQ.get(), tempDataMQ.get(),
+        tempStatusMQ.get(), tempElfGroup.get());
     if (!tempWriteThread->init()) {
-        _hidl_cb(Result::INVALID_ARGUMENTS,
-                 CommandMQ::Descriptor(), DataMQ::Descriptor(), StatusMQ::Descriptor(), threadInfo);
+        ALOGW("failed to start writer thread: %s", strerror(-status));
+        sendError(Result::INVALID_ARGUMENTS);
         return Void();
     }
     status = tempWriteThread->run("writer", PRIORITY_URGENT_AUDIO);
     if (status != OK) {
         ALOGW("failed to start writer thread: %s", strerror(-status));
-        _hidl_cb(Result::INVALID_ARGUMENTS,
-                CommandMQ::Descriptor(), DataMQ::Descriptor(), StatusMQ::Descriptor(), threadInfo);
+        sendError(Result::INVALID_ARGUMENTS);
         return Void();
     }
 
@@ -354,33 +380,34 @@
     mEfGroup = tempElfGroup.release();
     threadInfo.pid = getpid();
     threadInfo.tid = mWriteThread->getTid();
-    _hidl_cb(Result::OK,
-            *mCommandMQ->getDesc(), *mDataMQ->getDesc(), *mStatusMQ->getDesc(),
-            threadInfo);
+    _hidl_cb(Result::OK, *mCommandMQ->getDesc(), *mDataMQ->getDesc(),
+             *mStatusMQ->getDesc(), threadInfo);
     return Void();
 }
 
-Return<void> StreamOut::getRenderPosition(getRenderPosition_cb _hidl_cb)  {
+Return<void> StreamOut::getRenderPosition(getRenderPosition_cb _hidl_cb) {
     uint32_t halDspFrames;
     Result retval = Stream::analyzeStatus(
-            "get_render_position", mStream->get_render_position(mStream, &halDspFrames));
+        "get_render_position",
+        mStream->get_render_position(mStream, &halDspFrames));
     _hidl_cb(retval, halDspFrames);
     return Void();
 }
 
-Return<void> StreamOut::getNextWriteTimestamp(getNextWriteTimestamp_cb _hidl_cb)  {
+Return<void> StreamOut::getNextWriteTimestamp(
+    getNextWriteTimestamp_cb _hidl_cb) {
     Result retval(Result::NOT_SUPPORTED);
     int64_t timestampUs = 0;
     if (mStream->get_next_write_timestamp != NULL) {
         retval = Stream::analyzeStatus(
-                "get_next_write_timestamp",
-                mStream->get_next_write_timestamp(mStream, &timestampUs));
+            "get_next_write_timestamp",
+            mStream->get_next_write_timestamp(mStream, &timestampUs));
     }
     _hidl_cb(retval, timestampUs);
     return Void();
 }
 
-Return<Result> StreamOut::setCallback(const sp<IStreamOutCallback>& callback)  {
+Return<Result> StreamOut::setCallback(const sp<IStreamOutCallback>& callback) {
     if (mStream->set_callback == NULL) return Result::NOT_SUPPORTED;
     int result = mStream->set_callback(mStream, StreamOut::asyncCallback, this);
     if (result == 0) {
@@ -389,14 +416,15 @@
     return Stream::analyzeStatus("set_callback", result);
 }
 
-Return<Result> StreamOut::clearCallback()  {
+Return<Result> StreamOut::clearCallback() {
     if (mStream->set_callback == NULL) return Result::NOT_SUPPORTED;
     mCallback.clear();
     return Result::OK;
 }
 
 // static
-int StreamOut::asyncCallback(stream_callback_event_t event, void*, void *cookie) {
+int StreamOut::asyncCallback(stream_callback_event_t event, void*,
+                             void* cookie) {
     wp<StreamOut> weakSelf(reinterpret_cast<StreamOut*>(cookie));
     sp<StreamOut> self = weakSelf.promote();
     if (self == nullptr || self->mCallback == nullptr) return 0;
@@ -418,53 +446,57 @@
     return 0;
 }
 
-Return<void> StreamOut::supportsPauseAndResume(supportsPauseAndResume_cb _hidl_cb)  {
+Return<void> StreamOut::supportsPauseAndResume(
+    supportsPauseAndResume_cb _hidl_cb) {
     _hidl_cb(mStream->pause != NULL, mStream->resume != NULL);
     return Void();
 }
 
-Return<Result> StreamOut::pause()  {
-    return mStream->pause != NULL ?
-            Stream::analyzeStatus("pause", mStream->pause(mStream)) :
-            Result::NOT_SUPPORTED;
+Return<Result> StreamOut::pause() {
+    return mStream->pause != NULL
+               ? Stream::analyzeStatus("pause", mStream->pause(mStream))
+               : Result::NOT_SUPPORTED;
 }
 
-Return<Result> StreamOut::resume()  {
-    return mStream->resume != NULL ?
-            Stream::analyzeStatus("resume", mStream->resume(mStream)) :
-            Result::NOT_SUPPORTED;
+Return<Result> StreamOut::resume() {
+    return mStream->resume != NULL
+               ? Stream::analyzeStatus("resume", mStream->resume(mStream))
+               : Result::NOT_SUPPORTED;
 }
 
-Return<bool> StreamOut::supportsDrain()  {
+Return<bool> StreamOut::supportsDrain() {
     return mStream->drain != NULL;
 }
 
-Return<Result> StreamOut::drain(AudioDrain type)  {
-    return mStream->drain != NULL ?
-            Stream::analyzeStatus(
-                    "drain", mStream->drain(mStream, static_cast<audio_drain_type_t>(type))) :
-            Result::NOT_SUPPORTED;
+Return<Result> StreamOut::drain(AudioDrain type) {
+    return mStream->drain != NULL
+               ? Stream::analyzeStatus(
+                     "drain",
+                     mStream->drain(mStream,
+                                    static_cast<audio_drain_type_t>(type)))
+               : Result::NOT_SUPPORTED;
 }
 
-Return<Result> StreamOut::flush()  {
-    return mStream->flush != NULL ?
-            Stream::analyzeStatus("flush", mStream->flush(mStream)) :
-            Result::NOT_SUPPORTED;
+Return<Result> StreamOut::flush() {
+    return mStream->flush != NULL
+               ? Stream::analyzeStatus("flush", mStream->flush(mStream))
+               : Result::NOT_SUPPORTED;
 }
 
 // static
-Result StreamOut::getPresentationPositionImpl(
-        audio_stream_out_t *stream, uint64_t *frames, TimeSpec *timeStamp) {
+Result StreamOut::getPresentationPositionImpl(audio_stream_out_t* stream,
+                                              uint64_t* frames,
+                                              TimeSpec* timeStamp) {
     Result retval(Result::NOT_SUPPORTED);
     if (stream->get_presentation_position == NULL) return retval;
     struct timespec halTimeStamp;
     retval = Stream::analyzeStatus(
-            "get_presentation_position",
-            stream->get_presentation_position(stream, frames, &halTimeStamp),
-            // Don't logspam on EINVAL--it's normal for get_presentation_position
-            // to return it sometimes. EAGAIN may be returned by A2DP audio HAL
-            // implementation.
-            EINVAL, EAGAIN);
+        "get_presentation_position",
+        stream->get_presentation_position(stream, frames, &halTimeStamp),
+        // Don't logspam on EINVAL--it's normal for get_presentation_position
+        // to return it sometimes. EAGAIN may be returned by A2DP audio HAL
+        // implementation.
+        EINVAL, EAGAIN);
     if (retval == Result::OK) {
         timeStamp->tvSec = halTimeStamp.tv_sec;
         timeStamp->tvNSec = halTimeStamp.tv_nsec;
@@ -472,9 +504,10 @@
     return retval;
 }
 
-Return<void> StreamOut::getPresentationPosition(getPresentationPosition_cb _hidl_cb)  {
+Return<void> StreamOut::getPresentationPosition(
+    getPresentationPosition_cb _hidl_cb) {
     uint64_t frames = 0;
-    TimeSpec timeStamp = { 0, 0 };
+    TimeSpec timeStamp = {0, 0};
     Result retval = getPresentationPositionImpl(mStream, &frames, &timeStamp);
     _hidl_cb(retval, frames, timeStamp);
     return Void();
@@ -488,9 +521,10 @@
     return mStreamMmap->stop();
 }
 
-Return<void> StreamOut::createMmapBuffer(int32_t minSizeFrames, createMmapBuffer_cb _hidl_cb) {
+Return<void> StreamOut::createMmapBuffer(int32_t minSizeFrames,
+                                         createMmapBuffer_cb _hidl_cb) {
     return mStreamMmap->createMmapBuffer(
-            minSizeFrames, audio_stream_out_frame_size(mStream), _hidl_cb);
+        minSizeFrames, audio_stream_out_frame_size(mStream), _hidl_cb);
 }
 
 Return<void> StreamOut::getMmapPosition(getMmapPosition_cb _hidl_cb) {
diff --git a/audio/2.0/default/Util.h b/audio/2.0/default/Util.h
new file mode 100644
index 0000000..72eea50
--- /dev/null
+++ b/audio/2.0/default/Util.h
@@ -0,0 +1,37 @@
+/*
+ * 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_V2_0_UTIL_H
+#define ANDROID_HARDWARE_AUDIO_V2_0_UTIL_H
+
+namespace android {
+namespace hardware {
+namespace audio {
+namespace V2_0 {
+namespace implementation {
+
+/** @return true if gain is between 0 and 1 included. */
+constexpr bool isGainNormalized(float gain) {
+    return gain >= 0.0 && gain <= 1.0;
+}
+
+}  // namespace implementation
+}  // namespace V2_0
+}  // namespace audio
+}  // namespace hardware
+}  // namespace android
+
+#endif  // ANDROID_HARDWARE_AUDIO_V2_0_UTIL_H
diff --git a/audio/2.0/vts/functional/AudioPrimaryHidlHalTest.cpp b/audio/2.0/vts/functional/AudioPrimaryHidlHalTest.cpp
index 074903f..83a1db0 100644
--- a/audio/2.0/vts/functional/AudioPrimaryHidlHalTest.cpp
+++ b/audio/2.0/vts/functional/AudioPrimaryHidlHalTest.cpp
@@ -36,9 +36,9 @@
 #include <android/hardware/audio/2.0/types.h>
 #include <android/hardware/audio/common/2.0/types.h>
 
-#include "utility/ReturnIn.h"
 #include "utility/AssertOk.h"
 #include "utility/PrettyPrintAudioTypes.h"
+#include "utility/ReturnIn.h"
 
 using std::string;
 using std::to_string;
@@ -59,7 +59,8 @@
 using ::android::hardware::audio::V2_0::IStream;
 using ::android::hardware::audio::V2_0::IStreamIn;
 using ::android::hardware::audio::V2_0::TimeSpec;
-using ReadParameters = ::android::hardware::audio::V2_0::IStreamIn::ReadParameters;
+using ReadParameters =
+    ::android::hardware::audio::V2_0::IStreamIn::ReadParameters;
 using ReadStatus = ::android::hardware::audio::V2_0::IStreamIn::ReadStatus;
 using ::android::hardware::audio::V2_0::IStreamOut;
 using ::android::hardware::audio::V2_0::IStreamOutCallback;
@@ -82,35 +83,51 @@
 
 using utility::returnIn;
 
+const char* getTestName() {
+    return ::testing::UnitTest::GetInstance()->current_test_info()->name();
+}
+
 namespace doc {
 /** Document the current test case.
- * Eg: calling `doc::test("Dump the state of the hal")` in the "debugDump" test will output:
- *   <testcase name="debugDump" status="run" time="6" classname="AudioPrimaryHidlTest"
-            description="Dump the state of the hal." />
- * see https://github.com/google/googletest/blob/master/googletest/docs/AdvancedGuide.md#logging-additional-information
+ * Eg: calling `doc::test("Dump the state of the hal")` in the "debugDump" test
+ * will output:
+ *   <testcase name="debugDump" status="run" time="6"
+ *             classname="AudioPrimaryHidlTest"
+               description="Dump the state of the hal." />
+ * see
+ https://github.com/google/googletest/blob/master/googletest/docs/AdvancedGuide.md#logging-additional-information
  */
 void test(const std::string& testCaseDocumentation) {
     ::testing::Test::RecordProperty("description", testCaseDocumentation);
 }
 
-/** Document why a test was not fully run. Usually due to an optional feature not implemented. */
+/** Document why a test was not fully run. Usually due to an optional feature
+ * not implemented. */
 void partialTest(const std::string& reason) {
+    LOG(INFO) << "Test " << getTestName() << " partially run: " << reason;
     ::testing::Test::RecordProperty("partialyRunTest", reason);
 }
+
+/** Add a note to the test. */
+void note(const std::string& note) {
+    LOG(INFO) << "Test " << getTestName() << " noted: " << note;
+    ::testing::Test::RecordProperty("note", note);
+}
 }
 
 // Register callback for static object destruction
 // Avoid destroying static objects after main return.
-// Post main return destruction leads to incorrect gtest timing measurements as well as harder
+// Post main return destruction leads to incorrect gtest timing measurements as
+// well as harder
 // debuging if anything goes wrong during destruction.
 class Environment : public ::testing::Environment {
-public:
-    using TearDownFunc = std::function<void ()>;
-     void registerTearDown(TearDownFunc&& tearDown) {
-         tearDowns.push_back(std::move(tearDown));
+   public:
+    using TearDownFunc = std::function<void()>;
+    void registerTearDown(TearDownFunc&& tearDown) {
+        tearDowns.push_back(std::move(tearDown));
     }
 
-private:
+   private:
     void TearDown() override {
         // Call the tear downs in reverse order of insertion
         for (auto& tearDown : tearDowns) {
@@ -123,7 +140,7 @@
 static Environment* environment;
 
 class HidlTest : public ::testing::VtsHalHidlTargetTestBase {
-protected:
+   protected:
     // Convenient member to store results
     Result res;
 };
@@ -134,18 +151,19 @@
 
 // Test all audio devices
 class AudioHidlTest : public HidlTest {
-public:
+   public:
     void SetUp() override {
-        ASSERT_NO_FATAL_FAILURE(HidlTest::SetUp()); // setup base
+        ASSERT_NO_FATAL_FAILURE(HidlTest::SetUp());  // setup base
 
         if (devicesFactory == nullptr) {
-            environment->registerTearDown([]{ devicesFactory.clear(); });
-            devicesFactory = ::testing::VtsHalHidlTargetTestBase::getService<IDevicesFactory>();
+            environment->registerTearDown([] { devicesFactory.clear(); });
+            devicesFactory = ::testing::VtsHalHidlTargetTestBase::getService<
+                IDevicesFactory>();
         }
         ASSERT_TRUE(devicesFactory != nullptr);
     }
 
-protected:
+   protected:
     // Cache the devicesFactory retrieval to speed up each test by ~0.5s
     static sp<IDevicesFactory> devicesFactory;
 };
@@ -171,26 +189,27 @@
 
 // Test the primary device
 class AudioPrimaryHidlTest : public AudioHidlTest {
-public:
+   public:
     /** Primary HAL test are NOT thread safe. */
     void SetUp() override {
-        ASSERT_NO_FATAL_FAILURE(AudioHidlTest::SetUp()); // setup base
+        ASSERT_NO_FATAL_FAILURE(AudioHidlTest::SetUp());  // setup base
 
         if (device == nullptr) {
             IDevicesFactory::Result result;
             sp<IDevice> baseDevice;
-            ASSERT_OK(devicesFactory->openDevice(IDevicesFactory::Device::PRIMARY,
-                                                 returnIn(result, baseDevice)));
+            ASSERT_OK(
+                devicesFactory->openDevice(IDevicesFactory::Device::PRIMARY,
+                                           returnIn(result, baseDevice)));
             ASSERT_OK(result);
             ASSERT_TRUE(baseDevice != nullptr);
 
-            environment->registerTearDown([]{ device.clear(); });
+            environment->registerTearDown([] { device.clear(); });
             device = IPrimaryDevice::castFrom(baseDevice);
             ASSERT_TRUE(device != nullptr);
         }
     }
 
-protected:
+   protected:
     // Cache the device opening to speed up each test by ~0.5s
     static sp<IPrimaryDevice> device;
 };
@@ -211,15 +230,15 @@
 
 template <class Property>
 class AccessorPrimaryHidlTest : public AudioPrimaryHidlTest {
-protected:
-
+   protected:
     /** Test a property getter and setter. */
     template <class Getter, class Setter>
-    void testAccessors(const string& propertyName, const vector<Property>& valuesToTest,
-                       Setter setter, Getter getter,
+    void testAccessors(const string& propertyName,
+                       const vector<Property>& valuesToTest, Setter setter,
+                       Getter getter,
                        const vector<Property>& invalidValues = {}) {
-
-        Property initialValue; // Save initial value to restore it at the end of the test
+        Property initialValue;  // Save initial value to restore it at the end
+                                // of the test
         ASSERT_OK((device.get()->*getter)(returnIn(res, initialValue)));
         ASSERT_OK(res);
 
@@ -235,17 +254,21 @@
         }
 
         for (Property invalidValue : invalidValues) {
-            SCOPED_TRACE("Try to set " + propertyName + " with the invalid value " +
+            SCOPED_TRACE("Try to set " + propertyName +
+                         " with the invalid value " +
                          testing::PrintToString(invalidValue));
-            EXPECT_RESULT(Result::INVALID_ARGUMENTS, (device.get()->*setter)(invalidValue));
+            EXPECT_RESULT(Result::INVALID_ARGUMENTS,
+                          (device.get()->*setter)(invalidValue));
         }
 
-        ASSERT_OK((device.get()->*setter)(initialValue)); // restore initial value
+        ASSERT_OK(
+            (device.get()->*setter)(initialValue));  // restore initial value
     }
 
     /** Test the getter and setter of an optional feature. */
     template <class Getter, class Setter>
-    void testOptionalAccessors(const string& propertyName, const vector<Property>& valuesToTest,
+    void testOptionalAccessors(const string& propertyName,
+                               const vector<Property>& valuesToTest,
                                Setter setter, Getter getter,
                                const vector<Property>& invalidValues = {}) {
         doc::test("Test the optional " + propertyName + " getters and setter");
@@ -257,10 +280,11 @@
                 doc::partialTest(propertyName + " getter is not supported");
                 return;
             }
-            ASSERT_OK(res); // If it is supported it must succeed
+            ASSERT_OK(res);  // If it is supported it must succeed
         }
         // The feature is supported, test it
-        testAccessors(propertyName, valuesToTest, setter, getter, invalidValues);
+        testAccessors(propertyName, valuesToTest, setter, getter,
+                      invalidValues);
     }
 };
 
@@ -268,12 +292,15 @@
 
 TEST_F(BoolAccessorPrimaryHidlTest, MicMuteTest) {
     doc::test("Check that the mic can be muted and unmuted");
-    testAccessors("mic mute", {true, false, true}, &IDevice::setMicMute, &IDevice::getMicMute);
+    testAccessors("mic mute", {true, false, true}, &IDevice::setMicMute,
+                  &IDevice::getMicMute);
     // TODO: check that the mic is really muted (all sample are 0)
 }
 
 TEST_F(BoolAccessorPrimaryHidlTest, MasterMuteTest) {
-    doc::test("If master mute is supported, try to mute and unmute the master output");
+    doc::test(
+        "If master mute is supported, try to mute and unmute the master "
+        "output");
     testOptionalAccessors("master mute", {true, false, true},
                           &IDevice::setMasterMute, &IDevice::getMasterMute);
     // TODO: check that the master volume is really muted
@@ -282,7 +309,7 @@
 using FloatAccessorPrimaryHidlTest = AccessorPrimaryHidlTest<float>;
 TEST_F(FloatAccessorPrimaryHidlTest, MasterVolumeTest) {
     doc::test("Test the master volume if supported");
-    testOptionalAccessors("master volume",  {0, 0.5, 1},
+    testOptionalAccessors("master volume", {0, 0.5, 1},
                           &IDevice::setMasterVolume, &IDevice::getMasterVolume,
                           {-0.1, 1.1, NAN, INFINITY, -INFINITY,
                            1 + std::numeric_limits<float>::epsilon()});
@@ -294,10 +321,10 @@
 //////////////////////////////////////////////////////////////////////////////
 
 class AudioPatchPrimaryHidlTest : public AudioPrimaryHidlTest {
-protected:
+   protected:
     bool areAudioPatchesSupported() {
         auto result = device->supportsAudioPatches();
-        EXPECT_TRUE(result.isOk());
+        EXPECT_IS_OK(result);
         return result;
     }
 };
@@ -311,27 +338,30 @@
     // TODO: test audio patches
 }
 
-
 //////////////////////////////////////////////////////////////////////////////
 //////////////// Required and recommended audio format support ///////////////
-// From: https://source.android.com/compatibility/android-cdd.html#5_4_audio_recording
-// From: https://source.android.com/compatibility/android-cdd.html#5_5_audio_playback
+// From:
+// https://source.android.com/compatibility/android-cdd.html#5_4_audio_recording
+// From:
+// https://source.android.com/compatibility/android-cdd.html#5_5_audio_playback
 /////////// TODO: move to the beginning of the file for easier update ////////
 //////////////////////////////////////////////////////////////////////////////
 
 class AudioConfigPrimaryTest : public AudioPatchPrimaryHidlTest {
-public:
+   public:
     // Cache result ?
     static const vector<AudioConfig> getRequiredSupportPlaybackAudioConfig() {
-        return combineAudioConfig({AudioChannelMask::OUT_STEREO, AudioChannelMask::OUT_MONO},
-                                  {8000, 11025, 16000, 22050, 32000, 44100},
-                                  {AudioFormat::PCM_16_BIT});
+        return combineAudioConfig(
+            {AudioChannelMask::OUT_STEREO, AudioChannelMask::OUT_MONO},
+            {8000, 11025, 16000, 22050, 32000, 44100},
+            {AudioFormat::PCM_16_BIT});
     }
 
-    static const vector<AudioConfig> getRecommendedSupportPlaybackAudioConfig() {
-        return combineAudioConfig({AudioChannelMask::OUT_STEREO, AudioChannelMask::OUT_MONO},
-                                  {24000, 48000},
-                                  {AudioFormat::PCM_16_BIT});
+    static const vector<AudioConfig>
+    getRecommendedSupportPlaybackAudioConfig() {
+        return combineAudioConfig(
+            {AudioChannelMask::OUT_STEREO, AudioChannelMask::OUT_MONO},
+            {24000, 48000}, {AudioFormat::PCM_16_BIT});
     }
 
     static const vector<AudioConfig> getSupportedPlaybackAudioConfig() {
@@ -346,8 +376,7 @@
                                   {AudioFormat::PCM_16_BIT});
     }
     static const vector<AudioConfig> getRecommendedSupportCaptureAudioConfig() {
-        return combineAudioConfig({AudioChannelMask::IN_STEREO},
-                                  {22050, 48000},
+        return combineAudioConfig({AudioChannelMask::IN_STEREO}, {22050, 48000},
                                   {AudioFormat::PCM_16_BIT});
     }
     static const vector<AudioConfig> getSupportedCaptureAudioConfig() {
@@ -355,13 +384,13 @@
         // as declared in the policy configuration
         return {};
     }
-private:
+
+   private:
     static const vector<AudioConfig> combineAudioConfig(
-            vector<AudioChannelMask> channelMasks,
-            vector<uint32_t> sampleRates,
-            vector<AudioFormat> formats) {
+        vector<AudioChannelMask> channelMasks, vector<uint32_t> sampleRates,
+        vector<AudioFormat> formats) {
         vector<AudioConfig> configs;
-        for (auto channelMask: channelMasks) {
+        for (auto channelMask : channelMasks) {
             for (auto sampleRate : sampleRates) {
                 for (auto format : formats) {
                     AudioConfig config{};
@@ -383,28 +412,34 @@
  * As the only parameter changing are channel mask and sample rate,
  * only print those ones in the test name.
  */
-static string generateTestName(const testing::TestParamInfo<AudioConfig>& info) {
+static string generateTestName(
+    const testing::TestParamInfo<AudioConfig>& info) {
     const AudioConfig& config = info.param;
-    return to_string(info.index) + "__" + to_string(config.sampleRateHz)+ "_" +
-            // "MONO" is more clear than "FRONT_LEFT"
-            ((config.channelMask == AudioChannelMask::OUT_MONO ||
-              config.channelMask == AudioChannelMask::IN_MONO) ?
-                    "MONO" : toString(config.channelMask));
+    return to_string(info.index) + "__" + to_string(config.sampleRateHz) + "_" +
+           // "MONO" is more clear than "FRONT_LEFT"
+           ((config.channelMask == AudioChannelMask::OUT_MONO ||
+             config.channelMask == AudioChannelMask::IN_MONO)
+                ? "MONO"
+                : toString(config.channelMask));
 }
 
 //////////////////////////////////////////////////////////////////////////////
 ///////////////////////////// getInputBufferSize /////////////////////////////
 //////////////////////////////////////////////////////////////////////////////
 
-// FIXME: execute input test only if platform declares android.hardware.microphone
+// FIXME: execute input test only if platform declares
+// android.hardware.microphone
 //        how to get this value ? is it a property ???
 
-class AudioCaptureConfigPrimaryTest : public AudioConfigPrimaryTest,
-                                      public ::testing::WithParamInterface<AudioConfig> {
-protected:
-    void inputBufferSizeTest(const AudioConfig& audioConfig, bool supportRequired) {
+class AudioCaptureConfigPrimaryTest
+    : public AudioConfigPrimaryTest,
+      public ::testing::WithParamInterface<AudioConfig> {
+   protected:
+    void inputBufferSizeTest(const AudioConfig& audioConfig,
+                             bool supportRequired) {
         uint64_t bufferSize;
-        ASSERT_OK(device->getInputBufferSize(audioConfig, returnIn(res, bufferSize)));
+        ASSERT_OK(
+            device->getInputBufferSize(audioConfig, returnIn(res, bufferSize)));
 
         switch (res) {
             case Result::INVALID_ARGUMENTS:
@@ -416,36 +451,46 @@
                 EXPECT_GT(bufferSize, uint64_t(0));
                 break;
             default:
-                FAIL() << "Invalid return status: " << ::testing::PrintToString(res);
+                FAIL() << "Invalid return status: "
+                       << ::testing::PrintToString(res);
         }
     }
 };
 
-// Test that the required capture config and those declared in the policy are indeed supported
+// Test that the required capture config and those declared in the policy are
+// indeed supported
 class RequiredInputBufferSizeTest : public AudioCaptureConfigPrimaryTest {};
 TEST_P(RequiredInputBufferSizeTest, RequiredInputBufferSizeTest) {
-    doc::test("Input buffer size must be retrievable for a format with required support.");
+    doc::test(
+        "Input buffer size must be retrievable for a format with required "
+        "support.");
     inputBufferSizeTest(GetParam(), true);
 }
 INSTANTIATE_TEST_CASE_P(
-        RequiredInputBufferSize, RequiredInputBufferSizeTest,
-        ::testing::ValuesIn(AudioConfigPrimaryTest::getRequiredSupportCaptureAudioConfig()),
-         &generateTestName);
+    RequiredInputBufferSize, RequiredInputBufferSizeTest,
+    ::testing::ValuesIn(
+        AudioConfigPrimaryTest::getRequiredSupportCaptureAudioConfig()),
+    &generateTestName);
 INSTANTIATE_TEST_CASE_P(
-        SupportedInputBufferSize, RequiredInputBufferSizeTest,
-        ::testing::ValuesIn(AudioConfigPrimaryTest::getSupportedCaptureAudioConfig()),
-         &generateTestName);
+    SupportedInputBufferSize, RequiredInputBufferSizeTest,
+    ::testing::ValuesIn(
+        AudioConfigPrimaryTest::getSupportedCaptureAudioConfig()),
+    &generateTestName);
 
-// Test that the recommended capture config are supported or lead to a INVALID_ARGUMENTS return
+// Test that the recommended capture config are supported or lead to a
+// INVALID_ARGUMENTS return
 class OptionalInputBufferSizeTest : public AudioCaptureConfigPrimaryTest {};
 TEST_P(OptionalInputBufferSizeTest, OptionalInputBufferSizeTest) {
-    doc::test("Input buffer size should be retrievable for a format with recommended support.");
+    doc::test(
+        "Input buffer size should be retrievable for a format with recommended "
+        "support.");
     inputBufferSizeTest(GetParam(), false);
 }
 INSTANTIATE_TEST_CASE_P(
-        RecommendedCaptureAudioConfigSupport, OptionalInputBufferSizeTest,
-        ::testing::ValuesIn(AudioConfigPrimaryTest::getRecommendedSupportCaptureAudioConfig()),
-         &generateTestName);
+    RecommendedCaptureAudioConfigSupport, OptionalInputBufferSizeTest,
+    ::testing::ValuesIn(
+        AudioConfigPrimaryTest::getRecommendedSupportCaptureAudioConfig()),
+    &generateTestName);
 
 //////////////////////////////////////////////////////////////////////////////
 /////////////////////////////// setScreenState ///////////////////////////////
@@ -455,9 +500,10 @@
     doc::test("Check that the hal can receive the screen state");
     for (bool turnedOn : {false, true, true, false, false}) {
         auto ret = device->setScreenState(turnedOn);
-        ASSERT_TRUE(ret.isOk());
+        ASSERT_IS_OK(ret);
         Result result = ret;
-        ASSERT_TRUE(result == Result::OK || result == Result::NOT_SUPPORTED) << toString(result);
+        auto okOrNotSupported = {Result::OK, Result::NOT_SUPPORTED};
+        ASSERT_RESULT(okOrNotSupported, result);
     }
 }
 
@@ -481,34 +527,41 @@
 
 template <class DebugDump>
 static void testDebugDump(DebugDump debugDump) {
+    // Dump in a temporary file
+    // Note that SELinux must be deactivate for this test to work
     FILE* file = tmpfile();
     ASSERT_NE(nullptr, file) << errno;
 
+    // Wrap the temporary file file descriptor in a native handle
     auto* nativeHandle = native_handle_create(1, 0);
     ASSERT_NE(nullptr, nativeHandle);
     nativeHandle->data[0] = fileno(file);
 
+    // Wrap this native handle in a hidl handle
     hidl_handle handle;
     handle.setTo(nativeHandle, true /*take ownership*/);
 
-    // TODO: debugDump does not return a Result.
-    // This mean that the hal can not report that it not implementing the function.
     ASSERT_OK(debugDump(handle));
 
-    rewind(file); // can not fail
-
     // Check that at least one bit was written by the hal
+    // TODO: debugDump does not return a Result.
+    // This mean that the hal can not report that it not implementing the
+    // function.
+    rewind(file);  // can not fail
     char buff;
-    ASSERT_EQ(size_t{1}, fread(&buff, sizeof(buff), 1, file));
+    if (fread(&buff, sizeof(buff), 1, file) != 1) {
+        doc::note("debugDump does not seem implemented");
+    }
     EXPECT_EQ(0, fclose(file)) << errno;
 }
 
-TEST_F(AudioPrimaryHidlTest, debugDump) {
+TEST_F(AudioPrimaryHidlTest, DebugDump) {
     doc::test("Check that the hal can dump its state without error");
-    testDebugDump([this](const auto& handle){ return device->debugDump(handle); });
+    testDebugDump(
+        [this](const auto& handle) { return device->debugDump(handle); });
 }
 
-TEST_F(AudioPrimaryHidlTest, debugDumpInvalidArguments) {
+TEST_F(AudioPrimaryHidlTest, DebugDumpInvalidArguments) {
     doc::test("Check that the hal dump doesn't crash on invalid arguments");
     ASSERT_OK(device->debugDump(hidl_handle()));
 }
@@ -520,14 +573,16 @@
 template <class Stream>
 class OpenStreamTest : public AudioConfigPrimaryTest,
                        public ::testing::WithParamInterface<AudioConfig> {
-protected:
+   protected:
     template <class Open>
     void testOpen(Open openStream, const AudioConfig& config) {
         // FIXME: Open a stream without an IOHandle
         //        This is not required to be accepted by hal implementations
-        AudioIoHandle ioHandle = (AudioIoHandle)AudioHandleConsts::AUDIO_IO_HANDLE_NONE;
+        AudioIoHandle ioHandle =
+            (AudioIoHandle)AudioHandleConsts::AUDIO_IO_HANDLE_NONE;
         AudioConfig suggestedConfig{};
-        ASSERT_OK(openStream(ioHandle, config, returnIn(res, stream, suggestedConfig)));
+        ASSERT_OK(openStream(ioHandle, config,
+                             returnIn(res, stream, suggestedConfig)));
 
         // TODO: only allow failure for RecommendedPlaybackAudioConfig
         switch (res) {
@@ -538,16 +593,19 @@
             case Result::INVALID_ARGUMENTS:
                 ASSERT_TRUE(stream == nullptr);
                 AudioConfig suggestedConfigRetry;
-                // Could not open stream with config, try again with the suggested one
-                ASSERT_OK(openStream(ioHandle, suggestedConfig,
-                                     returnIn(res, stream, suggestedConfigRetry)));
+                // Could not open stream with config, try again with the
+                // suggested one
+                ASSERT_OK(
+                    openStream(ioHandle, suggestedConfig,
+                               returnIn(res, stream, suggestedConfigRetry)));
                 // This time it must succeed
                 ASSERT_OK(res);
-                ASSERT_TRUE(stream == nullptr);
+                ASSERT_TRUE(stream != nullptr);
                 audioConfig = suggestedConfig;
                 break;
             default:
-                FAIL() << "Invalid return status: " << ::testing::PrintToString(res);
+                FAIL() << "Invalid return status: "
+                       << ::testing::PrintToString(res);
         }
         open = true;
     }
@@ -556,15 +614,15 @@
         open = false;
         return stream->close();
     }
-private:
+
+   private:
     void TearDown() override {
         if (open) {
             ASSERT_OK(stream->close());
         }
     }
 
-protected:
-
+   protected:
     AudioConfig audioConfig;
     DeviceAddress address = {};
     sp<Stream> stream;
@@ -575,66 +633,84 @@
 
 class OutputStreamTest : public OpenStreamTest<IStreamOut> {
     virtual void SetUp() override {
-        ASSERT_NO_FATAL_FAILURE(OpenStreamTest::SetUp()); // setup base
+        ASSERT_NO_FATAL_FAILURE(OpenStreamTest::SetUp());  // setup base
         address.device = AudioDevice::OUT_DEFAULT;
         const AudioConfig& config = GetParam();
-        AudioOutputFlag flags = AudioOutputFlag::NONE; // TODO: test all flag combination
-        testOpen([&](AudioIoHandle handle, AudioConfig config, auto cb)
-                 { return device->openOutputStream(handle, address, config, flags, cb); },
-                 config);
+        AudioOutputFlag flags =
+            AudioOutputFlag::NONE;  // TODO: test all flag combination
+        testOpen(
+            [&](AudioIoHandle handle, AudioConfig config, auto cb) {
+                return device->openOutputStream(handle, address, config, flags,
+                                                cb);
+            },
+            config);
     }
 };
 TEST_P(OutputStreamTest, OpenOutputStreamTest) {
-    doc::test("Check that output streams can be open with the required and recommended config");
+    doc::test(
+        "Check that output streams can be open with the required and "
+        "recommended config");
     // Open done in SetUp
 }
 INSTANTIATE_TEST_CASE_P(
-        RequiredOutputStreamConfigSupport, OutputStreamTest,
-        ::testing::ValuesIn(AudioConfigPrimaryTest::getRequiredSupportPlaybackAudioConfig()),
-         &generateTestName);
+    RequiredOutputStreamConfigSupport, OutputStreamTest,
+    ::testing::ValuesIn(
+        AudioConfigPrimaryTest::getRequiredSupportPlaybackAudioConfig()),
+    &generateTestName);
 INSTANTIATE_TEST_CASE_P(
-        SupportedOutputStreamConfig, OutputStreamTest,
-        ::testing::ValuesIn(AudioConfigPrimaryTest::getSupportedPlaybackAudioConfig()),
-         &generateTestName);
+    SupportedOutputStreamConfig, OutputStreamTest,
+    ::testing::ValuesIn(
+        AudioConfigPrimaryTest::getSupportedPlaybackAudioConfig()),
+    &generateTestName);
 
 INSTANTIATE_TEST_CASE_P(
-        RecommendedOutputStreamConfigSupport, OutputStreamTest,
-        ::testing::ValuesIn(AudioConfigPrimaryTest::getRecommendedSupportPlaybackAudioConfig()),
-         &generateTestName);
+    RecommendedOutputStreamConfigSupport, OutputStreamTest,
+    ::testing::ValuesIn(
+        AudioConfigPrimaryTest::getRecommendedSupportPlaybackAudioConfig()),
+    &generateTestName);
 
 ////////////////////////////// openInputStream //////////////////////////////
 
 class InputStreamTest : public OpenStreamTest<IStreamIn> {
-
     virtual void SetUp() override {
-        ASSERT_NO_FATAL_FAILURE(OpenStreamTest::SetUp()); // setup base
+        ASSERT_NO_FATAL_FAILURE(OpenStreamTest::SetUp());  // setup base
         address.device = AudioDevice::IN_DEFAULT;
         const AudioConfig& config = GetParam();
-        AudioInputFlag flags = AudioInputFlag::NONE; // TODO: test all flag combination
-        AudioSource source = AudioSource::DEFAULT; // TODO: test all flag combination
-        testOpen([&](AudioIoHandle handle, AudioConfig config, auto cb)
-                 { return device->openInputStream(handle, address, config, flags, source, cb); },
-                 config);
+        AudioInputFlag flags =
+            AudioInputFlag::NONE;  // TODO: test all flag combination
+        AudioSource source =
+            AudioSource::DEFAULT;  // TODO: test all flag combination
+        testOpen(
+            [&](AudioIoHandle handle, AudioConfig config, auto cb) {
+                return device->openInputStream(handle, address, config, flags,
+                                               source, cb);
+            },
+            config);
     }
 };
 
 TEST_P(InputStreamTest, OpenInputStreamTest) {
-    doc::test("Check that input streams can be open with the required and recommended config");
+    doc::test(
+        "Check that input streams can be open with the required and "
+        "recommended config");
     // Open done in setup
 }
 INSTANTIATE_TEST_CASE_P(
-        RequiredInputStreamConfigSupport, InputStreamTest,
-        ::testing::ValuesIn(AudioConfigPrimaryTest::getRequiredSupportCaptureAudioConfig()),
-         &generateTestName);
+    RequiredInputStreamConfigSupport, InputStreamTest,
+    ::testing::ValuesIn(
+        AudioConfigPrimaryTest::getRequiredSupportCaptureAudioConfig()),
+    &generateTestName);
 INSTANTIATE_TEST_CASE_P(
-        SupportedInputStreamConfig, InputStreamTest,
-        ::testing::ValuesIn(AudioConfigPrimaryTest::getSupportedCaptureAudioConfig()),
-         &generateTestName);
+    SupportedInputStreamConfig, InputStreamTest,
+    ::testing::ValuesIn(
+        AudioConfigPrimaryTest::getSupportedCaptureAudioConfig()),
+    &generateTestName);
 
 INSTANTIATE_TEST_CASE_P(
-        RecommendedInputStreamConfigSupport, InputStreamTest,
-        ::testing::ValuesIn(AudioConfigPrimaryTest::getRecommendedSupportCaptureAudioConfig()),
-         &generateTestName);
+    RecommendedInputStreamConfigSupport, InputStreamTest,
+    ::testing::ValuesIn(
+        AudioConfigPrimaryTest::getRecommendedSupportCaptureAudioConfig()),
+    &generateTestName);
 
 //////////////////////////////////////////////////////////////////////////////
 ////////////////////////////// IStream getters ///////////////////////////////
@@ -645,7 +721,7 @@
 template <class R>
 static R extract(Return<R> ret) {
     if (!ret.isOk()) {
-        ADD_FAILURE();
+        EXPECT_IS_OK(ret);
         return R{};
     }
     return ret;
@@ -654,49 +730,63 @@
 /* Could not find a way to write a test for two parametrized class fixure
  * thus use this macro do duplicate tests for Input and Output stream */
 #define TEST_IO_STREAM(test_name, documentation, code) \
-    TEST_P(InputStreamTest, test_name) { \
-        doc::test(documentation); \
-        code; \
-    } \
-    TEST_P(OutputStreamTest, test_name) { \
-        doc::test(documentation); \
-        code; \
+    TEST_P(InputStreamTest, test_name) {               \
+        doc::test(documentation);                      \
+        code;                                          \
+    }                                                  \
+    TEST_P(OutputStreamTest, test_name) {              \
+        doc::test(documentation);                      \
+        code;                                          \
     }
 
-TEST_IO_STREAM(GetFrameCount, "Check that the stream frame count == the one it was opened with",
-               ASSERT_EQ(audioConfig.frameCount, extract(stream->getFrameCount())))
+TEST_IO_STREAM(
+    GetFrameCount,
+    "Check that the stream frame count == the one it was opened with",
+    ASSERT_EQ(audioConfig.frameCount, extract(stream->getFrameCount())))
 
-TEST_IO_STREAM(GetSampleRate, "Check that the stream sample rate == the one it was opened with",
-               ASSERT_EQ(audioConfig.sampleRateHz, extract(stream->getSampleRate())))
+TEST_IO_STREAM(
+    GetSampleRate,
+    "Check that the stream sample rate == the one it was opened with",
+    ASSERT_EQ(audioConfig.sampleRateHz, extract(stream->getSampleRate())))
 
-TEST_IO_STREAM(GetChannelMask, "Check that the stream channel mask == the one it was opened with",
-               ASSERT_EQ(audioConfig.channelMask, extract(stream->getChannelMask())))
+TEST_IO_STREAM(
+    GetChannelMask,
+    "Check that the stream channel mask == the one it was opened with",
+    ASSERT_EQ(audioConfig.channelMask, extract(stream->getChannelMask())))
 
-TEST_IO_STREAM(GetFormat, "Check that the stream format == the one it was opened with",
+TEST_IO_STREAM(GetFormat,
+               "Check that the stream format == the one it was opened with",
                ASSERT_EQ(audioConfig.format, extract(stream->getFormat())))
 
 // TODO: for now only check that the framesize is not incoherent
-TEST_IO_STREAM(GetFrameSize, "Check that the stream frame size == the one it was opened with",
+TEST_IO_STREAM(GetFrameSize,
+               "Check that the stream frame size == the one it was opened with",
                ASSERT_GT(extract(stream->getFrameSize()), 0U))
 
-TEST_IO_STREAM(GetBufferSize, "Check that the stream buffer size== the one it was opened with",
-               ASSERT_GE(extract(stream->getBufferSize()), \
-                                     extract(stream->getFrameSize())));
+TEST_IO_STREAM(GetBufferSize,
+               "Check that the stream buffer size== the one it was opened with",
+               ASSERT_GE(extract(stream->getBufferSize()),
+                         extract(stream->getFrameSize())));
 
 template <class Property, class CapabilityGetter, class Getter, class Setter>
-static void testCapabilityGetter(const string& name, IStream* stream, Property currentValue,
-                                 CapabilityGetter capablityGetter, Getter getter, Setter setter) {
+static void testCapabilityGetter(const string& name, IStream* stream,
+                                 Property currentValue,
+                                 CapabilityGetter capablityGetter,
+                                 Getter getter, Setter setter) {
     hidl_vec<Property> capabilities;
     ASSERT_OK((stream->*capablityGetter)(returnIn(capabilities)));
     if (capabilities.size() == 0) {
-        // The default hal should probably return a NOT_SUPPORTED if the hal does not expose
-        // capability retrieval. For now it returns an empty list if not implemented
+        // The default hal should probably return a NOT_SUPPORTED if the hal
+        // does not expose
+        // capability retrieval. For now it returns an empty list if not
+        // implemented
         doc::partialTest(name + " is not supported");
         return;
     };
-    // TODO: This code has never been tested on a hal that supports getSupportedSampleRates
+    // TODO: This code has never been tested on a hal that supports
+    // getSupportedSampleRates
     EXPECT_NE(std::find(capabilities.begin(), capabilities.end(), currentValue),
-             capabilities.end())
+              capabilities.end())
         << "current " << name << " is not in the list of the supported ones "
         << toString(capabilities);
 
@@ -707,69 +797,88 @@
     }
 }
 
-TEST_IO_STREAM(SupportedSampleRate, "Check that the stream sample rate is declared as supported",
-               testCapabilityGetter("getSupportedSampleRate", stream.get(), \
-                                    extract(stream->getSampleRate()), \
-                                    &IStream::getSupportedSampleRates, \
-                                    &IStream::getSampleRate, &IStream::setSampleRate))
+TEST_IO_STREAM(SupportedSampleRate,
+               "Check that the stream sample rate is declared as supported",
+               testCapabilityGetter("getSupportedSampleRate", stream.get(),
+                                    extract(stream->getSampleRate()),
+                                    &IStream::getSupportedSampleRates,
+                                    &IStream::getSampleRate,
+                                    &IStream::setSampleRate))
 
-TEST_IO_STREAM(SupportedChannelMask, "Check that the stream channel mask is declared as supported",
-               testCapabilityGetter("getSupportedChannelMask", stream.get(), \
-                                    extract(stream->getChannelMask()), \
-                                    &IStream::getSupportedChannelMasks, \
-                                    &IStream::getChannelMask, &IStream::setChannelMask))
+TEST_IO_STREAM(SupportedChannelMask,
+               "Check that the stream channel mask is declared as supported",
+               testCapabilityGetter("getSupportedChannelMask", stream.get(),
+                                    extract(stream->getChannelMask()),
+                                    &IStream::getSupportedChannelMasks,
+                                    &IStream::getChannelMask,
+                                    &IStream::setChannelMask))
 
-TEST_IO_STREAM(SupportedFormat, "Check that the stream format is declared as supported",
-               testCapabilityGetter("getSupportedFormat", stream.get(), \
-                                    extract(stream->getFormat()), \
-                                    &IStream::getSupportedFormats, \
+TEST_IO_STREAM(SupportedFormat,
+               "Check that the stream format is declared as supported",
+               testCapabilityGetter("getSupportedFormat", stream.get(),
+                                    extract(stream->getFormat()),
+                                    &IStream::getSupportedFormats,
                                     &IStream::getFormat, &IStream::setFormat))
 
 static void testGetDevice(IStream* stream, AudioDevice expectedDevice) {
+    // Unfortunately the interface does not allow the implementation to return
+    // NOT_SUPPORTED
+    // Thus allow NONE as signaling that the call is not supported.
     auto ret = stream->getDevice();
-    ASSERT_TRUE(ret.isOk());
+    ASSERT_IS_OK(ret);
     AudioDevice device = ret;
-    ASSERT_EQ(expectedDevice, device);
+    ASSERT_TRUE(device == expectedDevice || device == AudioDevice::NONE)
+        << "Expected: " << ::testing::PrintToString(expectedDevice)
+        << "\n  Actual: " << ::testing::PrintToString(device);
 }
 
-TEST_IO_STREAM(GetDevice, "Check that the stream device == the one it was opened with",
-               areAudioPatchesSupported() ? doc::partialTest("Audio patches are supported") : \
-                                            testGetDevice(stream.get(), address.device))
+TEST_IO_STREAM(GetDevice,
+               "Check that the stream device == the one it was opened with",
+               areAudioPatchesSupported()
+                   ? doc::partialTest("Audio patches are supported")
+                   : testGetDevice(stream.get(), address.device))
 
 static void testSetDevice(IStream* stream, const DeviceAddress& address) {
     DeviceAddress otherAddress = address;
-    otherAddress.device = (address.device & AudioDevice::BIT_IN) == 0 ?
-            AudioDevice::OUT_SPEAKER : AudioDevice::IN_BUILTIN_MIC;
+    otherAddress.device = (address.device & AudioDevice::BIT_IN) == 0
+                              ? AudioDevice::OUT_SPEAKER
+                              : AudioDevice::IN_BUILTIN_MIC;
     EXPECT_OK(stream->setDevice(otherAddress));
 
-    ASSERT_OK(stream->setDevice(address)); // Go back to the original value
+    ASSERT_OK(stream->setDevice(address));  // Go back to the original value
 }
 
-TEST_IO_STREAM(SetDevice, "Check that the stream can be rerouted to SPEAKER or BUILTIN_MIC",
-               areAudioPatchesSupported() ? doc::partialTest("Audio patches are supported") : \
-                                            testSetDevice(stream.get(), address))
+TEST_IO_STREAM(
+    SetDevice,
+    "Check that the stream can be rerouted to SPEAKER or BUILTIN_MIC",
+    areAudioPatchesSupported() ? doc::partialTest("Audio patches are supported")
+                               : testSetDevice(stream.get(), address))
 
-static void testGetAudioProperties(IStream* stream, AudioConfig expectedConfig) {
+static void testGetAudioProperties(IStream* stream,
+                                   AudioConfig expectedConfig) {
     uint32_t sampleRateHz;
     AudioChannelMask mask;
     AudioFormat format;
 
     stream->getAudioProperties(returnIn(sampleRateHz, mask, format));
 
-    // FIXME: the qcom hal it does not currently negotiate the sampleRate & channel mask
+    // FIXME: the qcom hal it does not currently negotiate the sampleRate &
+    // channel mask
     EXPECT_EQ(expectedConfig.sampleRateHz, sampleRateHz);
     EXPECT_EQ(expectedConfig.channelMask, mask);
     EXPECT_EQ(expectedConfig.format, format);
 }
 
-TEST_IO_STREAM(GetAudioProperties,
-               "Check that the stream audio properties == the ones it was opened with",
-               testGetAudioProperties(stream.get(), audioConfig))
+TEST_IO_STREAM(
+    GetAudioProperties,
+    "Check that the stream audio properties == the ones it was opened with",
+    testGetAudioProperties(stream.get(), audioConfig))
 
 static void testConnectedState(IStream* stream) {
     DeviceAddress address = {};
     using AD = AudioDevice;
-    for (auto device : {AD::OUT_HDMI, AD::OUT_WIRED_HEADPHONE, AD::IN_USB_HEADSET}) {
+    for (auto device :
+         {AD::OUT_HDMI, AD::OUT_WIRED_HEADPHONE, AD::IN_USB_HEADSET}) {
         address.device = device;
 
         ASSERT_OK(stream->setConnectedState(address, true));
@@ -777,52 +886,63 @@
     }
 }
 TEST_IO_STREAM(SetConnectedState,
-               "Check that the stream can be notified of device connection and deconnection",
+               "Check that the stream can be notified of device connection and "
+               "deconnection",
                testConnectedState(stream.get()))
 
-
-static auto invalidArgsOrNotSupported = {Result::INVALID_ARGUMENTS, Result::NOT_SUPPORTED};
+static auto invalidArgsOrNotSupportedOrOK = {Result::INVALID_ARGUMENTS,
+                                             Result::NOT_SUPPORTED, Result::OK};
 TEST_IO_STREAM(SetHwAvSync, "Try to set hardware sync to an invalid value",
-               ASSERT_RESULT(invalidArgsOrNotSupported, stream->setHwAvSync(666)))
+               ASSERT_RESULT(invalidArgsOrNotSupportedOrOK,
+                             stream->setHwAvSync(666)))
 
 TEST_IO_STREAM(GetHwAvSync, "Get hardware sync can not fail",
-               ASSERT_TRUE(device->getHwAvSync().isOk()))
+               ASSERT_IS_OK(device->getHwAvSync()));
 
-static void checkGetParameter(IStream* stream, hidl_vec<hidl_string> keys,
-                              vector<Result> expectedResults) {
+static void checkGetNoParameter(IStream* stream, hidl_vec<hidl_string> keys,
+                                vector<Result> expectedResults) {
     hidl_vec<ParameterValue> parameters;
     Result res;
     ASSERT_OK(stream->getParameters(keys, returnIn(res, parameters)));
     ASSERT_RESULT(expectedResults, res);
     if (res == Result::OK) {
-        ASSERT_EQ(0U, parameters.size());
+        for (auto& parameter : parameters) {
+            ASSERT_EQ(0U, parameter.value.size()) << toString(parameter);
+        }
     }
 }
 
-/* Get/Set parameter is intended to be an opaque channel between vendors app and their HALs.
+/* Get/Set parameter is intended to be an opaque channel between vendors app and
+ * their HALs.
  * Thus can not be meaningfully tested.
- * TODO: Doc missing. Should asking for an empty set of params raise an error ?
  */
 TEST_IO_STREAM(getEmptySetParameter, "Retrieve the values of an empty set",
-               checkGetParameter(stream.get(), {} /* keys */,
-                                 {Result::OK, Result::INVALID_ARGUMENTS}))
+               checkGetNoParameter(stream.get(), {} /* keys */, {Result::OK}))
 
+TEST_IO_STREAM(getNonExistingParameter,
+               "Retrieve the values of an non existing parameter",
+               checkGetNoParameter(stream.get(),
+                                   {"Non existing key"} /* keys */,
+                                   {Result::NOT_SUPPORTED}))
 
-TEST_IO_STREAM(getNonExistingParameter, "Retrieve the values of an non existing parameter",
-               checkGetParameter(stream.get(), {"Non existing key"} /* keys */,
-                                 {Result::INVALID_ARGUMENTS}))
+TEST_IO_STREAM(setEmptySetParameter,
+               "Set the values of an empty set of parameters",
+               ASSERT_RESULT(Result::OK, stream->setParameters({})))
 
-static vector<Result> okOrInvalidArguments = {Result::OK, Result::INVALID_ARGUMENTS};
-TEST_IO_STREAM(setEmptySetParameter, "Set the values of an empty set of parameters",
-               ASSERT_RESULT(okOrInvalidArguments, stream->setParameters({})))
-
-TEST_IO_STREAM(setNonExistingParameter, "Set the values of an non existing parameter",
-               ASSERT_RESULT(Result::INVALID_ARGUMENTS,
-                             stream->setParameters({{"non existing key", "0"}})))
+TEST_IO_STREAM(
+    setNonExistingParameter, "Set the values of an non existing parameter",
+    // Unfortunately, the set_parameter legacy interface did not return any
+    // error code when a key is not supported.
+    // To allow implementation to just wrapped the legacy one, consider OK as a
+    // valid result for setting a non existing parameter.
+    ASSERT_RESULT(invalidArgsOrNotSupportedOrOK,
+                  stream->setParameters({{"non existing key", "0"}})))
 
 TEST_IO_STREAM(DebugDump,
                "Check that a stream can dump its state without error",
-               testDebugDump([this](const auto& handle){ return stream->debugDump(handle); }))
+               testDebugDump([this](const auto& handle) {
+                   return stream->debugDump(handle);
+               }))
 
 TEST_IO_STREAM(DebugDumpInvalidArguments,
                "Check that the stream dump doesn't crash on invalid arguments",
@@ -834,39 +954,49 @@
 
 TEST_IO_STREAM(AddNonExistingEffect, "Adding a non existing effect should fail",
                ASSERT_RESULT(Result::INVALID_ARGUMENTS, stream->addEffect(666)))
-TEST_IO_STREAM(RemoveNonExistingEffect, "Removing a non existing effect should fail",
-               ASSERT_RESULT(Result::INVALID_ARGUMENTS, stream->removeEffect(666)))
+TEST_IO_STREAM(RemoveNonExistingEffect,
+               "Removing a non existing effect should fail",
+               ASSERT_RESULT(Result::INVALID_ARGUMENTS,
+                             stream->removeEffect(666)))
 
-//TODO: positive tests
+// TODO: positive tests
 
 //////////////////////////////////////////////////////////////////////////////
 /////////////////////////////// Control ////////////////////////////////
 //////////////////////////////////////////////////////////////////////////////
 
 TEST_IO_STREAM(standby, "Make sure the stream can be put in stanby",
-               ASSERT_OK(stream->standby())) // can not fail
+               ASSERT_OK(stream->standby()))  // can not fail
 
-static vector<Result> invalidStateOrNotSupported = {Result::INVALID_STATE, Result::NOT_SUPPORTED};
+static vector<Result> invalidStateOrNotSupported = {Result::INVALID_STATE,
+                                                    Result::NOT_SUPPORTED};
 
-TEST_IO_STREAM(startNoMmap, "Starting a mmaped stream before mapping it should fail",
+TEST_IO_STREAM(startNoMmap,
+               "Starting a mmaped stream before mapping it should fail",
                ASSERT_RESULT(invalidStateOrNotSupported, stream->start()))
 
-TEST_IO_STREAM(stopNoMmap, "Stopping a mmaped stream before mapping it should fail",
+TEST_IO_STREAM(stopNoMmap,
+               "Stopping a mmaped stream before mapping it should fail",
                ASSERT_RESULT(invalidStateOrNotSupported, stream->stop()))
 
-TEST_IO_STREAM(getMmapPositionNoMmap, "Get a stream Mmap position before mapping it should fail",
+TEST_IO_STREAM(getMmapPositionNoMmap,
+               "Get a stream Mmap position before mapping it should fail",
                ASSERT_RESULT(invalidStateOrNotSupported, stream->stop()))
 
-TEST_IO_STREAM(close, "Make sure a stream can be closed", ASSERT_OK(closeStream()))
+TEST_IO_STREAM(close, "Make sure a stream can be closed",
+               ASSERT_OK(closeStream()))
 TEST_IO_STREAM(closeTwice, "Make sure a stream can not be closed twice",
-               ASSERT_OK(closeStream()); \
+               ASSERT_OK(closeStream());
                ASSERT_RESULT(Result::INVALID_STATE, closeStream()))
 
+static auto invalidArgsOrNotSupported = {Result::INVALID_ARGUMENTS,
+                                         Result::NOT_SUPPORTED};
 static void testCreateTooBigMmapBuffer(IStream* stream) {
     MmapBufferInfo info;
     Result res;
     // Assume that int max is a value too big to be allocated
-    // This is true currently with a 32bit media server, but might not when it will run in 64 bit
+    // This is true currently with a 32bit media server, but might not when it
+    // will run in 64 bit
     auto minSizeFrames = std::numeric_limits<int32_t>::max();
     ASSERT_OK(stream->createMmapBuffer(minSizeFrames, returnIn(res, info)));
     ASSERT_RESULT(invalidArgsOrNotSupported, res);
@@ -875,7 +1005,6 @@
 TEST_IO_STREAM(CreateTooBigMmapBuffer, "Create mmap buffer too big should fail",
                testCreateTooBigMmapBuffer(stream.get()))
 
-
 static void testGetMmapPositionOfNonMmapedStream(IStream* stream) {
     Result res;
     MmapPosition position;
@@ -883,71 +1012,107 @@
     ASSERT_RESULT(invalidArgsOrNotSupported, res);
 }
 
-TEST_IO_STREAM(GetMmapPositionOfNonMmapedStream,
-               "Retrieving the mmap position of a non mmaped stream should fail",
-               testGetMmapPositionOfNonMmapedStream(stream.get()))
+TEST_IO_STREAM(
+    GetMmapPositionOfNonMmapedStream,
+    "Retrieving the mmap position of a non mmaped stream should fail",
+    testGetMmapPositionOfNonMmapedStream(stream.get()))
 
 //////////////////////////////////////////////////////////////////////////////
 ///////////////////////////////// StreamIn ///////////////////////////////////
 //////////////////////////////////////////////////////////////////////////////
 
 TEST_P(InputStreamTest, GetAudioSource) {
-    doc::test("Retrieving the audio source of an input stream should always succeed");
+    doc::test(
+        "Retrieving the audio source of an input stream should always succeed");
     AudioSource source;
     ASSERT_OK(stream->getAudioSource(returnIn(res, source)));
+    if (res == Result::NOT_SUPPORTED) {
+        doc::partialTest("getAudioSource is not supported");
+        return;
+    }
     ASSERT_OK(res);
     ASSERT_EQ(AudioSource::DEFAULT, source);
 }
 
-static void testUnitaryGain(std::function<Return<Result> (float)> setGain) {
-    for (float value : {0.0, 0.01, 0.5, 0.09, 1.0}) {
+static void testUnitaryGain(std::function<Return<Result>(float)> setGain) {
+    for (float value :
+         (float[]){-INFINITY, -1.0, 1.0 + std::numeric_limits<float>::epsilon(),
+                   2.0, INFINITY, NAN}) {
+        SCOPED_TRACE("value=" + to_string(value));
+        // FIXME: NAN should never be accepted
+        // FIXME: Missing api doc. What should the impl do if the volume is
+        // outside [0,1] ?
+        ASSERT_RESULT(Result::INVALID_ARGUMENTS, setGain(value));
+    }
+    // Do not consider -0.0 as an invalid value as it is == with 0.0
+    for (float value : {-0.0, 0.0, 0.01, 0.5, 0.09, 1.0 /* Restore volume*/}) {
         SCOPED_TRACE("value=" + to_string(value));
         ASSERT_OK(setGain(value));
     }
-    for (float value : (float[]){-INFINITY,-1.0, -0.0,
-                                 1.0 + std::numeric_limits<float>::epsilon(), 2.0, INFINITY,
-                                 NAN}) {
-        SCOPED_TRACE("value=" + to_string(value));
-        // FIXME: NAN should never be accepted
-        // FIXME: Missing api doc. What should the impl do if the volume is outside [0,1] ?
-        ASSERT_RESULT(Result::INVALID_ARGUMENTS, setGain(value));
+}
+
+static void testOptionalUnitaryGain(
+    std::function<Return<Result>(float)> setGain, string debugName) {
+    auto result = setGain(1);
+    ASSERT_IS_OK(result);
+    if (result == Result::NOT_SUPPORTED) {
+        doc::partialTest(debugName + " is not supported");
+        return;
     }
+    testUnitaryGain(setGain);
 }
 
 TEST_P(InputStreamTest, SetGain) {
     doc::test("The gain of an input stream should only be set between [0,1]");
-    testUnitaryGain([this](float volume) { return stream->setGain(volume); });
+    testOptionalUnitaryGain(
+        [this](float volume) { return stream->setGain(volume); },
+        "InputStream::setGain");
 }
 
-static void testPrepareForReading(IStreamIn* stream, uint32_t frameSize, uint32_t framesCount) {
+static void testPrepareForReading(IStreamIn* stream, uint32_t frameSize,
+                                  uint32_t framesCount) {
     Result res;
     // Ignore output parameters as the call should fail
-    ASSERT_OK(stream->prepareForReading(frameSize, framesCount,
-                                        [&res](auto r, auto&, auto&, auto&, auto&) { res = r; }));
+    ASSERT_OK(stream->prepareForReading(
+        frameSize, framesCount,
+        [&res](auto r, auto&, auto&, auto&, auto&) { res = r; }));
     EXPECT_RESULT(invalidArgsOrNotSupported, res);
 }
 
+TEST_P(InputStreamTest, PrepareForReadingWithZeroBuffer) {
+    doc::test(
+        "Preparing a stream for reading with a 0 sized buffer should fail");
+    testPrepareForReading(stream.get(), 0, 0);
+}
+
 TEST_P(InputStreamTest, PrepareForReadingWithHugeBuffer) {
-    doc::test("Preparing a stream for reading with a 2^32 sized buffer should fail");
-    testPrepareForReading(stream.get(), 1, std::numeric_limits<uint32_t>::max());
+    doc::test(
+        "Preparing a stream for reading with a 2^32 sized buffer should fail");
+    testPrepareForReading(stream.get(), 1,
+                          std::numeric_limits<uint32_t>::max());
 }
 
 TEST_P(InputStreamTest, PrepareForReadingCheckOverflow) {
-    doc::test("Preparing a stream for reading with a overflowing sized buffer should fail");
+    doc::test(
+        "Preparing a stream for reading with a overflowing sized buffer should "
+        "fail");
     auto uintMax = std::numeric_limits<uint32_t>::max();
     testPrepareForReading(stream.get(), uintMax, uintMax);
 }
 
 TEST_P(InputStreamTest, GetInputFramesLost) {
-    doc::test("The number of frames lost on a never started stream should be 0");
+    doc::test(
+        "The number of frames lost on a never started stream should be 0");
     auto ret = stream->getInputFramesLost();
-    ASSERT_TRUE(ret.isOk());
+    ASSERT_IS_OK(ret);
     uint32_t framesLost{ret};
     ASSERT_EQ(0U, framesLost);
 }
 
 TEST_P(InputStreamTest, getCapturePosition) {
-    doc::test("The capture position of a non prepared stream should not be retrievable");
+    doc::test(
+        "The capture position of a non prepared stream should not be "
+        "retrievable");
     uint64_t frames;
     uint64_t time;
     ASSERT_OK(stream->getCapturePosition(returnIn(res, frames, time)));
@@ -961,36 +1126,44 @@
 TEST_P(OutputStreamTest, getLatency) {
     doc::test("Make sure latency is over 0");
     auto result = stream->getLatency();
-    ASSERT_TRUE(result.isOk());
+    ASSERT_IS_OK(result);
     ASSERT_GT(result, 0U);
 }
 
 TEST_P(OutputStreamTest, setVolume) {
     doc::test("Try to set the output volume");
-    auto result = stream->setVolume(1, 1);
-    ASSERT_TRUE(result.isOk());
-    if (result == Result::NOT_SUPPORTED) {
-        doc::partialTest("setVolume is not supported");
-        return;
-    }
-    testUnitaryGain([this](float volume) { return stream->setVolume(volume, volume); });
+    testOptionalUnitaryGain(
+        [this](float volume) { return stream->setVolume(volume, volume); },
+        "setVolume");
 }
 
-static void testPrepareForWriting(IStreamOut* stream, uint32_t frameSize, uint32_t framesCount) {
+static void testPrepareForWriting(IStreamOut* stream, uint32_t frameSize,
+                                  uint32_t framesCount) {
     Result res;
     // Ignore output parameters as the call should fail
-    ASSERT_OK(stream->prepareForWriting(frameSize, framesCount,
-                                        [&res](auto r, auto&, auto&, auto&, auto&) { res = r; }));
+    ASSERT_OK(stream->prepareForWriting(
+        frameSize, framesCount,
+        [&res](auto r, auto&, auto&, auto&, auto&) { res = r; }));
     EXPECT_RESULT(invalidArgsOrNotSupported, res);
 }
 
+TEST_P(OutputStreamTest, PrepareForWriteWithZeroBuffer) {
+    doc::test(
+        "Preparing a stream for writing with a 0 sized buffer should fail");
+    testPrepareForWriting(stream.get(), 0, 0);
+}
+
 TEST_P(OutputStreamTest, PrepareForWriteWithHugeBuffer) {
-    doc::test("Preparing a stream for writing with a 2^32 sized buffer should fail");
-    testPrepareForWriting(stream.get(), 1, std::numeric_limits<uint32_t>::max());
+    doc::test(
+        "Preparing a stream for writing with a 2^32 sized buffer should fail");
+    testPrepareForWriting(stream.get(), 1,
+                          std::numeric_limits<uint32_t>::max());
 }
 
 TEST_P(OutputStreamTest, PrepareForWritingCheckOverflow) {
-    doc::test("Preparing a stream for writing with a overflowing sized buffer should fail");
+    doc::test(
+        "Preparing a stream for writing with a overflowing sized buffer should "
+        "fail");
     auto uintMax = std::numeric_limits<uint32_t>::max();
     testPrepareForWriting(stream.get(), uintMax, uintMax);
 }
@@ -999,7 +1172,7 @@
     Capability(IStreamOut* stream) {
         EXPECT_OK(stream->supportsPauseAndResume(returnIn(pause, resume)));
         auto ret = stream->supportsDrain();
-        EXPECT_TRUE(ret.isOk());
+        EXPECT_IS_OK(ret);
         if (ret.isOk()) {
             drain = ret;
         }
@@ -1010,31 +1183,44 @@
 };
 
 TEST_P(OutputStreamTest, SupportsPauseAndResumeAndDrain) {
-    doc::test("Implementation must expose pause, resume and drain capabilities");
+    doc::test(
+        "Implementation must expose pause, resume and drain capabilities");
     Capability(stream.get());
 }
 
+template <class Value>
+static void checkInvalidStateOr0(Result res, Value value) {
+    switch (res) {
+        case Result::INVALID_STATE:
+            break;
+        case Result::OK:
+            ASSERT_EQ(0U, value);
+            break;
+        default:
+            FAIL() << "Unexpected result " << toString(res);
+    }
+}
+
 TEST_P(OutputStreamTest, GetRenderPosition) {
-    doc::test("The render position should be 0 on a not started");
+    doc::test("A new stream render position should be 0 or INVALID_STATE");
     uint32_t dspFrames;
     ASSERT_OK(stream->getRenderPosition(returnIn(res, dspFrames)));
     if (res == Result::NOT_SUPPORTED) {
         doc::partialTest("getRenderPosition is not supported");
         return;
     }
-    ASSERT_OK(res);
-    ASSERT_EQ(0U, dspFrames);
+    checkInvalidStateOr0(res, dspFrames);
 }
 
 TEST_P(OutputStreamTest, GetNextWriteTimestamp) {
-    doc::test("The render position of a stream just created should be 0");
+    doc::test("A new stream next write timestamp should be 0 or INVALID_STATE");
     uint64_t timestampUs;
     ASSERT_OK(stream->getNextWriteTimestamp(returnIn(res, timestampUs)));
     if (res == Result::NOT_SUPPORTED) {
         doc::partialTest("getNextWriteTimestamp is not supported");
         return;
     }
-    ASSERT_EQ(Result::INVALID_STATE, res);
+    checkInvalidStateOr0(res, timestampUs);
 }
 
 /** Stub implementation of out stream callback. */
@@ -1044,16 +1230,19 @@
     Return<void> onError() override { return {}; }
 };
 
-static bool isAsyncModeSupported(IStreamOut *stream) {
+static bool isAsyncModeSupported(IStreamOut* stream) {
     auto res = stream->setCallback(new MockOutCallbacks);
-    stream->clearCallback(); // try to restore the no callback state, ignore any error
-    auto okOrNotSupported = { Result::OK, Result::NOT_SUPPORTED };
+    stream->clearCallback();  // try to restore the no callback state, ignore
+                              // any error
+    auto okOrNotSupported = {Result::OK, Result::NOT_SUPPORTED};
     EXPECT_RESULT(okOrNotSupported, res);
     return res.isOk() ? res == Result::OK : false;
 }
 
 TEST_P(OutputStreamTest, SetCallback) {
-    doc::test("If supported, registering callback for async operation should never fail");
+    doc::test(
+        "If supported, registering callback for async operation should never "
+        "fail");
     if (!isAsyncModeSupported(stream.get())) {
         doc::partialTest("The stream does not support async operations");
         return;
@@ -1063,7 +1252,9 @@
 }
 
 TEST_P(OutputStreamTest, clearCallback) {
-    doc::test("If supported, clearing a callback to go back to sync operation should not fail");
+    doc::test(
+        "If supported, clearing a callback to go back to sync operation should "
+        "not fail");
     if (!isAsyncModeSupported(stream.get())) {
         doc::partialTest("The stream does not support async operations");
         return;
@@ -1074,7 +1265,9 @@
 }
 
 TEST_P(OutputStreamTest, Resume) {
-    doc::test("If supported, a stream should fail to resume if not previously paused");
+    doc::test(
+        "If supported, a stream should fail to resume if not previously "
+        "paused");
     if (!Capability(stream.get()).resume) {
         doc::partialTest("The output stream does not support resume");
         return;
@@ -1083,7 +1276,9 @@
 }
 
 TEST_P(OutputStreamTest, Pause) {
-    doc::test("If supported, a stream should fail to pause if not previously started");
+    doc::test(
+        "If supported, a stream should fail to pause if not previously "
+        "started");
     if (!Capability(stream.get()).pause) {
         doc::partialTest("The output stream does not support pause");
         return;
@@ -1091,7 +1286,7 @@
     ASSERT_RESULT(Result::INVALID_STATE, stream->resume());
 }
 
-static void testDrain(IStreamOut *stream, AudioDrain type) {
+static void testDrain(IStreamOut* stream, AudioDrain type) {
     if (!Capability(stream).drain) {
         doc::partialTest("The output stream does not support drain");
         return;
@@ -1112,7 +1307,7 @@
 TEST_P(OutputStreamTest, FlushStop) {
     doc::test("If supported, a stream should always succeed to flush");
     auto ret = stream->flush();
-    ASSERT_TRUE(ret.isOk());
+    ASSERT_IS_OK(ret);
     if (ret == Result::NOT_SUPPORTED) {
         doc::partialTest("Flush is not supported");
         return;
@@ -1121,7 +1316,9 @@
 }
 
 TEST_P(OutputStreamTest, GetPresentationPositionStop) {
-    doc::test("If supported, a stream should always succeed to retrieve the presentation position");
+    doc::test(
+        "If supported, a stream should always succeed to retrieve the "
+        "presentation position");
     uint64_t frames;
     TimeSpec mesureTS;
     ASSERT_OK(stream->getPresentationPosition(returnIn(res, frames, mesureTS)));
@@ -1131,66 +1328,81 @@
     }
     ASSERT_EQ(0U, frames);
 
+    if (mesureTS.tvNSec == 0 && mesureTS.tvSec == 0) {
+        // As the stream has never written a frame yet,
+        // the timestamp does not really have a meaning, allow to return 0
+        return;
+    }
+
+    // Make sure the return measure is not more than 1s old.
     struct timespec currentTS;
     ASSERT_EQ(0, clock_gettime(CLOCK_MONOTONIC, &currentTS)) << errno;
 
-    auto toMicroSec = [](uint64_t sec, auto nsec) { return sec * 1e+6 + nsec / 1e+3; };
+    auto toMicroSec = [](uint64_t sec, auto nsec) {
+        return sec * 1e+6 + nsec / 1e+3;
+    };
     auto currentTime = toMicroSec(currentTS.tv_sec, currentTS.tv_nsec);
     auto mesureTime = toMicroSec(mesureTS.tvSec, mesureTS.tvNSec);
-    ASSERT_PRED2([](auto c, auto m){ return  c - m < 1e+6; }, currentTime, mesureTime);
+    ASSERT_PRED2([](auto c, auto m) { return c - m < 1e+6; }, currentTime,
+                 mesureTime);
 }
 
-
 //////////////////////////////////////////////////////////////////////////////
 /////////////////////////////// PrimaryDevice ////////////////////////////////
 //////////////////////////////////////////////////////////////////////////////
 
-
 TEST_F(AudioPrimaryHidlTest, setVoiceVolume) {
     doc::test("Make sure setVoiceVolume only succeed if volume is in [0,1]");
-    testUnitaryGain([this](float volume) { return device->setVoiceVolume(volume); });
+    testUnitaryGain(
+        [this](float volume) { return device->setVoiceVolume(volume); });
 }
 
 TEST_F(AudioPrimaryHidlTest, setMode) {
-    doc::test("Make sure setMode always succeeds if mode is valid");
-    for (AudioMode mode : {AudioMode::IN_CALL, AudioMode::IN_COMMUNICATION,
-                           AudioMode::RINGTONE, AudioMode::CURRENT,
-                           AudioMode::NORMAL /* Make sure to leave the test in normal mode */ }) {
+    doc::test(
+        "Make sure setMode always succeeds if mode is valid "
+        "and fails otherwise");
+    // Test Invalid values
+    for (AudioMode mode :
+         {AudioMode::INVALID, AudioMode::CURRENT, AudioMode::CNT}) {
+        SCOPED_TRACE("mode=" + toString(mode));
+        ASSERT_RESULT(Result::INVALID_ARGUMENTS, device->setMode(mode));
+    }
+    // Test valid values
+    for (AudioMode mode :
+         {AudioMode::IN_CALL, AudioMode::IN_COMMUNICATION, AudioMode::RINGTONE,
+          AudioMode::NORMAL /* Make sure to leave the test in normal mode */}) {
         SCOPED_TRACE("mode=" + toString(mode));
         ASSERT_OK(device->setMode(mode));
     }
-
-    // FIXME: Missing api doc. What should the impl do if the mode is invalid ?
-    ASSERT_RESULT(Result::INVALID_ARGUMENTS, device->setMode(AudioMode::INVALID));
 }
 
-
 TEST_F(BoolAccessorPrimaryHidlTest, BtScoNrecEnabled) {
     doc::test("Query and set the BT SCO NR&EC state");
     testOptionalAccessors("BtScoNrecEnabled", {true, false, true},
-                         &IPrimaryDevice::setBtScoNrecEnabled,
-                         &IPrimaryDevice::getBtScoNrecEnabled);
+                          &IPrimaryDevice::setBtScoNrecEnabled,
+                          &IPrimaryDevice::getBtScoNrecEnabled);
 }
 
 TEST_F(BoolAccessorPrimaryHidlTest, setGetBtScoWidebandEnabled) {
     doc::test("Query and set the SCO whideband state");
     testOptionalAccessors("BtScoWideband", {true, false, true},
-                         &IPrimaryDevice::setBtScoWidebandEnabled,
-                         &IPrimaryDevice::getBtScoWidebandEnabled);
+                          &IPrimaryDevice::setBtScoWidebandEnabled,
+                          &IPrimaryDevice::getBtScoWidebandEnabled);
 }
 
 using TtyModeAccessorPrimaryHidlTest = AccessorPrimaryHidlTest<TtyMode>;
 TEST_F(TtyModeAccessorPrimaryHidlTest, setGetTtyMode) {
     doc::test("Query and set the TTY mode state");
-    testOptionalAccessors("TTY mode", {TtyMode::OFF, TtyMode::HCO, TtyMode::VCO, TtyMode::FULL},
-                          &IPrimaryDevice::setTtyMode, &IPrimaryDevice::getTtyMode);
+    testOptionalAccessors(
+        "TTY mode", {TtyMode::OFF, TtyMode::HCO, TtyMode::VCO, TtyMode::FULL},
+        &IPrimaryDevice::setTtyMode, &IPrimaryDevice::getTtyMode);
 }
 
 TEST_F(BoolAccessorPrimaryHidlTest, setGetHac) {
     doc::test("Query and set the HAC state");
-    testAccessors("HAC", {true, false, true},
-                         &IPrimaryDevice::setHacEnabled,
-                         &IPrimaryDevice::getHacEnabled);
+    testOptionalAccessors("HAC", {true, false, true},
+                          &IPrimaryDevice::setHacEnabled,
+                          &IPrimaryDevice::getHacEnabled);
 }
 
 //////////////////////////////////////////////////////////////////////////////
diff --git a/audio/2.0/vts/functional/utility/AssertOk.h b/audio/2.0/vts/functional/utility/AssertOk.h
index 10b088c..4c8440e 100644
--- a/audio/2.0/vts/functional/utility/AssertOk.h
+++ b/audio/2.0/vts/functional/utility/AssertOk.h
@@ -14,58 +14,105 @@
  * limitations under the License.
  */
 
-#include <vector>
 #include <algorithm>
+#include <vector>
 
 #include <hidl/Status.h>
 
 namespace detail {
 
-// This is a detail namespace, thus it is OK to import a class as nobody else is allowed to use it
+// This is a detail namespace, thus it is OK to import a class as nobody else is
+// allowed to use it
 using ::android::hardware::Return;
 using ::android::hardware::audio::V2_0::Result;
 
-inline void assertResult(Result expected, Result result) {
-    ASSERT_EQ(expected, result);
+template <class T>
+inline ::testing::AssertionResult assertIsOk(const char* expr,
+                                             const Return<T>& ret) {
+    return ::testing::AssertionResult(ret.isOk())
+           << "Expected: " << expr
+           << "\n to be an OK Return but it is not: " << ret.description();
 }
 
-inline void assertResult(Result expected, const Return<Result> &ret) {
-    ASSERT_TRUE(ret.isOk());
-    Result result = ret;
-    assertResult(expected, result);
+// Call continuation if the provided result isOk
+template <class T, class Continuation>
+inline ::testing::AssertionResult continueIfIsOk(const char* expr,
+                                                 const Return<T>& ret,
+                                                 Continuation continuation) {
+    auto isOkStatus = assertIsOk(expr, ret);
+    return !isOkStatus ? isOkStatus : continuation();
 }
 
-inline void assertResult(const std::vector<Result> &expected, Result result) {
+// Expect two equal Results
+inline ::testing::AssertionResult assertResult(const char* e_expr,
+                                               const char* r_expr,
+                                               Result expected, Result result) {
+    return ::testing::AssertionResult(expected == result)
+           << "Value of: " << r_expr
+           << "\n  Actual: " << ::testing::PrintToString(result)
+           << "\nExpected: " << e_expr
+           << "\nWhich is: " << ::testing::PrintToString(expected);
+}
+
+// Expect two equal Results one being wrapped in an OK Return
+inline ::testing::AssertionResult assertResult(const char* e_expr,
+                                               const char* r_expr,
+                                               Result expected,
+                                               const Return<Result>& ret) {
+    return continueIfIsOk(r_expr, ret, [&] {
+        return assertResult(e_expr, r_expr, expected, Result{ret});
+    });
+}
+
+// Expect a Result to be part of a list of Results
+inline ::testing::AssertionResult assertResult(
+    const char* e_expr, const char* r_expr, const std::vector<Result>& expected,
+    Result result) {
     if (std::find(expected.begin(), expected.end(), result) != expected.end()) {
-        return; // result is in expected
+        return ::testing::AssertionSuccess();  // result is in expected
     }
-    FAIL() << "Expected result " << ::testing::PrintToString(result)
-           << " to be one of " << ::testing::PrintToString(expected);
+    return ::testing::AssertionFailure()
+           << "Value of: " << r_expr
+           << "\n  Actual: " << ::testing::PrintToString(result)
+           << "\nExpected one of: " << e_expr
+           << "\n       Which is: " << ::testing::PrintToString(expected);
 }
 
-inline void assertResult(const std::vector<Result> &expected, const Return<Result> &ret) {
-    ASSERT_TRUE(ret.isOk());
-    Result result = ret;
-    assertResult(expected, result);
+// Expect a Result wrapped in an OK Return to be part of a list of Results
+inline ::testing::AssertionResult assertResult(
+    const char* e_expr, const char* r_expr, const std::vector<Result>& expected,
+    const Return<Result>& ret) {
+    return continueIfIsOk(r_expr, ret, [&] {
+        return assertResult(e_expr, r_expr, expected, Result{ret});
+    });
 }
 
-inline void assertOk(const Return<void> &ret) {
-    ASSERT_TRUE(ret.isOk());
+inline ::testing::AssertionResult assertOk(const char* expr,
+                                           const Return<void>& ret) {
+    return assertIsOk(expr, ret);
 }
 
-inline void assertOk(Result result) {
-    assertResult(Result::OK, result);
+inline ::testing::AssertionResult assertOk(const char* expr, Result result) {
+    return ::testing::AssertionResult(result == Result::OK)
+           << "Expected success: " << expr
+           << "\nActual: " << ::testing::PrintToString(result);
 }
 
-inline void assertOk(const Return<Result> &ret) {
-    assertResult(Result::OK, ret);
+inline ::testing::AssertionResult assertOk(const char* expr,
+                                           const Return<Result>& ret) {
+    return continueIfIsOk(expr, ret,
+                          [&] { return assertOk(expr, Result{ret}); });
+}
 }
 
-}
+#define ASSERT_IS_OK(ret) ASSERT_PRED_FORMAT1(detail::assertIsOk, ret)
+#define EXPECT_IS_OK(ret) EXPECT_PRED_FORMAT1(detail::assertIsOk, ret)
 
 // Test anything provided is and contains only OK
-#define ASSERT_OK(ret) ASSERT_NO_FATAL_FAILURE(detail::assertOk(ret))
-#define EXPECT_OK(ret) EXPECT_NO_FATAL_FAILURE(detail::assertOk(ret))
+#define ASSERT_OK(ret) ASSERT_PRED_FORMAT1(detail::assertOk, ret)
+#define EXPECT_OK(ret) EXPECT_PRED_FORMAT1(detail::assertOk, ret)
 
-#define ASSERT_RESULT(expected, ret) ASSERT_NO_FATAL_FAILURE(detail::assertResult(expected, ret))
-#define EXPECT_RESULT(expected, ret) EXPECT_NO_FATAL_FAILURE(detail::assertResult(expected, ret))
+#define ASSERT_RESULT(expected, ret) \
+    ASSERT_PRED_FORMAT2(detail::assertResult, expected, ret)
+#define EXPECT_RESULT(expected, ret) \
+    EXPECT_PRED_FORMAT2(detail::assertResult, expected, ret)
diff --git a/automotive/vehicle/2.0/default/common/include/vhal_v2_0/RecurrentTimer.h b/automotive/vehicle/2.0/default/common/include/vhal_v2_0/RecurrentTimer.h
index be25adc..0ed8742 100644
--- a/automotive/vehicle/2.0/default/common/include/vhal_v2_0/RecurrentTimer.h
+++ b/automotive/vehicle/2.0/default/common/include/vhal_v2_0/RecurrentTimer.h
@@ -26,6 +26,7 @@
 #include <set>
 #include <thread>
 #include <unordered_map>
+#include <vector>
 
 /**
  * This class allows to specify multiple time intervals to receive
diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleHal.h b/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleHal.h
index 009485d..c25e083 100644
--- a/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleHal.h
+++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleHal.h
@@ -25,14 +25,11 @@
 
 #include <utils/SystemClock.h>
 
-#include "VehicleHalProto.pb.h"
-
 #include <vhal_v2_0/RecurrentTimer.h>
 #include <vhal_v2_0/VehicleHal.h>
 #include "vhal_v2_0/VehiclePropertyStore.h"
 
 #include "DefaultConfig.h"
-#include "VehicleHalProto.pb.h"
 #include "VehicleEmulator.h"
 #include "FakeValueGenerator.h"
 
diff --git a/automotive/vehicle/2.1/default/impl/vhal_v2_1/EmulatedVehicleHal.cpp b/automotive/vehicle/2.1/default/impl/vhal_v2_1/EmulatedVehicleHal.cpp
index 1d19aa2..46e062b 100644
--- a/automotive/vehicle/2.1/default/impl/vhal_v2_1/EmulatedVehicleHal.cpp
+++ b/automotive/vehicle/2.1/default/impl/vhal_v2_1/EmulatedVehicleHal.cpp
@@ -23,7 +23,6 @@
 #include <algorithm>
 
 #include "EmulatedVehicleHal.h"
-#include "VehicleHalProto.pb.h"
 
 #define DEBUG_SOCKET    (33452)
 
diff --git a/bluetooth/1.0/default/service.cpp b/bluetooth/1.0/default/service.cpp
index fa5106f..a588c37 100644
--- a/bluetooth/1.0/default/service.cpp
+++ b/bluetooth/1.0/default/service.cpp
@@ -20,10 +20,13 @@
 
 #include <hidl/LegacySupport.h>
 
+// Add an extra thread for calls to the scheduler service.
+static const size_t kMaxThreads = 2;
+
 // Generated HIDL files
 using android::hardware::bluetooth::V1_0::IBluetoothHci;
 using android::hardware::defaultPassthroughServiceImplementation;
 
 int main() {
-  return defaultPassthroughServiceImplementation<IBluetoothHci>();
+    return defaultPassthroughServiceImplementation<IBluetoothHci>(kMaxThreads);
 }
diff --git a/compatibility_matrix.xml b/compatibility_matrix.xml
index c643fc7..51a096c 100644
--- a/compatibility_matrix.xml
+++ b/compatibility_matrix.xml
@@ -8,6 +8,14 @@
         <version>2.0</version>
     </hal>
     <hal format="hidl" optional="true">
+        <name>android.hardware.automotive.evs</name>
+        <version>1.0</version>
+    </hal>
+    <hal format="hidl" optional="true">
+        <name>android.hardware.automotive.vehicle</name>
+        <version>2.1</version>
+    </hal>
+    <hal format="hidl" optional="true">
         <name>android.hardware.biometrics.fingerprint</name>
         <version>2.1</version>
     </hal>
diff --git a/configstore/utils/include/configstore/Utils.h b/configstore/utils/include/configstore/Utils.h
index a54ce85..c9c830b 100644
--- a/configstore/utils/include/configstore/Utils.h
+++ b/configstore/utils/include/configstore/Utils.h
@@ -17,7 +17,7 @@
 #ifndef ANDROID_HARDWARE_CONFIGSTORE_UTILS_H
 #define ANDROID_HARDWARE_CONFIGSTORE_UTILS_H
 
-#include <android/hardware/configstore/1.0/ISurfaceFlingerConfigs.h>
+#include <android/hardware/configstore/1.0/types.h>
 #include <hidl/Status.h>
 
 #include <sstream>
@@ -34,7 +34,14 @@
 }  // namespace details
 
 namespace configstore {
-using namespace android::hardware::configstore::V1_0;
+// import types from V1_0
+using ::android::hardware::configstore::V1_0::OptionalBool;
+using ::android::hardware::configstore::V1_0::OptionalInt32;
+using ::android::hardware::configstore::V1_0::OptionalUInt32;
+using ::android::hardware::configstore::V1_0::OptionalInt64;
+using ::android::hardware::configstore::V1_0::OptionalUInt64;
+using ::android::hardware::configstore::V1_0::OptionalString;
+
 // arguments V: type for the value (i.e., OptionalXXX)
 //           I: interface class name
 //           func: member function pointer
diff --git a/graphics/composer/2.1/default/service.cpp b/graphics/composer/2.1/default/service.cpp
index aa0604a..82a33f6 100644
--- a/graphics/composer/2.1/default/service.cpp
+++ b/graphics/composer/2.1/default/service.cpp
@@ -40,5 +40,5 @@
         ALOGE("Couldn't set SCHED_FIFO: %d", errno);
     }
 
-    return defaultPassthroughServiceImplementation<IComposer>();
+    return defaultPassthroughServiceImplementation<IComposer>(4);
 }