Merge "Reapply "Add media.c2 AIDL service to media.swcodec"" into main
diff --git a/media/audioaidlconversion/AidlConversionCppNdk.cpp b/media/audioaidlconversion/AidlConversionCppNdk.cpp
index 5558259..947352f 100644
--- a/media/audioaidlconversion/AidlConversionCppNdk.cpp
+++ b/media/audioaidlconversion/AidlConversionCppNdk.cpp
@@ -565,7 +565,8 @@
                 AudioDeviceType::IN_DEVICE, AudioDeviceType::OUT_DEVICE);
         append_AudioDeviceDescription(pairs,
                 AUDIO_DEVICE_IN_PROXY, AUDIO_DEVICE_OUT_PROXY,
-                AudioDeviceType::IN_AFE_PROXY, AudioDeviceType::OUT_AFE_PROXY);
+                AudioDeviceType::IN_AFE_PROXY, AudioDeviceType::OUT_AFE_PROXY,
+                GET_DEVICE_DESC_CONNECTION(VIRTUAL));
         append_AudioDeviceDescription(pairs,
                 AUDIO_DEVICE_IN_USB_HEADSET, AUDIO_DEVICE_OUT_USB_HEADSET,
                 AudioDeviceType::IN_HEADSET, AudioDeviceType::OUT_HEADSET,
diff --git a/media/codec2/sfplugin/CCodec.cpp b/media/codec2/sfplugin/CCodec.cpp
index 8082dd7..cd3a80f 100644
--- a/media/codec2/sfplugin/CCodec.cpp
+++ b/media/codec2/sfplugin/CCodec.cpp
@@ -2326,9 +2326,12 @@
 void CCodec::onWorkDone(std::list<std::unique_ptr<C2Work>> &workItems) {
     if (!workItems.empty()) {
         Mutexed<std::list<std::unique_ptr<C2Work>>>::Locked queue(mWorkDoneQueue);
+        bool shouldPost = queue->empty();
         queue->splice(queue->end(), workItems);
+        if (shouldPost) {
+            (new AMessage(kWhatWorkDone, this))->post();
+        }
     }
-    (new AMessage(kWhatWorkDone, this))->post();
 }
 
 void CCodec::onInputBufferDone(uint64_t frameIndex, size_t arrayIndex) {
diff --git a/media/libaudioclient/AudioRecord.cpp b/media/libaudioclient/AudioRecord.cpp
index 073a030..c912d27 100644
--- a/media/libaudioclient/AudioRecord.cpp
+++ b/media/libaudioclient/AudioRecord.cpp
@@ -68,10 +68,9 @@
     }
 
     // We double the size of input buffer for ping pong use of record buffer.
-    // Assumes audio_is_linear_pcm(format)
-    const auto sampleSize = audio_channel_count_from_in_mask(channelMask) *
-                                      audio_bytes_per_sample(format);
-    if (sampleSize == 0 || ((*frameCount = (size * 2) / sampleSize) == 0)) {
+    const auto frameSize = audio_bytes_per_frame(
+            audio_channel_count_from_in_mask(channelMask), format);
+    if (frameSize == 0 || ((*frameCount = (size * 2) / frameSize) == 0)) {
         ALOGE("%s(): Unsupported configuration: sampleRate %u, format %#x, channelMask %#x",
                 __func__, sampleRate, format, channelMask);
         return BAD_VALUE;
@@ -353,12 +352,7 @@
     }
 
     mChannelCount = audio_channel_count_from_in_mask(mChannelMask);
-
-    if (audio_is_linear_pcm(mFormat)) {
-        mFrameSize = mChannelCount * audio_bytes_per_sample(mFormat);
-    } else {
-        mFrameSize = sizeof(uint8_t);
-    }
+    mFrameSize = audio_bytes_per_frame(mChannelCount, mFormat);
 
     // mFrameCount is initialized in createRecord_l
     mReqFrameCount = frameCount;
diff --git a/media/libaudioclient/AudioTrack.cpp b/media/libaudioclient/AudioTrack.cpp
index f3539a1..f050a20 100644
--- a/media/libaudioclient/AudioTrack.cpp
+++ b/media/libaudioclient/AudioTrack.cpp
@@ -594,18 +594,13 @@
     channelCount = audio_channel_count_from_out_mask(channelMask);
     mChannelCount = channelCount;
 
-    if (mFlags & AUDIO_OUTPUT_FLAG_DIRECT) {
-        if (audio_has_proportional_frames(format)) {
-            mFrameSize = channelCount * audio_bytes_per_sample(format);
-        } else {
-            mFrameSize = sizeof(uint8_t);
-        }
-    } else {
-        ALOG_ASSERT(audio_has_proportional_frames(format));
-        mFrameSize = channelCount * audio_bytes_per_sample(format);
+    if (!(mFlags & AUDIO_OUTPUT_FLAG_DIRECT)) {
         // createTrack will return an error if PCM format is not supported by server,
         // so no need to check for specific PCM formats here
+        ALOGW_IF(!audio_has_proportional_frames(format), "%s(): no direct flag for format 0x%x",
+            __func__, format);
     }
+    mFrameSize = audio_bytes_per_frame(channelCount, format);
 
     // sampling rate must be specified for direct outputs
     if (sampleRate == 0 && (mFlags & AUDIO_OUTPUT_FLAG_DIRECT) != 0) {
diff --git a/media/libaudiofoundation/include/media/DeviceDescriptorBase.h b/media/libaudiofoundation/include/media/DeviceDescriptorBase.h
index 501831d..2ab8053 100644
--- a/media/libaudiofoundation/include/media/DeviceDescriptorBase.h
+++ b/media/libaudiofoundation/include/media/DeviceDescriptorBase.h
@@ -79,8 +79,8 @@
 
     bool equals(const sp<DeviceDescriptorBase>& other) const;
 
-    status_t writeToParcelable(media::AudioPortFw* parcelable) const;
-    status_t readFromParcelable(const media::AudioPortFw& parcelable);
+    virtual status_t writeToParcelable(media::AudioPortFw* parcelable) const;
+    virtual status_t readFromParcelable(const media::AudioPortFw& parcelable);
 
 protected:
     AudioDeviceTypeAddr mDeviceTypeAddr;
diff --git a/media/libaudiohal/impl/DeviceHalAidl.cpp b/media/libaudiohal/impl/DeviceHalAidl.cpp
index e2233c7..5bc25ae 100644
--- a/media/libaudiohal/impl/DeviceHalAidl.cpp
+++ b/media/libaudiohal/impl/DeviceHalAidl.cpp
@@ -28,6 +28,7 @@
 #include <media/AidlConversionNdkCpp.h>
 #include <media/AidlConversionUtil.h>
 #include <mediautils/TimeCheck.h>
+#include <system/audio.h>
 #include <Utils.h>
 #include <utils/Log.h>
 
@@ -41,6 +42,7 @@
 using aidl::android::media::audio::common::AudioConfig;
 using aidl::android::media::audio::common::AudioDevice;
 using aidl::android::media::audio::common::AudioDeviceAddress;
+using aidl::android::media::audio::common::AudioDeviceDescription;
 using aidl::android::media::audio::common::AudioDeviceType;
 using aidl::android::media::audio::common::AudioFormatDescription;
 using aidl::android::media::audio::common::AudioFormatType;
@@ -185,23 +187,77 @@
     RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(mModule->getAudioPorts(&ports)));
     ALOGW_IF(ports.empty(), "%s: module %s returned an empty list of audio ports",
             __func__, mInstance.c_str());
-    std::transform(ports.begin(), ports.end(), std::inserter(mPorts, mPorts.end()),
-            [](const auto& p) { return std::make_pair(p.id, p); });
     mDefaultInputPortId = mDefaultOutputPortId = -1;
     const int defaultDeviceFlag = 1 << AudioPortDeviceExt::FLAG_INDEX_DEFAULT_DEVICE;
-    for (const auto& pair : mPorts) {
-        const auto& p = pair.second;
-        if (p.ext.getTag() == AudioPortExt::Tag::device &&
-                (p.ext.get<AudioPortExt::Tag::device>().flags & defaultDeviceFlag) != 0) {
-            if (p.flags.getTag() == AudioIoFlags::Tag::input) {
-                mDefaultInputPortId = p.id;
-            } else if (p.flags.getTag() == AudioIoFlags::Tag::output) {
-                mDefaultOutputPortId = p.id;
+    for (auto it = ports.begin(); it != ports.end(); ) {
+        const auto& port = *it;
+        if (port.ext.getTag() != AudioPortExt::Tag::device) {
+            ++it;
+            continue;
+        }
+        const AudioPortDeviceExt& deviceExt = port.ext.get<AudioPortExt::Tag::device>();
+        if ((deviceExt.flags & defaultDeviceFlag) != 0) {
+            if (port.flags.getTag() == AudioIoFlags::Tag::input) {
+                mDefaultInputPortId = port.id;
+            } else if (port.flags.getTag() == AudioIoFlags::Tag::output) {
+                mDefaultOutputPortId = port.id;
             }
         }
+        // For compatibility with HIDL, hide "template" remote submix ports from ports list.
+        if (const auto& devDesc = deviceExt.device;
+                (devDesc.type.type == AudioDeviceType::IN_SUBMIX ||
+                        devDesc.type.type == AudioDeviceType::OUT_SUBMIX) &&
+                devDesc.type.connection == AudioDeviceDescription::CONNECTION_VIRTUAL) {
+            if (devDesc.type.type == AudioDeviceType::IN_SUBMIX) {
+                mRemoteSubmixIn = port;
+            } else {
+                mRemoteSubmixOut = port;
+            }
+            it = ports.erase(it);
+        } else {
+            ++it;
+        }
     }
+    if (mRemoteSubmixIn.has_value() != mRemoteSubmixOut.has_value()) {
+        ALOGE("%s: The configuration only has input or output remote submix device, must have both",
+                __func__);
+        mRemoteSubmixIn.reset();
+        mRemoteSubmixOut.reset();
+    }
+    if (mRemoteSubmixIn.has_value()) {
+        AudioPort connectedRSubmixIn = *mRemoteSubmixIn;
+        connectedRSubmixIn.ext.get<AudioPortExt::Tag::device>().device.address =
+                AUDIO_REMOTE_SUBMIX_DEVICE_ADDRESS;
+        ALOGD("%s: connecting remote submix input", __func__);
+        RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(mModule->connectExternalDevice(
+                                connectedRSubmixIn, &connectedRSubmixIn)));
+        // The template port for the remote submix input couldn't be "default" because it is not
+        // attached. The connected port can now be made default because we never disconnect it.
+        if (mDefaultInputPortId == -1) {
+            mDefaultInputPortId = connectedRSubmixIn.id;
+        }
+        ports.push_back(std::move(connectedRSubmixIn));
+
+        // Remote submix output must not be connected until the framework actually starts
+        // using it, however for legacy compatibility we need to provide an "augmented template"
+        // port with an address and profiles. It is obtained by connecting the output and then
+        // immediately disconnecting it. This is a cheap operation as we don't open any streams.
+        AudioPort tempConnectedRSubmixOut = *mRemoteSubmixOut;
+        tempConnectedRSubmixOut.ext.get<AudioPortExt::Tag::device>().device.address =
+                AUDIO_REMOTE_SUBMIX_DEVICE_ADDRESS;
+        ALOGD("%s: temporarily connecting and disconnecting remote submix output", __func__);
+        RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(mModule->connectExternalDevice(
+                                tempConnectedRSubmixOut, &tempConnectedRSubmixOut)));
+        RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(mModule->disconnectExternalDevice(
+                                tempConnectedRSubmixOut.id)));
+        tempConnectedRSubmixOut.id = mRemoteSubmixOut->id;
+        ports.push_back(std::move(tempConnectedRSubmixOut));
+    }
+
     ALOGI("%s: module %s default port ids: input %d, output %d",
             __func__, mInstance.c_str(), mDefaultInputPortId, mDefaultOutputPortId);
+    std::transform(ports.begin(), ports.end(), std::inserter(mPorts, mPorts.end()),
+            [](const auto& p) { return std::make_pair(p.id, p); });
     RETURN_STATUS_IF_ERROR(updateRoutes());
     std::vector<AudioPortConfig> portConfigs;
     RETURN_STATUS_IF_ERROR(
@@ -1079,6 +1135,7 @@
 }
 
 status_t DeviceHalAidl::setConnectedState(const struct audio_port_v7 *port, bool connected) {
+    ALOGD("%p %s::%s", this, getClassName().c_str(), __func__);
     TIME_CHECK();
     if (!mModule) return NO_INIT;
     if (port == nullptr) {
@@ -1104,20 +1161,43 @@
     }
     if (connected) {
         AudioDevice matchDevice = aidlPort.ext.get<AudioPortExt::device>().device;
-        // Reset the device address to find the "template" port.
-        matchDevice.address = AudioDeviceAddress::make<AudioDeviceAddress::id>();
-        auto portsIt = findPort(matchDevice);
-        if (portsIt == mPorts.end()) {
-            // Since 'setConnectedState' is called for all modules, it is normal when the device
-            // port not found in every one of them.
-            return BAD_VALUE;
+        std::optional<AudioPort> templatePort;
+        auto erasePortAfterConnectionIt = mPorts.end();
+        // Connection of remote submix out with address "0" is a special case. Since there is
+        // already an "augmented template" port with this address in mPorts, we need to replace
+        // it with a connected port.
+        // Connection of remote submix outs with any other address is done as usual except that
+        // the template port is in `mRemoteSubmixOut`.
+        if (mRemoteSubmixOut.has_value() &&
+                matchDevice.type.type == AudioDeviceType::OUT_SUBMIX) {
+            if (matchDevice.address == AudioDeviceAddress::make<AudioDeviceAddress::id>(
+                            AUDIO_REMOTE_SUBMIX_DEVICE_ADDRESS)) {
+                erasePortAfterConnectionIt = findPort(matchDevice);
+            }
+            templatePort = mRemoteSubmixOut;
+        } else if (mRemoteSubmixIn.has_value() &&
+                matchDevice.type.type == AudioDeviceType::IN_SUBMIX) {
+            templatePort = mRemoteSubmixIn;
         } else {
-            ALOGD("%s: device port for device %s found in the module %s",
-                    __func__, matchDevice.toString().c_str(), mInstance.c_str());
+            // Reset the device address to find the "template" port.
+            matchDevice.address = AudioDeviceAddress::make<AudioDeviceAddress::id>();
+        }
+        if (!templatePort.has_value()) {
+            auto portsIt = findPort(matchDevice);
+            if (portsIt == mPorts.end()) {
+                // Since 'setConnectedState' is called for all modules, it is normal when the device
+                // port not found in every one of them.
+                return BAD_VALUE;
+            } else {
+                ALOGD("%s: device port for device %s found in the module %s",
+                        __func__, matchDevice.toString().c_str(), mInstance.c_str());
+            }
+            templatePort = portsIt->second;
         }
         resetUnusedPatchesAndPortConfigs();
+
         // Use the ID of the "template" port, use all the information from the provided port.
-        aidlPort.id = portsIt->first;
+        aidlPort.id = templatePort->id;
         AudioPort connectedPort;
         RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(mModule->connectExternalDevice(
                                 aidlPort, &connectedPort)));
@@ -1127,6 +1207,9 @@
                 __func__, mInstance.c_str(), connectedPort.toString().c_str(),
                 it->second.toString().c_str());
         mConnectedPorts[connectedPort.id] = false;
+        if (erasePortAfterConnectionIt != mPorts.end()) {
+            mPorts.erase(erasePortAfterConnectionIt);
+        }
     } else {  // !connected
         AudioDevice matchDevice = aidlPort.ext.get<AudioPortExt::device>().device;
         auto portsIt = findPort(matchDevice);
@@ -1139,14 +1222,24 @@
                     __func__, matchDevice.toString().c_str(), mInstance.c_str());
         }
         resetUnusedPatchesAndPortConfigs();
+
+        // Disconnection of remote submix out with address "0" is a special case. We need to replace
+        // the connected port entry with the "augmented template".
+        const int32_t portId = portsIt->second.id;
+        if (mRemoteSubmixOut.has_value() && matchDevice.type.type == AudioDeviceType::OUT_SUBMIX &&
+                matchDevice.address == AudioDeviceAddress::make<AudioDeviceAddress::id>(
+                        AUDIO_REMOTE_SUBMIX_DEVICE_ADDRESS)) {
+            mDisconnectedPortReplacement = std::make_pair(portId, *mRemoteSubmixOut);
+            auto& port = mDisconnectedPortReplacement.second;
+            port.ext.get<AudioPortExt::Tag::device>().device = matchDevice;
+            port.profiles = portsIt->second.profiles;
+        }
         // Streams are closed by AudioFlinger independently from device disconnections.
         // It is possible that the stream has not been closed yet.
-        const int32_t portId = portsIt->second.id;
         if (!isPortHeldByAStream(portId)) {
             RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(
                             mModule->disconnectExternalDevice(portId)));
-            mPorts.erase(portsIt);
-            mConnectedPorts.erase(portId);
+            eraseConnectedPort(portId);
         } else {
             ALOGD("%s: since device port ID %d is used by a stream, "
                     "external device disconnection postponed", __func__, portId);
@@ -1216,6 +1309,17 @@
     return OK;
 }
 
+void DeviceHalAidl::eraseConnectedPort(int32_t portId) {
+    mPorts.erase(portId);
+    mConnectedPorts.erase(portId);
+    if (mDisconnectedPortReplacement.first == portId) {
+        const auto& port = mDisconnectedPortReplacement.second;
+        mPorts.insert(std::make_pair(port.id, port));
+        ALOGD("%s: disconnected port replacement: %s", __func__, port.toString().c_str());
+        mDisconnectedPortReplacement = std::pair<int32_t, AudioPort>();
+    }
+}
+
 status_t DeviceHalAidl::filterAndRetrieveBtA2dpParameters(
         AudioParameter &keys, AudioParameter *result) {
     TIME_CHECK();
@@ -1847,8 +1951,7 @@
         if (!isPortHeldByAStream(portId)) {
             TIME_CHECK();
             if (auto status = mModule->disconnectExternalDevice(portId); status.isOk()) {
-                mPorts.erase(portId);
-                mConnectedPorts.erase(portId);
+                eraseConnectedPort(portId);
                 ALOGD("%s: executed postponed external device disconnection for port ID %d",
                         __func__, portId);
             }
@@ -1865,6 +1968,30 @@
             statusTFromBinderStatus(mModule->getAudioRoutes(&mRoutes)));
     ALOGW_IF(mRoutes.empty(), "%s: module %s returned an empty list of audio routes",
             __func__, mInstance.c_str());
+    if (mRemoteSubmixIn.has_value()) {
+        // Remove mentions of the template remote submix input from routes.
+        int32_t rSubmixInId = mRemoteSubmixIn->id;
+        // Remove mentions of the template remote submix out only if it is not in mPorts
+        // (that means there is a connected port in mPorts).
+        int32_t rSubmixOutId = mPorts.find(mRemoteSubmixOut->id) == mPorts.end() ?
+                mRemoteSubmixOut->id : -1;
+        for (auto it = mRoutes.begin(); it != mRoutes.end();) {
+            auto& route = *it;
+            if (route.sinkPortId == rSubmixOutId) {
+                it = mRoutes.erase(it);
+                continue;
+            }
+            if (auto sourceIt = std::find(route.sourcePortIds.begin(), route.sourcePortIds.end(),
+                            rSubmixInId); sourceIt != route.sourcePortIds.end()) {
+                route.sourcePortIds.erase(sourceIt);
+                if (route.sourcePortIds.empty()) {
+                    it = mRoutes.erase(it);
+                    continue;
+                }
+            }
+            ++it;
+        }
+    }
     mRoutingMatrix.clear();
     for (const auto& r : mRoutes) {
         for (auto portId : r.sourcePortIds) {
diff --git a/media/libaudiohal/impl/DeviceHalAidl.h b/media/libaudiohal/impl/DeviceHalAidl.h
index e1fe4d1..99e8503 100644
--- a/media/libaudiohal/impl/DeviceHalAidl.h
+++ b/media/libaudiohal/impl/DeviceHalAidl.h
@@ -223,6 +223,7 @@
     status_t createOrUpdatePortConfig(
             const ::aidl::android::media::audio::common::AudioPortConfig& requestedPortConfig,
             PortConfigs::iterator* result, bool *created);
+    void eraseConnectedPort(int32_t portId);
     status_t filterAndRetrieveBtA2dpParameters(AudioParameter &keys, AudioParameter *result);
     status_t filterAndUpdateBtA2dpParameters(AudioParameter &parameters);
     status_t filterAndUpdateBtHfpParameters(AudioParameter &parameters);
@@ -313,6 +314,10 @@
     std::shared_ptr<::aidl::android::hardware::audio::core::sounddose::ISoundDose>
         mSoundDose = nullptr;
     Ports mPorts;
+    // Remote submix "template" ports (no address specified, no profiles).
+    // They are excluded from `mPorts` as their presence confuses the framework code.
+    std::optional<::aidl::android::media::audio::common::AudioPort> mRemoteSubmixIn;
+    std::optional<::aidl::android::media::audio::common::AudioPort> mRemoteSubmixOut;
     int32_t mDefaultInputPortId = -1;
     int32_t mDefaultOutputPortId = -1;
     PortConfigs mPortConfigs;
@@ -326,6 +331,8 @@
     std::map<void*, Callbacks> mCallbacks GUARDED_BY(mLock);
     std::set<audio_port_handle_t> mDeviceDisconnectionNotified;
     ConnectedPorts mConnectedPorts;
+    std::pair<int32_t, ::aidl::android::media::audio::common::AudioPort>
+            mDisconnectedPortReplacement;
 };
 
 } // namespace android
diff --git a/media/libeffects/lvm/wrapper/Bundle/EffectBundle.cpp b/media/libeffects/lvm/wrapper/Bundle/EffectBundle.cpp
index df64676..1a37622 100644
--- a/media/libeffects/lvm/wrapper/Bundle/EffectBundle.cpp
+++ b/media/libeffects/lvm/wrapper/Bundle/EffectBundle.cpp
@@ -17,7 +17,7 @@
 #ifndef LVM_FLOAT
 typedef float LVM_FLOAT;
 #endif
-#define LOG_TAG "Bundle"
+#define LOG_TAG "EffectBundle"
 #define ARRAY_SIZE(array) (sizeof(array) / sizeof(array)[0])
 //#define LOG_NDEBUG 0
 
@@ -1191,11 +1191,13 @@
 //  0            if the configuration is supported
 //----------------------------------------------------------------------------
 int VirtualizerIsDeviceSupported(audio_devices_t deviceType) {
+    ALOGV("%s: deviceType:%#x", __func__, deviceType);
     switch (deviceType) {
         case AUDIO_DEVICE_OUT_WIRED_HEADSET:
         case AUDIO_DEVICE_OUT_WIRED_HEADPHONE:
         case AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES:
         case AUDIO_DEVICE_OUT_USB_HEADSET:
+        case AUDIO_DEVICE_OUT_BLE_HEADSET:
             // case AUDIO_DEVICE_OUT_USB_DEVICE:  // For USB testing of the virtualizer only.
             return 0;
         default:
@@ -3372,10 +3374,10 @@
             if (pContext->EffectType == LVM_BASS_BOOST) {
                 if ((device == AUDIO_DEVICE_OUT_SPEAKER) ||
                     (device == AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT) ||
-                    (device == AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER)) {
-                    ALOGV("\tEFFECT_CMD_SET_DEVICE device is invalid for LVM_BASS_BOOST %d",
-                          *(int32_t*)pCmdData);
-                    ALOGV("\tEFFECT_CMD_SET_DEVICE temporary disable LVM_BAS_BOOST");
+                     device == AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER ||
+                     device == AUDIO_DEVICE_OUT_BLE_SPEAKER) {
+                    ALOGV("%s: EFFECT_CMD_SET_DEVICE device %#x is invalid for LVM_BASS_BOOST",
+                            __func__, device);
 
                     // If a device doesn't support bassboost the effect must be temporarily disabled
                     // the effect must still report its original state as this can only be changed
diff --git a/media/libnbaio/NBAIO.cpp b/media/libnbaio/NBAIO.cpp
index 1cb4410..3abc35e 100644
--- a/media/libnbaio/NBAIO.cpp
+++ b/media/libnbaio/NBAIO.cpp
@@ -55,8 +55,7 @@
     ret.mSampleRate = sampleRate;
     ret.mChannelCount = channelCount;
     ret.mFormat = format;
-    ret.mFrameSize = audio_is_linear_pcm(format) ?
-            channelCount * audio_bytes_per_sample(format) : sizeof(uint8_t);
+    ret.mFrameSize = audio_bytes_per_frame(channelCount, format);
     return ret;
 }
 
diff --git a/media/libstagefright/httplive/fuzzer/Android.bp b/media/libstagefright/httplive/fuzzer/Android.bp
index dd49714..cb2f4ee 100644
--- a/media/libstagefright/httplive/fuzzer/Android.bp
+++ b/media/libstagefright/httplive/fuzzer/Android.bp
@@ -48,6 +48,7 @@
         "libstagefright_httplive_headers",
     ],
     shared_libs: [
+        "libbase",
         "libcrypto",
         "libstagefright_foundation",
         "libhidlbase",
diff --git a/media/libstagefright/tests/VideoRenderQualityTracker_test.cpp b/media/libstagefright/tests/VideoRenderQualityTracker_test.cpp
index 7823922..ee76a67 100644
--- a/media/libstagefright/tests/VideoRenderQualityTracker_test.cpp
+++ b/media/libstagefright/tests/VideoRenderQualityTracker_test.cpp
@@ -261,7 +261,7 @@
     Configuration::GetServerConfigurableFlagFn getServerConfigurableFlagFn{
         [](const std::string &, const std::string &flag, const std::string &) -> std::string {
             if (flag == "render_metrics_enabled") {
-                return "false";
+                return "true";
             } else if (flag == "render_metrics_are_skipped_frames_dropped") {
                 return "false";
             } else if (flag == "render_metrics_max_expected_content_frame_duration_us") {
@@ -304,7 +304,7 @@
     // default - if we are accidentally configuring to the default then we're not necessarily
     // testing the parsing.
     Configuration d;
-    EXPECT_EQ(c.enabled, false);
+    EXPECT_EQ(c.enabled, true);
     EXPECT_NE(c.enabled, d.enabled);
     EXPECT_EQ(c.areSkippedFramesDropped, false);
     EXPECT_NE(c.areSkippedFramesDropped, d.areSkippedFramesDropped);
@@ -357,6 +357,7 @@
 
 TEST_F(VideoRenderQualityTrackerTest, countsReleasedFrames) {
     Configuration c;
+    c.enabled = true;
     Helper h(16.66, c);
     h.drop(10);
     h.render({16.66, 16.66, 16.66});
@@ -368,6 +369,7 @@
 
 TEST_F(VideoRenderQualityTrackerTest, countsSkippedFrames) {
     Configuration c;
+    c.enabled = true;
     Helper h(16.66, c);
     h.drop(10); // dropped frames are not counted
     h.skip(10); // frames skipped before rendering a frame are not counted
@@ -382,6 +384,7 @@
 
 TEST_F(VideoRenderQualityTrackerTest, whenSkippedFramesAreDropped_countsDroppedFrames) {
     Configuration c;
+    c.enabled = true;
     c.areSkippedFramesDropped = true;
     Helper h(16.66, c);
     h.skip(10); // skipped frames at the beginning of playback are not counted
@@ -398,6 +401,7 @@
 
 TEST_F(VideoRenderQualityTrackerTest, whenNotSkippedFramesAreDropped_countsDroppedFrames) {
     Configuration c;
+    c.enabled = true;
     c.areSkippedFramesDropped = false;
     Helper h(16.66, c);
     h.skip(10); // skipped frames at the beginning of playback are not counted
@@ -414,6 +418,7 @@
 
 TEST_F(VideoRenderQualityTrackerTest, countsRenderedFrames) {
     Configuration c;
+    c.enabled = true;
     Helper h(16.66, c);
     h.drop(10); // dropped frames are not counted
     h.render({16.66, 16.66, 16.66});
@@ -425,6 +430,7 @@
 
 TEST_F(VideoRenderQualityTrackerTest, detectsFrameRate) {
     Configuration c;
+    c.enabled = true;
     c.frameRateDetectionToleranceUs = 2 * 1000; // 2 ms
     Helper h(16.66, c);
     h.render({16.6, 16.7, 16.6, 16.7});
@@ -434,6 +440,7 @@
 
 TEST_F(VideoRenderQualityTrackerTest, handlesSeeking) {
     Configuration c;
+    c.enabled = true;
     c.maxExpectedContentFrameDurationUs = 30;
     VideoRenderQualityTracker v(c);
     v.onFrameReleased(0, 0);
@@ -472,6 +479,7 @@
 
 TEST_F(VideoRenderQualityTrackerTest, withSkipping_handlesSeeking) {
     Configuration c;
+    c.enabled = true;
     c.maxExpectedContentFrameDurationUs = 30;
     VideoRenderQualityTracker v(c);
     v.onFrameReleased(0, 0);
@@ -508,6 +516,7 @@
 
 TEST_F(VideoRenderQualityTrackerTest, whenLowTolerance_doesntDetectFrameRate) {
     Configuration c;
+    c.enabled = true;
     c.frameRateDetectionToleranceUs = 0;
     Helper h(16.66, c);
     h.render({16.6, 16.7, 16.6, 16.7});
@@ -517,6 +526,7 @@
 
 TEST_F(VideoRenderQualityTrackerTest, whenFrameRateDestabilizes_detectsFrameRate) {
     Configuration c;
+    c.enabled = true;
     c.frameRateDetectionToleranceUs = 2 * 1000; // 2 ms
     Helper h(16.66, c);
     h.render({16.6, 16.7, 16.6, 16.7});
@@ -527,6 +537,7 @@
 
 TEST_F(VideoRenderQualityTrackerTest, detects32Pulldown) {
     Configuration c;
+    c.enabled = true;
     c.frameRateDetectionToleranceUs = 2 * 1000; // 2 ms
     Helper h(41.66, c);
     h.render({49.9, 33.2, 50.0, 33.4, 50.1, 33.2});
@@ -536,6 +547,7 @@
 
 TEST_F(VideoRenderQualityTrackerTest, whenBad32Pulldown_doesntDetect32Pulldown) {
     Configuration c;
+    c.enabled = true;
     c.frameRateDetectionToleranceUs = 2 * 1000; // 2 ms
     Helper h(41.66, c);
     h.render({50.0, 33.33, 33.33, 50.00, 33.33, 50.00});
@@ -545,6 +557,7 @@
 
 TEST_F(VideoRenderQualityTrackerTest, whenFrameRateChanges_detectsMostRecentFrameRate) {
     Configuration c;
+    c.enabled = true;
     c.frameRateDetectionToleranceUs = 2 * 1000; // 2 ms
     Helper h(16.66, c);
     h.render({16.6, 16.7, 16.6, 16.7});
@@ -558,6 +571,7 @@
 
 TEST_F(VideoRenderQualityTrackerTest, whenFrameRateIsUnstable_doesntDetectFrameRate) {
     Configuration c;
+    c.enabled = true;
     c.frameRateDetectionToleranceUs = 2 * 1000; // 2 ms
     Helper h(16.66, c);
     h.render({16.66, 30.0, 16.66, 30.0, 16.66});
@@ -567,6 +581,7 @@
 
 TEST_F(VideoRenderQualityTrackerTest, capturesFreezeRate) {
     Configuration c;
+    c.enabled = true;
     Helper h(20, c);
     h.render(3);
     EXPECT_EQ(h.getMetrics().freezeRate, 0);
@@ -579,6 +594,7 @@
 
 TEST_F(VideoRenderQualityTrackerTest, capturesFreezeDurationHistogram) {
     Configuration c;
+    c.enabled = true;
     // +17 because freeze durations include the render time of the previous frame
     c.freezeDurationMsHistogramBuckets = {2 * 17 + 17, 3 * 17 + 17, 6 * 17 + 17};
     Helper h(17, c);
@@ -612,6 +628,7 @@
 
 TEST_F(VideoRenderQualityTrackerTest, capturesFreezeDistanceHistogram) {
     Configuration c;
+    c.enabled = true;
     c.freezeDistanceMsHistogramBuckets = {1 * 17, 5 * 17, 6 * 17};
     Helper h(17, c);
     h.render(1);
@@ -643,6 +660,7 @@
 
 TEST_F(VideoRenderQualityTrackerTest, when60hz_hasNoJudder) {
     Configuration c;
+    c.enabled = true;
     Helper h(16.66, c); // ~24Hz
     h.render({16.66, 16.66, 16.66, 16.66, 16.66, 16.66, 16.66});
     EXPECT_LE(h.getMetrics().judderScoreHistogram.getMax(), 0);
@@ -651,6 +669,7 @@
 
 TEST_F(VideoRenderQualityTrackerTest, whenSmallVariance60hz_hasNoJudder) {
     Configuration c;
+    c.enabled = true;
     Helper h(16.66, c); // ~24Hz
     h.render({14, 18, 14, 18, 14, 18, 14, 18});
     EXPECT_LE(h.getMetrics().judderScoreHistogram.getMax(), 0);
@@ -659,6 +678,7 @@
 
 TEST_F(VideoRenderQualityTrackerTest, whenBadSmallVariance60Hz_hasJudder) {
     Configuration c;
+    c.enabled = true;
     Helper h(16.66, c); // ~24Hz
     h.render({14, 18, 14, /* no 18 between 14s */ 14, 18, 14, 18});
     EXPECT_EQ(h.getMetrics().judderScoreHistogram.getCount(), 1);
@@ -666,6 +686,7 @@
 
 TEST_F(VideoRenderQualityTrackerTest, when30Hz_hasNoJudder) {
     Configuration c;
+    c.enabled = true;
     Helper h(33.33, c);
     h.render({33.33, 33.33, 33.33, 33.33, 33.33, 33.33});
     EXPECT_LE(h.getMetrics().judderScoreHistogram.getMax(), 0);
@@ -674,6 +695,7 @@
 
 TEST_F(VideoRenderQualityTrackerTest, whenSmallVariance30Hz_hasNoJudder) {
     Configuration c;
+    c.enabled = true;
     Helper h(33.33, c);
     h.render({29.0, 35.0, 29.0, 35.0, 29.0, 35.0});
     EXPECT_LE(h.getMetrics().judderScoreHistogram.getMax(), 0);
@@ -682,6 +704,7 @@
 
 TEST_F(VideoRenderQualityTrackerTest, whenBadSmallVariance30Hz_hasJudder) {
     Configuration c;
+    c.enabled = true;
     Helper h(33.33, c);
     h.render({29.0, 35.0, 29.0, /* no 35 between 29s */ 29.0, 35.0, 29.0, 35.0});
     EXPECT_EQ(h.getMetrics().judderScoreHistogram.getCount(), 1);
@@ -689,6 +712,7 @@
 
 TEST_F(VideoRenderQualityTrackerTest, whenBad30HzTo60Hz_hasJudder) {
     Configuration c;
+    c.enabled = true;
     Helper h(33.33, c);
     h.render({33.33, 33.33, 50.0, /* frame stayed 1 vsync too long */ 16.66, 33.33, 33.33});
     EXPECT_EQ(h.getMetrics().judderScoreHistogram.getCount(), 2); // note: 2 counts of judder
@@ -696,6 +720,7 @@
 
 TEST_F(VideoRenderQualityTrackerTest, when24HzTo60Hz_hasNoJudder) {
     Configuration c;
+    c.enabled = true;
     Helper h(41.66, c);
     h.render({50.0, 33.33, 50.0, 33.33, 50.0, 33.33});
     EXPECT_LE(h.getMetrics().judderScoreHistogram.getMax(), 0);
@@ -704,6 +729,7 @@
 
 TEST_F(VideoRenderQualityTrackerTest, when25HzTo60Hz_hasJudder) {
     Configuration c;
+    c.enabled = true;
     Helper h(40, c);
     h.render({33.33, 33.33, 50.0});
     h.render({33.33, 33.33, 50.0});
@@ -716,6 +742,7 @@
 
 TEST_F(VideoRenderQualityTrackerTest, when50HzTo60Hz_hasJudder) {
     Configuration c;
+    c.enabled = true;
     Helper h(20, c);
     h.render({16.66, 16.66, 16.66, 33.33});
     h.render({16.66, 16.66, 16.66, 33.33});
@@ -728,6 +755,7 @@
 
 TEST_F(VideoRenderQualityTrackerTest, when30HzTo50Hz_hasJudder) {
     Configuration c;
+    c.enabled = true;
     Helper h(33.33, c);
     h.render({40.0, 40.0, 40.0, 60.0});
     h.render({40.0, 40.0, 40.0, 60.0});
@@ -739,6 +767,7 @@
 
 TEST_F(VideoRenderQualityTrackerTest, whenSmallVariancePulldown24HzTo60Hz_hasNoJudder) {
     Configuration c;
+    c.enabled = true;
     Helper h(41.66, c);
     h.render({52.0, 31.33, 52.0, 31.33, 52.0, 31.33});
     EXPECT_EQ(h.getMetrics().judderScoreHistogram.getCount(), 0);
@@ -746,6 +775,7 @@
 
 TEST_F(VideoRenderQualityTrackerTest, whenBad24HzTo60Hz_hasJudder) {
     Configuration c;
+    c.enabled = true;
     Helper h(41.66, c);
     h.render({50.0, 33.33, 50.0, 33.33, /* no 50 between 33s */ 33.33, 50.0, 33.33});
     EXPECT_EQ(h.getMetrics().judderScoreHistogram.getCount(), 1);
@@ -753,6 +783,7 @@
 
 TEST_F(VideoRenderQualityTrackerTest, capturesJudderScoreHistogram) {
     Configuration c;
+    c.enabled = true;
     c.judderErrorToleranceUs = 2000;
     c.judderScoreHistogramBuckets = {1, 5, 8};
     Helper h(16, c);
@@ -767,6 +798,7 @@
 TEST_F(VideoRenderQualityTrackerTest, ranksJudderScoresInOrder) {
     // Each rendering is ranked from best to worst from a user experience
     Configuration c;
+    c.enabled = true;
     c.judderErrorToleranceUs = 2000;
     c.judderScoreHistogramBuckets = {0, 1000};
     int64_t previousScore = 0;
@@ -846,6 +878,7 @@
 
 TEST_F(VideoRenderQualityTrackerTest, capturesFreezeEvents) {
     Configuration c;
+    c.enabled = true;
     c.freezeEventMax = 5;
     c.freezeEventDetailsMax = 4;
     c.freezeEventDistanceToleranceMs = 1000;
@@ -938,6 +971,7 @@
 
 TEST_F(VideoRenderQualityTrackerTest, capturesJudderEvents) {
     Configuration c;
+    c.enabled = true;
     c.judderEventMax = 4;
     c.judderEventDetailsMax = 3;
     c.judderEventDistanceToleranceMs = 100;
@@ -988,6 +1022,7 @@
 
 TEST_F(VideoRenderQualityTrackerTest, capturesOverallFreezeScore) {
     Configuration c;
+    c.enabled = true;
     // # drops * 20ms + 20ms because current frame is frozen + 1 for bucket threshold
     c.freezeDurationMsHistogramBuckets = {1 * 20 + 21, 5 * 20 + 21, 10 * 20 + 21};
     c.freezeDurationMsHistogramToScore = {10, 100, 1000};
@@ -1012,6 +1047,7 @@
 
 TEST_F(VideoRenderQualityTrackerTest, capturesOverallJudderScore) {
     Configuration c;
+    c.enabled = true;
     c.judderScoreHistogramBuckets = {0, 6, 10};
     c.judderScoreHistogramToScore = {10, 100, 1000};
     Helper h(20, c);
diff --git a/media/module/mpeg2ts/ATSParser.cpp b/media/module/mpeg2ts/ATSParser.cpp
index 6aeea3b..86187bd 100644
--- a/media/module/mpeg2ts/ATSParser.cpp
+++ b/media/module/mpeg2ts/ATSParser.cpp
@@ -23,8 +23,8 @@
 #include "ESQueue.h"
 
 #include <android/hardware/cas/native/1.0/IDescrambler.h>
-#include <android/hidl/allocator/1.0/IAllocator.h>
 #include <android/hidl/memory/1.0/IMemory.h>
+#include <cutils/ashmem.h>
 #include <cutils/native_handle.h>
 #include <hidlmemory/mapping.h>
 #include <media/cas/DescramblerAPI.h>
@@ -46,12 +46,12 @@
 #include <inttypes.h>
 
 namespace android {
+using hardware::hidl_handle;
 using hardware::hidl_string;
 using hardware::hidl_vec;
 using hardware::hidl_memory;
 using namespace hardware::cas::V1_0;
 using namespace hardware::cas::native::V1_0;
-typedef hidl::allocator::V1_0::IAllocator TAllocator;
 typedef hidl::memory::V1_0::IMemory TMemory;
 
 // I want the expression "y" evaluated even if verbose logging is off.
@@ -210,7 +210,6 @@
     bool mSampleEncrypted;
     sp<AMessage> mSampleAesKeyItem;
     sp<TMemory> mHidlMemory;
-    sp<TAllocator> mHidlAllocator;
     hardware::cas::native::V1_0::SharedBuffer mDescramblerSrcBuffer;
     sp<ABuffer> mDescrambledBuffer;
     List<SubSampleInfo> mSubSamples;
@@ -1006,34 +1005,29 @@
     sp<ABuffer> newBuffer, newScrambledBuffer;
     sp<TMemory> newMem;
     if (mScrambled) {
-        if (mHidlAllocator == nullptr) {
-            mHidlAllocator = TAllocator::getService("ashmem");
-            if (mHidlAllocator == nullptr) {
-                ALOGE("[stream %d] can't get hidl allocator", mElementaryPID);
-                return false;
+        int fd = ashmem_create_region("mediaATS", neededSize);
+        if (fd < 0) {
+             ALOGE("[stream %d] create_ashmem_region failed for size %zu. FD returned: %d",
+                    mElementaryPID, neededSize, fd);
+            return false;
+        }
+
+        native_handle_t* handle = native_handle_create(1 /*numFds*/, 0/*numInts*/);
+        if (handle == nullptr) {
+            ALOGE("[stream %d] failed to create a native_handle_t", mElementaryPID);
+            if (close(fd)) {
+                ALOGE("[stream %d] failed to close ashmem fd. errno: %s", mElementaryPID,
+                      strerror(errno));
             }
-        }
 
-        hidl_memory hidlMemToken;
-        bool success;
-        auto transStatus = mHidlAllocator->allocate(
-                neededSize,
-                [&success, &hidlMemToken](
-                        bool s,
-                        hidl_memory const& m) {
-                    success = s;
-                    hidlMemToken = m;
-                });
-
-        if (!transStatus.isOk()) {
-            ALOGE("[stream %d] hidl allocator failed at the transport: %s",
-                    mElementaryPID, transStatus.description().c_str());
             return false;
         }
-        if (!success) {
-            ALOGE("[stream %d] hidl allocator failed", mElementaryPID);
-            return false;
-        }
+
+        handle->data[0] = fd;
+        hidl_handle memHandle;
+        memHandle.setTo(handle, true /*shouldOwn*/);
+        hidl_memory hidlMemToken("ashmem", memHandle, neededSize);
+
         newMem = mapMemory(hidlMemToken);
         if (newMem == nullptr || newMem->getPointer() == nullptr) {
             ALOGE("[stream %d] hidl failed to map memory", mElementaryPID);
diff --git a/media/module/mpeg2ts/Android.bp b/media/module/mpeg2ts/Android.bp
index bf762c6..c710ffb 100644
--- a/media/module/mpeg2ts/Android.bp
+++ b/media/module/mpeg2ts/Android.bp
@@ -44,7 +44,6 @@
         "libhidlmemory",
         "android.hardware.cas.native@1.0",
         "android.hidl.memory@1.0",
-        "android.hidl.allocator@1.0",
     ],
 
     header_libs: [
diff --git a/media/module/mpeg2ts/test/Android.bp b/media/module/mpeg2ts/test/Android.bp
index 34a8d3e..cccefac 100644
--- a/media/module/mpeg2ts/test/Android.bp
+++ b/media/module/mpeg2ts/test/Android.bp
@@ -37,9 +37,8 @@
     shared_libs: [
         "android.hardware.cas@1.0",
         "android.hardware.cas.native@1.0",
-        "android.hidl.token@1.0-utils",
-        "android.hidl.allocator@1.0",
         "libcrypto",
+        "libcutils",
         "libhidlbase",
         "libhidlmemory",
         "liblog",
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index 29c6845..46384ef 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -27,6 +27,7 @@
 //#define BUFLOG_NDEBUG 0
 #include <afutils/BufLog.h>
 #include <afutils/DumpTryLock.h>
+#include <afutils/NBAIO_Tee.h>
 #include <afutils/Permission.h>
 #include <afutils/PropertyUtils.h>
 #include <afutils/TypedLogger.h>
@@ -2090,7 +2091,8 @@
     }
 }
 
-void AudioFlinger::ioConfigChanged(audio_io_config_event_t event,
+// Hold either AudioFlinger::mutex or ThreadBase::mutex
+void AudioFlinger::ioConfigChanged_l(audio_io_config_event_t event,
                                    const sp<AudioIoDescriptor>& ioDesc,
                                    pid_t pid) {
     media::AudioIoConfigEvent eventAidl = VALUE_OR_FATAL(
@@ -2944,7 +2946,7 @@
             latencyMs = playbackThread->latency();
 
             // notify client processes of the new output creation
-            playbackThread->ioConfigChanged(AUDIO_OUTPUT_OPENED);
+            playbackThread->ioConfigChanged_l(AUDIO_OUTPUT_OPENED);
 
             // the first primary output opened designates the primary hw device if no HW module
             // named "primary" was already loaded.
@@ -2958,7 +2960,7 @@
                 mHardwareStatus = AUDIO_HW_IDLE;
             }
         } else {
-            thread->ioConfigChanged(AUDIO_OUTPUT_OPENED);
+            thread->ioConfigChanged_l(AUDIO_OUTPUT_OPENED);
         }
         response->output = VALUE_OR_RETURN_STATUS(legacy2aidl_audio_io_handle_t_int32_t(output));
         response->config = VALUE_OR_RETURN_STATUS(
@@ -2991,7 +2993,7 @@
     thread->addOutputTrack(thread2);
     mPlaybackThreads.add(id, thread);
     // notify client processes of the new output creation
-    thread->ioConfigChanged(AUDIO_OUTPUT_OPENED);
+    thread->ioConfigChanged_l(AUDIO_OUTPUT_OPENED);
     return id;
 }
 
@@ -3051,7 +3053,7 @@
             mMmapThreads.removeItem(output);
             ALOGD("closing mmapThread %p", mmapThread.get());
         }
-        ioConfigChanged(AUDIO_OUTPUT_CLOSED, sp<AudioIoDescriptor>::make(output));
+        ioConfigChanged_l(AUDIO_OUTPUT_CLOSED, sp<AudioIoDescriptor>::make(output));
         mPatchPanel->notifyStreamClosed(output);
     }
     // The thread entity (active unit of execution) is no longer running here,
@@ -3154,7 +3156,7 @@
 
     if (thread != 0) {
         // notify client processes of the new input creation
-        thread->ioConfigChanged(AUDIO_INPUT_OPENED);
+        thread->ioConfigChanged_l(AUDIO_INPUT_OPENED);
         return NO_ERROR;
     }
     return NO_INIT;
@@ -3313,7 +3315,7 @@
             dumpToThreadLog_l(mmapThread);
             mMmapThreads.removeItem(input);
         }
-        ioConfigChanged(AUDIO_INPUT_CLOSED, sp<AudioIoDescriptor>::make(input));
+        ioConfigChanged_l(AUDIO_INPUT_CLOSED, sp<AudioIoDescriptor>::make(input));
     }
     // FIXME: calling thread->exit() without mutex() held should not be needed anymore now that
     // we have a different lock for notification client
@@ -3693,7 +3695,8 @@
         return {};
     }
 
-    return thread->outDeviceTypes();
+    audio_utils::lock_guard l(thread->mutex());
+    return thread->outDeviceTypes_l();
 }
 
 IAfPlaybackThread* AudioFlinger::fastPlaybackThread_l() const
@@ -4487,8 +4490,9 @@
     }
 
     for (size_t i = 0; i < mPlaybackThreads.size(); i++) {
-        sp<IAfEffectChain> ec =
-                mPlaybackThreads.valueAt(i)->getEffectChain_l(AUDIO_SESSION_OUTPUT_MIX);
+        const auto thread = mPlaybackThreads.valueAt(i);
+        audio_utils::lock_guard l(thread->mutex());
+        const sp<IAfEffectChain> ec = thread->getEffectChain_l(AUDIO_SESSION_OUTPUT_MIX);
         if (ec != 0 && ec->isNonOffloadableEnabled()) {
             return true;
         }
diff --git a/services/audioflinger/AudioFlinger.h b/services/audioflinger/AudioFlinger.h
index e7f9255..b1751da 100644
--- a/services/audioflinger/AudioFlinger.h
+++ b/services/audioflinger/AudioFlinger.h
@@ -342,7 +342,8 @@
 
     // ----- begin IAfThreadCallback interface
 
-    bool isNonOffloadableGlobalEffectEnabled_l() const final REQUIRES(mutex());
+    bool isNonOffloadableGlobalEffectEnabled_l() const final
+            REQUIRES(mutex()) EXCLUDES_ThreadBase_Mutex;
     bool btNrecIsOff() const final { return mBtNrecIsOff.load(); }
     float masterVolume_l() const final REQUIRES(mutex());
     bool masterMute_l() const final REQUIRES(mutex());
@@ -387,7 +388,8 @@
             const audioflinger::SyncEventCallback& callBack,
             const wp<IAfTrackBase>& cookie) final EXCLUDES_AudioFlinger_Mutex;
 
-    void ioConfigChanged(audio_io_config_event_t event,
+    // Hold either AudioFlinger::mutex or ThreadBase::mutex
+    void ioConfigChanged_l(audio_io_config_event_t event,
             const sp<AudioIoDescriptor>& ioDesc,
             pid_t pid = 0) final EXCLUDES_AudioFlinger_ClientMutex;
     void onNonOffloadableGlobalEffectEnable() final EXCLUDES_AudioFlinger_Mutex;
diff --git a/services/audioflinger/Effects.cpp b/services/audioflinger/Effects.cpp
index 0f3e130..95fed5b 100644
--- a/services/audioflinger/Effects.cpp
+++ b/services/audioflinger/Effects.cpp
@@ -2570,6 +2570,7 @@
             uint32_t rightZero = 0;
             volumeControlEffect->setVolume(&leftZero, &rightZero, true /*controller*/);
         }
+        mVolumeControlEffect = volumeControlEffect;
     }
     mLeftVolume = newLeft;
     mRightVolume = newRight;
@@ -3084,7 +3085,10 @@
     return t->sampleRate();
 }
 
-audio_channel_mask_t EffectChain::EffectCallback::inChannelMask(int id) const {
+audio_channel_mask_t EffectChain::EffectCallback::inChannelMask(int id) const
+NO_THREAD_SAFETY_ANALYSIS
+// calling function 'hasAudioSession_l' requires holding mutex 'ThreadBase_Mutex' exclusively
+{
     const sp<IAfThreadBase> t = thread().promote();
     if (t == nullptr) {
         return AUDIO_CHANNEL_NONE;
@@ -3120,7 +3124,10 @@
     return audio_channel_count_from_out_mask(inChannelMask(id));
 }
 
-audio_channel_mask_t EffectChain::EffectCallback::outChannelMask() const {
+audio_channel_mask_t EffectChain::EffectCallback::outChannelMask() const
+NO_THREAD_SAFETY_ANALYSIS
+// calling function 'hasAudioSession_l' requires holding mutex 'ThreadBase_Mutex' exclusively
+{
     const sp<IAfThreadBase> t = thread().promote();
     if (t == nullptr) {
         return AUDIO_CHANNEL_NONE;
diff --git a/services/audioflinger/Effects.h b/services/audioflinger/Effects.h
index aeb0fea..8869b69 100644
--- a/services/audioflinger/Effects.h
+++ b/services/audioflinger/Effects.h
@@ -488,8 +488,10 @@
     bool isBitPerfectCompatible() const final;
 
     // isCompatibleWithThread_l() must be called with thread->mutex() held
-    bool isCompatibleWithThread_l(const sp<IAfThreadBase>& thread) const final;
+    bool isCompatibleWithThread_l(const sp<IAfThreadBase>& thread) const final
+            REQUIRES(audio_utils::ThreadBase_Mutex);
 
+    // Requires either IAfThreadBase::mutex() or EffectChain::mutex() held
     bool containsHapticGeneratingEffect_l() final;
 
     void setHapticIntensity_l(int id, os::HapticScale intensity) final;
@@ -648,7 +650,7 @@
 
              const sp<EffectCallback> mEffectCallback;
 
-             wp<EffectModule> mVolumeControlEffect;
+             wp<IAfEffectModule> mVolumeControlEffect;
 };
 
 class DeviceEffectProxy : public IAfDeviceEffectProxy, public EffectBase {
diff --git a/services/audioflinger/IAfThread.h b/services/audioflinger/IAfThread.h
index fc2f805..8b41740 100644
--- a/services/audioflinger/IAfThread.h
+++ b/services/audioflinger/IAfThread.h
@@ -70,7 +70,7 @@
     virtual audio_utils::mutex& mutex() const
             RETURN_CAPABILITY(audio_utils::AudioFlinger_Mutex) = 0;
     virtual bool isNonOffloadableGlobalEffectEnabled_l() const
-            REQUIRES(mutex()) = 0;  // Tracks
+            REQUIRES(mutex()) EXCLUDES_ThreadBase_Mutex = 0;  // Tracks
     virtual audio_unique_id_t nextUniqueId(audio_unique_id_use_t use) = 0;
     virtual bool btNrecIsOff() const = 0;
     virtual float masterVolume_l() const
@@ -110,7 +110,8 @@
             const wp<IAfTrackBase>& cookie)
             EXCLUDES_AudioFlinger_Mutex = 0;
 
-    virtual void ioConfigChanged(audio_io_config_event_t event,
+    // Hold either AudioFlinger::mutex or ThreadBase::mutex
+    virtual void ioConfigChanged_l(audio_io_config_event_t event,
             const sp<AudioIoDescriptor>& ioDesc,
             pid_t pid = 0) EXCLUDES_AudioFlinger_ClientMutex = 0;
     virtual void onNonOffloadableGlobalEffectEnable() EXCLUDES_AudioFlinger_Mutex = 0;
@@ -140,7 +141,7 @@
     static bool isValidPcmSinkFormat(audio_format_t format);
 
     virtual status_t readyToRun() = 0;
-    virtual void clearPowerManager() = 0;
+    virtual void clearPowerManager() EXCLUDES_ThreadBase_Mutex = 0;
     virtual status_t initCheck() const = 0;
     virtual type_t type() const = 0;
     virtual bool isDuplicating() const = 0;
@@ -156,21 +157,23 @@
     virtual size_t frameCount() const = 0;
     virtual audio_channel_mask_t hapticChannelMask() const = 0;
     virtual uint32_t hapticChannelCount() const = 0;
-    virtual uint32_t latency_l() const = 0;
-    virtual void setVolumeForOutput_l(float left, float right) const = 0;
+    virtual uint32_t latency_l() const = 0;  // NO_THREAD_SAFETY_ANALYSIS
+    virtual void setVolumeForOutput_l(float left, float right) const REQUIRES(mutex()) = 0;
 
     // Return's the HAL's frame count i.e. fast mixer buffer size.
     virtual size_t frameCountHAL() const = 0;
     virtual size_t frameSize() const = 0;
     // Should be "virtual status_t requestExitAndWait()" and override same
     // method in Thread, but Thread::requestExitAndWait() is not yet virtual.
-    virtual void exit() = 0;
-    virtual bool checkForNewParameter_l(const String8& keyValuePair, status_t& status) = 0;
-    virtual status_t setParameters(const String8& keyValuePairs) = 0;
-    virtual String8 getParameters(const String8& keys) = 0;
-    virtual void ioConfigChanged(
+    virtual void exit() EXCLUDES_ThreadBase_Mutex = 0;
+    virtual bool checkForNewParameter_l(const String8& keyValuePair, status_t& status)
+             REQUIRES(mutex()) = 0;
+    virtual status_t setParameters(const String8& keyValuePairs) EXCLUDES_ThreadBase_Mutex = 0;
+    virtual String8 getParameters(const String8& keys) EXCLUDES_ThreadBase_Mutex = 0;
+    virtual void ioConfigChanged_l(
             audio_io_config_event_t event, pid_t pid = 0,
-            audio_port_handle_t portId = AUDIO_PORT_HANDLE_NONE) = 0;
+            audio_port_handle_t portId = AUDIO_PORT_HANDLE_NONE)
+            /* holds either AF::mutex or TB::mutex */ = 0;
 
     // sendConfigEvent_l() must be called with ThreadBase::mLock held
     // Can temporarily release the lock if waiting for a reply from
@@ -178,38 +181,53 @@
     // status_t sendConfigEvent_l(sp<ConfigEvent>& event);
     virtual void sendIoConfigEvent(
             audio_io_config_event_t event, pid_t pid = 0,
-            audio_port_handle_t portId = AUDIO_PORT_HANDLE_NONE) = 0;
+            audio_port_handle_t portId = AUDIO_PORT_HANDLE_NONE) EXCLUDES_ThreadBase_Mutex = 0;
     virtual void sendIoConfigEvent_l(
             audio_io_config_event_t event, pid_t pid = 0,
-            audio_port_handle_t portId = AUDIO_PORT_HANDLE_NONE) = 0;
-    virtual void sendPrioConfigEvent(pid_t pid, pid_t tid, int32_t prio, bool forApp) = 0;
-    virtual void sendPrioConfigEvent_l(pid_t pid, pid_t tid, int32_t prio, bool forApp) = 0;
-    virtual status_t sendSetParameterConfigEvent_l(const String8& keyValuePair) = 0;
+            audio_port_handle_t portId = AUDIO_PORT_HANDLE_NONE) REQUIRES(mutex()) = 0;
+    virtual void sendPrioConfigEvent(pid_t pid, pid_t tid, int32_t prio, bool forApp)
+            EXCLUDES_ThreadBase_Mutex = 0;
+    virtual void sendPrioConfigEvent_l(pid_t pid, pid_t tid, int32_t prio, bool forApp)
+            REQUIRES(mutex()) = 0;
+    virtual status_t sendSetParameterConfigEvent_l(const String8& keyValuePair)
+            REQUIRES(mutex()) = 0;
     virtual status_t sendCreateAudioPatchConfigEvent(
-            const struct audio_patch* patch, audio_patch_handle_t* handle) = 0;
-    virtual status_t sendReleaseAudioPatchConfigEvent(audio_patch_handle_t handle) = 0;
+            const struct audio_patch* patch, audio_patch_handle_t* handle)
+            EXCLUDES_ThreadBase_Mutex = 0;
+    virtual status_t sendReleaseAudioPatchConfigEvent(audio_patch_handle_t handle)
+            EXCLUDES_ThreadBase_Mutex = 0;
     virtual status_t sendUpdateOutDeviceConfigEvent(
-            const DeviceDescriptorBaseVector& outDevices) = 0;
-    virtual void sendResizeBufferConfigEvent_l(int32_t maxSharedAudioHistoryMs) = 0;
-    virtual void sendCheckOutputStageEffectsEvent() = 0;
-    virtual void sendCheckOutputStageEffectsEvent_l() = 0;
-    virtual void sendHalLatencyModesChangedEvent_l() = 0;
+            const DeviceDescriptorBaseVector& outDevices) EXCLUDES_ThreadBase_Mutex = 0;
+    virtual void sendResizeBufferConfigEvent_l(int32_t maxSharedAudioHistoryMs)
+            REQUIRES(mutex()) = 0;
+    virtual void sendCheckOutputStageEffectsEvent() EXCLUDES_ThreadBase_Mutex = 0;
+    virtual void sendCheckOutputStageEffectsEvent_l()
+            REQUIRES(mutex()) = 0;
+    virtual void sendHalLatencyModesChangedEvent_l()
+            REQUIRES(mutex()) = 0;
 
-    virtual void processConfigEvents_l() = 0;
-    virtual void setCheckOutputStageEffects() = 0;
-    virtual void cacheParameters_l() = 0;
+    virtual void processConfigEvents_l()
+            REQUIRES(mutex()) = 0;
+    virtual void setCheckOutputStageEffects() = 0;  // no mutex needed
+    virtual void cacheParameters_l()
+            REQUIRES(mutex()) = 0;
     virtual status_t createAudioPatch_l(
-            const struct audio_patch* patch, audio_patch_handle_t* handle) = 0;
-    virtual status_t releaseAudioPatch_l(const audio_patch_handle_t handle) = 0;
-    virtual void updateOutDevices(const DeviceDescriptorBaseVector& outDevices) = 0;
-    virtual void toAudioPortConfig(struct audio_port_config* config) = 0;
-    virtual void resizeInputBuffer_l(int32_t maxSharedAudioHistoryMs) = 0;
+            const struct audio_patch* patch, audio_patch_handle_t* handle)
+            REQUIRES(mutex()) = 0;
+    virtual status_t releaseAudioPatch_l(const audio_patch_handle_t handle)
+            REQUIRES(mutex()) = 0;
+    virtual void updateOutDevices(const DeviceDescriptorBaseVector& outDevices)
+            EXCLUDES_ThreadBase_Mutex = 0;
+    virtual void toAudioPortConfig(struct audio_port_config* config)
+            EXCLUDES_ThreadBase_Mutex = 0;
+    virtual void resizeInputBuffer_l(int32_t maxSharedAudioHistoryMs)
+            REQUIRES(mutex()) = 0;
 
     // see note at declaration of mStandby, mOutDevice and mInDevice
     virtual bool inStandby() const = 0;
-    virtual const DeviceTypeSet outDeviceTypes() const = 0;
-    virtual audio_devices_t inDeviceType() const = 0;
-    virtual DeviceTypeSet getDeviceTypes() const = 0;
+    virtual const DeviceTypeSet outDeviceTypes_l() const REQUIRES(mutex()) = 0;
+    virtual audio_devices_t inDeviceType_l() const REQUIRES(mutex()) = 0;
+    virtual DeviceTypeSet getDeviceTypes_l() const REQUIRES(mutex()) = 0;
     virtual const AudioDeviceTypeAddrVector& outDeviceTypeAddrs() const = 0;
     virtual const AudioDeviceTypeAddr& inDeviceTypeAddr() const = 0;
     virtual bool isOutput() const = 0;
@@ -226,7 +244,7 @@
             bool pinned,
             bool probe,
             bool notifyFramesProcessed)
-            REQUIRES(audio_utils::AudioFlinger_Mutex) = 0;
+            REQUIRES(audio_utils::AudioFlinger_Mutex) EXCLUDES_ThreadBase_Mutex = 0;
 
     // return values for hasAudioSession (bit field)
     enum effect_state {
@@ -243,28 +261,39 @@
     };
 
     // get effect chain corresponding to session Id.
-    virtual sp<IAfEffectChain> getEffectChain(audio_session_t sessionId) const = 0;
+    virtual sp<IAfEffectChain> getEffectChain(audio_session_t sessionId) const
+            EXCLUDES_ThreadBase_Mutex = 0;
     // same as getEffectChain() but must be called with ThreadBase mutex locked
-    virtual sp<IAfEffectChain> getEffectChain_l(audio_session_t sessionId) const = 0;
-    virtual std::vector<int> getEffectIds_l(audio_session_t sessionId) const = 0;
+    virtual sp<IAfEffectChain> getEffectChain_l(audio_session_t sessionId) const
+            REQUIRES(mutex()) = 0;
+    virtual std::vector<int> getEffectIds_l(audio_session_t sessionId) const
+            REQUIRES(mutex()) = 0;
     // add an effect chain to the chain list (mEffectChains)
-    virtual status_t addEffectChain_l(const sp<IAfEffectChain>& chain) = 0;
+    virtual status_t addEffectChain_l(const sp<IAfEffectChain>& chain)
+            REQUIRES(mutex()) = 0;
     // remove an effect chain from the chain list (mEffectChains)
-    virtual size_t removeEffectChain_l(const sp<IAfEffectChain>& chain) = 0;
+    virtual size_t removeEffectChain_l(const sp<IAfEffectChain>& chain)
+            REQUIRES(mutex()) = 0;
     // lock all effect chains Mutexes. Must be called before releasing the
     // ThreadBase mutex before processing the mixer and effects. This guarantees the
     // integrity of the chains during the process.
     // Also sets the parameter 'effectChains' to current value of mEffectChains.
-    virtual void lockEffectChains_l(Vector<sp<IAfEffectChain>>& effectChains) = 0;
+    virtual void lockEffectChains_l(Vector<sp<IAfEffectChain>>& effectChains)
+            REQUIRES(mutex()) = 0;
     // unlock effect chains after process
-    virtual void unlockEffectChains(const Vector<sp<IAfEffectChain>>& effectChains) = 0;
+    virtual void unlockEffectChains(const Vector<sp<IAfEffectChain>>& effectChains)
+            EXCLUDES_ThreadBase_Mutex = 0;
     // get a copy of mEffectChains vector
-    virtual Vector<sp<IAfEffectChain>> getEffectChains_l() const = 0;
+    virtual Vector<sp<IAfEffectChain>> getEffectChains_l() const
+            REQUIRES(mutex()) = 0;
     // set audio mode to all effect chains
-    virtual void setMode(audio_mode_t mode) = 0;
+    virtual void setMode(audio_mode_t mode)
+            EXCLUDES_ThreadBase_Mutex = 0;
     // get effect module with corresponding ID on specified audio session
-    virtual sp<IAfEffectModule> getEffect(audio_session_t sessionId, int effectId) const = 0;
-    virtual sp<IAfEffectModule> getEffect_l(audio_session_t sessionId, int effectId) const = 0;
+    virtual sp<IAfEffectModule> getEffect(audio_session_t sessionId, int effectId) const
+            EXCLUDES_ThreadBase_Mutex = 0;
+    virtual sp<IAfEffectModule> getEffect_l(audio_session_t sessionId, int effectId) const
+            REQUIRES(mutex()) = 0;
     // add and effect module. Also creates the effect chain is none exists for
     // the effects audio session. Only called in a context of moving an effect
     // from one thread to another
@@ -272,29 +301,36 @@
             REQUIRES(audio_utils::AudioFlinger_Mutex, mutex()) = 0;
     // remove and effect module. Also removes the effect chain is this was the last
     // effect
-    virtual void removeEffect_l(const sp<IAfEffectModule>& effect, bool release = false) = 0;
+    virtual void removeEffect_l(const sp<IAfEffectModule>& effect, bool release = false)
+            REQUIRES(mutex()) = 0;
     // disconnect an effect handle from module and destroy module if last handle
-    virtual void disconnectEffectHandle(IAfEffectHandle* handle, bool unpinIfLast) = 0;
+    virtual void disconnectEffectHandle(IAfEffectHandle* handle, bool unpinIfLast)
+            EXCLUDES_ThreadBase_Mutex = 0;
     // detach all tracks connected to an auxiliary effect
-    virtual void detachAuxEffect_l(int effectId) = 0;
+    virtual void detachAuxEffect_l(int effectId) REQUIRES(mutex()) = 0;
     // returns a combination of:
     // - EFFECT_SESSION if effects on this audio session exist in one chain
     // - TRACK_SESSION if tracks on this audio session exist
     // - FAST_SESSION if fast tracks on this audio session exist
     // - SPATIALIZED_SESSION if spatialized tracks on this audio session exist
-    virtual uint32_t hasAudioSession_l(audio_session_t sessionId) const = 0;
-    virtual uint32_t hasAudioSession(audio_session_t sessionId) const = 0;
+    virtual uint32_t hasAudioSession_l(audio_session_t sessionId) const REQUIRES(mutex()) = 0;
+    virtual uint32_t hasAudioSession(audio_session_t sessionId) const
+            EXCLUDES_ThreadBase_Mutex = 0;
 
     // the value returned by default implementation is not important as the
     // strategy is only meaningful for PlaybackThread which implements this method
-    virtual product_strategy_t getStrategyForSession_l(audio_session_t sessionId) const = 0;
+    virtual product_strategy_t getStrategyForSession_l(audio_session_t sessionId) const
+            REQUIRES(mutex()) = 0;
 
     // check if some effects must be suspended/restored when an effect is enabled
     // or disabled
     virtual void checkSuspendOnEffectEnabled(
-            bool enabled, audio_session_t sessionId, bool threadLocked) = 0;
+            bool enabled, audio_session_t sessionId, bool threadLocked)
+            EXCLUDES_ThreadBase_Mutex = 0;
 
-    virtual status_t setSyncEvent(const sp<audioflinger::SyncEvent>& event) = 0;
+    virtual status_t setSyncEvent(const sp<audioflinger::SyncEvent>& event)
+            EXCLUDES_ThreadBase_Mutex = 0;
+    // internally static, perhaps make static member.
     virtual bool isValidSyncEvent(const sp<audioflinger::SyncEvent>& event) const = 0;
 
     // Return a reference to a per-thread heap which can be used to allocate IMemory
@@ -307,33 +343,35 @@
 
     virtual sp<IMemory> pipeMemory() const = 0;
 
-    virtual void systemReady() = 0;
+    virtual void systemReady() EXCLUDES_ThreadBase_Mutex = 0;
 
     // checkEffectCompatibility_l() must be called with ThreadBase::mLock held
     virtual status_t checkEffectCompatibility_l(
-            const effect_descriptor_t* desc, audio_session_t sessionId) = 0;
+            const effect_descriptor_t* desc, audio_session_t sessionId) REQUIRES(mutex()) = 0;
 
-    virtual void broadcast_l() = 0;
+    virtual void broadcast_l() REQUIRES(mutex()) = 0;
 
-    virtual bool isTimestampCorrectionEnabled() const = 0;
+    virtual bool isTimestampCorrectionEnabled_l() const REQUIRES(mutex()) = 0;
 
     virtual bool isMsdDevice() const = 0;
 
-    virtual void dump(int fd, const Vector<String16>& args) = 0;
+    virtual void dump(int fd, const Vector<String16>& args) EXCLUDES_ThreadBase_Mutex = 0;
 
     // deliver stats to mediametrics.
-    virtual void sendStatistics(bool force) = 0;
+    virtual void sendStatistics(bool force) EXCLUDES_ThreadBase_Mutex = 0;
 
     virtual audio_utils::mutex& mutex() const
             RETURN_CAPABILITY(audio_utils::ThreadBase_Mutex) = 0;
 
-    virtual void onEffectEnable(const sp<IAfEffectModule>& effect) = 0;
-    virtual void onEffectDisable() = 0;
+    virtual void onEffectEnable(const sp<IAfEffectModule>& effect) EXCLUDES_ThreadBase_Mutex = 0;
+    virtual void onEffectDisable() EXCLUDES_ThreadBase_Mutex = 0;
 
     // invalidateTracksForAudioSession_l must be called with holding mLock.
-    virtual void invalidateTracksForAudioSession_l(audio_session_t sessionId) const = 0;
+    virtual void invalidateTracksForAudioSession_l(audio_session_t sessionId) const
+            REQUIRES(mutex()) = 0;
     // Invalidate all the tracks with the given audio session.
-    virtual void invalidateTracksForAudioSession(audio_session_t sessionId) const = 0;
+    virtual void invalidateTracksForAudioSession(audio_session_t sessionId) const
+            EXCLUDES_ThreadBase_Mutex = 0;
 
     virtual bool isStreamInitialized() const = 0;
     virtual void startMelComputation_l(const sp<audio_utils::MelProcessor>& processor)
@@ -341,10 +379,12 @@
     virtual void stopMelComputation_l()
             REQUIRES(audio_utils::AudioFlinger_Mutex) = 0;
 
-    virtual product_strategy_t getStrategyForStream(audio_stream_type_t stream) const = 0;
+    virtual product_strategy_t getStrategyForStream(audio_stream_type_t stream) const
+            EXCLUDES_AUDIO_ALL = 0;
 
     virtual void setEffectSuspended_l(
-            const effect_uuid_t* type, bool suspend, audio_session_t sessionId) = 0;
+            const effect_uuid_t* type, bool suspend, audio_session_t sessionId)
+            REQUIRES(mutex()) = 0;
 
     // Dynamic cast to derived interface
     virtual sp<IAfDirectOutputThread> asIAfDirectOutputThread() { return nullptr; }
@@ -392,7 +432,7 @@
     // return estimated latency in milliseconds, as reported by HAL
     virtual uint32_t latency() const = 0;  // should be in IAfThreadBase?
 
-    virtual uint32_t& fastTrackAvailMask_l() = 0;
+    virtual uint32_t& fastTrackAvailMask_l() REQUIRES(mutex()) = 0;
 
     virtual sp<IAfTrack> createTrack_l(
             const sp<Client>& client,
@@ -418,12 +458,12 @@
             bool isBitPerfect)
             REQUIRES(audio_utils::AudioFlinger_Mutex) = 0;
 
-    virtual status_t addTrack_l(const sp<IAfTrack>& track) = 0;
-    virtual bool destroyTrack_l(const sp<IAfTrack>& track) = 0;
-    virtual bool isTrackActive(const sp<IAfTrack>& track) const = 0;
-    virtual void addOutputTrack_l(const sp<IAfTrack>& track) = 0;
+    virtual status_t addTrack_l(const sp<IAfTrack>& track) REQUIRES(mutex()) = 0;
+    virtual bool destroyTrack_l(const sp<IAfTrack>& track) REQUIRES(mutex()) = 0;
+    virtual bool isTrackActive(const sp<IAfTrack>& track) const REQUIRES(mutex()) = 0;
+    virtual void addOutputTrack_l(const sp<IAfTrack>& track) REQUIRES(mutex()) = 0;
 
-    virtual AudioStreamOut* getOutput_l() const = 0;
+    virtual AudioStreamOut* getOutput_l() const REQUIRES(mutex()) = 0;
     virtual AudioStreamOut* getOutput() const = 0;
     virtual AudioStreamOut* clearOutput() = 0;
 
@@ -431,50 +471,57 @@
     virtual void suspend() = 0;
     virtual void restore() = 0;
     virtual bool isSuspended() const = 0;
-    virtual status_t getRenderPosition(uint32_t* halFrames, uint32_t* dspFrames) const = 0;
+    virtual status_t getRenderPosition(uint32_t* halFrames, uint32_t* dspFrames) const
+            EXCLUDES_ThreadBase_Mutex = 0;
     // Consider also removing and passing an explicit mMainBuffer initialization
     // parameter to AF::IAfTrack::Track().
     virtual float* sinkBuffer() const = 0;
 
-    virtual status_t attachAuxEffect(const sp<IAfTrack>& track, int EffectId) = 0;
-    virtual status_t attachAuxEffect_l(const sp<IAfTrack>& track, int EffectId) = 0;
+    virtual status_t attachAuxEffect(const sp<IAfTrack>& track, int EffectId)
+            EXCLUDES_ThreadBase_Mutex = 0;
+    virtual status_t attachAuxEffect_l(const sp<IAfTrack>& track, int EffectId)
+            REQUIRES(mutex()) = 0;
 
     // called with AudioFlinger lock held
-    virtual bool invalidateTracks_l(audio_stream_type_t streamType) = 0;
-    virtual bool invalidateTracks_l(std::set<audio_port_handle_t>& portIds) = 0;
-    virtual void invalidateTracks(audio_stream_type_t streamType) = 0;
+    virtual bool invalidateTracks_l(audio_stream_type_t streamType) REQUIRES(mutex()) = 0;
+    virtual bool invalidateTracks_l(std::set<audio_port_handle_t>& portIds) REQUIRES(mutex()) = 0;
+    virtual void invalidateTracks(audio_stream_type_t streamType)
+            EXCLUDES_ThreadBase_Mutex = 0;
     // Invalidate tracks by a set of port ids. The port id will be removed from
     // the given set if the corresponding track is found and invalidated.
-    virtual void invalidateTracks(std::set<audio_port_handle_t>& portIds) = 0;
+    virtual void invalidateTracks(std::set<audio_port_handle_t>& portIds)
+            EXCLUDES_ThreadBase_Mutex = 0;
 
-    virtual status_t getTimestamp_l(AudioTimestamp& timestamp) = 0;
-    virtual void addPatchTrack(const sp<IAfPatchTrack>& track) = 0;
-    virtual void deletePatchTrack(const sp<IAfPatchTrack>& track) = 0;
+    virtual status_t getTimestamp_l(AudioTimestamp& timestamp) REQUIRES(mutex()) = 0;
+    virtual void addPatchTrack(const sp<IAfPatchTrack>& track) EXCLUDES_ThreadBase_Mutex = 0;
+    virtual void deletePatchTrack(const sp<IAfPatchTrack>& track) EXCLUDES_ThreadBase_Mutex = 0;
 
     // Return the asynchronous signal wait time.
-    virtual int64_t computeWaitTimeNs_l() const = 0;
+    virtual int64_t computeWaitTimeNs_l() const REQUIRES(mutex()) = 0;
     // returns true if the track is allowed to be added to the thread.
     virtual bool isTrackAllowed_l(
             audio_channel_mask_t channelMask, audio_format_t format, audio_session_t sessionId,
-            uid_t uid) const = 0;
+            uid_t uid) const REQUIRES(mutex()) = 0;
 
     virtual bool supportsHapticPlayback() const = 0;
 
-    virtual void setDownStreamPatch(const struct audio_patch* patch) = 0;
+    virtual void setDownStreamPatch(const struct audio_patch* patch)
+            EXCLUDES_ThreadBase_Mutex = 0;
 
-    virtual IAfTrack* getTrackById_l(audio_port_handle_t trackId) = 0;
+    virtual IAfTrack* getTrackById_l(audio_port_handle_t trackId) REQUIRES(mutex()) = 0;
 
     virtual bool hasMixer() const = 0;
 
     virtual status_t setRequestedLatencyMode(audio_latency_mode_t mode) = 0;
 
-    virtual status_t getSupportedLatencyModes(std::vector<audio_latency_mode_t>* modes) = 0;
+    virtual status_t getSupportedLatencyModes(std::vector<audio_latency_mode_t>* modes)
+           EXCLUDES_ThreadBase_Mutex = 0;
 
     virtual status_t setBluetoothVariableLatencyEnabled(bool enabled) = 0;
 
-    virtual void setStandby() = 0;
-    virtual void setStandby_l() = 0;
-    virtual bool waitForHalStart() = 0;
+    virtual void setStandby() EXCLUDES_ThreadBase_Mutex = 0;
+    virtual void setStandby_l() REQUIRES(mutex()) = 0;
+    virtual bool waitForHalStart() EXCLUDES_ThreadBase_Mutex = 0;
 
     virtual bool hasFastMixer() const = 0;
     virtual FastTrackUnderruns getFastTrackUnderruns(size_t fastIndex) const = 0;
@@ -494,9 +541,9 @@
             const sp<IAfThreadCallback>& afThreadCallback, IAfPlaybackThread* mainThread,
             audio_io_handle_t id, bool systemReady);
 
-    virtual void addOutputTrack(IAfPlaybackThread* thread) = 0;
+    virtual void addOutputTrack(IAfPlaybackThread* thread) EXCLUDES_ThreadBase_Mutex = 0;
     virtual uint32_t waitTimeMs() const = 0;
-    virtual void removeOutputTrack(IAfPlaybackThread* thread) = 0;
+    virtual void removeOutputTrack(IAfPlaybackThread* thread) EXCLUDES_ThreadBase_Mutex = 0;
 };
 
 class IAfRecordThread : public virtual IAfThreadBase {
@@ -521,32 +568,39 @@
             status_t* status /*non-NULL*/,
             audio_port_handle_t portId,
             int32_t maxSharedAudioHistoryMs)
-            REQUIRES(audio_utils::AudioFlinger_Mutex) = 0;
-    virtual void destroyTrack_l(const sp<IAfRecordTrack>& track) = 0;
-    virtual void removeTrack_l(const sp<IAfRecordTrack>& track) = 0;
+            REQUIRES(audio_utils::AudioFlinger_Mutex) EXCLUDES_ThreadBase_Mutex = 0;
+    virtual void destroyTrack_l(const sp<IAfRecordTrack>& track) REQUIRES(mutex()) = 0;
+    virtual void removeTrack_l(const sp<IAfRecordTrack>& track) REQUIRES(mutex()) = 0;
 
     virtual status_t start(
             IAfRecordTrack* recordTrack, AudioSystem::sync_event_t event,
-            audio_session_t triggerSession) = 0;
+            audio_session_t triggerSession) EXCLUDES_ThreadBase_Mutex = 0;
 
     // ask the thread to stop the specified track, and
     // return true if the caller should then do it's part of the stopping process
-    virtual bool stop(IAfRecordTrack* recordTrack) = 0;
+    virtual bool stop(IAfRecordTrack* recordTrack) EXCLUDES_ThreadBase_Mutex = 0;
 
+    // NO_THREAD_SAFETY_ANALYSIS: consider atomics
     virtual AudioStreamIn* getInput() const = 0;
     virtual AudioStreamIn* clearInput() = 0;
 
     virtual status_t getActiveMicrophones(
-            std::vector<media::MicrophoneInfoFw>* activeMicrophones) const = 0;
-    virtual status_t setPreferredMicrophoneDirection(audio_microphone_direction_t direction) = 0;
-    virtual status_t setPreferredMicrophoneFieldDimension(float zoom) = 0;
+            std::vector<media::MicrophoneInfoFw>* activeMicrophones)
+            const EXCLUDES_ThreadBase_Mutex = 0;
+    virtual status_t setPreferredMicrophoneDirection(audio_microphone_direction_t direction)
+            EXCLUDES_ThreadBase_Mutex = 0;
+    virtual status_t setPreferredMicrophoneFieldDimension(float zoom)
+            EXCLUDES_ThreadBase_Mutex = 0;
 
-    virtual void addPatchTrack(const sp<IAfPatchRecord>& record) = 0;
-    virtual void deletePatchTrack(const sp<IAfPatchRecord>& record) = 0;
+    virtual void addPatchTrack(const sp<IAfPatchRecord>& record)
+            EXCLUDES_ThreadBase_Mutex = 0;
+    virtual void deletePatchTrack(const sp<IAfPatchRecord>& record)
+            EXCLUDES_ThreadBase_Mutex = 0;
     virtual bool fastTrackAvailable() const = 0;
     virtual void setFastTrackAvailable(bool available) = 0;
 
-    virtual void setRecordSilenced(audio_port_handle_t portId, bool silenced) = 0;
+    virtual void setRecordSilenced(audio_port_handle_t portId, bool silenced)
+            EXCLUDES_ThreadBase_Mutex = 0;
     virtual bool hasFastCapture() const = 0;
 
     virtual void checkBtNrec() = 0;
@@ -555,8 +609,8 @@
     virtual status_t shareAudioHistory(
             const std::string& sharedAudioPackageName,
             audio_session_t sharedSessionId = AUDIO_SESSION_NONE,
-            int64_t sharedAudioStartMs = -1) = 0;
-    virtual void resetAudioHistory_l() = 0;
+            int64_t sharedAudioStartMs = -1) EXCLUDES_ThreadBase_Mutex = 0;
+    virtual void resetAudioHistory_l() REQUIRES(mutex()) = 0;
 };
 
 class IAfMmapThread : public virtual IAfThreadBase {
@@ -576,7 +630,7 @@
             const sp<MmapStreamCallback>& callback,
             audio_port_handle_t deviceId,
             audio_port_handle_t portId) = 0;
-    virtual void disconnect() = 0;
+    virtual void disconnect() EXCLUDES_ThreadBase_Mutex = 0;
 
     // MmapStreamInterface handling (see adapter)
     virtual status_t createMmapBuffer(
@@ -591,10 +645,12 @@
     virtual status_t reportData(const void* buffer, size_t frameCount) = 0;
 
     // TODO(b/291317898)  move to IAfThreadBase?
-    virtual void invalidateTracks(std::set<audio_port_handle_t>& portIds) = 0;
+    virtual void invalidateTracks(std::set<audio_port_handle_t>& portIds)
+            EXCLUDES_ThreadBase_Mutex = 0;
 
     // Sets the UID records silence - TODO(b/291317898)  move to IAfMmapCaptureThread
-    virtual void setRecordSilenced(audio_port_handle_t portId, bool silenced) = 0;
+    virtual void setRecordSilenced(audio_port_handle_t portId, bool silenced)
+            EXCLUDES_ThreadBase_Mutex = 0;
 
     virtual sp<IAfMmapPlaybackThread> asIAfMmapPlaybackThread() { return nullptr; }
     virtual sp<IAfMmapCaptureThread> asIAfMmapCaptureThread() { return nullptr; }
@@ -606,7 +662,7 @@
             const sp<IAfThreadCallback>& afThreadCallback, audio_io_handle_t id,
             AudioHwDevice* hwDev, AudioStreamOut* output, bool systemReady);
 
-    virtual AudioStreamOut* clearOutput() = 0;
+    virtual AudioStreamOut* clearOutput() EXCLUDES_ThreadBase_Mutex = 0;
 };
 
 class IAfMmapCaptureThread : public virtual IAfMmapThread {
@@ -615,7 +671,7 @@
             const sp<IAfThreadCallback>& afThreadCallback, audio_io_handle_t id,
             AudioHwDevice* hwDev, AudioStreamIn* input, bool systemReady);
 
-    virtual AudioStreamIn* clearInput() = 0;
+    virtual AudioStreamIn* clearInput() EXCLUDES_ThreadBase_Mutex = 0;
 };
 
 }  // namespace android
diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp
index 0b73fba..1fa5262 100644
--- a/services/audioflinger/Threads.cpp
+++ b/services/audioflinger/Threads.cpp
@@ -875,7 +875,7 @@
         } break;
         case CFG_EVENT_IO: {
             IoConfigEventData *data = (IoConfigEventData *)event->mData.get();
-            ioConfigChanged(data->mEvent, data->mPid, data->mPortId);
+            ioConfigChanged_l(data->mEvent, data->mPid, data->mPortId);
         } break;
         case CFG_EVENT_SET_PARAMETER: {
             SetParameterConfigEventData *data = (SetParameterConfigEventData *)event->mData.get();
@@ -886,22 +886,22 @@
             }
         } break;
         case CFG_EVENT_CREATE_AUDIO_PATCH: {
-            const DeviceTypeSet oldDevices = getDeviceTypes();
+            const DeviceTypeSet oldDevices = getDeviceTypes_l();
             CreateAudioPatchConfigEventData *data =
                                             (CreateAudioPatchConfigEventData *)event->mData.get();
             event->mStatus = createAudioPatch_l(&data->mPatch, &data->mHandle);
-            const DeviceTypeSet newDevices = getDeviceTypes();
+            const DeviceTypeSet newDevices = getDeviceTypes_l();
             configChanged = oldDevices != newDevices;
             mLocalLog.log("CFG_EVENT_CREATE_AUDIO_PATCH: old device %s (%s) new device %s (%s)",
                     dumpDeviceTypes(oldDevices).c_str(), toString(oldDevices).c_str(),
                     dumpDeviceTypes(newDevices).c_str(), toString(newDevices).c_str());
         } break;
         case CFG_EVENT_RELEASE_AUDIO_PATCH: {
-            const DeviceTypeSet oldDevices = getDeviceTypes();
+            const DeviceTypeSet oldDevices = getDeviceTypes_l();
             ReleaseAudioPatchConfigEventData *data =
                                             (ReleaseAudioPatchConfigEventData *)event->mData.get();
             event->mStatus = releaseAudioPatch_l(data->mHandle);
-            const DeviceTypeSet newDevices = getDeviceTypes();
+            const DeviceTypeSet newDevices = getDeviceTypes_l();
             configChanged = oldDevices != newDevices;
             mLocalLog.log("CFG_EVENT_RELEASE_AUDIO_PATCH: old device %s (%s) new device %s (%s)",
                     dumpDeviceTypes(oldDevices).c_str(), toString(oldDevices).c_str(),
@@ -1089,9 +1089,9 @@
     }
     // Note: output device may be used by capture threads for effects such as AEC.
     dprintf(fd, "  Output devices: %s (%s)\n",
-            dumpDeviceTypes(outDeviceTypes()).c_str(), toString(outDeviceTypes()).c_str());
+            dumpDeviceTypes(outDeviceTypes_l()).c_str(), toString(outDeviceTypes_l()).c_str());
     dprintf(fd, "  Input device: %#x (%s)\n",
-            inDeviceType(), toString(inDeviceType()).c_str());
+            inDeviceType_l(), toString(inDeviceType_l()).c_str());
     dprintf(fd, "  Audio source: %d (%s)\n", mAudioSource, toString(mAudioSource).c_str());
 
     // Dump timestamp statistics for the Thread types that support it.
@@ -1102,7 +1102,8 @@
             || mType == OFFLOAD
             || mType == SPATIALIZER) {
         dprintf(fd, "  Timestamp stats: %s\n", mTimestampVerifier.toString().c_str());
-        dprintf(fd, "  Timestamp corrected: %s\n", isTimestampCorrectionEnabled() ? "yes" : "no");
+        dprintf(fd, "  Timestamp corrected: %s\n",
+                isTimestampCorrectionEnabled_l() ? "yes" : "no");
     }
 
     if (mLastIoBeginNs > 0) { // MMAP may not set this
@@ -1979,7 +1980,7 @@
 }
 
 template <typename T>
-void ThreadBase::ActiveTracks<T>::updatePowerState(
+void ThreadBase::ActiveTracks<T>::updatePowerState_l(
         const sp<ThreadBase>& thread, bool force) {
     // Updates ActiveTracks client uids to the thread wakelock.
     if (mActiveTracksGeneration != mLastActiveTracksGeneration || force) {
@@ -2045,6 +2046,7 @@
 // Call only from threadLoop() or when it is idle.
 // Do not call from high performance code as this may do binder rpc to the MediaMetrics service.
 void ThreadBase::sendStatistics(bool force)
+NO_THREAD_SAFETY_ANALYSIS
 {
     // Do not log if we have no stats.
     // We choose the timestamp verifier because it is the most likely item to be present.
@@ -2076,8 +2078,8 @@
     item->setInt64(MM_PREFIX "channelMask", (int64_t)mChannelMask);
     item->setCString(MM_PREFIX "encoding", toString(mFormat).c_str());
     item->setInt32(MM_PREFIX "frameCount", (int32_t)mFrameCount);
-    item->setCString(MM_PREFIX "outDevice", toString(outDeviceTypes()).c_str());
-    item->setCString(MM_PREFIX "inDevice", toString(inDeviceType()).c_str());
+    item->setCString(MM_PREFIX "outDevice", toString(outDeviceTypes_l()).c_str());
+    item->setCString(MM_PREFIX "inDevice", toString(inDeviceType_l()).c_str());
 
     // thread statistics
     if (mIoJitterMs.getN() > 0) {
@@ -2791,6 +2793,8 @@
     return latency_l();
 }
 uint32_t PlaybackThread::latency_l() const
+NO_THREAD_SAFETY_ANALYSIS
+// Fix later.
 {
     uint32_t latency;
     if (initCheck() == NO_ERROR && mOutput->stream->getLatency(&latency) == OK) {
@@ -3026,7 +3030,7 @@
     return mOutput->stream->selectPresentation(presentationId, programId);
 }
 
-void PlaybackThread::ioConfigChanged(audio_io_config_event_t event, pid_t pid,
+void PlaybackThread::ioConfigChanged_l(audio_io_config_event_t event, pid_t pid,
                                                    audio_port_handle_t portId) {
     ALOGV("PlaybackThread::ioConfigChanged, thread %p, event %d", this, event);
     sp<AudioIoDescriptor> desc;
@@ -3048,7 +3052,7 @@
         desc = sp<AudioIoDescriptor>::make(mId);
         break;
     }
-    mAfThreadCallback->ioConfigChanged(event, desc, pid);
+    mAfThreadCallback->ioConfigChanged_l(event, desc, pid);
 }
 
 void PlaybackThread::onWriteReady()
@@ -3234,8 +3238,8 @@
     if (hasMixer()) {
         mNormalFrameCount = (mNormalFrameCount + 15) & ~15;
     }
-    ALOGI("HAL output buffer size %zu frames, normal sink buffer size %zu frames", mFrameCount,
-            mNormalFrameCount);
+    ALOGI("HAL output buffer size %zu frames, normal sink buffer size %zu frames",
+            (size_t)mFrameCount, mNormalFrameCount);
 
     // Check if we want to throttle the processing to no more than 2x normal rate
     mThreadThrottle = property_get_bool("af.thread.throttle", true /* default_value */);
@@ -3472,7 +3476,7 @@
             ALOGD("ro.audio.silent is ignored since no output device is set");
             return;
         }
-        if (isSingleDeviceType(outDeviceTypes(), AUDIO_DEVICE_OUT_REMOTE_SUBMIX)) {
+        if (isSingleDeviceType(outDeviceTypes_l(), AUDIO_DEVICE_OUT_REMOTE_SUBMIX)) {
             ALOGD("ro.audio.silent will be ignored for threads on AUDIO_DEVICE_OUT_REMOTE_SUBMIX");
             return;
         }
@@ -3642,7 +3646,7 @@
 
     // make sure standby delay is not too short when connected to an A2DP sink to avoid
     // truncating audio when going to standby.
-    if (!Intersection(outDeviceTypes(),  getAudioDeviceOutAllA2dpSet()).empty()) {
+    if (!Intersection(outDeviceTypes_l(),  getAudioDeviceOutAllA2dpSet()).empty()) {
         if (mStandbyDelayNs < kDefaultStandbyTimeInNsecs) {
             mStandbyDelayNs = kDefaultStandbyTimeInNsecs;
         }
@@ -3990,7 +3994,7 @@
         // If the device is AUDIO_DEVICE_OUT_BUS, check for downstream latency.
         //
         // Note: we access outDeviceTypes() outside of mutex().
-        if (isMsdDevice() && outDeviceTypes().count(AUDIO_DEVICE_OUT_BUS) != 0) {
+        if (isMsdDevice() && outDeviceTypes_l().count(AUDIO_DEVICE_OUT_BUS) != 0) {
             // Here, we try for the AF lock, but do not block on it as the latency
             // is more informational.
             if (mAfThreadCallback->mutex().try_lock()) {
@@ -4135,7 +4139,7 @@
             // mMixerStatusIgnoringFastTracks is also updated internally
             mMixerStatus = prepareTracks_l(&tracksToRemove);
 
-            mActiveTracks.updatePowerState(this);
+            mActiveTracks.updatePowerState_l(this);
 
             metadataUpdate = updateMetadata_l();
 
@@ -4508,9 +4512,10 @@
                                 // notify of throttle end on debug log
                                 // but prevent spamming for bluetooth
                                 ALOGD_IF(!isSingleDeviceType(
-                                                 outDeviceTypes(), audio_is_a2dp_out_device) &&
+                                                 outDeviceTypes_l(), audio_is_a2dp_out_device) &&
                                          !isSingleDeviceType(
-                                                 outDeviceTypes(), audio_is_hearing_aid_out_device),
+                                                 outDeviceTypes_l(),
+                                                 audio_is_hearing_aid_out_device),
                                         "mixer(%p) throttle end: throttle time(%u)", this, diff);
                                 mThreadThrottleEndMs = mThreadThrottleTimeMs;
                             }
@@ -4606,7 +4611,7 @@
                 timestamp.mTimeNs[ExtendedTimestamp::LOCATION_KERNEL],
                 mSampleRate);
 
-        if (isTimestampCorrectionEnabled()) {
+        if (isTimestampCorrectionEnabled_l()) {
             ALOGVV("TS_BEFORE: %d %lld %lld", id(),
                     (long long)timestamp.mTimeNs[ExtendedTimestamp::LOCATION_KERNEL],
                     (long long)timestamp.mPosition[ExtendedTimestamp::LOCATION_KERNEL]);
@@ -7218,6 +7223,7 @@
 {
     if (mFlushPending || mHwPaused) {
         // If a flush is pending or track was paused, just discard buffered data
+        audio_utils::lock_guard l(mutex());
         flushHw_l();
     } else {
         mMixerStatus = MIXER_DRAIN_ALL;
@@ -8261,7 +8267,7 @@
 
             }
 
-            mActiveTracks.updatePowerState(this);
+            mActiveTracks.updatePowerState_l(this);
 
             updateMetadata_l();
 
@@ -8439,7 +8445,12 @@
                 mTimestampVerifier.add(position, time, mSampleRate);
 
                 // Correct timestamps
-                if (isTimestampCorrectionEnabled()) {
+                bool timestampCorrectionEnabled = false;
+                {
+                    audio_utils::lock_guard l(mutex());
+                    timestampCorrectionEnabled = isTimestampCorrectionEnabled_l();
+                }
+                if (timestampCorrectionEnabled) {
                     ALOGVV("TS_BEFORE: %d %lld %lld",
                             id(), (long long)time, (long long)position);
                     auto correctedTimestamp = mTimestampVerifier.getLastCorrectedTimestamp();
@@ -9418,7 +9429,7 @@
 {
     // disable AEC and NS if the device is a BT SCO headset supporting those
     // pre processings
-    bool suspend = audio_is_bluetooth_sco_device(inDeviceType()) &&
+    bool suspend = audio_is_bluetooth_sco_device(inDeviceType_l()) &&
                         mAfThreadCallback->btNrecIsOff();
     if (mBtNrecSuspended.exchange(suspend) != suspend) {
         for (size_t i = 0; i < mEffectChains.size(); i++) {
@@ -9529,7 +9540,7 @@
     return {};
 }
 
-void RecordThread::ioConfigChanged(audio_io_config_event_t event, pid_t pid,
+void RecordThread::ioConfigChanged_l(audio_io_config_event_t event, pid_t pid,
                                                  audio_port_handle_t portId) {
     sp<AudioIoDescriptor> desc;
     switch (event) {
@@ -9547,7 +9558,7 @@
         desc = sp<AudioIoDescriptor>::make(mId);
         break;
     }
-    mAfThreadCallback->ioConfigChanged(event, desc, pid);
+    mAfThreadCallback->ioConfigChanged_l(event, desc, pid);
 }
 
 void RecordThread::readInputParameters_l()
@@ -10345,7 +10356,10 @@
 
 bool MmapThread::threadLoop()
 {
-    checkSilentMode_l();
+    {
+        audio_utils::unique_lock _l(mutex());
+        checkSilentMode_l();
+    }
 
     const String8 myName(String8::format("thread %p type %d TID %d", this, mType, gettid()));
 
@@ -10385,7 +10399,7 @@
 
         checkInvalidTracks_l();
 
-        mActiveTracks.updatePowerState(this);
+        mActiveTracks.updatePowerState_l(this);
 
         updateMetadata_l();
 
@@ -10442,7 +10456,7 @@
     return {};
 }
 
-void MmapThread::ioConfigChanged(audio_io_config_event_t event, pid_t pid,
+void MmapThread::ioConfigChanged_l(audio_io_config_event_t event, pid_t pid,
                                                audio_port_handle_t portId __unused) {
     sp<AudioIoDescriptor> desc;
     bool isInput = false;
@@ -10464,7 +10478,7 @@
         desc = sp<AudioIoDescriptor>::make(mId);
         break;
     }
-    mAfThreadCallback->ioConfigChanged(event, desc, pid);
+    mAfThreadCallback->ioConfigChanged_l(event, desc, pid);
 }
 
 status_t MmapThread::createAudioPatch_l(const struct audio_patch* patch,
@@ -10760,14 +10774,24 @@
         AudioHwDevice *hwDev,  AudioStreamOut *output, bool systemReady)
     : MmapThread(afThreadCallback, id, hwDev, output->stream, systemReady, true /* isOut */),
       mStreamType(AUDIO_STREAM_MUSIC),
-      mStreamVolume(1.0),
-      mStreamMute(false),
       mOutput(output)
 {
     snprintf(mThreadName, kThreadNameLength, "AudioMmapOut_%X", id);
     mChannelCount = audio_channel_count_from_out_mask(mChannelMask);
     mMasterVolume = afThreadCallback->masterVolume_l();
     mMasterMute = afThreadCallback->masterMute_l();
+
+    for (int i = AUDIO_STREAM_MIN; i < AUDIO_STREAM_FOR_POLICY_CNT; ++i) {
+        const audio_stream_type_t stream{static_cast<audio_stream_type_t>(i)};
+        mStreamTypes[stream].volume = 0.0f;
+        mStreamTypes[stream].mute = mAfThreadCallback->streamMute_l(stream);
+    }
+    // Audio patch and call assistant volume are always max
+    mStreamTypes[AUDIO_STREAM_PATCH].volume = 1.0f;
+    mStreamTypes[AUDIO_STREAM_PATCH].mute = false;
+    mStreamTypes[AUDIO_STREAM_CALL_ASSISTANT].volume = 1.0f;
+    mStreamTypes[AUDIO_STREAM_CALL_ASSISTANT].mute = false;
+
     if (mAudioHwDev) {
         if (mAudioHwDev->canSetMasterVolume()) {
             mMasterVolume = 1.0;
@@ -10824,8 +10848,8 @@
 void MmapPlaybackThread::setStreamVolume(audio_stream_type_t stream, float value)
 {
     audio_utils::lock_guard _l(mutex());
+    mStreamTypes[stream].volume = value;
     if (stream == mStreamType) {
-        mStreamVolume = value;
         broadcast_l();
     }
 }
@@ -10833,17 +10857,14 @@
 float MmapPlaybackThread::streamVolume(audio_stream_type_t stream) const
 {
     audio_utils::lock_guard _l(mutex());
-    if (stream == mStreamType) {
-        return mStreamVolume;
-    }
-    return 0.0f;
+    return mStreamTypes[stream].volume;
 }
 
 void MmapPlaybackThread::setStreamMute(audio_stream_type_t stream, bool muted)
 {
     audio_utils::lock_guard _l(mutex());
+    mStreamTypes[stream].mute = muted;
     if (stream == mStreamType) {
-        mStreamMute= muted;
         broadcast_l();
     }
 }
@@ -10883,14 +10904,13 @@
 {
     float volume;
 
-    if (mMasterMute || mStreamMute) {
+    if (mMasterMute || streamMuted_l()) {
         volume = 0;
     } else {
-        volume = mMasterVolume * mStreamVolume;
+        volume = mMasterVolume * streamVolume_l();
     }
 
     if (volume != mHalVolFloat) {
-
         // Convert volumes from float to 8.24
         uint32_t vol = (uint32_t)(volume * (1 << 24));
 
@@ -10924,8 +10944,8 @@
             track->setMetadataHasChanged();
             track->processMuteEvent_l(mAfThreadCallback->getOrCreateAudioManager(),
                 /*muteState=*/{mMasterMute,
-                               mStreamVolume == 0.f,
-                               mStreamMute,
+                               streamVolume_l() == 0.f,
+                               streamMuted_l(),
                                // TODO(b/241533526): adjust logic to include mute from AppOps
                                false /*muteFromPlaybackRestricted*/,
                                false /*muteFromClientVolume*/,
@@ -11038,7 +11058,7 @@
     MmapThread::dumpInternals_l(fd, args);
 
     dprintf(fd, "  Stream type: %d Stream volume: %f HAL volume: %f Stream mute %d\n",
-            mStreamType, mStreamVolume, mHalVolFloat, mStreamMute);
+            mStreamType, streamVolume_l(), mHalVolFloat, streamMuted_l());
     dprintf(fd, "  Master volume: %f Master mute %d\n", mMasterVolume, mMasterMute);
 }
 
diff --git a/services/audioflinger/Threads.h b/services/audioflinger/Threads.h
index 3105ad7..9020342 100644
--- a/services/audioflinger/Threads.h
+++ b/services/audioflinger/Threads.h
@@ -51,7 +51,7 @@
     ~ThreadBase() override;
 
     status_t readyToRun() final;
-    void clearPowerManager() final;
+    void clearPowerManager() final EXCLUDES_ThreadBase_Mutex;
 
     // base for record and playback
     enum {
@@ -68,11 +68,9 @@
 
     class ConfigEventData: public RefBase {
     public:
-        virtual ~ConfigEventData() {}
-
         virtual  void dump(char *buffer, size_t size) = 0;
     protected:
-        ConfigEventData() {}
+        ConfigEventData() = default;
     };
 
     // Config event sequence by client if status needed (e.g binder thread calling setParameters()):
@@ -103,14 +101,22 @@
             }
         }
 
-        audio_utils::mutex& mutex() const { return mMutex; }
+        audio_utils::mutex& mutex() const RETURN_CAPABILITY(audio_utils::ConfigEvent_Mutex) {
+            return mMutex;
+        }
         const int mType; // event type e.g. CFG_EVENT_IO
         mutable audio_utils::mutex mMutex; // mutex associated with mCondition
         audio_utils::condition_variable mCondition; // condition for status return
+
+        // NO_THREAD_SAFETY_ANALYSIS Can we add GUARDED_BY?
         status_t mStatus; // status communicated to sender
-        bool mWaitStatus; // true if sender is waiting for status
-        bool mRequiresSystemReady; // true if must wait for system ready to enter event queue
-        sp<ConfigEventData> mData;     // event specific parameter data
+
+        bool mWaitStatus GUARDED_BY(mutex()); // true if sender is waiting for status
+        // true if must wait for system ready to enter event queue
+        bool mRequiresSystemReady GUARDED_BY(mutex());
+
+        // NO_THREAD_SAFETY_ANALYSIS Can we add GUARDED_BY?
+        sp<ConfigEventData> mData; // event specific parameter data
 
     protected:
         explicit ConfigEvent(int type, bool requiresSystemReady = false) :
@@ -197,7 +203,7 @@
         }
 
         const struct audio_patch mPatch;
-        audio_patch_handle_t mHandle;
+        audio_patch_handle_t mHandle;  // cannot be const
     };
 
     class CreateAudioPatchConfigEvent : public ConfigEvent {
@@ -219,7 +225,7 @@
             snprintf(buffer, size, "- Patch handle: %u\n", mHandle);
         }
 
-        audio_patch_handle_t mHandle;
+        const audio_patch_handle_t mHandle;
     };
 
     class ReleaseAudioPatchConfigEvent : public ConfigEvent {
@@ -240,7 +246,7 @@
             snprintf(buffer, size, "- Devices: %s", android::toString(mOutDevices).c_str());
         }
 
-        DeviceDescriptorBaseVector mOutDevices;
+        const DeviceDescriptorBaseVector mOutDevices;
     };
 
     class UpdateOutDevicesConfigEvent : public ConfigEvent {
@@ -260,7 +266,7 @@
             snprintf(buffer, size, "- mMaxSharedAudioHistoryMs: %d", mMaxSharedAudioHistoryMs);
         }
 
-        int32_t mMaxSharedAudioHistoryMs;
+        const int32_t mMaxSharedAudioHistoryMs;
     };
 
     class ResizeBufferConfigEvent : public ConfigEvent {
@@ -289,15 +295,14 @@
     class PMDeathRecipient : public IBinder::DeathRecipient {
     public:
         explicit    PMDeathRecipient(const wp<ThreadBase>& thread) : mThread(thread) {}
-        virtual     ~PMDeathRecipient() {}
 
         // IBinder::DeathRecipient
-        virtual     void        binderDied(const wp<IBinder>& who);
+        void binderDied(const wp<IBinder>& who) final;
 
     private:
         DISALLOW_COPY_AND_ASSIGN(PMDeathRecipient);
 
-        wp<ThreadBase> mThread;
+        const wp<ThreadBase> mThread;
     };
 
     type_t type() const final { return mType; }
@@ -311,8 +316,9 @@
     uint32_t channelCount() const final { return mChannelCount; }
     audio_channel_mask_t hapticChannelMask() const override { return AUDIO_CHANNEL_NONE; }
     uint32_t hapticChannelCount() const override { return 0; }
-    uint32_t latency_l() const override { return 0; }
-    void setVolumeForOutput_l(float /* left */, float /* right */) const override {}
+    uint32_t latency_l() const override { return 0; }  // NO_THREAD_SAFETY_ANALYSIS
+    void setVolumeForOutput_l(float /* left */, float /* right */) const override
+            REQUIRES(mutex()) {}
 
                 // Return's the HAL's frame count i.e. fast mixer buffer size.
     size_t frameCountHAL() const final { return mFrameCount; }
@@ -320,44 +326,49 @@
 
     // Should be "virtual status_t requestExitAndWait()" and override same
     // method in Thread, but Thread::requestExitAndWait() is not yet virtual.
-    void exit() final;
-    status_t setParameters(const String8& keyValuePairs) final;
+    void exit() final EXCLUDES_ThreadBase_Mutex;
+    status_t setParameters(const String8& keyValuePairs) final EXCLUDES_ThreadBase_Mutex;
 
                 // sendConfigEvent_l() must be called with ThreadBase::mutex() held
                 // Can temporarily release the lock if waiting for a reply from
                 // processConfigEvents_l().
-    status_t sendConfigEvent_l(sp<ConfigEvent>& event);
+    status_t sendConfigEvent_l(sp<ConfigEvent>& event) REQUIRES(mutex());
     void sendIoConfigEvent(audio_io_config_event_t event, pid_t pid = 0,
-            audio_port_handle_t portId = AUDIO_PORT_HANDLE_NONE) final;
+            audio_port_handle_t portId = AUDIO_PORT_HANDLE_NONE) final EXCLUDES_ThreadBase_Mutex;
     void sendIoConfigEvent_l(audio_io_config_event_t event, pid_t pid = 0,
-            audio_port_handle_t portId = AUDIO_PORT_HANDLE_NONE) final;
-    void sendPrioConfigEvent(pid_t pid, pid_t tid, int32_t prio, bool forApp) final;
-    void sendPrioConfigEvent_l(pid_t pid, pid_t tid, int32_t prio, bool forApp) final;
-    status_t sendSetParameterConfigEvent_l(const String8& keyValuePair) final;
+            audio_port_handle_t portId = AUDIO_PORT_HANDLE_NONE) final REQUIRES(mutex());
+    void sendPrioConfigEvent(pid_t pid, pid_t tid, int32_t prio, bool forApp) final
+            EXCLUDES_ThreadBase_Mutex;
+    void sendPrioConfigEvent_l(pid_t pid, pid_t tid, int32_t prio, bool forApp) final
+            REQUIRES(mutex());
+    status_t sendSetParameterConfigEvent_l(const String8& keyValuePair) final REQUIRES(mutex());
     status_t sendCreateAudioPatchConfigEvent(const struct audio_patch* patch,
-            audio_patch_handle_t* handle) final;
-    status_t sendReleaseAudioPatchConfigEvent(audio_patch_handle_t handle) final;
+            audio_patch_handle_t* handle) final EXCLUDES_ThreadBase_Mutex;
+    status_t sendReleaseAudioPatchConfigEvent(audio_patch_handle_t handle) final
+            EXCLUDES_ThreadBase_Mutex;
     status_t sendUpdateOutDeviceConfigEvent(
-            const DeviceDescriptorBaseVector& outDevices) final;
-    void sendResizeBufferConfigEvent_l(int32_t maxSharedAudioHistoryMs) final;
-    void sendCheckOutputStageEffectsEvent() final;
-    void sendCheckOutputStageEffectsEvent_l() final;
-    void sendHalLatencyModesChangedEvent_l() final;
+            const DeviceDescriptorBaseVector& outDevices) final EXCLUDES_ThreadBase_Mutex;
+    void sendResizeBufferConfigEvent_l(int32_t maxSharedAudioHistoryMs) final REQUIRES(mutex());
+    void sendCheckOutputStageEffectsEvent() final EXCLUDES_ThreadBase_Mutex;
+    void sendCheckOutputStageEffectsEvent_l() final REQUIRES(mutex());
+    void sendHalLatencyModesChangedEvent_l() final REQUIRES(mutex());
 
-    void processConfigEvents_l() final;
+    void processConfigEvents_l() final REQUIRES(mutex());
     void setCheckOutputStageEffects() override {}
     void updateOutDevices(const DeviceDescriptorBaseVector& outDevices) override;
     void toAudioPortConfig(struct audio_port_config* config) override;
-    void resizeInputBuffer_l(int32_t maxSharedAudioHistoryMs) override;
+    void resizeInputBuffer_l(int32_t maxSharedAudioHistoryMs) override REQUIRES(mutex());
 
     // see note at declaration of mStandby, mOutDevice and mInDevice
     bool inStandby() const override { return mStandby; }
-    const DeviceTypeSet outDeviceTypes() const final {
+    const DeviceTypeSet outDeviceTypes_l() const final REQUIRES(mutex()) {
         return getAudioDeviceTypes(mOutDeviceTypeAddrs);
     }
-    audio_devices_t inDeviceType() const final { return mInDeviceTypeAddr.mType; }
-    DeviceTypeSet getDeviceTypes() const final {
-        return isOutput() ? outDeviceTypes() : DeviceTypeSet({inDeviceType()});
+    audio_devices_t inDeviceType_l() const final REQUIRES(mutex()) {
+        return mInDeviceTypeAddr.mType;
+    }
+    DeviceTypeSet getDeviceTypes_l() const final REQUIRES(mutex()) {
+        return isOutput() ? outDeviceTypes_l() : DeviceTypeSet({inDeviceType_l()});
     }
 
     const AudioDeviceTypeAddrVector& outDeviceTypeAddrs() const final {
@@ -417,16 +428,19 @@
                 // ThreadBase mutex before processing the mixer and effects. This guarantees the
                 // integrity of the chains during the process.
                 // Also sets the parameter 'effectChains' to current value of mEffectChains.
-    void lockEffectChains_l(Vector<sp<IAfEffectChain>>& effectChains) final;
+    void lockEffectChains_l(Vector<sp<IAfEffectChain>>& effectChains) final REQUIRES(mutex());
                 // unlock effect chains after process
     void unlockEffectChains(const Vector<sp<IAfEffectChain>>& effectChains) final;
                 // get a copy of mEffectChains vector
-    Vector<sp<IAfEffectChain>> getEffectChains_l() const final { return mEffectChains; };
+    Vector<sp<IAfEffectChain>> getEffectChains_l() const final REQUIRES(mutex()) {
+        return mEffectChains;
+    }
                 // set audio mode to all effect chains
     void setMode(audio_mode_t mode) final;
                 // get effect module with corresponding ID on specified audio session
     sp<IAfEffectModule> getEffect(audio_session_t sessionId, int effectId) const final;
-    sp<IAfEffectModule> getEffect_l(audio_session_t sessionId, int effectId) const final;
+    sp<IAfEffectModule> getEffect_l(audio_session_t sessionId, int effectId) const final
+            REQUIRES(mutex());
                 // add and effect module. Also creates the effect chain is none exists for
                 // the effects audio session. Only called in a context of moving an effect
                 // from one thread to another
@@ -434,17 +448,18 @@
             REQUIRES(audio_utils::AudioFlinger_Mutex, mutex());
                 // remove and effect module. Also removes the effect chain is this was the last
                 // effect
-    void removeEffect_l(const sp<IAfEffectModule>& effect, bool release = false) final;
+    void removeEffect_l(const sp<IAfEffectModule>& effect, bool release = false) final
+            REQUIRES(mutex());
                 // disconnect an effect handle from module and destroy module if last handle
     void disconnectEffectHandle(IAfEffectHandle* handle, bool unpinIfLast) final;
                 // detach all tracks connected to an auxiliary effect
-    void detachAuxEffect_l(int /* effectId */) override {}
+    void detachAuxEffect_l(int /* effectId */) override REQUIRES(mutex()) {}
     // TODO(b/291317898) - remove hasAudioSession_l below.
-    uint32_t hasAudioSession_l(audio_session_t sessionId) const override = 0;
-    uint32_t hasAudioSession(audio_session_t sessionId) const final {
-                    std::lock_guard _l(mutex());
-                    return hasAudioSession_l(sessionId);
-                }
+    uint32_t hasAudioSession_l(audio_session_t sessionId) const override REQUIRES(mutex()) = 0;
+    uint32_t hasAudioSession(audio_session_t sessionId) const final EXCLUDES_ThreadBase_Mutex {
+        std::lock_guard _l(mutex());
+        return hasAudioSession_l(sessionId);
+    }
 
                 template <typename T>
                 uint32_t hasAudioSession_l(audio_session_t sessionId, const T& tracks) const {
@@ -476,9 +491,9 @@
                 // the value returned by default implementation is not important as the
                 // strategy is only meaningful for PlaybackThread which implements this method
     product_strategy_t getStrategyForSession_l(
-            audio_session_t /* sessionId */) const override {
-                    return static_cast<product_strategy_t>(0);
-                }
+            audio_session_t /* sessionId */) const override REQUIRES(mutex()){
+        return static_cast<product_strategy_t>(0);
+    }
 
                 // check if some effects must be suspended/restored when an effect is enabled
                 // or disabled
@@ -497,38 +512,40 @@
 
     sp<IMemory> pipeMemory() const override { return nullptr; }
 
-    void systemReady() final;
+    void systemReady() final EXCLUDES_ThreadBase_Mutex;
 
-    void broadcast_l() final;
+    void broadcast_l() final REQUIRES(mutex());
 
-    bool isTimestampCorrectionEnabled() const override { return false; }
+    bool isTimestampCorrectionEnabled_l() const override REQUIRES(mutex()) { return false; }
 
     bool isMsdDevice() const final { return mIsMsdDevice; }
 
     void dump(int fd, const Vector<String16>& args) override;
 
                 // deliver stats to mediametrics.
-    void sendStatistics(bool force) final;
+    void sendStatistics(bool force) final EXCLUDES_ThreadBase_Mutex;
 
     audio_utils::mutex& mutex() const final RETURN_CAPABILITY(audio_utils::ThreadBase_Mutex) {
         return mMutex;
     }
     mutable audio_utils::mutex mMutex;
 
-    void onEffectEnable(const sp<IAfEffectModule>& effect) final;
-    void onEffectDisable() final;
+    void onEffectEnable(const sp<IAfEffectModule>& effect) final EXCLUDES_ThreadBase_Mutex;
+    void onEffectDisable() final EXCLUDES_ThreadBase_Mutex;
 
                 // invalidateTracksForAudioSession_l must be called with holding mutex().
-    void invalidateTracksForAudioSession_l(audio_session_t /* sessionId */) const override {}
+    void invalidateTracksForAudioSession_l(audio_session_t /* sessionId */) const override
+            REQUIRES(mutex()) {}
                 // Invalidate all the tracks with the given audio session.
-    void invalidateTracksForAudioSession(audio_session_t sessionId) const final {
+    void invalidateTracksForAudioSession(audio_session_t sessionId) const final
+            EXCLUDES_ThreadBase_Mutex {
                     std::lock_guard _l(mutex());
                     invalidateTracksForAudioSession_l(sessionId);
                 }
 
                 template <typename T>
-                void invalidateTracksForAudioSession_l(audio_session_t sessionId,
-                                                       const T& tracks) const {
+    void invalidateTracksForAudioSession_l(audio_session_t sessionId,
+            const T& tracks) const REQUIRES(mutex()) {
                     for (size_t i = 0; i < tracks.size(); ++i) {
                         const sp<IAfTrackBase>& track = tracks[i];
                         if (sessionId == track->sessionId()) {
@@ -553,41 +570,41 @@
                     effect_uuid_t mType;    // effect type UUID
                 };
 
-                void        acquireWakeLock();
-                virtual void acquireWakeLock_l();
-                void        releaseWakeLock();
-                void        releaseWakeLock_l();
-                void        updateWakeLockUids_l(const SortedVector<uid_t> &uids);
-                void        getPowerManager_l();
+    void acquireWakeLock() EXCLUDES_ThreadBase_Mutex;
+    virtual void acquireWakeLock_l() REQUIRES(mutex());
+    void releaseWakeLock() EXCLUDES_ThreadBase_Mutex;
+    void releaseWakeLock_l() REQUIRES(mutex());
+    void updateWakeLockUids_l(const SortedVector<uid_t> &uids) REQUIRES(mutex());
+    void getPowerManager_l() REQUIRES(mutex());
                 // suspend or restore effects of the specified type (or all if type is NULL)
                 // on a given session. The number of suspend requests is counted and restore
                 // occurs when all suspend requests are cancelled.
-                void setEffectSuspended_l(const effect_uuid_t *type,
+    void setEffectSuspended_l(const effect_uuid_t *type,
                                           bool suspend,
-                                          audio_session_t sessionId) final;
+            audio_session_t sessionId) final REQUIRES(mutex());
                 // updated mSuspendedSessions when an effect is suspended or restored
-                void        updateSuspendedSessions_l(const effect_uuid_t *type,
+    void updateSuspendedSessions_l(const effect_uuid_t *type,
                                                       bool suspend,
-                                                      audio_session_t sessionId);
+            audio_session_t sessionId) REQUIRES(mutex());
                 // check if some effects must be suspended when an effect chain is added
-                void checkSuspendOnAddEffectChain_l(const sp<IAfEffectChain>& chain);
+    void checkSuspendOnAddEffectChain_l(const sp<IAfEffectChain>& chain) REQUIRES(mutex());
 
                 // sends the metadata of the active tracks to the HAL
                 struct MetadataUpdate {
                     std::vector<playback_track_metadata_v7_t> playbackMetadataUpdate;
                     std::vector<record_track_metadata_v7_t>   recordMetadataUpdate;
                 };
-    virtual     MetadataUpdate           updateMetadata_l() = 0;
+    virtual MetadataUpdate updateMetadata_l() REQUIRES(mutex()) = 0;
 
                 String16 getWakeLockTag();
 
-    virtual     void        preExit() { }
-    virtual     void        setMasterMono_l(bool mono __unused) { }
+    virtual void preExit() EXCLUDES_ThreadBase_Mutex {}
+    virtual void setMasterMono_l(bool mono __unused) REQUIRES(mutex()) {}
     virtual     bool        requireMonoBlend() { return false; }
 
                             // called within the threadLoop to obtain timestamp from the HAL.
-    virtual     status_t    threadloop_getHalTimestamp_l(
-                                    ExtendedTimestamp *timestamp __unused) const {
+    virtual status_t threadloop_getHalTimestamp_l(
+            ExtendedTimestamp *timestamp __unused) const REQUIRES(mutex()) {
                                 return INVALID_OPERATION;
                             }
 public:
@@ -595,11 +612,12 @@
                 product_strategy_t getStrategyForStream(audio_stream_type_t stream) const;
 protected:
 
-    virtual     void        onHalLatencyModesChanged_l() {}
+    virtual void onHalLatencyModesChanged_l() REQUIRES(mutex()) {}
 
-    virtual     void        dumpInternals_l(int fd __unused, const Vector<String16>& args __unused)
-                            { }
-    virtual     void        dumpTracks_l(int fd __unused, const Vector<String16>& args __unused) { }
+    virtual void dumpInternals_l(int fd __unused, const Vector<String16>& args __unused)
+            REQUIRES(mutex()) {}
+    virtual void dumpTracks_l(int fd __unused, const Vector<String16>& args __unused)
+            REQUIRES(mutex()) {}
 
                 const type_t            mType;
 
@@ -624,8 +642,10 @@
                                                            // HAL format if Fastmixer is used.
                 audio_format_t          mHALFormat;
                 size_t                  mBufferSize;       // HAL buffer size for read() or write()
-                AudioDeviceTypeAddrVector mOutDeviceTypeAddrs; // output device types and addresses
-                AudioDeviceTypeAddr       mInDeviceTypeAddr;   // input device type and address
+
+     // output device types and addresses
+    AudioDeviceTypeAddrVector mOutDeviceTypeAddrs GUARDED_BY(mutex());
+    AudioDeviceTypeAddr mInDeviceTypeAddr GUARDED_BY(mutex());   // input device type and address
                 Vector< sp<ConfigEvent> >     mConfigEvents;
                 Vector< sp<ConfigEvent> >     mPendingConfigEvents; // events awaiting system ready
 
@@ -764,7 +784,8 @@
                     // ThreadBase thread.
                     void            clear();
                     // periodically called in the threadLoop() to update power state uids.
-                    void updatePowerState(const sp<ThreadBase>& thread, bool force = false);
+                    void updatePowerState_l(const sp<ThreadBase>& thread, bool force = false)
+                            REQUIRES(audio_utils::ThreadBase_Mutex);
 
                     /** @return true if one or move active tracks was added or removed since the
                      *          last time this function was called or the vector was created.
@@ -799,11 +820,11 @@
                     bool                mHasChanged = false;
                 };
 
-                SimpleLog mLocalLog;
+                SimpleLog mLocalLog;  // locked internally
 
 private:
-                void dumpBase_l(int fd, const Vector<String16>& args);
-                void dumpEffectChains_l(int fd, const Vector<String16>& args);
+    void dumpBase_l(int fd, const Vector<String16>& args) REQUIRES(mutex());
+    void dumpEffectChains_l(int fd, const Vector<String16>& args) REQUIRES(mutex());
 };
 
 // --- PlaybackThread ---
@@ -836,15 +857,15 @@
     ~PlaybackThread() override;
 
     // Thread virtuals
-    bool threadLoop() final;
+    bool threadLoop() final EXCLUDES_ThreadBase_Mutex;
 
     // RefBase
     void onFirstRef() override;
 
     status_t checkEffectCompatibility_l(
-            const effect_descriptor_t* desc, audio_session_t sessionId) final;
+            const effect_descriptor_t* desc, audio_session_t sessionId) final REQUIRES(mutex());
 
-    void addOutputTrack_l(const sp<IAfTrack>& track) final {
+    void addOutputTrack_l(const sp<IAfTrack>& track) final REQUIRES(mutex()) {
         mTracks.add(track);
     }
 
@@ -877,9 +898,9 @@
 protected:
 
     virtual     bool        waitingAsyncCallback();
-    virtual     bool        waitingAsyncCallback_l();
-    virtual     bool        shouldStandby_l();
-    virtual     void        onAddNewTrack_l();
+    virtual bool waitingAsyncCallback_l() REQUIRES(mutex());
+    virtual bool shouldStandby_l() REQUIRES(mutex());
+    virtual void onAddNewTrack_l() REQUIRES(mutex());
 public:  // AsyncCallbackThread
                 void        onAsyncError(); // error reported by AsyncCallbackThread
 protected:
@@ -888,20 +909,20 @@
             const std::basic_string<uint8_t>& metadataBs) final;
 
     // ThreadBase virtuals
-    virtual     void        preExit();
+    void preExit() final EXCLUDES_ThreadBase_Mutex;
 
     virtual     bool        keepWakeLock() const { return true; }
-    virtual     void        acquireWakeLock_l() {
+    virtual void acquireWakeLock_l() REQUIRES(mutex()) {
                                 ThreadBase::acquireWakeLock_l();
-                                mActiveTracks.updatePowerState(this, true /* force */);
+        mActiveTracks.updatePowerState_l(this, true /* force */);
                             }
 
     virtual     void        checkOutputStageEffects() {}
     virtual     void        setHalLatencyMode_l() {}
 
 
-    void dumpInternals_l(int fd, const Vector<String16>& args) override;
-    void dumpTracks_l(int fd, const Vector<String16>& args) final;
+    void dumpInternals_l(int fd, const Vector<String16>& args) override REQUIRES(mutex());
+    void dumpTracks_l(int fd, const Vector<String16>& args) final REQUIRES(mutex());
 
 public:
 
@@ -910,15 +931,15 @@
                 // return estimated latency in milliseconds, as reported by HAL
     uint32_t latency() const final;
                 // same, but lock must already be held
-    uint32_t latency_l() const final;
+    uint32_t latency_l() const final /* REQUIRES(mutex()) */;  // NO_THREAD_SAFETY_ANALYSIS
 
                 // VolumeInterface
     void setMasterVolume(float value) final;
-    void setMasterBalance(float balance) override;
+    void setMasterBalance(float balance) override EXCLUDES_ThreadBase_Mutex;
     void setMasterMute(bool muted) final;
-    void setStreamVolume(audio_stream_type_t stream, float value) final;
-    void setStreamMute(audio_stream_type_t stream, bool muted) final;
-    float streamVolume(audio_stream_type_t stream) const final;
+    void setStreamVolume(audio_stream_type_t stream, float value) final EXCLUDES_ThreadBase_Mutex;
+    void setStreamMute(audio_stream_type_t stream, bool muted) final EXCLUDES_ThreadBase_Mutex;
+    float streamVolume(audio_stream_type_t stream) const final EXCLUDES_ThreadBase_Mutex;
     void setVolumeForOutput_l(float left, float right) const final;
 
     sp<IAfTrack> createTrack_l(
@@ -949,7 +970,7 @@
         return mActiveTracks.indexOf(track) >= 0;
     }
 
-    AudioStreamOut* getOutput_l() const final { return mOutput; }
+    AudioStreamOut* getOutput_l() const final REQUIRES(mutex()) { return mOutput; }
     AudioStreamOut* getOutput() const final;
     AudioStreamOut* clearOutput() final;
     sp<StreamHalInterface> stream() const final;
@@ -967,38 +988,48 @@
     bool isSuspended() const final
                                 { return android_atomic_acquire_load(&mSuspended) > 0; }
 
-    String8 getParameters(const String8& keys);
-    void ioConfigChanged(audio_io_config_event_t event, pid_t pid = 0,
+    String8 getParameters(const String8& keys) EXCLUDES_ThreadBase_Mutex;
+
+    // Hold either the AudioFlinger::mutex or the ThreadBase::mutex
+    void ioConfigChanged_l(audio_io_config_event_t event, pid_t pid = 0,
             audio_port_handle_t portId = AUDIO_PORT_HANDLE_NONE) final;
-    status_t getRenderPosition(uint32_t* halFrames, uint32_t* dspFrames) const final;
+    status_t getRenderPosition(uint32_t* halFrames, uint32_t* dspFrames) const final
+            EXCLUDES_ThreadBase_Mutex;
                 // Consider also removing and passing an explicit mMainBuffer initialization
                 // parameter to AF::IAfTrack::Track().
     float* sinkBuffer() const final {
                     return reinterpret_cast<float *>(mSinkBuffer); };
 
-    void detachAuxEffect_l(int effectId) final;
+    void detachAuxEffect_l(int effectId) final REQUIRES(mutex());
 
-    status_t attachAuxEffect(const sp<IAfTrack>& track, int EffectId) final;
-    status_t attachAuxEffect_l(const sp<IAfTrack>& track, int EffectId) final;
+    status_t attachAuxEffect(const sp<IAfTrack>& track, int EffectId) final
+            EXCLUDES_ThreadBase_Mutex;
+    status_t attachAuxEffect_l(const sp<IAfTrack>& track, int EffectId) final REQUIRES(mutex());
 
-    status_t addEffectChain_l(const sp<IAfEffectChain>& chain) final;
-    size_t removeEffectChain_l(const sp<IAfEffectChain>& chain) final;
-    uint32_t hasAudioSession_l(audio_session_t sessionId) const final {
+    status_t addEffectChain_l(const sp<IAfEffectChain>& chain) final REQUIRES(mutex());
+    size_t removeEffectChain_l(const sp<IAfEffectChain>& chain) final REQUIRES(mutex());
+    uint32_t hasAudioSession_l(audio_session_t sessionId) const final REQUIRES(mutex()) {
                             return ThreadBase::hasAudioSession_l(sessionId, mTracks);
                         }
-    product_strategy_t getStrategyForSession_l(audio_session_t sessionId) const final;
+    product_strategy_t getStrategyForSession_l(audio_session_t sessionId) const final
+            REQUIRES(mutex());
 
 
-    status_t setSyncEvent(const sp<audioflinger::SyncEvent>& event) final;
+    status_t setSyncEvent(const sp<audioflinger::SyncEvent>& event) final
+            EXCLUDES_ThreadBase_Mutex;
+    // could be static.
     bool isValidSyncEvent(const sp<audioflinger::SyncEvent>& event) const final;
 
-                // called with AudioFlinger lock held
-    bool invalidateTracks_l(audio_stream_type_t streamType) final;
-    bool invalidateTracks_l(std::set<audio_port_handle_t>& portIds) final;
+    // Does this require the AudioFlinger mutex as well?
+    bool invalidateTracks_l(audio_stream_type_t streamType) final
+            REQUIRES(mutex());
+    bool invalidateTracks_l(std::set<audio_port_handle_t>& portIds) final
+            REQUIRES(mutex());
     void invalidateTracks(audio_stream_type_t streamType) override;
                 // Invalidate tracks by a set of port ids. The port id will be removed from
                 // the given set if the corresponding track is found and invalidated.
-    void invalidateTracks(std::set<audio_port_handle_t>& portIds) override;
+    void invalidateTracks(std::set<audio_port_handle_t>& portIds) override
+            EXCLUDES_ThreadBase_Mutex;
 
     size_t frameCount() const final { return mNormalFrameCount; }
 
@@ -1006,30 +1037,32 @@
                     return mMixerChannelMask;
                 }
 
-    status_t getTimestamp_l(AudioTimestamp& timestamp) final;
+    status_t getTimestamp_l(AudioTimestamp& timestamp) final REQUIRES(mutex());
 
-    void addPatchTrack(const sp<IAfPatchTrack>& track) final;
-    void deletePatchTrack(const sp<IAfPatchTrack>& track) final;
+    void addPatchTrack(const sp<IAfPatchTrack>& track) final EXCLUDES_ThreadBase_Mutex;
+    void deletePatchTrack(const sp<IAfPatchTrack>& track) final EXCLUDES_ThreadBase_Mutex;
 
+    // NO_THREAD_SAFETY_ANALYSIS - fix this to use atomics.
     void toAudioPortConfig(struct audio_port_config* config) final;
 
                 // Return the asynchronous signal wait time.
-    int64_t computeWaitTimeNs_l() const override { return INT64_MAX; }
+    int64_t computeWaitTimeNs_l() const override REQUIRES(mutex()) { return INT64_MAX; }
                 // returns true if the track is allowed to be added to the thread.
     bool isTrackAllowed_l(
                                     audio_channel_mask_t channelMask __unused,
                                     audio_format_t format __unused,
                                     audio_session_t sessionId __unused,
-                                    uid_t uid) const override {
+            uid_t uid) const override REQUIRES(mutex()) {
                                 return trackCountForUid_l(uid) < PlaybackThread::kMaxTracksPerUid
                                        && mTracks.size() < PlaybackThread::kMaxTracks;
                             }
 
-    bool isTimestampCorrectionEnabled() const final {
-                                return audio_is_output_devices(mTimestampCorrectedDevice)
-                                        && outDeviceTypes().count(mTimestampCorrectedDevice) != 0;
+    bool isTimestampCorrectionEnabled_l() const final REQUIRES(mutex()) {
+        return audio_is_output_devices(mTimestampCorrectedDevice)
+                && outDeviceTypes_l().count(mTimestampCorrectedDevice) != 0;
                             }
 
+    // NO_THREAD_SAFETY_ANALYSIS - fix this to be atomic.
     bool isStreamInitialized() const final {
                                 return !(mOutput == nullptr || mOutput->stream == nullptr);
                             }
@@ -1046,12 +1079,12 @@
                     return (mHapticChannelMask & AUDIO_CHANNEL_HAPTIC_ALL) != AUDIO_CHANNEL_NONE;
                 }
 
-    void setDownStreamPatch(const struct audio_patch* patch) final {
+    void setDownStreamPatch(const struct audio_patch* patch) final EXCLUDES_ThreadBase_Mutex {
                     std::lock_guard _l(mutex());
                     mDownStreamPatch = *patch;
                 }
 
-    IAfTrack* getTrackById_l(audio_port_handle_t trackId) final;
+    IAfTrack* getTrackById_l(audio_port_handle_t trackId) final REQUIRES(mutex());
 
     bool hasMixer() const final {
                     return mType == MIXER || mType == DUPLICATING || mType == SPATIALIZER;
@@ -1079,14 +1112,14 @@
                     setStandby_l();
                 }
 
-    void setStandby_l() final {
+    void setStandby_l() final REQUIRES(mutex()) {
                     mStandby = true;
                     mHalStarted = false;
                     mKernelPositionOnStandby =
                         mTimestamp.mPosition[ExtendedTimestamp::LOCATION_KERNEL];
                 }
 
-    bool waitForHalStart() final {
+    bool waitForHalStart() final EXCLUDES_ThreadBase_Mutex {
                     audio_utils::unique_lock _l(mutex());
                     static const nsecs_t kWaitHalTimeoutNs = seconds(2);
                     nsecs_t endWaitTimetNs = systemTime() + kWaitHalTimeoutNs;
@@ -1224,24 +1257,28 @@
     // No sleep in standby mode; waits on a condition
 
     // Code snippets that are temporarily lifted up out of threadLoop() until the merge
-    virtual void checkSilentMode_l() final;  // consider unification with MMapThread
+
+    // consider unification with MMapThread
+    virtual void checkSilentMode_l() final REQUIRES(mutex());
 
     // Non-trivial for DUPLICATING only
     virtual     void        saveOutputTracks() { }
     virtual     void        clearOutputTracks() { }
 
     // Cache various calculated values, at threadLoop() entry and after a parameter change
-    virtual     void        cacheParameters_l();
+    virtual void cacheParameters_l() REQUIRES(mutex());
                 void        setCheckOutputStageEffects() override {
                                 mCheckOutputStageEffects.store(true);
                             }
 
-    virtual     uint32_t    correctLatency_l(uint32_t latency) const;
+    virtual uint32_t correctLatency_l(uint32_t latency) const REQUIRES(mutex());
 
     virtual     status_t    createAudioPatch_l(const struct audio_patch *patch,
-                                   audio_patch_handle_t *handle);
-    virtual     status_t    releaseAudioPatch_l(const audio_patch_handle_t handle);
+            audio_patch_handle_t *handle) REQUIRES(mutex());
+    virtual status_t releaseAudioPatch_l(const audio_patch_handle_t handle)
+            REQUIRES(mutex());
 
+    // NO_THREAD_SAFETY_ANALYSIS - fix this to use atomics
     bool usesHwAvSync() const final { return mType == DIRECT && mOutput != nullptr
                                     && mHwSupportsPause
                                     && (mOutput->flags & AUDIO_OUTPUT_FLAG_HW_AV_SYNC); }
@@ -1249,22 +1286,23 @@
                 uint32_t    trackCountForUid_l(uid_t uid) const;
 
                 void        invalidateTracksForAudioSession_l(
-    audio_session_t sessionId) const override {
+            audio_session_t sessionId) const override REQUIRES(mutex()) {
                                 ThreadBase::invalidateTracksForAudioSession_l(sessionId, mTracks);
                             }
 
     DISALLOW_COPY_AND_ASSIGN(PlaybackThread);
 
-    status_t addTrack_l(const sp<IAfTrack>& track) final;
-    bool destroyTrack_l(const sp<IAfTrack>& track) final;
+    status_t addTrack_l(const sp<IAfTrack>& track) final REQUIRES(mutex());
+    bool destroyTrack_l(const sp<IAfTrack>& track) final REQUIRES(mutex());
 
-    void        removeTrack_l(const sp<IAfTrack>& track);
+    void removeTrack_l(const sp<IAfTrack>& track) REQUIRES(mutex());
 
-    void        readOutputParameters_l();
-    MetadataUpdate          updateMetadata_l() final;
-    virtual void sendMetadataToBackend_l(const StreamOutHalInterface::SourceMetadata& metadata);
+    void readOutputParameters_l() REQUIRES(mutex());
+    MetadataUpdate updateMetadata_l() final REQUIRES(mutex());
+    virtual void sendMetadataToBackend_l(const StreamOutHalInterface::SourceMetadata& metadata)
+            REQUIRES(mutex()) ;
 
-    void        collectTimestamps_l();
+    void collectTimestamps_l() REQUIRES(mutex());
 
     // The Tracks class manages tracks added and removed from the Thread.
     template <typename T>
@@ -1412,7 +1450,7 @@
 
 protected:
                 // accessed by both binder threads and within threadLoop(), lock on mutex needed
-     uint32_t& fastTrackAvailMask_l() final { return mFastTrackAvailMask; }
+     uint32_t& fastTrackAvailMask_l() final REQUIRES(mutex()) { return mFastTrackAvailMask; }
      uint32_t mFastTrackAvailMask;  // bit i set if fast track [i] is available
                 bool        mHwSupportsPause;
                 bool        mHwPaused;
@@ -1481,18 +1519,19 @@
 
     // Thread virtuals
 
-    bool checkForNewParameter_l(const String8& keyValuePair, status_t& status) final;
+    bool checkForNewParameter_l(const String8& keyValuePair, status_t& status) final
+            REQUIRES(mutex());
 
     bool isTrackAllowed_l(
                                     audio_channel_mask_t channelMask, audio_format_t format,
-                                    audio_session_t sessionId, uid_t uid) const final;
+            audio_session_t sessionId, uid_t uid) const final REQUIRES(mutex());
 protected:
     mixer_state prepareTracks_l(Vector<sp<IAfTrack>>* tracksToRemove) override;
     uint32_t idleSleepTimeUs() const final;
     uint32_t suspendSleepTimeUs() const final;
-    void cacheParameters_l() override;
+    void cacheParameters_l() override REQUIRES(mutex());
 
-    void acquireWakeLock_l() final {
+    void acquireWakeLock_l() final REQUIRES(mutex()) {
         PlaybackThread::acquireWakeLock_l();
         if (hasFastMixer()) {
             mFastMixer->setBoottimeOffset(
@@ -1500,18 +1539,19 @@
         }
     }
 
-                void        dumpInternals_l(int fd, const Vector<String16>& args) override;
+    void dumpInternals_l(int fd, const Vector<String16>& args) override REQUIRES(mutex());
 
     // threadLoop snippets
     ssize_t threadLoop_write() override;
     void threadLoop_standby() override;
     void threadLoop_mix() override;
     void threadLoop_sleepTime() override;
-    uint32_t correctLatency_l(uint32_t latency) const final;
+    uint32_t correctLatency_l(uint32_t latency) const final REQUIRES(mutex());
 
     status_t createAudioPatch_l(
-            const struct audio_patch* patch, audio_patch_handle_t* handle) final;
-    status_t releaseAudioPatch_l(const audio_patch_handle_t handle) final;
+            const struct audio_patch* patch, audio_patch_handle_t* handle)
+            final REQUIRES(mutex());
+    status_t releaseAudioPatch_l(const audio_patch_handle_t handle) final REQUIRES(mutex());
 
                 AudioMixer* mAudioMixer;    // normal mixer
 
@@ -1550,8 +1590,8 @@
                               return mFastMixerDumpState.mTracks[fastIndex].mUnderruns;
                             }
 
-                status_t    threadloop_getHalTimestamp_l(
-                                    ExtendedTimestamp *timestamp) const override {
+    status_t threadloop_getHalTimestamp_l(
+            ExtendedTimestamp *timestamp) const override REQUIRES(mutex()) {
                                 if (mNormalSink.get() != nullptr) {
                                     return mNormalSink->getTimestamp(*timestamp);
                                 }
@@ -1575,16 +1615,16 @@
                 // and blending without limiter is idempotent but inefficient to do twice.
     virtual     bool       requireMonoBlend() { return mMasterMono.load() && !hasFastMixer(); }
 
-                void       setMasterBalance(float balance) override {
+    void setMasterBalance(float balance) override EXCLUDES_ThreadBase_Mutex {
                                mMasterBalance.store(balance);
                                if (hasFastMixer()) {
                                    mFastMixer->setMasterBalance(balance);
                                }
                            }
 
-                void       updateHalSupportedLatencyModes_l();
-                void       onHalLatencyModesChanged_l() override;
-                void       setHalLatencyMode_l() override;
+    void updateHalSupportedLatencyModes_l() REQUIRES(mutex());
+    void onHalLatencyModesChanged_l() override REQUIRES(mutex());
+    void setHalLatencyMode_l() override REQUIRES(mutex());
 };
 
 class DirectOutputThread : public PlaybackThread, public virtual IAfDirectOutputThread {
@@ -1599,35 +1639,35 @@
                        const audio_offload_info_t& offloadInfo)
         : DirectOutputThread(afThreadCallback, output, id, DIRECT, systemReady, offloadInfo) { }
 
-    virtual                 ~DirectOutputThread();
+    ~DirectOutputThread() override;
 
     status_t selectPresentation(int presentationId, int programId) final;
 
     // Thread virtuals
 
     virtual     bool        checkForNewParameter_l(const String8& keyValuePair,
-                                                   status_t& status);
+            status_t& status) REQUIRES(mutex());
 
-                void        flushHw_l() override;
+    void flushHw_l() override REQUIRES(mutex());
 
-                void        setMasterBalance(float balance) override;
+    void setMasterBalance(float balance) override EXCLUDES_ThreadBase_Mutex;
 
 protected:
     virtual     uint32_t    activeSleepTimeUs() const;
     virtual     uint32_t    idleSleepTimeUs() const;
     virtual     uint32_t    suspendSleepTimeUs() const;
-    virtual     void        cacheParameters_l();
+    virtual void cacheParameters_l() REQUIRES(mutex());
 
-                void        dumpInternals_l(int fd, const Vector<String16>& args) override;
+    void dumpInternals_l(int fd, const Vector<String16>& args) override REQUIRES(mutex());
 
     // threadLoop snippets
-    virtual     mixer_state prepareTracks_l(Vector<sp<IAfTrack>>* tracksToRemove);
+    virtual mixer_state prepareTracks_l(Vector<sp<IAfTrack>>* tracksToRemove) REQUIRES(mutex());
     virtual     void        threadLoop_mix();
     virtual     void        threadLoop_sleepTime();
     virtual     void        threadLoop_exit();
-    virtual     bool        shouldStandby_l();
+    virtual bool shouldStandby_l() REQUIRES(mutex());
 
-    virtual     void        onAddNewTrack_l();
+    virtual void onAddNewTrack_l() REQUIRES(mutex());
 
     const       audio_offload_info_t mOffloadInfo;
 
@@ -1637,7 +1677,7 @@
     DirectOutputThread(const sp<IAfThreadCallback>& afThreadCallback, AudioStreamOut* output,
                        audio_io_handle_t id, ThreadBase::type_t type, bool systemReady,
                        const audio_offload_info_t& offloadInfo);
-    void processVolume_l(IAfTrack *track, bool lastTrack);
+    void processVolume_l(IAfTrack *track, bool lastTrack) REQUIRES(mutex());
     bool isTunerStream() const { return (mOffloadInfo.content_id > 0); }
 
     // prepareTracks_l() tells threadLoop_mix() the name of the single active track
@@ -1652,7 +1692,7 @@
 public:
     virtual     bool        hasFastMixer() const { return false; }
 
-    virtual     int64_t     computeWaitTimeNs_l() const override;
+    virtual int64_t computeWaitTimeNs_l() const override REQUIRES(mutex());
 
     status_t    threadloop_getHalTimestamp_l(ExtendedTimestamp *timestamp) const override {
                     // For DIRECT and OFFLOAD threads, query the output sink directly.
@@ -1679,19 +1719,20 @@
                   audio_io_handle_t id, bool systemReady,
                   const audio_offload_info_t& offloadInfo);
     virtual                 ~OffloadThread() {};
-                void        flushHw_l() override;
+    void flushHw_l() final REQUIRES(mutex());
 
 protected:
     // threadLoop snippets
-    virtual     mixer_state prepareTracks_l(Vector<sp<IAfTrack>>* tracksToRemove);
-    virtual     void        threadLoop_exit();
+    mixer_state prepareTracks_l(Vector<sp<IAfTrack>>* tracksToRemove) final
+            REQUIRES(mutex());
+    void threadLoop_exit() final;
 
-    virtual     bool        waitingAsyncCallback();
-    virtual     bool        waitingAsyncCallback_l();
-    virtual     void        invalidateTracks(audio_stream_type_t streamType);
-                void        invalidateTracks(std::set<audio_port_handle_t>& portIds) override;
+    bool waitingAsyncCallback() final;
+    bool waitingAsyncCallback_l() final REQUIRES(mutex());
+    void invalidateTracks(audio_stream_type_t streamType) final EXCLUDES_ThreadBase_Mutex;
+    void invalidateTracks(std::set<audio_port_handle_t>& portIds) final EXCLUDES_ThreadBase_Mutex;
 
-    virtual     bool        keepWakeLock() const { return (mKeepWakeLock || (mDrainSequence & 1)); }
+    bool keepWakeLock() const final { return (mKeepWakeLock || (mDrainSequence & 1)); }
 
 private:
     size_t      mPausedWriteLength;     // length in bytes of write interrupted by pause
@@ -1730,7 +1771,9 @@
     mutable audio_utils::mutex mMutex;
     bool                       mAsyncError;
 
-    audio_utils::mutex& mutex() const { return mMutex; }
+    audio_utils::mutex& mutex() const RETURN_CAPABILITY(audio_utils::AsyncCallbackThread_Mutex) {
+        return mMutex;
+    }
 };
 
 class DuplicatingThread : public MixerThread, public IAfDuplicatingThread {
@@ -1745,32 +1788,32 @@
     }
 
     // Thread virtuals
-    void addOutputTrack(IAfPlaybackThread* thread) final;
-    void removeOutputTrack(IAfPlaybackThread* thread) final;
+    void addOutputTrack(IAfPlaybackThread* thread) final EXCLUDES_ThreadBase_Mutex;
+    void removeOutputTrack(IAfPlaybackThread* thread) final EXCLUDES_ThreadBase_Mutex;
     uint32_t waitTimeMs() const final { return mWaitTimeMs; }
 
                 void        sendMetadataToBackend_l(
-                        const StreamOutHalInterface::SourceMetadata& metadata) override;
+            const StreamOutHalInterface::SourceMetadata& metadata) final REQUIRES(mutex());
 protected:
     virtual     uint32_t    activeSleepTimeUs() const;
-                void        dumpInternals_l(int fd, const Vector<String16>& args) override;
+    void dumpInternals_l(int fd, const Vector<String16>& args) final REQUIRES(mutex());
 
 private:
                 bool        outputsReady();
 protected:
     // threadLoop snippets
-    virtual     void        threadLoop_mix();
-    virtual     void        threadLoop_sleepTime();
-    virtual     ssize_t     threadLoop_write();
-    virtual     void        threadLoop_standby();
-    virtual     void        cacheParameters_l();
+    void threadLoop_mix() final;
+    void threadLoop_sleepTime() final;
+    ssize_t threadLoop_write() final;
+    void threadLoop_standby() final;
+    void cacheParameters_l() final REQUIRES(mutex());
 
 private:
     // called from threadLoop, addOutputTrack, removeOutputTrack
-    virtual     void        updateWaitTime_l();
+    void updateWaitTime_l() REQUIRES(mutex());
 protected:
-    virtual     void        saveOutputTracks();
-    virtual     void        clearOutputTracks();
+    void saveOutputTracks() final;
+    void clearOutputTracks() final;
 private:
 
                 uint32_t    mWaitTimeMs;
@@ -1779,7 +1822,7 @@
 public:
     virtual     bool        hasFastMixer() const { return false; }
                 status_t    threadloop_getHalTimestamp_l(
-                                    ExtendedTimestamp *timestamp) const override {
+            ExtendedTimestamp *timestamp) const override REQUIRES(mutex()) {
         if (mOutputTracks.size() > 0) {
             // forward the first OutputTrack's kernel information for timestamp.
             const ExtendedTimestamp trackTimestamp =
@@ -1806,11 +1849,11 @@
 
     bool hasFastMixer() const final { return false; }
 
-    status_t setRequestedLatencyMode(audio_latency_mode_t mode) final;
+    status_t setRequestedLatencyMode(audio_latency_mode_t mode) final EXCLUDES_ThreadBase_Mutex;
 
 protected:
-    void checkOutputStageEffects() final;
-    void setHalLatencyMode_l() final;
+    void checkOutputStageEffects() final EXCLUDES_ThreadBase_Mutex;
+    void setHalLatencyMode_l() final REQUIRES(mutex());
 
 private:
             // Do not request a specific mode by default
@@ -1836,15 +1879,15 @@
     ~RecordThread() override;
 
     // no addTrack_l ?
-    void destroyTrack_l(const sp<IAfRecordTrack>& track) final;
-    void removeTrack_l(const sp<IAfRecordTrack>& track) final;
+    void destroyTrack_l(const sp<IAfRecordTrack>& track) final REQUIRES(mutex());
+    void removeTrack_l(const sp<IAfRecordTrack>& track) final REQUIRES(mutex());
 
     // Thread virtuals
-    bool threadLoop() final;
-    void preExit() final;
+    bool threadLoop() final EXCLUDES_ThreadBase_Mutex;
+    void preExit() final EXCLUDES_ThreadBase_Mutex;
 
     // RefBase
-    void onFirstRef() final;
+    void onFirstRef() final EXCLUDES_ThreadBase_Mutex;
 
     status_t initCheck() const final { return mInput == nullptr ? NO_INIT : NO_ERROR; }
 
@@ -1868,15 +1911,15 @@
                     status_t *status /*non-NULL*/,
                     audio_port_handle_t portId,
                     int32_t maxSharedAudioHistoryMs) final
-            REQUIRES(audio_utils::AudioFlinger_Mutex);
+            REQUIRES(audio_utils::AudioFlinger_Mutex) EXCLUDES_ThreadBase_Mutex;
 
             status_t start(IAfRecordTrack* recordTrack,
                               AudioSystem::sync_event_t event,
-                              audio_session_t triggerSession) final;
+            audio_session_t triggerSession) final EXCLUDES_ThreadBase_Mutex;
 
             // ask the thread to stop the specified track, and
             // return true if the caller should then do it's part of the stopping process
-    bool stop(IAfRecordTrack* recordTrack) final;
+    bool stop(IAfRecordTrack* recordTrack) final EXCLUDES_ThreadBase_Mutex;
     AudioStreamIn* getInput() const final { return mInput; }
     AudioStreamIn* clearInput() final;
 
@@ -1884,27 +1927,30 @@
             virtual sp<StreamHalInterface> stream() const;
 
 
-    virtual bool        checkForNewParameter_l(const String8& keyValuePair,
-                                               status_t& status);
-    virtual void        cacheParameters_l() {}
-    virtual String8     getParameters(const String8& keys);
-    void ioConfigChanged(audio_io_config_event_t event, pid_t pid = 0,
+    virtual bool checkForNewParameter_l(const String8& keyValuePair,
+                                               status_t& status) REQUIRES(mutex());
+    virtual void cacheParameters_l() REQUIRES(mutex()) {}
+    virtual String8 getParameters(const String8& keys) EXCLUDES_ThreadBase_Mutex;
+
+    // Hold either the AudioFlinger::mutex or the ThreadBase::mutex
+    void ioConfigChanged_l(audio_io_config_event_t event, pid_t pid = 0,
             audio_port_handle_t portId = AUDIO_PORT_HANDLE_NONE) final;
     virtual status_t    createAudioPatch_l(const struct audio_patch *patch,
-                                           audio_patch_handle_t *handle);
-    virtual status_t    releaseAudioPatch_l(const audio_patch_handle_t handle);
-            void        updateOutDevices(const DeviceDescriptorBaseVector& outDevices) override;
-            void        resizeInputBuffer_l(int32_t maxSharedAudioHistoryMs) override;
+            audio_patch_handle_t *handle) REQUIRES(mutex());
+    virtual status_t releaseAudioPatch_l(const audio_patch_handle_t handle) REQUIRES(mutex());
+    void updateOutDevices(const DeviceDescriptorBaseVector& outDevices) override
+            EXCLUDES_ThreadBase_Mutex;
+    void resizeInputBuffer_l(int32_t maxSharedAudioHistoryMs) override REQUIRES(mutex());
 
-    void addPatchTrack(const sp<IAfPatchRecord>& record) final;
-    void deletePatchTrack(const sp<IAfPatchRecord>& record) final;
+    void addPatchTrack(const sp<IAfPatchRecord>& record) final EXCLUDES_ThreadBase_Mutex;
+    void deletePatchTrack(const sp<IAfPatchRecord>& record) final EXCLUDES_ThreadBase_Mutex;
 
-            void        readInputParameters_l();
-    uint32_t getInputFramesLost() const final;
+    void readInputParameters_l() REQUIRES(mutex());
+    uint32_t getInputFramesLost() const final EXCLUDES_ThreadBase_Mutex;
 
-    virtual status_t addEffectChain_l(const sp<IAfEffectChain>& chain);
-    virtual size_t removeEffectChain_l(const sp<IAfEffectChain>& chain);
-            uint32_t hasAudioSession_l(audio_session_t sessionId) const override {
+    virtual status_t addEffectChain_l(const sp<IAfEffectChain>& chain) REQUIRES(mutex());
+    virtual size_t removeEffectChain_l(const sp<IAfEffectChain>& chain) REQUIRES(mutex());
+    uint32_t hasAudioSession_l(audio_session_t sessionId) const override REQUIRES(mutex()) {
                          return ThreadBase::hasAudioSession_l(sessionId, mTracks);
                      }
 
@@ -1913,7 +1959,8 @@
             // FIXME replace by Set [and implement Bag/Multiset for other uses].
             KeyedVector<audio_session_t, bool> sessionIds() const;
 
-            status_t setSyncEvent(const sp<audioflinger::SyncEvent>& event) override;
+    status_t setSyncEvent(const sp<audioflinger::SyncEvent>& event) override
+            EXCLUDES_ThreadBase_Mutex;
             bool     isValidSyncEvent(const sp<audioflinger::SyncEvent>& event) const override;
 
     static void syncStartEventCallback(const wp<audioflinger::SyncEvent>& event);
@@ -1922,52 +1969,55 @@
     bool hasFastCapture() const final { return mFastCapture != 0; }
     virtual void        toAudioPortConfig(struct audio_port_config *config);
 
-    virtual status_t    checkEffectCompatibility_l(const effect_descriptor_t *desc,
-                                                   audio_session_t sessionId);
+    virtual status_t checkEffectCompatibility_l(const effect_descriptor_t *desc,
+            audio_session_t sessionId) REQUIRES(mutex());
 
-    virtual void        acquireWakeLock_l() {
+    virtual void acquireWakeLock_l() REQUIRES(mutex()) {
                             ThreadBase::acquireWakeLock_l();
-                            mActiveTracks.updatePowerState(this, true /* force */);
+        mActiveTracks.updatePowerState_l(this, true /* force */);
                         }
 
-    void checkBtNrec() final;
+    void checkBtNrec() final EXCLUDES_ThreadBase_Mutex;
 
             // Sets the UID records silence
-    void setRecordSilenced(audio_port_handle_t portId, bool silenced) final;
+    void setRecordSilenced(audio_port_handle_t portId, bool silenced) final
+            EXCLUDES_ThreadBase_Mutex;
 
     status_t getActiveMicrophones(
-            std::vector<media::MicrophoneInfoFw>* activeMicrophones) const final;
-    status_t setPreferredMicrophoneDirection(audio_microphone_direction_t direction) final;
-    status_t setPreferredMicrophoneFieldDimension(float zoom) final;
+            std::vector<media::MicrophoneInfoFw>* activeMicrophones) const final
+            EXCLUDES_ThreadBase_Mutex;
+    status_t setPreferredMicrophoneDirection(audio_microphone_direction_t direction) final
+            EXCLUDES_ThreadBase_Mutex;
+    status_t setPreferredMicrophoneFieldDimension(float zoom) final EXCLUDES_ThreadBase_Mutex;
 
-            MetadataUpdate        updateMetadata_l() override;
+    MetadataUpdate updateMetadata_l() override REQUIRES(mutex());
 
     bool fastTrackAvailable() const final { return mFastTrackAvail; }
     void setFastTrackAvailable(bool available) final { mFastTrackAvail = available; }
 
-            bool        isTimestampCorrectionEnabled() const override {
+    bool isTimestampCorrectionEnabled_l() const override REQUIRES(mutex()) {
                             // checks popcount for exactly one device.
                             // Is currently disabled. Before enabling,
                             // verify compressed record timestamps.
                             return audio_is_input_device(mTimestampCorrectedDevice)
-                                    && inDeviceType() == mTimestampCorrectedDevice;
+                && inDeviceType_l() == mTimestampCorrectedDevice;
                         }
 
     status_t shareAudioHistory(const std::string& sharedAudioPackageName,
                                           audio_session_t sharedSessionId = AUDIO_SESSION_NONE,
-            int64_t sharedAudioStartMs = -1) final;
+            int64_t sharedAudioStartMs = -1) final EXCLUDES_ThreadBase_Mutex;
             status_t    shareAudioHistory_l(const std::string& sharedAudioPackageName,
                                           audio_session_t sharedSessionId = AUDIO_SESSION_NONE,
-                                          int64_t sharedAudioStartMs = -1);
-    void resetAudioHistory_l() final;
+            int64_t sharedAudioStartMs = -1) REQUIRES(mutex());
+    void resetAudioHistory_l() final REQUIRES(mutex());
 
     bool isStreamInitialized() const final {
                             return !(mInput == nullptr || mInput->stream == nullptr);
                         }
 
 protected:
-            void        dumpInternals_l(int fd, const Vector<String16>& args) override;
-            void        dumpTracks_l(int fd, const Vector<String16>& args) override;
+    void dumpInternals_l(int fd, const Vector<String16>& args) override REQUIRES(mutex());
+    void dumpTracks_l(int fd, const Vector<String16>& args) override REQUIRES(mutex());
 
 private:
             // Enter standby if not already in standby, and set mStandby flag
@@ -1976,10 +2026,10 @@
             // Call the HAL standby method unconditionally, and don't change mStandby flag
             void    inputStandBy();
 
-            void    checkBtNrec_l();
+    void checkBtNrec_l() REQUIRES(mutex());
 
-            int32_t getOldestFront_l();
-            void    updateFronts_l(int32_t offset);
+    int32_t getOldestFront_l() REQUIRES(mutex());
+    void updateFronts_l(int32_t offset) REQUIRES(mutex());
 
             AudioStreamIn                       *mInput;
             Source                              *mSource;
@@ -2067,16 +2117,16 @@
                                       audio_port_handle_t deviceId,
                                       audio_port_handle_t portId) override;
 
-    void disconnect() final;
+    void disconnect() final EXCLUDES_ThreadBase_Mutex;
 
     // MmapStreamInterface for adapter.
     status_t createMmapBuffer(int32_t minSizeFrames, struct audio_mmap_buffer_info* info) final;
     status_t getMmapPosition(struct audio_mmap_position* position) const override;
     status_t start(const AudioClient& client,
                    const audio_attributes_t *attr,
-            audio_port_handle_t* handle) final;
-    status_t stop(audio_port_handle_t handle) final;
-    status_t standby() final;
+            audio_port_handle_t* handle) final EXCLUDES_ThreadBase_Mutex;
+    status_t stop(audio_port_handle_t handle) final EXCLUDES_ThreadBase_Mutex;
+    status_t standby() final EXCLUDES_ThreadBase_Mutex;
     status_t getExternalPosition(uint64_t* position, int64_t* timeNanos) const = 0;
     status_t reportData(const void* buffer, size_t frameCount) override;
 
@@ -2084,69 +2134,77 @@
     void onFirstRef() final;
 
     // Thread virtuals
-    bool threadLoop() final;
+    bool threadLoop() final EXCLUDES_ThreadBase_Mutex;
 
     // Not in ThreadBase
     virtual void threadLoop_exit() final;
     virtual void threadLoop_standby() final;
-    virtual bool shouldStandby_l() final { return false; }
+    virtual bool shouldStandby_l() final REQUIRES(mutex()){ return false; }
     virtual status_t exitStandby_l() REQUIRES(mutex());
 
     status_t initCheck() const final { return mHalStream == nullptr ? NO_INIT : NO_ERROR; }
     size_t frameCount() const final { return mFrameCount; }
-    bool checkForNewParameter_l(const String8& keyValuePair, status_t& status) final;
-    String8 getParameters(const String8& keys) final;
-    void ioConfigChanged(audio_io_config_event_t event, pid_t pid = 0,
-            audio_port_handle_t portId = AUDIO_PORT_HANDLE_NONE) final;
-                void        readHalParameters_l();
-    void cacheParameters_l() final {}
+    bool checkForNewParameter_l(const String8& keyValuePair, status_t& status)
+            final REQUIRES(mutex());
+    String8 getParameters(const String8& keys) final EXCLUDES_ThreadBase_Mutex;
+    void ioConfigChanged_l(audio_io_config_event_t event, pid_t pid = 0,
+            audio_port_handle_t portId = AUDIO_PORT_HANDLE_NONE) final
+            /* holds either AF::mutex or TB::mutex */;
+    void readHalParameters_l() REQUIRES(mutex());
+    void cacheParameters_l() final REQUIRES(mutex()) {}
     status_t createAudioPatch_l(
-            const struct audio_patch* patch, audio_patch_handle_t* handle) final;
-    status_t releaseAudioPatch_l(const audio_patch_handle_t handle) final;
+            const struct audio_patch* patch, audio_patch_handle_t* handle) final
+            REQUIRES(mutex());
+    status_t releaseAudioPatch_l(const audio_patch_handle_t handle) final
+            REQUIRES(mutex());
     void toAudioPortConfig(struct audio_port_config* config) override;
 
     sp<StreamHalInterface> stream() const final { return mHalStream; }
-    status_t addEffectChain_l(const sp<IAfEffectChain>& chain) final;
-    size_t removeEffectChain_l(const sp<IAfEffectChain>& chain) final;
+    status_t addEffectChain_l(const sp<IAfEffectChain>& chain) final REQUIRES(mutex());
+    size_t removeEffectChain_l(const sp<IAfEffectChain>& chain) final REQUIRES(mutex());
     status_t checkEffectCompatibility_l(
-            const effect_descriptor_t *desc, audio_session_t sessionId) final;
+            const effect_descriptor_t *desc, audio_session_t sessionId) final REQUIRES(mutex());
 
-    uint32_t hasAudioSession_l(audio_session_t sessionId) const override {
+    uint32_t hasAudioSession_l(audio_session_t sessionId) const override REQUIRES(mutex()) {
                                 // Note: using mActiveTracks as no mTracks here.
                                 return ThreadBase::hasAudioSession_l(sessionId, mActiveTracks);
                             }
     status_t setSyncEvent(const sp<audioflinger::SyncEvent>& event) final;
     bool isValidSyncEvent(const sp<audioflinger::SyncEvent>& event) const final;
 
-    virtual void checkSilentMode_l() {} // cannot be const (RecordThread)
-    virtual void processVolume_l() {}
+    virtual void checkSilentMode_l() REQUIRES(mutex()) {} // cannot be const (RecordThread)
+    virtual void processVolume_l() REQUIRES(mutex()) {}
                 void        checkInvalidTracks_l();
 
     // Not in ThreadBase
     virtual audio_stream_type_t streamType() const { return AUDIO_STREAM_DEFAULT; }
-    virtual void invalidateTracks(audio_stream_type_t /* streamType */) {}
-    void invalidateTracks(std::set<audio_port_handle_t>& /* portIds */) override {}
+    virtual void invalidateTracks(audio_stream_type_t /* streamType */)
+            EXCLUDES_ThreadBase_Mutex {}
+    void invalidateTracks(std::set<audio_port_handle_t>& /* portIds */) override
+            EXCLUDES_ThreadBase_Mutex {}
 
                 // Sets the UID records silence
     void setRecordSilenced(
-            audio_port_handle_t /* portId */, bool /* silenced */) override {}
+            audio_port_handle_t /* portId */, bool /* silenced */) override
+            EXCLUDES_ThreadBase_Mutex {}
 
     bool isStreamInitialized() const override { return false; }
 
-                void        setClientSilencedState_l(audio_port_handle_t portId, bool silenced) {
+    void setClientSilencedState_l(audio_port_handle_t portId, bool silenced) REQUIRES(mutex()) {
                                 mClientSilencedStates[portId] = silenced;
                             }
 
-                size_t      eraseClientSilencedState_l(audio_port_handle_t portId) {
+    size_t eraseClientSilencedState_l(audio_port_handle_t portId) REQUIRES(mutex()) {
                                 return mClientSilencedStates.erase(portId);
                             }
 
-                bool        isClientSilenced_l(audio_port_handle_t portId) const {
+    bool isClientSilenced_l(audio_port_handle_t portId) const REQUIRES(mutex()) {
                                 const auto it = mClientSilencedStates.find(portId);
                                 return it != mClientSilencedStates.end() ? it->second : false;
                             }
 
-                void        setClientSilencedIfExists_l(audio_port_handle_t portId, bool silenced) {
+    void setClientSilencedIfExists_l(audio_port_handle_t portId, bool silenced)
+            REQUIRES(mutex()) {
                                 const auto it = mClientSilencedStates.find(portId);
                                 if (it != mClientSilencedStates.end()) {
                                     it->second = silenced;
@@ -2154,8 +2212,8 @@
                             }
 
  protected:
-    void dumpInternals_l(int fd, const Vector<String16>& args) override;
-    void dumpTracks_l(int fd, const Vector<String16>& args) final;
+    void dumpInternals_l(int fd, const Vector<String16>& args) override REQUIRES(mutex());
+    void dumpTracks_l(int fd, const Vector<String16>& args) final REQUIRES(mutex());
 
                 /**
                  * @brief mDeviceId  current device port unique identifier
@@ -2195,26 +2253,27 @@
                                       audio_port_handle_t deviceId,
                                       audio_port_handle_t portId) final;
 
-    AudioStreamOut* clearOutput() final;
+    AudioStreamOut* clearOutput() final EXCLUDES_ThreadBase_Mutex;
 
                 // VolumeInterface
     void setMasterVolume(float value) final;
-    void setMasterBalance(float /* value */) final {}  // Needs implementation?
+    // Needs implementation?
+    void setMasterBalance(float /* value */) final EXCLUDES_ThreadBase_Mutex {}
     void setMasterMute(bool muted) final;
-    void setStreamVolume(audio_stream_type_t stream, float value) final;
-    void setStreamMute(audio_stream_type_t stream, bool muted) final;
-    float streamVolume(audio_stream_type_t stream) const final;
+    void setStreamVolume(audio_stream_type_t stream, float value) final EXCLUDES_ThreadBase_Mutex;
+    void setStreamMute(audio_stream_type_t stream, bool muted) final EXCLUDES_ThreadBase_Mutex;
+    float streamVolume(audio_stream_type_t stream) const final EXCLUDES_ThreadBase_Mutex;
 
                 void        setMasterMute_l(bool muted) { mMasterMute = muted; }
 
-    void invalidateTracks(audio_stream_type_t streamType) final;
-    void invalidateTracks(std::set<audio_port_handle_t>& portIds) final;
+    void invalidateTracks(audio_stream_type_t streamType) final EXCLUDES_ThreadBase_Mutex;
+    void invalidateTracks(std::set<audio_port_handle_t>& portIds) final EXCLUDES_ThreadBase_Mutex;
 
     audio_stream_type_t streamType() const final { return mStreamType; }
-    void checkSilentMode_l() final;
-    void processVolume_l() final;
+    void checkSilentMode_l() final REQUIRES(mutex());
+    void processVolume_l() final REQUIRES(mutex());
 
-    MetadataUpdate updateMetadata_l() final;
+    MetadataUpdate updateMetadata_l() final REQUIRES(mutex());
 
     void toAudioPortConfig(struct audio_port_config* config) final;
 
@@ -2232,13 +2291,18 @@
             REQUIRES(audio_utils::AudioFlinger_Mutex);
 
 protected:
-    void dumpInternals_l(int fd, const Vector<String16>& args) final;
+    void dumpInternals_l(int fd, const Vector<String16>& args) final REQUIRES(mutex());
+                float       streamVolume_l() const {
+                    return mStreamTypes[mStreamType].volume;
+                }
+                bool     streamMuted_l() const {
+                    return mStreamTypes[mStreamType].mute;
+                }
 
+                stream_type_t               mStreamTypes[AUDIO_STREAM_CNT];
                 audio_stream_type_t         mStreamType;
                 float                       mMasterVolume;
-                float                       mStreamVolume;
                 bool                        mMasterMute;
-                bool                        mStreamMute;
                 AudioStreamOut*             mOutput;
 
                 mediautils::atomic_sp<audio_utils::MelProcessor> mMelProcessor;
@@ -2254,13 +2318,14 @@
         return sp<IAfMmapCaptureThread>::fromExisting(this);
     }
 
-    AudioStreamIn* clearInput() final;
+    AudioStreamIn* clearInput() final EXCLUDES_ThreadBase_Mutex;
 
     status_t exitStandby_l() REQUIRES(mutex()) final;
 
-    MetadataUpdate updateMetadata_l() final;
-    void processVolume_l() final;
-    void setRecordSilenced(audio_port_handle_t portId, bool silenced) final;
+    MetadataUpdate updateMetadata_l() final REQUIRES(mutex());
+    void processVolume_l() final REQUIRES(mutex());
+    void setRecordSilenced(audio_port_handle_t portId, bool silenced) final
+            EXCLUDES_ThreadBase_Mutex;
 
     void toAudioPortConfig(struct audio_port_config* config) final;
 
@@ -2281,7 +2346,7 @@
                      audio_io_handle_t id, bool systemReady);
 
 protected:
-    mixer_state prepareTracks_l(Vector<sp<IAfTrack>>* tracksToRemove) final;
+    mixer_state prepareTracks_l(Vector<sp<IAfTrack>>* tracksToRemove) final REQUIRES(mutex());
     void threadLoop_mix() final;
 
 private:
diff --git a/services/audioflinger/Tracks.cpp b/services/audioflinger/Tracks.cpp
index 31246ec..4811586 100644
--- a/services/audioflinger/Tracks.cpp
+++ b/services/audioflinger/Tracks.cpp
@@ -113,8 +113,7 @@
         mChannelCount(isOut ?
                 audio_channel_count_from_out_mask(channelMask) :
                 audio_channel_count_from_in_mask(channelMask)),
-        mFrameSize(audio_has_proportional_frames(format) ?
-                mChannelCount * audio_bytes_per_sample(format) : sizeof(int8_t)),
+        mFrameSize(audio_bytes_per_frame(mChannelCount, format)),
         mFrameCount(frameCount),
         mSessionId(sessionId),
         mIsOut(isOut),
@@ -451,6 +450,10 @@
     if (*_aidl_return != OK) {
         return Status::ok();
     }
+
+    // restrict position modulo INT_MAX to avoid integer sanitization abort
+    legacy.mPosition &= INT_MAX;
+
     *timestamp = legacy2aidl_AudioTimestamp_AudioTimestampInternal(legacy).value();
     return Status::ok();
 }
@@ -1170,9 +1173,11 @@
     if (thread != 0) {
         if (isOffloaded()) {
             audio_utils::lock_guard _laf(thread->afThreadCallback()->mutex());
+            const bool nonOffloadableGlobalEffectEnabled =
+                    thread->afThreadCallback()->isNonOffloadableGlobalEffectEnabled_l();
             audio_utils::lock_guard _lth(thread->mutex());
             sp<IAfEffectChain> ec = thread->getEffectChain_l(mSessionId);
-            if (thread->afThreadCallback()->isNonOffloadableGlobalEffectEnabled_l() ||
+            if (nonOffloadableGlobalEffectEnabled ||
                     (ec != 0 && ec->isNonOffloadableEnabled())) {
                 invalidate();
                 return PERMISSION_DENIED;
diff --git a/services/audiopolicy/common/managerdefinitions/include/DeviceDescriptor.h b/services/audiopolicy/common/managerdefinitions/include/DeviceDescriptor.h
index 80e098b..6c130fd 100644
--- a/services/audiopolicy/common/managerdefinitions/include/DeviceDescriptor.h
+++ b/services/audiopolicy/common/managerdefinitions/include/DeviceDescriptor.h
@@ -89,6 +89,8 @@
     void importAudioPortAndPickAudioProfile(const sp<PolicyAudioPort>& policyPort,
                                             bool force = false);
 
+    status_t readFromParcelable(const media::AudioPortFw& parcelable) override;
+
     void setEncapsulationInfoFromHal(AudioPolicyClientInterface *clientInterface);
 
     void dump(String8 *dst, int spaces, bool verbose = true) const;
@@ -104,7 +106,7 @@
     std::string mTagName; // Unique human readable identifier for a device port found in conf file.
     audio_format_t      mCurrentEncodedFormat;
     bool                mIsDynamic = false;
-    const std::string   mDeclaredAddress; // Original device address
+    std::string         mDeclaredAddress; // Original device address
 };
 
 class DeviceVector : public SortedVector<sp<DeviceDescriptor> >
diff --git a/services/audiopolicy/common/managerdefinitions/src/AudioPolicyConfig.cpp b/services/audiopolicy/common/managerdefinitions/src/AudioPolicyConfig.cpp
index 8c7a7de..4edd11f 100644
--- a/services/audiopolicy/common/managerdefinitions/src/AudioPolicyConfig.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/AudioPolicyConfig.cpp
@@ -29,6 +29,8 @@
 
 namespace android {
 
+using media::audio::common::AudioDeviceAddress;
+using media::audio::common::AudioDeviceType;
 using media::audio::common::AudioIoFlags;
 using media::audio::common::AudioPortDeviceExt;
 using media::audio::common::AudioPortExt;
@@ -113,12 +115,17 @@
             ports.emplace(aidlPort.id, devicePort);
 
             if (const auto& deviceExt = aidlPort.ext.get<AudioPortExt::device>();
-                    deviceExt.device.type.connection.empty()) {  // Attached device
+                    deviceExt.device.type.connection.empty() ||
+                    // DeviceHalAidl connects remote submix input with an address.
+                    (deviceExt.device.type.type == AudioDeviceType::IN_SUBMIX &&
+                            deviceExt.device.address != AudioDeviceAddress())) {
+                // Attached device.
                 if (isInput) {
                     attachedInputDevices->add(devicePort);
                 } else {
                     attachedOutputDevices->add(devicePort);
-                    if ((deviceExt.flags & defaultDeviceFlag) != 0) {
+                    if (*defaultOutputDevice == nullptr &&
+                            (deviceExt.flags & defaultDeviceFlag) != 0) {
                         *defaultOutputDevice = devicePort;
                     }
                 }
diff --git a/services/audiopolicy/common/managerdefinitions/src/DeviceDescriptor.cpp b/services/audiopolicy/common/managerdefinitions/src/DeviceDescriptor.cpp
index 514601c..fe25693 100644
--- a/services/audiopolicy/common/managerdefinitions/src/DeviceDescriptor.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/DeviceDescriptor.cpp
@@ -154,6 +154,12 @@
     policyPort->pickAudioProfile(mSamplingRate, mChannelMask, mFormat);
 }
 
+status_t DeviceDescriptor::readFromParcelable(const media::AudioPortFw& parcelable) {
+    RETURN_STATUS_IF_ERROR(DeviceDescriptorBase::readFromParcelable(parcelable));
+    mDeclaredAddress = DeviceDescriptorBase::address();
+    return OK;
+}
+
 void DeviceDescriptor::setEncapsulationInfoFromHal(
         AudioPolicyClientInterface *clientInterface) {
     AudioParameter param(String8(mDeviceTypeAddr.getAddress()));