[automerger skipped] Merge "AudioFlinger: Extract TeePatch" into main am: c4670a1091 am: c67cb6220d -s ours

am skip reason: Merged-In I88576005a266fd6beeabec873a2d531a65dcf9fd with SHA-1 09788e278f is already in history

Original change: https://android-review.googlesource.com/c/platform/frameworks/av/+/2778279

Change-Id: I24a5fd200c56917af39d5e2ed90ffa053d3b8924
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
diff --git a/camera/ndk/Android.bp b/camera/ndk/Android.bp
index 24a11e3..921aab2 100644
--- a/camera/ndk/Android.bp
+++ b/camera/ndk/Android.bp
@@ -177,6 +177,7 @@
     shared_libs: [
         "libcamera2ndk_vendor",
         "libcamera_metadata",
+        "libhidlbase",
         "libmediandk",
         "libnativewindow",
         "libutils",
@@ -186,6 +187,7 @@
     ],
     static_libs: [
         "android.hardware.camera.common@1.0-helper",
+        "android.hidl.token@1.0",
     ],
     cflags: [
         "-D__ANDROID_VNDK__",
diff --git a/camera/ndk/include/camera/NdkCameraMetadataTags.h b/camera/ndk/include/camera/NdkCameraMetadataTags.h
index bd679e5..fe0ef67 100644
--- a/camera/ndk/include/camera/NdkCameraMetadataTags.h
+++ b/camera/ndk/include/camera/NdkCameraMetadataTags.h
@@ -584,6 +584,19 @@
      * <p>Only constrains auto-exposure (AE) algorithm, not
      * manual control of ACAMERA_SENSOR_EXPOSURE_TIME and
      * ACAMERA_SENSOR_FRAME_DURATION.</p>
+     * <p>Note that the actual achievable max framerate also depends on the minimum frame
+     * duration of the output streams. The max frame rate will be
+     * <code>min(aeTargetFpsRange.maxFps, 1 / max(individual stream min durations)</code>. For example,
+     * if the application sets this key to <code>{60, 60}</code>, but the maximum minFrameDuration among
+     * all configured streams is 33ms, the maximum framerate won't be 60fps, but will be
+     * 30fps.</p>
+     * <p>To start a CaptureSession with a target FPS range different from the
+     * capture request template's default value, the application
+     * is strongly recommended to call
+     * {@link ACameraDevice_createCaptureSessionWithSessionParameters }
+     * with the target fps range before creating the capture session. The aeTargetFpsRange is
+     * typically a session parameter. Specifying it at session creation time helps avoid
+     * session reconfiguration delays in cases like 60fps or high speed recording.</p>
      *
      * @see ACAMERA_SENSOR_EXPOSURE_TIME
      * @see ACAMERA_SENSOR_FRAME_DURATION
@@ -1128,6 +1141,12 @@
      * ACAMERA_CONTROL_VIDEO_STABILIZATION_MODE field will return
      * OFF if the recording output is not stabilized, or if there are no output
      * Surface types that can be stabilized.</p>
+     * <p>The application is strongly recommended to call
+     * {@link ACameraDevice_createCaptureSessionWithSessionParameters }
+     * with the desired video stabilization mode before creating the capture session.
+     * Video stabilization mode is a session parameter on many devices. Specifying
+     * it at session creation time helps avoid reconfiguration delay caused by difference
+     * between the default value and the first CaptureRequest.</p>
      * <p>If a camera device supports both this mode and OIS
      * (ACAMERA_LENS_OPTICAL_STABILIZATION_MODE), turning both modes on may
      * produce undesirable interaction, so it is recommended not to enable
@@ -5384,7 +5403,7 @@
      * <a href="https://developer.android.com/reference/android/hardware/camera2/CameraMetadata.html#SENSOR_PIXEL_MODE_DEFAULT">CameraMetadata#SENSOR_PIXEL_MODE_DEFAULT</a> mode.
      * They can be queried through
      * <a href="https://developer.android.com/reference/android/hardware/camera2/CameraCharacteristics.html#get">CameraCharacteristics#get</a> with
-     * <a href="https://developer.android.com/reference/CameraCharacteristics.html#SCALER_STREAM_CONFIGURATION_MAP_MAXIMUM_RESOLUTION)">CameraCharacteristics#SCALER_STREAM_CONFIGURATION_MAP_MAXIMUM_RESOLUTION)</a>.
+     * <a href="https://developer.android.com/reference/CameraCharacteristics.html#SCALER_STREAM_CONFIGURATION_MAP_MAXIMUM_RESOLUTION">CameraCharacteristics#SCALER_STREAM_CONFIGURATION_MAP_MAXIMUM_RESOLUTION</a>.
      * Unless reported by both
      * <a href="https://developer.android.com/reference/android/hardware/camera2/params/StreamConfigurationMap.html">StreamConfigurationMap</a>s, the outputs from
      * <code>android.scaler.streamConfigurationMapMaximumResolution</code> and
@@ -5399,13 +5418,12 @@
      * <ul>
      * <li>
      * <p>The mandatory stream combinations listed in
-     *   <a href="https://developer.android.com/reference/android/hardware/camera2/CameraCharacteristics/mandatoryMaximumResolutionStreamCombinations.html">mandatoryMaximumResolutionStreamCombinations</a>
-     *   would not apply.</p>
+     *   android.scaler.mandatoryMaximumResolutionStreamCombinations  would not apply.</p>
      * </li>
      * <li>
      * <p>The bayer pattern of {@code RAW} streams when
      *   <a href="https://developer.android.com/reference/android/hardware/camera2/CameraMetadata.html#SENSOR_PIXEL_MODE_MAXIMUM_RESOLUTION">CameraMetadata#SENSOR_PIXEL_MODE_MAXIMUM_RESOLUTION</a>
-     *   is selected will be the one listed in <a href="https://developer.android.com/reference/android/sensor/info/binningFactor.html">binningFactor</a>.</p>
+     *   is selected will be the one listed in ACAMERA_SENSOR_INFO_BINNING_FACTOR.</p>
      * </li>
      * <li>
      * <p>The following keys will always be present:</p>
@@ -5419,6 +5437,7 @@
      * </ul>
      *
      * @see ACAMERA_SENSOR_INFO_ACTIVE_ARRAY_SIZE_MAXIMUM_RESOLUTION
+     * @see ACAMERA_SENSOR_INFO_BINNING_FACTOR
      * @see ACAMERA_SENSOR_INFO_PIXEL_ARRAY_SIZE_MAXIMUM_RESOLUTION
      * @see ACAMERA_SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE_MAXIMUM_RESOLUTION
      */
diff --git a/camera/ndk/ndk_vendor/tests/AImageReaderVendorTest.cpp b/camera/ndk/ndk_vendor/tests/AImageReaderVendorTest.cpp
index 7f6ea9d..74c6cad 100644
--- a/camera/ndk/ndk_vendor/tests/AImageReaderVendorTest.cpp
+++ b/camera/ndk/ndk_vendor/tests/AImageReaderVendorTest.cpp
@@ -31,10 +31,13 @@
 #include <stdio.h>
 
 #include <android/log.h>
+#include <android/hidl/manager/1.2/IServiceManager.h>
+#include <android/hidl/token/1.0/ITokenManager.h>
 #include <camera/NdkCameraError.h>
 #include <camera/NdkCameraManager.h>
 #include <camera/NdkCameraDevice.h>
 #include <camera/NdkCameraCaptureSession.h>
+#include <hidl/ServiceManagement.h>
 #include <media/NdkImage.h>
 #include <media/NdkImageReader.h>
 #include <cutils/native_handle.h>
@@ -50,6 +53,8 @@
 static constexpr int kTestImageFormat = AIMAGE_FORMAT_YUV_420_888;
 
 using android::hardware::camera::common::V1_0::helper::VendorTagDescriptorCache;
+using android::hidl::manager::V1_0::IServiceManager;
+using android::hidl::token::V1_0::ITokenManager;
 using ConfiguredWindows = std::set<const native_handle_t *>;
 
 class CameraHelper {
@@ -981,11 +986,19 @@
 
 
 TEST_F(AImageReaderVendorTest, CreateWindowNativeHandle) {
+    auto transport = android::hardware::defaultServiceManager()->getTransport(ITokenManager::descriptor, "default");
+    if (transport.isOk() && transport == IServiceManager::Transport::EMPTY) {
+        GTEST_SKIP() << "This device no longer supports AImageReader_getWindowNativeHandle";
+    }
     testBasicTakePictures(/*prepareSurfaces*/ false);
     testBasicTakePictures(/*prepareSurfaces*/ true);
 }
 
 TEST_F(AImageReaderVendorTest, LogicalCameraPhysicalStream) {
+    auto transport = android::hardware::defaultServiceManager()->getTransport(ITokenManager::descriptor, "default");
+    if (transport.isOk() && transport == IServiceManager::Transport::EMPTY) {
+        GTEST_SKIP() << "This device no longer supports AImageReader_getWindowNativeHandle";
+    }
     for (auto & v2 : {true, false}) {
         testLogicalCameraPhysicalStream(false/*usePhysicalSettings*/, v2);
         testLogicalCameraPhysicalStream(true/*usePhysicalSettings*/, v2);
diff --git a/media/audioserver/main_audioserver.cpp b/media/audioserver/main_audioserver.cpp
index 1e3bfe0..c7a1bfd 100644
--- a/media/audioserver/main_audioserver.cpp
+++ b/media/audioserver/main_audioserver.cpp
@@ -184,7 +184,7 @@
         // attempting to call audio flinger on a null pointer could make the process crash
         // and attract attentions.
         std::vector<AudioMMapPolicyInfo> policyInfos;
-        status_t status = af->getMmapPolicyInfos(
+        status_t status = sp<IAudioFlinger>::cast(af)->getMmapPolicyInfos(
                 AudioMMapPolicyType::DEFAULT, &policyInfos);
         // Initialize aaudio service when querying mmap policy succeeds and
         // any of the policy supports MMAP.
diff --git a/media/libaudioclient/IAudioFlinger.cpp b/media/libaudioclient/IAudioFlinger.cpp
index 7caaaaf..4bd12b8 100644
--- a/media/libaudioclient/IAudioFlinger.cpp
+++ b/media/libaudioclient/IAudioFlinger.cpp
@@ -646,7 +646,7 @@
     return result.value_or(0);
 }
 
-uint32_t AudioFlingerClientAdapter::getPrimaryOutputSamplingRate() {
+uint32_t AudioFlingerClientAdapter::getPrimaryOutputSamplingRate() const {
     auto result = [&]() -> ConversionResult<uint32_t> {
         int32_t aidlRet;
         RETURN_IF_ERROR(statusTFromBinderStatus(
@@ -657,7 +657,7 @@
     return result.value_or(0);
 }
 
-size_t AudioFlingerClientAdapter::getPrimaryOutputFrameCount() {
+size_t AudioFlingerClientAdapter::getPrimaryOutputFrameCount() const {
     auto result = [&]() -> ConversionResult<size_t> {
         int64_t aidlRet;
         RETURN_IF_ERROR(statusTFromBinderStatus(
@@ -672,7 +672,7 @@
     return statusTFromBinderStatus(mDelegate->setLowRamDevice(isLowRamDevice, totalMemory));
 }
 
-status_t AudioFlingerClientAdapter::getAudioPort(struct audio_port_v7* port) {
+status_t AudioFlingerClientAdapter::getAudioPort(struct audio_port_v7* port) const {
     media::AudioPortFw portAidl = VALUE_OR_RETURN_STATUS(
             legacy2aidl_audio_port_v7_AudioPortFw(*port));
     media::AudioPortFw aidlRet;
@@ -705,7 +705,7 @@
 }
 
 status_t AudioFlingerClientAdapter::listAudioPatches(unsigned int* num_patches,
-                                                     struct audio_patch* patches) {
+                                                     struct audio_patch* patches) const {
     std::vector<media::AudioPatchFw> aidlRet;
     int32_t maxPatches = VALUE_OR_RETURN_STATUS(convertIntegral<int32_t>(*num_patches));
     RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(
@@ -753,7 +753,8 @@
 }
 
 status_t
-AudioFlingerClientAdapter::getMicrophones(std::vector<media::MicrophoneInfoFw>* microphones) {
+AudioFlingerClientAdapter::getMicrophones(
+        std::vector<media::MicrophoneInfoFw>* microphones) const {
     std::vector<media::MicrophoneInfoFw> aidlRet;
     RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(mDelegate->getMicrophones(&aidlRet)));
     if (microphones != nullptr) {
@@ -788,7 +789,7 @@
     return statusTFromBinderStatus(mDelegate->getMmapPolicyInfos(policyType, policyInfos));
 }
 
-int32_t AudioFlingerClientAdapter::getAAudioMixerBurstCount() {
+int32_t AudioFlingerClientAdapter::getAAudioMixerBurstCount() const {
     auto result = [&]() -> ConversionResult<int32_t> {
         int32_t aidlRet;
         RETURN_IF_ERROR(statusTFromBinderStatus(mDelegate->getAAudioMixerBurstCount(&aidlRet)));
@@ -798,7 +799,7 @@
     return result.value_or(0);
 }
 
-int32_t AudioFlingerClientAdapter::getAAudioHardwareBurstMinUsec() {
+int32_t AudioFlingerClientAdapter::getAAudioHardwareBurstMinUsec() const {
     auto result = [&]() -> ConversionResult<int32_t> {
         int32_t aidlRet;
         RETURN_IF_ERROR(statusTFromBinderStatus(
@@ -829,7 +830,7 @@
 }
 
 status_t AudioFlingerClientAdapter::getSupportedLatencyModes(
-        audio_io_handle_t output, std::vector<audio_latency_mode_t>* modes) {
+        audio_io_handle_t output, std::vector<audio_latency_mode_t>* modes) const {
     if (modes == nullptr) {
         return BAD_VALUE;
     }
@@ -851,7 +852,7 @@
     return statusTFromBinderStatus(mDelegate->setBluetoothVariableLatencyEnabled(enabled));
 }
 
-status_t AudioFlingerClientAdapter::isBluetoothVariableLatencyEnabled(bool* enabled) {
+status_t AudioFlingerClientAdapter::isBluetoothVariableLatencyEnabled(bool* enabled) const {
     if (enabled == nullptr) {
         return BAD_VALUE;
     }
@@ -862,7 +863,7 @@
     return NO_ERROR;
 }
 
-status_t AudioFlingerClientAdapter::supportsBluetoothVariableLatency(bool* support) {
+status_t AudioFlingerClientAdapter::supportsBluetoothVariableLatency(bool* support) const {
     if (support == nullptr) {
         return BAD_VALUE;
     }
@@ -875,7 +876,7 @@
 
 status_t AudioFlingerClientAdapter::getSoundDoseInterface(
         const sp<media::ISoundDoseCallback> &callback,
-        sp<media::ISoundDose>* soundDose) {
+        sp<media::ISoundDose>* soundDose) const {
     return statusTFromBinderStatus(mDelegate->getSoundDoseInterface(callback, soundDose));
 }
 
diff --git a/media/libaudioclient/include/media/IAudioFlinger.h b/media/libaudioclient/include/media/IAudioFlinger.h
index 2e2ef65..3c96862 100644
--- a/media/libaudioclient/include/media/IAudioFlinger.h
+++ b/media/libaudioclient/include/media/IAudioFlinger.h
@@ -303,8 +303,8 @@
     // helpers for android.media.AudioManager.getProperty(), see description there for meaning
     // FIXME move these APIs to AudioPolicy to permit a more accurate implementation
     // that looks on primary device for a stream with fast flag, primary flag, or first one.
-    virtual uint32_t getPrimaryOutputSamplingRate() = 0;
-    virtual size_t getPrimaryOutputFrameCount() = 0;
+    virtual uint32_t getPrimaryOutputSamplingRate() const = 0;
+    virtual size_t getPrimaryOutputFrameCount() const = 0;
 
     // Intended for AudioService to inform AudioFlinger of device's low RAM attribute,
     // and should be called at most once.  For a definition of what "low RAM" means, see
@@ -313,7 +313,7 @@
     virtual status_t setLowRamDevice(bool isLowRamDevice, int64_t totalMemory) = 0;
 
     /* Get attributes for a given audio port */
-    virtual status_t getAudioPort(struct audio_port_v7 *port) = 0;
+    virtual status_t getAudioPort(struct audio_port_v7* port) const = 0;
 
     /* Create an audio patch between several source and sink ports */
     virtual status_t createAudioPatch(const struct audio_patch *patch,
@@ -324,7 +324,7 @@
 
     /* List existing audio patches */
     virtual status_t listAudioPatches(unsigned int *num_patches,
-                                      struct audio_patch *patches) = 0;
+                                      struct audio_patch* patches) const = 0;
     /* Set audio port configuration */
     virtual status_t setAudioPortConfig(const struct audio_port_config *config) = 0;
 
@@ -341,7 +341,7 @@
     virtual size_t frameCountHAL(audio_io_handle_t ioHandle) const = 0;
 
     /* List available microphones and their characteristics */
-    virtual status_t getMicrophones(std::vector<media::MicrophoneInfoFw> *microphones) = 0;
+    virtual status_t getMicrophones(std::vector<media::MicrophoneInfoFw>* microphones) const = 0;
 
     virtual status_t setAudioHalPids(const std::vector<pid_t>& pids) = 0;
 
@@ -357,9 +357,9 @@
             media::audio::common::AudioMMapPolicyType policyType,
             std::vector<media::audio::common::AudioMMapPolicyInfo> *policyInfos) = 0;
 
-    virtual int32_t getAAudioMixerBurstCount() = 0;
+    virtual int32_t getAAudioMixerBurstCount() const = 0;
 
-    virtual int32_t getAAudioHardwareBurstMinUsec() = 0;
+    virtual int32_t getAAudioHardwareBurstMinUsec() const = 0;
 
     virtual status_t setDeviceConnectedState(const struct audio_port_v7 *port,
                                              media::DeviceConnectedState state) = 0;
@@ -370,18 +370,18 @@
             audio_io_handle_t output, audio_latency_mode_t mode) = 0;
 
     virtual status_t getSupportedLatencyModes(audio_io_handle_t output,
-            std::vector<audio_latency_mode_t>* modes) = 0;
+            std::vector<audio_latency_mode_t>* modes) const = 0;
 
     virtual status_t getSoundDoseInterface(const sp<media::ISoundDoseCallback>& callback,
-                                           sp<media::ISoundDose>* soundDose) = 0;
+                                           sp<media::ISoundDose>* soundDose) const = 0;
 
     virtual status_t invalidateTracks(const std::vector<audio_port_handle_t>& portIds) = 0;
 
     virtual status_t setBluetoothVariableLatencyEnabled(bool enabled) = 0;
 
-    virtual status_t isBluetoothVariableLatencyEnabled(bool* enabled) = 0;
+    virtual status_t isBluetoothVariableLatencyEnabled(bool* enabled) const = 0;
 
-    virtual status_t supportsBluetoothVariableLatency(bool* support) = 0;
+    virtual status_t supportsBluetoothVariableLatency(bool* support) const = 0;
 
     virtual status_t getAudioPolicyConfig(media::AudioPolicyConfig* output) = 0;
 };
@@ -459,22 +459,22 @@
                             audio_session_t sessionId,
                             bool suspended) override;
     audio_module_handle_t loadHwModule(const char* name) override;
-    uint32_t getPrimaryOutputSamplingRate() override;
-    size_t getPrimaryOutputFrameCount() override;
+    uint32_t getPrimaryOutputSamplingRate() const override;
+    size_t getPrimaryOutputFrameCount() const override;
     status_t setLowRamDevice(bool isLowRamDevice, int64_t totalMemory) override;
-    status_t getAudioPort(struct audio_port_v7* port) override;
+    status_t getAudioPort(struct audio_port_v7* port) const override;
     status_t createAudioPatch(const struct audio_patch* patch,
                               audio_patch_handle_t* handle) override;
     status_t releaseAudioPatch(audio_patch_handle_t handle) override;
     status_t listAudioPatches(unsigned int* num_patches,
-                              struct audio_patch* patches) override;
+                              struct audio_patch* patches) const override;
     status_t setAudioPortConfig(const struct audio_port_config* config) override;
     audio_hw_sync_t getAudioHwSyncForSession(audio_session_t sessionId) override;
     status_t systemReady() override;
     status_t audioPolicyReady() override;
 
     size_t frameCountHAL(audio_io_handle_t ioHandle) const override;
-    status_t getMicrophones(std::vector<media::MicrophoneInfoFw>* microphones) override;
+    status_t getMicrophones(std::vector<media::MicrophoneInfoFw>* microphones) const override;
     status_t setAudioHalPids(const std::vector<pid_t>& pids) override;
     status_t setVibratorInfos(const std::vector<media::AudioVibratorInfo>& vibratorInfos) override;
     status_t updateSecondaryOutputs(
@@ -482,20 +482,20 @@
     status_t getMmapPolicyInfos(
             media::audio::common::AudioMMapPolicyType policyType,
             std::vector<media::audio::common::AudioMMapPolicyInfo> *policyInfos) override;
-    int32_t getAAudioMixerBurstCount() override;
-    int32_t getAAudioHardwareBurstMinUsec() override;
+    int32_t getAAudioMixerBurstCount() const override;
+    int32_t getAAudioHardwareBurstMinUsec() const override;
     status_t setDeviceConnectedState(const struct audio_port_v7 *port,
                                      media::DeviceConnectedState state) override;
     status_t setSimulateDeviceConnections(bool enabled) override;
     status_t setRequestedLatencyMode(audio_io_handle_t output,
             audio_latency_mode_t mode) override;
     status_t getSupportedLatencyModes(
-            audio_io_handle_t output, std::vector<audio_latency_mode_t>* modes) override;
+            audio_io_handle_t output, std::vector<audio_latency_mode_t>* modes) const override;
     status_t setBluetoothVariableLatencyEnabled(bool enabled) override;
-    status_t isBluetoothVariableLatencyEnabled(bool* enabled) override;
-    status_t supportsBluetoothVariableLatency(bool* support) override;
+    status_t isBluetoothVariableLatencyEnabled(bool* enabled) const override;
+    status_t supportsBluetoothVariableLatency(bool* support) const override;
     status_t getSoundDoseInterface(const sp<media::ISoundDoseCallback>& callback,
-                                   sp<media::ISoundDose>* soundDose) override;
+                                   sp<media::ISoundDose>* soundDose) const override;
     status_t invalidateTracks(const std::vector<audio_port_handle_t>& portIds) override;
     status_t getAudioPolicyConfig(media::AudioPolicyConfig* output) override;
 
diff --git a/media/libstagefright/rtsp/ARTPWriter.cpp b/media/libstagefright/rtsp/ARTPWriter.cpp
index 41e9aff..bc57ef7 100644
--- a/media/libstagefright/rtsp/ARTPWriter.cpp
+++ b/media/libstagefright/rtsp/ARTPWriter.cpp
@@ -105,6 +105,7 @@
 
     mRTCPAddr = mRTPAddr;
     mRTCPAddr.sin_port = htons(ntohs(mRTPAddr.sin_port) | 1);
+    mVPSBuf = NULL;
     mSPSBuf = NULL;
     mPPSBuf = NULL;
 
diff --git a/media/mtp/MtpFfsHandle.cpp b/media/mtp/MtpFfsHandle.cpp
index 2ffd775..ef8c9aa 100644
--- a/media/mtp/MtpFfsHandle.cpp
+++ b/media/mtp/MtpFfsHandle.cpp
@@ -297,6 +297,10 @@
 }
 
 void MtpFfsHandle::close() {
+    auto timeout = std::chrono::seconds(2);
+    std::unique_lock lk(m);
+    cv.wait_for(lk, timeout ,[this]{return child_threads==0;});
+
     io_destroy(mCtx);
     closeEndpoints();
     closeConfig();
@@ -669,6 +673,11 @@
     char *temp = new char[me.length];
     memcpy(temp, me.data, me.length);
     me.data = temp;
+
+    std::unique_lock lk(m);
+    child_threads++;
+    lk.unlock();
+
     std::thread t([this, me]() { return this->doSendEvent(me); });
     t.detach();
     return 0;
@@ -680,6 +689,11 @@
     if (static_cast<unsigned>(ret) != length)
         PLOG(ERROR) << "Mtp error sending event thread!";
     delete[] reinterpret_cast<char*>(me.data);
+
+    std::unique_lock lk(m);
+    child_threads--;
+    lk.unlock();
+    cv.notify_one();
 }
 
 } // namespace android
diff --git a/media/mtp/MtpFfsHandle.h b/media/mtp/MtpFfsHandle.h
index e552e03..51cdef0 100644
--- a/media/mtp/MtpFfsHandle.h
+++ b/media/mtp/MtpFfsHandle.h
@@ -60,6 +60,10 @@
     bool mCanceled;
     bool mBatchCancel;
 
+    std::mutex m;
+    std::condition_variable cv;
+    std::atomic<int> child_threads{0};
+
     android::base::unique_fd mControl;
     // "in" from the host's perspective => sink for mtp server
     android::base::unique_fd mBulkIn;
diff --git a/media/mtp/MtpPacket.cpp b/media/mtp/MtpPacket.cpp
index f069a83..5faaac2 100644
--- a/media/mtp/MtpPacket.cpp
+++ b/media/mtp/MtpPacket.cpp
@@ -92,24 +92,46 @@
 }
 
 uint16_t MtpPacket::getUInt16(int offset) const {
-    return ((uint16_t)mBuffer[offset + 1] << 8) | (uint16_t)mBuffer[offset];
+    if ((unsigned long)(offset+2) <= mBufferSize) {
+        return ((uint16_t)mBuffer[offset + 1] << 8) | (uint16_t)mBuffer[offset];
+    }
+    else {
+        ALOGE("offset for buffer read is greater than buffer size!");
+        abort();
+    }
 }
 
 uint32_t MtpPacket::getUInt32(int offset) const {
-    return ((uint32_t)mBuffer[offset + 3] << 24) | ((uint32_t)mBuffer[offset + 2] << 16) |
-           ((uint32_t)mBuffer[offset + 1] << 8)  | (uint32_t)mBuffer[offset];
+    if ((unsigned long)(offset+4) <= mBufferSize) {
+        return ((uint32_t)mBuffer[offset + 3] << 24) | ((uint32_t)mBuffer[offset + 2] << 16) |
+               ((uint32_t)mBuffer[offset + 1] << 8)  | (uint32_t)mBuffer[offset];
+    }
+    else {
+        ALOGE("offset for buffer read is greater than buffer size!");
+        abort();
+    }
 }
 
 void MtpPacket::putUInt16(int offset, uint16_t value) {
-    mBuffer[offset++] = (uint8_t)(value & 0xFF);
-    mBuffer[offset++] = (uint8_t)((value >> 8) & 0xFF);
+    if ((unsigned long)(offset+2) <= mBufferSize) {
+        mBuffer[offset++] = (uint8_t)(value & 0xFF);
+        mBuffer[offset++] = (uint8_t)((value >> 8) & 0xFF);
+    }
+    else {
+        ALOGE("offset for buffer write is greater than buffer size!");
+    }
 }
 
 void MtpPacket::putUInt32(int offset, uint32_t value) {
-    mBuffer[offset++] = (uint8_t)(value & 0xFF);
-    mBuffer[offset++] = (uint8_t)((value >> 8) & 0xFF);
-    mBuffer[offset++] = (uint8_t)((value >> 16) & 0xFF);
-    mBuffer[offset++] = (uint8_t)((value >> 24) & 0xFF);
+    if ((unsigned long)(offset+4) <= mBufferSize) {
+        mBuffer[offset++] = (uint8_t)(value & 0xFF);
+        mBuffer[offset++] = (uint8_t)((value >> 8) & 0xFF);
+        mBuffer[offset++] = (uint8_t)((value >> 16) & 0xFF);
+        mBuffer[offset++] = (uint8_t)((value >> 24) & 0xFF);
+    }
+    else {
+        ALOGE("offset for buffer write is greater than buffer size!");
+    }
 }
 
 uint16_t MtpPacket::getContainerCode() const {
diff --git a/media/ndk/NdkImageReader.cpp b/media/ndk/NdkImageReader.cpp
index caee37d..7b19ac0 100644
--- a/media/ndk/NdkImageReader.cpp
+++ b/media/ndk/NdkImageReader.cpp
@@ -570,6 +570,9 @@
     }
 }
 
+// The LL-NDK API is now deprecated. New devices will no longer have the token
+// manager service installed, so createHalToken will return false and this
+// will return AMEDIA_ERROR_UNKNOWN on those devices.
 media_status_t AImageReader::getWindowNativeHandle(native_handle **handle) {
     if (mWindowHandle != nullptr) {
         *handle = mWindowHandle;
diff --git a/media/ndk/include/media/NdkImageReader.h b/media/ndk/include/media/NdkImageReader.h
index b6dcaae..b722b74 100644
--- a/media/ndk/include/media/NdkImageReader.h
+++ b/media/ndk/include/media/NdkImageReader.h
@@ -534,15 +534,22 @@
  * Get the native_handle_t corresponding to the ANativeWindow owned by the
  * AImageReader provided.
  *
+ * This is deprecated in API level 35 and will return AMEDIA_ERROR_UNKNOWN.
+ * The native_handle_t is no longer used with AIDL interfaces and
+ * ANativeWindow is used directly instead.
+ * Use AImageRead_getWindow to get the ANativeWindow and use that object.
+ *
  * @param reader The image reader of interest.
  * @param handle The output native_handle_t. This native handle is owned by
  *               this image reader.
  *
  * @return AMEDIA_OK if the method call succeeds.
  *         AMEDIA_ERROR_INVALID_PARAMETER if reader or handle are NULL.
- *         AMEDIA_ERROR_UNKNOWN if some other error is encountered.
+ *         AMEDIA_ERROR_UNKNOWN if some other error is encountered or
+ *         the device no longer has android.hidl.token service to
+ *         satisfy the request because it is deprecated.
  */
-media_status_t AImageReader_getWindowNativeHandle(
+[[deprecated]] media_status_t AImageReader_getWindowNativeHandle(
     AImageReader *reader, /* out */native_handle_t **handle);
 #endif
 
diff --git a/services/audioflinger/Android.bp b/services/audioflinger/Android.bp
index 17e6d15..0cd6243 100644
--- a/services/audioflinger/Android.bp
+++ b/services/audioflinger/Android.bp
@@ -149,6 +149,7 @@
 
     srcs: [
         "AudioFlinger.cpp",
+        "Client.cpp",
         "DeviceEffectManager.cpp",
         "Effects.cpp",
         "MelReporter.cpp",
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index 203af2f..0d539c0 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -15,7 +15,6 @@
 ** limitations under the License.
 */
 
-
 #define LOG_TAG "AudioFlinger"
 //#define LOG_NDEBUG 0
 
@@ -23,71 +22,43 @@
 #define AUDIO_ARRAYS_STATIC_CHECK 1
 
 #include "Configuration.h"
-#include <dirent.h>
-#include <math.h>
-#include <signal.h>
-#include <string>
-#include <sys/time.h>
-#include <sys/resource.h>
-#include <thread>
+#include "AudioFlinger.h"
 
+//#define BUFLOG_NDEBUG 0
+#include <afutils/BufLog.h>
+#include <afutils/DumpTryLock.h>
+#include <afutils/Permission.h>
+#include <afutils/PropertyUtils.h>
+#include <afutils/TypedLogger.h>
 #include <android-base/stringprintf.h>
 #include <android/media/IAudioPolicyService.h>
-#include <android/os/IExternalVibratorService.h>
+#include <audiomanager/IAudioManager.h>
 #include <binder/IPCThreadState.h>
 #include <binder/IServiceManager.h>
-#include <utils/Log.h>
-#include <utils/Trace.h>
 #include <binder/Parcel.h>
-#include <media/audiohal/AudioHalVersionInfo.h>
-#include <media/audiohal/DeviceHalInterface.h>
-#include <media/audiohal/DevicesFactoryHalInterface.h>
-#include <media/audiohal/EffectsFactoryHalInterface.h>
+#include <cutils/properties.h>
+#include <media/AidlConversion.h>
 #include <media/AudioParameter.h>
+#include <media/AudioValidator.h>
+#include <media/IMediaLogService.h>
 #include <media/MediaMetricsItem.h>
 #include <media/TypeConverter.h>
-#include <mediautils/TimeCheck.h>
-#include <memunreachable/memunreachable.h>
-#include <utils/String16.h>
-#include <utils/threads.h>
-
-#include <cutils/atomic.h>
-#include <cutils/properties.h>
-
-#include <system/audio.h>
-#include <audiomanager/IAudioManager.h>
-
-#include "AudioFlinger.h"
-#include "EffectConfiguration.h"
-#include <afutils/PropertyUtils.h>
-
-#include <media/AudioResamplerPublic.h>
-
-#include <system/audio_effects/effect_visualizer.h>
-#include <system/audio_effects/effect_ns.h>
-#include <system/audio_effects/effect_aec.h>
-#include <system/audio_effects/effect_hapticgenerator.h>
-#include <system/audio_effects/effect_spatializer.h>
-
-#include <audio_utils/primitives.h>
-
-#include <powermanager/PowerManager.h>
-
-#include <media/IMediaLogService.h>
-#include <media/AidlConversion.h>
-#include <media/AudioValidator.h>
-#include <media/nbaio/Pipe.h>
-#include <media/nbaio/PipeReader.h>
 #include <mediautils/BatteryNotifier.h>
 #include <mediautils/MemoryLeakTrackUtil.h>
 #include <mediautils/MethodStatistics.h>
 #include <mediautils/ServiceUtilities.h>
 #include <mediautils/TimeCheck.h>
-#include <private/android_filesystem_config.h>
+#include <memunreachable/memunreachable.h>
+// required for effect matching
+#include <system/audio_effects/effect_aec.h>
+#include <system/audio_effects/effect_ns.h>
+#include <system/audio_effects/effect_spatializer.h>
+#include <system/audio_effects/effect_visualizer.h>
+#include <utils/Log.h>
 
-//#define BUFLOG_NDEBUG 0
-#include <afutils/BufLog.h>
-#include <afutils/TypedLogger.h>
+// not needed with the includes above, added to prevent transitive include dependency.
+#include <chrono>
+#include <thread>
 
 // ----------------------------------------------------------------------------
 
@@ -124,10 +95,6 @@
 
 static constexpr char kAudioServiceName[] = "audio";
 
-nsecs_t AudioFlinger::mStandbyTimeInNsecs = kDefaultStandbyTimeInNsecs;
-
-uint32_t AudioFlinger::mScreenState;
-
 // In order to avoid invalidating offloaded tracks each time a Visualizer is turned on and off
 // we define a minimum time during which a global effect is considered enabled.
 static const nsecs_t kMinGlobalEffectEnabletimeNs = seconds(7200);
@@ -148,21 +115,6 @@
     }
 }
 
-// Keep a strong reference to external vibrator service
-static sp<os::IExternalVibratorService> sExternalVibratorService;
-
-static sp<os::IExternalVibratorService> getExternalVibratorService() {
-    if (sExternalVibratorService == 0) {
-        sp<IBinder> binder = defaultServiceManager()->getService(
-            String16("external_vibrator_service"));
-        if (binder != 0) {
-            sExternalVibratorService =
-                interface_cast<os::IExternalVibratorService>(binder);
-        }
-    }
-    return sExternalVibratorService;
-}
-
 // Creates association between Binder code to name for IAudioFlinger.
 #define IAUDIOFLINGER_BINDER_METHOD_MACRO_LIST \
 BINDER_METHOD_ENTRY(createTrack) \
@@ -269,41 +221,6 @@
     }
 };
 
-// TODO b/182392769: use attribution source util
-/* static */
-AttributionSourceState AudioFlinger::checkAttributionSourcePackage(
-        const AttributionSourceState& attributionSource) {
-    Vector<String16> packages;
-    PermissionController{}.getPackagesForUid(attributionSource.uid, packages);
-
-    AttributionSourceState checkedAttributionSource = attributionSource;
-    if (!attributionSource.packageName.has_value()
-            || attributionSource.packageName.value().size() == 0) {
-        if (!packages.isEmpty()) {
-            checkedAttributionSource.packageName =
-                std::move(legacy2aidl_String16_string(packages[0]).value());
-        }
-    } else {
-        String16 opPackageLegacy = VALUE_OR_FATAL(
-            aidl2legacy_string_view_String16(attributionSource.packageName.value_or("")));
-        if (std::find_if(packages.begin(), packages.end(),
-                [&opPackageLegacy](const auto& package) {
-                return opPackageLegacy == package; }) == packages.end()) {
-            ALOGW("The package name(%s) provided does not correspond to the uid %d",
-                    attributionSource.packageName.value_or("").c_str(), attributionSource.uid);
-        }
-    }
-    return checkedAttributionSource;
-}
-
-// ----------------------------------------------------------------------------
-
-std::string formatToString(audio_format_t format) {
-    std::string result;
-    FormatConverter::toString(format, result);
-    return result;
-}
-
 // ----------------------------------------------------------------------------
 
 void AudioFlinger::instantiate() {
@@ -314,25 +231,6 @@
 }
 
 AudioFlinger::AudioFlinger()
-    : mMediaLogNotifier(new AudioFlinger::MediaLogNotifier()),
-      mPrimaryHardwareDev(NULL),
-      mAudioHwDevs(NULL),
-      mHardwareStatus(AUDIO_HW_IDLE),
-      mMasterVolume(1.0f),
-      mMasterMute(false),
-      // mNextUniqueId(AUDIO_UNIQUE_ID_USE_MAX),
-      mMode(AUDIO_MODE_INVALID),
-      mBtNrecIsOff(false),
-      mIsLowRamDevice(true),
-      mIsDeviceTypeKnown(false),
-      mTotalMemory(0),
-      mClientSharedHeapSize(kMinimumClientSharedHeapSizeBytes),
-      mGlobalEffectEnableTime(0),
-      mPatchCommandThread(sp<PatchCommandThread>::make()),
-      mDeviceEffectManager(sp<DeviceEffectManager>::make(*this)),
-      mMelReporter(sp<MelReporter>::make(*this)),
-      mSystemReady(false),
-      mBluetoothLatencyModesEnabled(true)
 {
     // Move the audio session unique ID generator start base as time passes to limit risk of
     // generating the same ID again after an audioserver restart.
@@ -369,9 +267,6 @@
     // in bad state, reset the state upon service start.
     BatteryNotifier::getInstance().noteResetAudio();
 
-    mDevicesFactoryHal = DevicesFactoryHalInterface::create();
-    mEffectsFactoryHal = audioflinger::EffectConfiguration::getEffectsFactoryHal();
-
     mMediaLogNotifier->run("MediaLogNotifier");
     std::vector<pid_t> halPids;
     mDevicesFactoryHal->getHalPids(&halPids);
@@ -385,26 +280,13 @@
 
 void AudioFlinger::onFirstRef()
 {
-    Mutex::Autolock _l(mLock);
-
-    /* TODO: move all this work into an Init() function */
-    char val_str[PROPERTY_VALUE_MAX] = { 0 };
-    if (property_get("ro.audio.flinger_standbytime_ms", val_str, NULL) >= 0) {
-        uint32_t int_val;
-        if (1 == sscanf(val_str, "%u", &int_val)) {
-            mStandbyTimeInNsecs = milliseconds(int_val);
-            ALOGI("Using %u mSec as standby time.", int_val);
-        } else {
-            mStandbyTimeInNsecs = kDefaultStandbyTimeInNsecs;
-            ALOGI("Using default %u mSec as standby time.",
-                    (uint32_t)(mStandbyTimeInNsecs / 1000000));
-        }
-    }
+    audio_utils::lock_guard _l(mutex());
 
     mMode = AUDIO_MODE_NORMAL;
 
     gAudioFlinger = this;  // we are already refcounted, store into atomic pointer.
-
+    mDeviceEffectManager = sp<DeviceEffectManager>::make(
+            sp<IAfDeviceEffectManagerCallback>::fromExisting(this)),
     mDevicesFactoryHalCallback = new DevicesFactoryHalCallbackImpl;
     mDevicesFactoryHal->setCallbackOnce(mDevicesFactoryHalCallback);
 
@@ -412,6 +294,9 @@
         mAAudioBurstsPerBuffer = getAAudioMixerBurstCountFromSystemProperty();
         mAAudioHwBurstMinMicros = getAAudioHardwareBurstMinUsecFromSystemProperty();
     }
+
+    mPatchPanel = IAfPatchPanel::create(sp<IAfPatchPanelCallback>::fromExisting(this));
+    mMelReporter = sp<MelReporter>::make(sp<IAfMelReporterCallback>::fromExisting(this));
 }
 
 status_t AudioFlinger::setAudioHalPids(const std::vector<pid_t>& pids) {
@@ -421,19 +306,19 @@
 
 status_t AudioFlinger::setVibratorInfos(
         const std::vector<media::AudioVibratorInfo>& vibratorInfos) {
-    Mutex::Autolock _l(mLock);
+    audio_utils::lock_guard _l(mutex());
     mAudioVibratorInfos = vibratorInfos;
     return NO_ERROR;
 }
 
 status_t AudioFlinger::updateSecondaryOutputs(
         const TrackSecondaryOutputsMap& trackSecondaryOutputs) {
-    Mutex::Autolock _l(mLock);
+    audio_utils::lock_guard _l(mutex());
     for (const auto& [trackId, secondaryOutputs] : trackSecondaryOutputs) {
         size_t i = 0;
         for (; i < mPlaybackThreads.size(); ++i) {
             IAfPlaybackThread* thread = mPlaybackThreads.valueAt(i).get();
-            Mutex::Autolock _tl(thread->mutex());
+            audio_utils::lock_guard _tl(thread->mutex());
             sp<IAfTrack> track = thread->getTrackById_l(trackId);
             if (track != nullptr) {
                 ALOGD("%s trackId: %u", __func__, trackId);
@@ -449,13 +334,13 @@
 
 status_t AudioFlinger::getMmapPolicyInfos(
             AudioMMapPolicyType policyType, std::vector<AudioMMapPolicyInfo> *policyInfos) {
-    Mutex::Autolock _l(mLock);
+    audio_utils::lock_guard _l(mutex());
     if (const auto it = mPolicyInfos.find(policyType); it != mPolicyInfos.end()) {
         *policyInfos = it->second;
         return NO_ERROR;
     }
     if (mDevicesFactoryHal->getHalVersion() > kMaxAAudioPropertyDeviceHalVersion) {
-        AutoMutex lock(mHardwareLock);
+        audio_utils::lock_guard lock(hardwareMutex());
         for (size_t i = 0; i < mAudioHwDevs.size(); ++i) {
             AudioHwDevice *dev = mAudioHwDevs.valueAt(i);
             std::vector<AudioMMapPolicyInfo> infos;
@@ -475,21 +360,21 @@
     return NO_ERROR;
 }
 
-int32_t AudioFlinger::getAAudioMixerBurstCount() {
-    Mutex::Autolock _l(mLock);
+int32_t AudioFlinger::getAAudioMixerBurstCount() const {
+    audio_utils::lock_guard _l(mutex());
     return mAAudioBurstsPerBuffer;
 }
 
-int32_t AudioFlinger::getAAudioHardwareBurstMinUsec() {
-    Mutex::Autolock _l(mLock);
+int32_t AudioFlinger::getAAudioHardwareBurstMinUsec() const {
+    audio_utils::lock_guard _l(mutex());
     return mAAudioHwBurstMinMicros;
 }
 
 status_t AudioFlinger::setDeviceConnectedState(const struct audio_port_v7 *port,
                                                media::DeviceConnectedState state) {
     status_t final_result = NO_INIT;
-    Mutex::Autolock _l(mLock);
-    AutoMutex lock(mHardwareLock);
+    audio_utils::lock_guard _l(mutex());
+    audio_utils::lock_guard lock(hardwareMutex());
     mHardwareStatus = AUDIO_HW_SET_CONNECTED_STATE;
     for (size_t i = 0; i < mAudioHwDevs.size(); i++) {
         sp<DeviceHalInterface> dev = mAudioHwDevs.valueAt(i)->hwDevice();
@@ -509,8 +394,8 @@
 status_t AudioFlinger::setSimulateDeviceConnections(bool enabled) {
     bool at_least_one_succeeded = false;
     status_t last_error = INVALID_OPERATION;
-    Mutex::Autolock _l(mLock);
-    AutoMutex lock(mHardwareLock);
+    audio_utils::lock_guard _l(mutex());
+    audio_utils::lock_guard lock(hardwareMutex());
     mHardwareStatus = AUDIO_HW_SET_SIMULATE_CONNECTIONS;
     for (size_t i = 0; i < mAudioHwDevs.size(); i++) {
         sp<DeviceHalInterface> dev = mAudioHwDevs.valueAt(i)->hwDevice();
@@ -526,7 +411,7 @@
 }
 
 // getDefaultVibratorInfo_l must be called with AudioFlinger lock held.
-std::optional<media::AudioVibratorInfo> AudioFlinger::getDefaultVibratorInfo_l() {
+std::optional<media::AudioVibratorInfo> AudioFlinger::getDefaultVibratorInfo_l() const {
     if (mAudioVibratorInfos.empty()) {
         return {};
     }
@@ -553,7 +438,7 @@
     }
 
     for (size_t i = 0; i < mAudioHwDevs.size(); i++) {
-        // no mHardwareLock needed, as there are no other references to this
+        // no hardwareMutex() needed, as there are no other references to this
         delete mAudioHwDevs.valueAt(i);
     }
 
@@ -579,7 +464,7 @@
                                              sp<MmapStreamInterface>& interface,
                                              audio_port_handle_t *handle)
 {
-    // TODO: Use ServiceManager to get IAudioFlinger instead of by atomic pointer.
+    // TODO(b/292281786): Use ServiceManager to get IAudioFlinger instead of by atomic pointer.
     // This allows moving oboeservice (AAudio) to a separate process in the future.
     sp<AudioFlinger> af = AudioFlinger::gAudioFlinger.load();  // either nullptr or singleton AF.
     status_t ret = NO_INIT;
@@ -637,7 +522,7 @@
                  __func__, callingUid, callingPid, clientPid);
         adjAttributionSource.pid = VALUE_OR_RETURN_STATUS(legacy2aidl_pid_t_int32_t(callingPid));
     }
-    adjAttributionSource = AudioFlinger::checkAttributionSourcePackage(
+    adjAttributionSource = afutils::checkAttributionSourcePackage(
             adjAttributionSource);
 
     if (direction == MmapStreamInterface::DIRECTION_OUTPUT) {
@@ -675,6 +560,9 @@
         return ret;
     }
 
+    // use unique_lock as we may selectively unlock.
+    audio_utils::unique_lock l(mutex());
+
     // at this stage, a MmapThread was created when openOutput() or openInput() was called by
     // audio policy manager and we can retrieve it
     const sp<IAfMmapThread> thread = mMmapThreads.valueFor(io);
@@ -687,12 +575,14 @@
         config->channel_mask = thread->channelMask();
         config->format = thread->format();
     } else {
+        l.unlock();
         if (direction == MmapStreamInterface::DIRECTION_OUTPUT) {
             AudioSystem::releaseOutput(portId);
         } else {
             AudioSystem::releaseInput(portId);
         }
         ret = NO_INIT;
+        // we don't reacquire the lock here as nothing left to do.
     }
 
     ALOGV("%s done status %d portId %d", __FUNCTION__, ret, portId);
@@ -700,37 +590,9 @@
     return ret;
 }
 
-/* static */
-os::HapticScale AudioFlinger::onExternalVibrationStart(
-        const sp<os::ExternalVibration>& externalVibration) {
-    sp<os::IExternalVibratorService> evs = getExternalVibratorService();
-    if (evs != nullptr) {
-        int32_t ret;
-        binder::Status status = evs->onExternalVibrationStart(*externalVibration, &ret);
-        if (status.isOk()) {
-            ALOGD("%s, start external vibration with intensity as %d", __func__, ret);
-            return os::ExternalVibration::externalVibrationScaleToHapticScale(ret);
-        }
-    }
-    ALOGD("%s, start external vibration with intensity as MUTE due to %s",
-            __func__,
-            evs == nullptr ? "external vibration service not found"
-                           : "error when querying intensity");
-    return os::HapticScale::MUTE;
-}
-
-/* static */
-void AudioFlinger::onExternalVibrationStop(const sp<os::ExternalVibration>& externalVibration) {
-    sp<os::IExternalVibratorService> evs = getExternalVibratorService();
-    if (evs != 0) {
-        ALOGD("%s, stopping external vibration", __func__);
-        evs->onExternalVibrationStop(*externalVibration);
-    }
-}
-
 status_t AudioFlinger::addEffectToHal(
         const struct audio_port_config *device, const sp<EffectHalInterface>& effect) {
-    AutoMutex lock(mHardwareLock);
+    audio_utils::lock_guard lock(hardwareMutex());
     AudioHwDevice *audioHwDevice = mAudioHwDevs.valueFor(device->ext.device.hw_module);
     if (audioHwDevice == nullptr) {
         return NO_INIT;
@@ -740,7 +602,7 @@
 
 status_t AudioFlinger::removeEffectFromHal(
         const struct audio_port_config *device, const sp<EffectHalInterface>& effect) {
-    AutoMutex lock(mHardwareLock);
+    audio_utils::lock_guard lock(hardwareMutex());
     AudioHwDevice *audioHwDevice = mAudioHwDevs.valueFor(device->ext.device.hw_module);
     if (audioHwDevice == nullptr) {
         return NO_INIT;
@@ -760,11 +622,11 @@
 {
     // if module is 0, the request comes from an old policy manager and we should load
     // well known modules
-    AutoMutex lock(mHardwareLock);
+    audio_utils::lock_guard lock(hardwareMutex());
     if (module == 0) {
         ALOGW("findSuitableHwDev_l() loading well know audio hw modules");
         for (size_t i = 0; i < arraysize(audio_interfaces); i++) {
-            loadHwModule_l(audio_interfaces[i]);
+            loadHwModule_ll(audio_interfaces[i]);
         }
         // then try to find a module supporting the requested device.
         for (size_t i = 0; i < mAudioHwDevs.size(); i++) {
@@ -787,7 +649,7 @@
     return NULL;
 }
 
-void AudioFlinger::dumpClients(int fd, const Vector<String16>& args __unused)
+void AudioFlinger::dumpClients_ll(int fd, const Vector<String16>& args __unused)
 {
     String8 result;
 
@@ -821,17 +683,14 @@
 }
 
 
-void AudioFlinger::dumpInternals(int fd, const Vector<String16>& args __unused)
+void AudioFlinger::dumpInternals_l(int fd, const Vector<String16>& args __unused)
 {
     const size_t SIZE = 256;
     char buffer[SIZE];
     String8 result;
     hardware_call_state hardwareStatus = mHardwareStatus;
 
-    snprintf(buffer, SIZE, "Hardware status: %d\n"
-                           "Standby Time mSec: %u\n",
-                            hardwareStatus,
-                            (uint32_t)(mStandbyTimeInNsecs / 1000000));
+    snprintf(buffer, SIZE, "Hardware status: %d\n", hardwareStatus);
     result.append(buffer);
     write(fd, result.c_str(), result.size());
 
@@ -856,12 +715,6 @@
     write(fd, result.c_str(), result.size());
 }
 
-bool AudioFlinger::dumpTryLock(Mutex& mutex)
-{
-    status_t err = mutex.timedLock(kDumpLockTimeoutNs);
-    return err == NO_ERROR;
-}
-
 status_t AudioFlinger::dump(int fd, const Vector<String16>& args)
 NO_THREAD_SAFETY_ANALYSIS  // conditional try lock
 {
@@ -869,15 +722,15 @@
         dumpPermissionDenial(fd, args);
     } else {
         // get state of hardware lock
-        bool hardwareLocked = dumpTryLock(mHardwareLock);
+        const bool hardwareLocked = afutils::dumpTryLock(hardwareMutex());
         if (!hardwareLocked) {
             String8 result(kHardwareLockedString);
             write(fd, result.c_str(), result.size());
         } else {
-            mHardwareLock.unlock();
+            hardwareMutex().unlock();
         }
 
-        const bool locked = dumpTryLock(mLock);
+        const bool locked = afutils::dumpTryLock(mutex());
 
         // failed to lock - AudioFlinger is probably deadlocked
         if (!locked) {
@@ -885,7 +738,7 @@
             write(fd, result.c_str(), result.size());
         }
 
-        bool clientLocked = dumpTryLock(mClientLock);
+        const bool clientLocked = afutils::dumpTryLock(clientMutex());
         if (!clientLocked) {
             String8 result(kClientLockedString);
             write(fd, result.c_str(), result.size());
@@ -898,12 +751,12 @@
             write(fd, result.c_str(), result.size());
         }
 
-        dumpClients(fd, args);
+        dumpClients_ll(fd, args);
         if (clientLocked) {
-            mClientLock.unlock();
+            clientMutex().unlock();
         }
 
-        dumpInternals(fd, args);
+        dumpInternals_l(fd, args);
 
         // dump playback threads
         for (size_t i = 0; i < mPlaybackThreads.size(); i++) {
@@ -958,7 +811,7 @@
         BUFLOG_RESET;
 
         if (locked) {
-            mLock.unlock();
+            mutex().unlock();
         }
 
 #ifdef TEE_SINK
@@ -1030,12 +883,12 @@
 
 sp<Client> AudioFlinger::registerPid(pid_t pid)
 {
-    Mutex::Autolock _cl(mClientLock);
+    audio_utils::lock_guard _cl(clientMutex());
     // If pid is already in the mClients wp<> map, then use that entry
     // (for which promote() is always != 0), otherwise create a new entry and Client.
     sp<Client> client = mClients.valueFor(pid).promote();
     if (client == 0) {
-        client = new Client(this, pid);
+        client = sp<Client>::make(sp<IAfClientCallback>::fromExisting(this), pid);
         mClients.add(pid, client);
     }
 
@@ -1053,7 +906,7 @@
     // If allocation fails, consult the vector of previously unregistered writers
     // and garbage-collect one or more them until an allocation succeeds
     if (shared == 0) {
-        Mutex::Autolock _l(mUnregisteredWritersLock);
+        audio_utils::lock_guard _l(unregisteredWritersMutex());
         for (size_t count = mUnregisteredWriters.size(); count > 0; count--) {
             {
                 // Pick the oldest stale writer to garbage-collect
@@ -1093,7 +946,7 @@
     }
     // Rather than removing the writer immediately, append it to a queue of old writers to
     // be garbage-collected later.  This allows us to continue to view old logs for a while.
-    Mutex::Autolock _l(mUnregisteredWritersLock);
+    audio_utils::lock_guard _l(unregisteredWritersMutex());
     mUnregisteredWriters.push(writer);
 }
 
@@ -1143,7 +996,7 @@
         clientPid = callingPid;
         adjAttributionSource.pid = VALUE_OR_RETURN_STATUS(legacy2aidl_pid_t_int32_t(callingPid));
     }
-    adjAttributionSource = AudioFlinger::checkAttributionSourcePackage(
+    adjAttributionSource = afutils::checkAttributionSourcePackage(
             adjAttributionSource);
 
     audio_session_t sessionId = input.sessionId;
@@ -1189,7 +1042,7 @@
     }
 
     {
-        Mutex::Autolock _l(mLock);
+        audio_utils::lock_guard _l(mutex());
         IAfPlaybackThread* thread = checkPlaybackThread_l(output.outputId);
         if (thread == NULL) {
             ALOGE("no playback thread found for output handle %d", output.outputId);
@@ -1240,8 +1093,8 @@
         output.portId = portId;
 
         if (lStatus == NO_ERROR) {
-            // no risk of deadlock because AudioFlinger::mLock is held
-            Mutex::Autolock _dl(thread->mutex());
+            // no risk of deadlock because AudioFlinger::mutex() is held
+            audio_utils::lock_guard _dl(thread->mutex());
             // Connect secondary outputs. Failure on a secondary output must not imped the primary
             // Any secondary output setup failure will lead to a desync between the AP and AF until
             // the track is destroyed.
@@ -1249,8 +1102,9 @@
             // move effect chain to this output thread if an effect on same session was waiting
             // for a track to be created
             if (effectThread != nullptr) {
-                Mutex::Autolock _sl(effectThread->mutex());
-                if (moveEffectChain_l(sessionId, effectThread, thread) == NO_ERROR) {
+                // No thread safety analysis: double lock on a thread capability.
+                audio_utils::lock_guard_no_thread_safety_analysis _sl(effectThread->mutex());
+                if (moveEffectChain_ll(sessionId, effectThread, thread) == NO_ERROR) {
                     effectThreadId = thread->id();
                     effectIds = thread->getEffectIds_l(sessionId);
                 }
@@ -1279,11 +1133,11 @@
 
     if (lStatus != NO_ERROR) {
         // remove local strong reference to Client before deleting the Track so that the
-        // Client destructor is called by the TrackBase destructor with mClientLock held
-        // Don't hold mClientLock when releasing the reference on the track as the
+        // Client destructor is called by the TrackBase destructor with clientMutex() held
+        // Don't hold clientMutex() when releasing the reference on the track as the
         // destructor will acquire it.
         {
-            Mutex::Autolock _cl(mClientLock);
+            audio_utils::lock_guard _cl(clientMutex());
             client.clear();
         }
         track.clear();
@@ -1308,7 +1162,7 @@
 
 uint32_t AudioFlinger::sampleRate(audio_io_handle_t ioHandle) const
 {
-    Mutex::Autolock _l(mLock);
+    audio_utils::lock_guard _l(mutex());
     IAfThreadBase* const thread = checkThread_l(ioHandle);
     if (thread == NULL) {
         ALOGW("sampleRate() unknown thread %d", ioHandle);
@@ -1319,7 +1173,7 @@
 
 audio_format_t AudioFlinger::format(audio_io_handle_t output) const
 {
-    Mutex::Autolock _l(mLock);
+    audio_utils::lock_guard _l(mutex());
     IAfPlaybackThread* const thread = checkPlaybackThread_l(output);
     if (thread == NULL) {
         ALOGW("format() unknown thread %d", output);
@@ -1330,7 +1184,7 @@
 
 size_t AudioFlinger::frameCount(audio_io_handle_t ioHandle) const
 {
-    Mutex::Autolock _l(mLock);
+    audio_utils::lock_guard _l(mutex());
     IAfThreadBase* const thread = checkThread_l(ioHandle);
     if (thread == NULL) {
         ALOGW("frameCount() unknown thread %d", ioHandle);
@@ -1343,7 +1197,7 @@
 
 size_t AudioFlinger::frameCountHAL(audio_io_handle_t ioHandle) const
 {
-    Mutex::Autolock _l(mLock);
+    audio_utils::lock_guard _l(mutex());
     IAfThreadBase* const thread = checkThread_l(ioHandle);
     if (thread == NULL) {
         ALOGW("frameCountHAL() unknown thread %d", ioHandle);
@@ -1354,7 +1208,7 @@
 
 uint32_t AudioFlinger::latency(audio_io_handle_t output) const
 {
-    Mutex::Autolock _l(mLock);
+    audio_utils::lock_guard _l(mutex());
     IAfPlaybackThread* const thread = checkPlaybackThread_l(output);
     if (thread == NULL) {
         ALOGW("latency(): no playback thread found for output handle %d", output);
@@ -1375,12 +1229,12 @@
         return PERMISSION_DENIED;
     }
 
-    Mutex::Autolock _l(mLock);
+    audio_utils::lock_guard _l(mutex());
     mMasterVolume = value;
 
     // Set master volume in the HALs which support it.
     {
-        AutoMutex lock(mHardwareLock);
+        audio_utils::lock_guard lock(hardwareMutex());
         for (size_t i = 0; i < mAudioHwDevs.size(); i++) {
             AudioHwDevice *dev = mAudioHwDevs.valueAt(i);
 
@@ -1422,7 +1276,7 @@
         return BAD_VALUE;
     }
 
-    Mutex::Autolock _l(mLock);
+    audio_utils::lock_guard _l(mutex());
 
     // short cut.
     if (mMasterBalance == balance) return NO_ERROR;
@@ -1456,18 +1310,18 @@
     }
 
     { // scope for the lock
-        AutoMutex lock(mHardwareLock);
+        audio_utils::lock_guard lock(hardwareMutex());
         if (mPrimaryHardwareDev == nullptr) {
             return INVALID_OPERATION;
         }
-        sp<DeviceHalInterface> dev = mPrimaryHardwareDev->hwDevice();
+        sp<DeviceHalInterface> dev = mPrimaryHardwareDev.load()->hwDevice();
         mHardwareStatus = AUDIO_HW_SET_MODE;
         ret = dev->setMode(mode);
         mHardwareStatus = AUDIO_HW_IDLE;
     }
 
     if (NO_ERROR == ret) {
-        Mutex::Autolock _l(mLock);
+        audio_utils::lock_guard _l(mutex());
         mMode = mode;
         for (size_t i = 0; i < mPlaybackThreads.size(); i++) {
             mPlaybackThreads.valueAt(i)->setMode(mode);
@@ -1493,11 +1347,11 @@
         return PERMISSION_DENIED;
     }
 
-    AutoMutex lock(mHardwareLock);
+    audio_utils::lock_guard lock(hardwareMutex());
     if (mPrimaryHardwareDev == nullptr) {
         return INVALID_OPERATION;
     }
-    sp<DeviceHalInterface> primaryDev = mPrimaryHardwareDev->hwDevice();
+    sp<DeviceHalInterface> primaryDev = mPrimaryHardwareDev.load()->hwDevice();
     if (primaryDev == nullptr) {
         ALOGW("%s: no primary HAL device", __func__);
         return INVALID_OPERATION;
@@ -1521,11 +1375,11 @@
     if (ret != NO_ERROR) {
         return false;
     }
-    AutoMutex lock(mHardwareLock);
+    audio_utils::lock_guard lock(hardwareMutex());
     if (mPrimaryHardwareDev == nullptr) {
         return false;
     }
-    sp<DeviceHalInterface> primaryDev = mPrimaryHardwareDev->hwDevice();
+    sp<DeviceHalInterface> primaryDev = mPrimaryHardwareDev.load()->hwDevice();
     if (primaryDev == nullptr) {
         ALOGW("%s: no primary HAL device", __func__);
         return false;
@@ -1542,7 +1396,7 @@
 {
     ALOGV("AudioFlinger::setRecordSilenced(portId:%d, silenced:%d)", portId, silenced);
 
-    AutoMutex lock(mLock);
+    audio_utils::lock_guard lock(mutex());
     for (size_t i = 0; i < mRecordThreads.size(); i++) {
         mRecordThreads[i]->setRecordSilenced(portId, silenced);
     }
@@ -1563,12 +1417,12 @@
         return PERMISSION_DENIED;
     }
 
-    Mutex::Autolock _l(mLock);
+    audio_utils::lock_guard _l(mutex());
     mMasterMute = muted;
 
     // Set master mute in the HALs which support it.
     {
-        AutoMutex lock(mHardwareLock);
+        audio_utils::lock_guard lock(hardwareMutex());
         for (size_t i = 0; i < mAudioHwDevs.size(); i++) {
             AudioHwDevice *dev = mAudioHwDevs.valueAt(i);
 
@@ -1594,20 +1448,20 @@
 
 float AudioFlinger::masterVolume() const
 {
-    Mutex::Autolock _l(mLock);
+    audio_utils::lock_guard _l(mutex());
     return masterVolume_l();
 }
 
 status_t AudioFlinger::getMasterBalance(float *balance) const
 {
-    Mutex::Autolock _l(mLock);
+    audio_utils::lock_guard _l(mutex());
     *balance = getMasterBalance_l();
     return NO_ERROR; // if called through binder, may return a transactional error
 }
 
 bool AudioFlinger::masterMute() const
 {
-    Mutex::Autolock _l(mLock);
+    audio_utils::lock_guard _l(mutex());
     return masterMute_l();
 }
 
@@ -1626,7 +1480,8 @@
     return mMasterMute;
 }
 
-status_t AudioFlinger::checkStreamType(audio_stream_type_t stream) const
+/* static */
+status_t AudioFlinger::checkStreamType(audio_stream_type_t stream)
 {
     if (uint32_t(stream) >= AUDIO_STREAM_CNT) {
         ALOGW("checkStreamType() invalid stream %d", stream);
@@ -1659,7 +1514,7 @@
     LOG_ALWAYS_FATAL_IF(stream == AUDIO_STREAM_PATCH && value != 1.0f,
                         "AUDIO_STREAM_PATCH must have full scale volume");
 
-    AutoMutex lock(mLock);
+    audio_utils::lock_guard lock(mutex());
     sp<VolumeInterface> volumeInterface = getVolumeInterface_l(output);
     if (volumeInterface == NULL) {
         return BAD_VALUE;
@@ -1674,7 +1529,7 @@
     if (output == AUDIO_IO_HANDLE_NONE) {
         return BAD_VALUE;
     }
-    AutoMutex lock(mLock);
+    audio_utils::lock_guard lock(mutex());
     IAfPlaybackThread* const thread = checkPlaybackThread_l(output);
     if (thread == nullptr) {
         return BAD_VALUE;
@@ -1683,11 +1538,11 @@
 }
 
 status_t AudioFlinger::getSupportedLatencyModes(audio_io_handle_t output,
-            std::vector<audio_latency_mode_t>* modes) {
+            std::vector<audio_latency_mode_t>* modes) const {
     if (output == AUDIO_IO_HANDLE_NONE) {
         return BAD_VALUE;
     }
-    AutoMutex lock(mLock);
+    audio_utils::lock_guard lock(mutex());
     IAfPlaybackThread* const thread = checkPlaybackThread_l(output);
     if (thread == nullptr) {
         return BAD_VALUE;
@@ -1696,7 +1551,7 @@
 }
 
 status_t AudioFlinger::setBluetoothVariableLatencyEnabled(bool enabled) {
-    Mutex::Autolock _l(mLock);
+    audio_utils::lock_guard _l(mutex());
     status_t status = INVALID_OPERATION;
     for (size_t i = 0; i < mPlaybackThreads.size(); i++) {
         // Success if at least one PlaybackThread supports Bluetooth latency modes
@@ -1710,7 +1565,7 @@
     return status;
 }
 
-status_t AudioFlinger::isBluetoothVariableLatencyEnabled(bool *enabled) {
+status_t AudioFlinger::isBluetoothVariableLatencyEnabled(bool* enabled) const {
     if (enabled == nullptr) {
         return BAD_VALUE;
     }
@@ -1718,11 +1573,11 @@
     return NO_ERROR;
 }
 
-status_t AudioFlinger::supportsBluetoothVariableLatency(bool* support) {
+status_t AudioFlinger::supportsBluetoothVariableLatency(bool* support) const {
     if (support == nullptr) {
         return BAD_VALUE;
     }
-    Mutex::Autolock _l(mLock);
+    audio_utils::lock_guard _l(hardwareMutex());
     *support = false;
     for (size_t i = 0; i < mAudioHwDevs.size(); i++) {
         if (mAudioHwDevs.valueAt(i)->supportsBluetoothVariableLatency()) {
@@ -1734,7 +1589,7 @@
 }
 
 status_t AudioFlinger::getSoundDoseInterface(const sp<media::ISoundDoseCallback>& callback,
-                                             sp<media::ISoundDose>* soundDose) {
+                                             sp<media::ISoundDose>* soundDose) const {
     if (soundDose == nullptr) {
         return BAD_VALUE;
     }
@@ -1761,7 +1616,7 @@
         return BAD_VALUE;
     }
 
-    AutoMutex lock(mLock);
+    audio_utils::lock_guard lock(mutex());
     mStreamTypes[stream].mute = muted;
     std::vector<sp<VolumeInterface>> volumeInterfaces = getAllVolumeInterfaces_l();
     for (size_t i = 0; i < volumeInterfaces.size(); i++) {
@@ -1781,7 +1636,7 @@
         return 0.0f;
     }
 
-    AutoMutex lock(mLock);
+    audio_utils::lock_guard lock(mutex());
     sp<VolumeInterface> volumeInterface = getVolumeInterface_l(output);
     if (volumeInterface == NULL) {
         return 0.0f;
@@ -1797,7 +1652,7 @@
         return true;
     }
 
-    AutoMutex lock(mLock);
+    audio_utils::lock_guard lock(mutex());
     return streamMute_l(stream);
 }
 
@@ -1816,7 +1671,7 @@
     }
 }
 
-// forwardAudioHwSyncToDownstreamPatches_l() must be called with AudioFlinger::mLock held
+// forwardAudioHwSyncToDownstreamPatches_l() must be called with AudioFlinger::mutex() held
 void AudioFlinger::forwardParametersToDownstreamPatches_l(
         audio_io_handle_t upStream, const String8& keyValuePairs,
         const std::function<bool(const sp<IAfPlaybackThread>&)>& useThread)
@@ -1921,11 +1776,11 @@
 
     // AUDIO_IO_HANDLE_NONE means the parameters are global to the audio hardware interface
     if (ioHandle == AUDIO_IO_HANDLE_NONE) {
-        Mutex::Autolock _l(mLock);
+        audio_utils::lock_guard _l(mutex());
         // result will remain NO_INIT if no audio device is present
         status_t final_result = NO_INIT;
         {
-            AutoMutex lock(mHardwareLock);
+            audio_utils::lock_guard lock(hardwareMutex());
             mHardwareStatus = AUDIO_HW_SET_PARAMETER;
             for (size_t i = 0; i < mAudioHwDevs.size(); i++) {
                 sp<DeviceHalInterface> dev = mAudioHwDevs.valueAt(i)->hwDevice();
@@ -1953,8 +1808,8 @@
         String8 screenState;
         if (param.get(String8(AudioParameter::keyScreenState), screenState) == NO_ERROR) {
             bool isOff = (screenState == AudioParameter::valueOff);
-            if (isOff != (AudioFlinger::mScreenState & 1)) {
-                AudioFlinger::mScreenState = ((AudioFlinger::mScreenState & ~1) + 2) | isOff;
+            if (isOff != (mScreenState & 1)) {
+                mScreenState = ((mScreenState & ~1) + 2) | isOff;
             }
         }
         return final_result;
@@ -1964,7 +1819,7 @@
     // and the thread is exited once the lock is released
     sp<IAfThreadBase> thread;
     {
-        Mutex::Autolock _l(mLock);
+        audio_utils::lock_guard _l(mutex());
         thread = checkPlaybackThread_l(ioHandle);
         if (thread == 0) {
             thread = checkRecordThread_l(ioHandle);
@@ -1983,6 +1838,7 @@
     }
     if (thread != 0) {
         status_t result = thread->setParameters(filteredKeyValuePairs);
+        audio_utils::lock_guard _l(mutex());
         forwardParametersToDownstreamPatches_l(thread->id(), filteredKeyValuePairs);
         return result;
     }
@@ -1994,12 +1850,12 @@
     ALOGVV("getParameters() io %d, keys %s, calling pid %d",
             ioHandle, keys.c_str(), IPCThreadState::self()->getCallingPid());
 
-    Mutex::Autolock _l(mLock);
+    audio_utils::lock_guard _l(mutex());
 
     if (ioHandle == AUDIO_IO_HANDLE_NONE) {
         String8 out_s8;
 
-        AutoMutex lock(mHardwareLock);
+        audio_utils::lock_guard lock(hardwareMutex());
         for (size_t i = 0; i < mAudioHwDevs.size(); i++) {
             String8 s;
             mHardwareStatus = AUDIO_HW_GET_PARAMETER;
@@ -2037,13 +1893,13 @@
         return 0;
     }
 
-    AutoMutex lock(mHardwareLock);
+    audio_utils::lock_guard lock(hardwareMutex());
     if (mPrimaryHardwareDev == nullptr) {
         return 0;
     }
     mHardwareStatus = AUDIO_HW_GET_INPUT_BUFFER_SIZE;
 
-    sp<DeviceHalInterface> dev = mPrimaryHardwareDev->hwDevice();
+    sp<DeviceHalInterface> dev = mPrimaryHardwareDev.load()->hwDevice();
 
     std::vector<audio_channel_mask_t> channelMasks = {channelMask};
     if (channelMask != AUDIO_CHANNEL_IN_MONO) {
@@ -2109,7 +1965,7 @@
 
 uint32_t AudioFlinger::getInputFramesLost(audio_io_handle_t ioHandle) const
 {
-    Mutex::Autolock _l(mLock);
+    audio_utils::lock_guard _l(mutex());
 
     IAfRecordThread* const recordThread = checkRecordThread_l(ioHandle);
     if (recordThread != NULL) {
@@ -2130,11 +1986,11 @@
         return PERMISSION_DENIED;
     }
 
-    AutoMutex lock(mHardwareLock);
+    audio_utils::lock_guard lock(hardwareMutex());
     if (mPrimaryHardwareDev == nullptr) {
         return INVALID_OPERATION;
     }
-    sp<DeviceHalInterface> dev = mPrimaryHardwareDev->hwDevice();
+    sp<DeviceHalInterface> dev = mPrimaryHardwareDev.load()->hwDevice();
     mHardwareStatus = AUDIO_HW_SET_VOICE_VOLUME;
     ret = dev->setVoiceVolume(value);
     mHardwareStatus = AUDIO_HW_IDLE;
@@ -2149,7 +2005,7 @@
 status_t AudioFlinger::getRenderPosition(uint32_t *halFrames, uint32_t *dspFrames,
         audio_io_handle_t output) const
 {
-    Mutex::Autolock _l(mLock);
+    audio_utils::lock_guard _l(mutex());
 
     IAfPlaybackThread* const playbackThread = checkPlaybackThread_l(output);
     if (playbackThread != NULL) {
@@ -2161,14 +2017,14 @@
 
 void AudioFlinger::registerClient(const sp<media::IAudioFlingerClient>& client)
 {
-    Mutex::Autolock _l(mLock);
+    audio_utils::lock_guard _l(mutex());
     if (client == 0) {
         return;
     }
     pid_t pid = IPCThreadState::self()->getCallingPid();
     const uid_t uid = IPCThreadState::self()->getCallingUid();
     {
-        Mutex::Autolock _cl(mClientLock);
+        audio_utils::lock_guard _cl(clientMutex());
         if (mNotificationClients.indexOfKey(pid) < 0) {
             sp<NotificationClient> notificationClient = new NotificationClient(this,
                                                                                 client,
@@ -2184,9 +2040,10 @@
         }
     }
 
-    // mClientLock should not be held here because ThreadBase::sendIoConfigEvent() will lock the
-    // ThreadBase mutex and the locking order is ThreadBase::mLock then AudioFlinger::mClientLock.
-    // the config change is always sent from playback or record threads to avoid deadlock
+    // clientMutex() should not be held here because ThreadBase::sendIoConfigEvent()
+    // will lock the ThreadBase::mutex() and the locking order is
+    // ThreadBase::mutex() then AudioFlinger::clientMutex().
+    // The config change is always sent from playback or record threads to avoid deadlock
     // with AudioSystem::gLock
     for (size_t i = 0; i < mPlaybackThreads.size(); i++) {
         mPlaybackThreads.valueAt(i)->sendIoConfigEvent(AUDIO_OUTPUT_REGISTERED, pid);
@@ -2201,9 +2058,9 @@
 {
     std::vector<sp<IAfEffectModule>> removedEffects;
     {
-        Mutex::Autolock _l(mLock);
+        audio_utils::lock_guard _l(mutex());
         {
-            Mutex::Autolock _cl(mClientLock);
+            audio_utils::lock_guard _cl(clientMutex());
             mNotificationClients.removeItem(pid);
         }
 
@@ -2240,7 +2097,7 @@
     media::AudioIoDescriptor descAidl = VALUE_OR_FATAL(
             legacy2aidl_AudioIoDescriptor_AudioIoDescriptor(ioDesc));
 
-    Mutex::Autolock _l(mClientLock);
+    audio_utils::lock_guard _l(clientMutex());
     size_t size = mNotificationClients.size();
     for (size_t i = 0; i < size; i++) {
         if ((pid == 0) || (mNotificationClients.keyAt(i) == pid)) {
@@ -2257,7 +2114,7 @@
                 convertContainer<std::vector<media::audio::common::AudioLatencyMode>>(
                         modes, legacy2aidl_audio_latency_mode_t_AudioLatencyMode));
 
-    Mutex::Autolock _l(mClientLock);
+    audio_utils::lock_guard _l(clientMutex());
     size_t size = mNotificationClients.size();
     for (size_t i = 0; i < size; i++) {
         mNotificationClients.valueAt(i)->audioFlingerClient()
@@ -2265,7 +2122,7 @@
     }
 }
 
-// removeClient_l() must be called with AudioFlinger::mClientLock held
+// removeClient_l() must be called with AudioFlinger::clientMutex() held
 void AudioFlinger::removeClient_l(pid_t pid)
 {
     ALOGV("removeClient_l() pid %d, calling pid %d", pid,
@@ -2273,7 +2130,7 @@
     mClients.removeItem(pid);
 }
 
-// getEffectThread_l() must be called with AudioFlinger::mLock held
+// getEffectThread_l() must be called with AudioFlinger::mutex() held
 sp<IAfThreadBase> AudioFlinger::getEffectThread_l(audio_session_t sessionId,
         int effectId)
 {
@@ -2306,27 +2163,6 @@
     return thread;
 }
 
-
-
-// ----------------------------------------------------------------------------
-
-Client::Client(const sp<AudioFlinger>& audioFlinger, pid_t pid)
-    :   RefBase(),
-        mAudioFlinger(audioFlinger),
-        mPid(pid),
-        mClientAllocator(AllocatorFactory::getClientAllocator()) {}
-
-// Client destructor must be called with AudioFlinger::mClientLock held
-Client::~Client()
-{
-    mAudioFlinger->removeClient_l(mPid);
-}
-
-AllocatorFactory::ClientAllocator& Client::allocator()
-{
-    return mClientAllocator;
-}
-
 // ----------------------------------------------------------------------------
 
 AudioFlinger::NotificationClient::NotificationClient(const sp<AudioFlinger>& audioFlinger,
@@ -2353,9 +2189,9 @@
 
 
 void AudioFlinger::MediaLogNotifier::requestMerge() {
-    AutoMutex _l(mMutex);
+    audio_utils::lock_guard _l(mMutex);
     mPendingRequests = true;
-    mCond.signal();
+    mCondition.notify_one();
 }
 
 bool AudioFlinger::MediaLogNotifier::threadLoop() {
@@ -2365,10 +2201,10 @@
     }
     // Wait until there are pending requests
     {
-        AutoMutex _l(mMutex);
+        audio_utils::unique_lock _l(mMutex);
         mPendingRequests = false; // to ignore past requests
         while (!mPendingRequests) {
-            mCond.wait(mMutex);
+            mCondition.wait(_l);
             // TODO may also need an exitPending check
         }
         mPendingRequests = false;
@@ -2423,7 +2259,7 @@
                  __func__, callingUid, callingPid, currentPid);
         adjAttributionSource.pid = VALUE_OR_RETURN_STATUS(legacy2aidl_pid_t_int32_t(callingPid));
     }
-    adjAttributionSource = AudioFlinger::checkAttributionSourcePackage(
+    adjAttributionSource = afutils::checkAttributionSourcePackage(
             adjAttributionSource);
     // we don't yet support anything other than linear PCM
     if (!audio_is_valid_format(input.config.format) || !audio_is_linear_pcm(input.config.format)) {
@@ -2479,7 +2315,7 @@
     }
 
     {
-        Mutex::Autolock _l(mLock);
+        audio_utils::lock_guard _l(mutex());
         IAfRecordThread* const thread = checkRecordThread_l(output.inputId);
         if (thread == NULL) {
             ALOGW("createRecord() checkRecordThread_l failed, input handle %d", output.inputId);
@@ -2536,7 +2372,7 @@
         // session and move it to this thread.
         sp<IAfEffectChain> chain = getOrphanEffectChain_l(sessionId);
         if (chain != 0) {
-            Mutex::Autolock _l2(thread->mutex());
+            audio_utils::lock_guard _l2(thread->mutex());
             thread->addEffectChain_l(chain);
         }
         break;
@@ -2555,11 +2391,11 @@
 Exit:
     if (lStatus != NO_ERROR) {
         // remove local strong reference to Client before deleting the RecordTrack so that the
-        // Client destructor is called by the TrackBase destructor with mClientLock held
-        // Don't hold mClientLock when releasing the reference on the track as the
+        // Client destructor is called by the TrackBase destructor with clientMutex() held
+        // Don't hold clientMutex() when releasing the reference on the track as the
         // destructor will acquire it.
         {
-            Mutex::Autolock _cl(mClientLock);
+            audio_utils::lock_guard _cl(clientMutex());
             client.clear();
         }
         recordTrack.clear();
@@ -2580,8 +2416,8 @@
     if (config == nullptr) {
         return BAD_VALUE;
     }
-    Mutex::Autolock _l(mLock);
-    AutoMutex lock(mHardwareLock);
+    audio_utils::lock_guard _l(mutex());
+    audio_utils::lock_guard lock(hardwareMutex());
     RETURN_STATUS_IF_ERROR(
             mDevicesFactoryHal->getSurroundSoundConfig(&config->surroundSoundConfig));
     RETURN_STATUS_IF_ERROR(mDevicesFactoryHal->getEngineConfig(&config->engineConfig));
@@ -2589,7 +2425,7 @@
     RETURN_STATUS_IF_ERROR(mDevicesFactoryHal->getDeviceNames(&hwModuleNames));
     std::set<AudioMode> allSupportedModes;
     for (const auto& name : hwModuleNames) {
-        AudioHwDevice* module = loadHwModule_l(name.c_str());
+        AudioHwDevice* module = loadHwModule_ll(name.c_str());
         if (module == nullptr) continue;
         media::AudioHwModule aidlModule;
         if (module->hwDevice()->getAudioPorts(&aidlModule.ports) == OK &&
@@ -2624,14 +2460,15 @@
     if (!settingsAllowed()) {
         return AUDIO_MODULE_HANDLE_NONE;
     }
-    Mutex::Autolock _l(mLock);
-    AutoMutex lock(mHardwareLock);
-    AudioHwDevice* module = loadHwModule_l(name);
+    audio_utils::lock_guard _l(mutex());
+    audio_utils::lock_guard lock(hardwareMutex());
+    AudioHwDevice* module = loadHwModule_ll(name);
     return module != nullptr ? module->handle() : AUDIO_MODULE_HANDLE_NONE;
 }
 
-// loadHwModule_l() must be called with AudioFlinger::mLock and AudioFlinger::mHardwareLock held
-AudioHwDevice* AudioFlinger::loadHwModule_l(const char *name)
+// loadHwModule_l() must be called with AudioFlinger::mutex()
+// and AudioFlinger::hardwareMutex() held
+AudioHwDevice* AudioFlinger::loadHwModule_ll(const char *name)
 {
     for (size_t i = 0; i < mAudioHwDevs.size(); i++) {
         if (strncmp(mAudioHwDevs.valueAt(i)->moduleName(), name, strlen(name)) == 0) {
@@ -2710,7 +2547,7 @@
     if (strcmp(name, AUDIO_HARDWARE_MODULE_ID_PRIMARY) == 0) {
         mPrimaryHardwareDev = audioDevice;
         mHardwareStatus = AUDIO_HW_SET_MODE;
-        mPrimaryHardwareDev->hwDevice()->setMode(mMode);
+        mPrimaryHardwareDev.load()->hwDevice()->setMode(mMode);
         mHardwareStatus = AUDIO_HW_IDLE;
     }
 
@@ -2735,16 +2572,16 @@
 
 // ----------------------------------------------------------------------------
 
-uint32_t AudioFlinger::getPrimaryOutputSamplingRate()
+uint32_t AudioFlinger::getPrimaryOutputSamplingRate() const
 {
-    Mutex::Autolock _l(mLock);
+    audio_utils::lock_guard _l(mutex());
     IAfPlaybackThread* const thread = fastPlaybackThread_l();
     return thread != NULL ? thread->sampleRate() : 0;
 }
 
-size_t AudioFlinger::getPrimaryOutputFrameCount()
+size_t AudioFlinger::getPrimaryOutputFrameCount() const
 {
-    Mutex::Autolock _l(mLock);
+    audio_utils::lock_guard _l(mutex());
     IAfPlaybackThread* const thread = fastPlaybackThread_l();
     return thread != NULL ? thread->frameCountHAL() : 0;
 }
@@ -2757,7 +2594,7 @@
     if (!isAudioServerOrSystemServerUid(uid)) {
         return PERMISSION_DENIED;
     }
-    Mutex::Autolock _l(mLock);
+    audio_utils::lock_guard _l(mutex());
     if (mIsDeviceTypeKnown) {
         return INVALID_OPERATION;
     }
@@ -2815,8 +2652,8 @@
         module = config->ext.mix.hw_module;
     }
 
-    Mutex::Autolock _l(mLock);
-    AutoMutex lock(mHardwareLock);
+    audio_utils::lock_guard _l(mutex());
+    audio_utils::lock_guard lock(hardwareMutex());
     ssize_t index = mAudioHwDevs.indexOfKey(module);
     if (index < 0) {
         ALOGW("%s() bad hw module %d", __func__, module);
@@ -2829,7 +2666,7 @@
 
 audio_hw_sync_t AudioFlinger::getAudioHwSyncForSession(audio_session_t sessionId)
 {
-    Mutex::Autolock _l(mLock);
+    audio_utils::lock_guard _l(mutex());
 
     ssize_t index = mHwAvSyncIds.indexOfKey(sessionId);
     if (index >= 0) {
@@ -2840,11 +2677,11 @@
 
     sp<DeviceHalInterface> dev;
     {
-        AutoMutex lock(mHardwareLock);
+        audio_utils::lock_guard lock(hardwareMutex());
         if (mPrimaryHardwareDev == nullptr) {
             return AUDIO_HW_SYNC_INVALID;
         }
-        dev = mPrimaryHardwareDev->hwDevice();
+        dev = mPrimaryHardwareDev.load()->hwDevice();
     }
     if (dev == nullptr) {
         return AUDIO_HW_SYNC_INVALID;
@@ -2889,7 +2726,7 @@
 
 status_t AudioFlinger::systemReady()
 {
-    Mutex::Autolock _l(mLock);
+    audio_utils::lock_guard _l(mutex());
     ALOGI("%s", __FUNCTION__);
     if (mSystemReady) {
         ALOGW("%s called twice", __FUNCTION__);
@@ -2930,9 +2767,9 @@
     return mAudioManager.load();
 }
 
-status_t AudioFlinger::getMicrophones(std::vector<media::MicrophoneInfoFw> *microphones)
+status_t AudioFlinger::getMicrophones(std::vector<media::MicrophoneInfoFw>* microphones) const
 {
-    AutoMutex lock(mHardwareLock);
+    audio_utils::lock_guard lock(hardwareMutex());
     status_t status = INVALID_OPERATION;
 
     for (size_t i = 0; i < mAudioHwDevs.size(); i++) {
@@ -2956,7 +2793,7 @@
     return status;
 }
 
-// setAudioHwSyncForSession_l() must be called with AudioFlinger::mLock held
+// setAudioHwSyncForSession_l() must be called with AudioFlinger::mutex() held
 void AudioFlinger::setAudioHwSyncForSession_l(
         IAfPlaybackThread* const thread, audio_session_t sessionId)
 {
@@ -3000,28 +2837,6 @@
     }
 
     mHardwareStatus = AUDIO_HW_OUTPUT_OPEN;
-
-    // FOR TESTING ONLY:
-    // This if statement allows overriding the audio policy settings
-    // and forcing a specific format or channel mask to the HAL/Sink device for testing.
-    if (!(flags & (AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD | AUDIO_OUTPUT_FLAG_DIRECT))) {
-        // Check only for Normal Mixing mode
-        if (kEnableExtendedPrecision) {
-            // Specify format (uncomment one below to choose)
-            //halConfig->format = AUDIO_FORMAT_PCM_FLOAT;
-            //halConfig->format = AUDIO_FORMAT_PCM_24_BIT_PACKED;
-            //halConfig->format = AUDIO_FORMAT_PCM_32_BIT;
-            //halConfig->format = AUDIO_FORMAT_PCM_8_24_BIT;
-            // ALOGV("openOutput_l() upgrading format to %#08x", halConfig->format);
-        }
-        if (kEnableExtendedChannels) {
-            // Specify channel mask (uncomment one below to choose)
-            //halConfig->channel_mask = audio_channel_out_mask_from_count(4);  // for USB 4ch
-            //halConfig->channel_mask = audio_channel_mask_from_representation_and_bits(
-            //        AUDIO_CHANNEL_REPRESENTATION_INDEX, (1 << 4) - 1);  // another 4ch example
-        }
-    }
-
     AudioStreamOut *outputStream = NULL;
     status_t status = outHwDev->openOutputStream(
             &outputStream,
@@ -3059,8 +2874,8 @@
                 ALOGV("openOutput_l() created offload output: ID %d thread %p",
                       *output, thread.get());
             } else if ((flags & AUDIO_OUTPUT_FLAG_DIRECT)
-                    || !isValidPcmSinkFormat(halConfig->format)
-                    || !isValidPcmSinkChannelMask(halConfig->channel_mask)) {
+                    || !IAfThreadBase::isValidPcmSinkFormat(halConfig->format)
+                    || !IAfThreadBase::isValidPcmSinkChannelMask(halConfig->channel_mask)) {
                 thread = IAfPlaybackThread::createDirectOutputThread(this, outputStream, *output,
                         mSystemReady, halConfig->offload_info);
                 ALOGV("openOutput_l() created direct output: ID %d thread %p",
@@ -3117,7 +2932,7 @@
         return BAD_VALUE;
     }
 
-    Mutex::Autolock _l(mLock);
+    audio_utils::lock_guard _l(mutex());
 
     const sp<IAfThreadBase> thread = openOutput_l(module, &output, &halConfig,
             &mixerConfig, deviceType, address, flags);
@@ -3132,13 +2947,13 @@
 
             // the first primary output opened designates the primary hw device if no HW module
             // named "primary" was already loaded.
-            AutoMutex lock(mHardwareLock);
+            audio_utils::lock_guard lock(hardwareMutex());
             if ((mPrimaryHardwareDev == nullptr) && (flags & AUDIO_OUTPUT_FLAG_PRIMARY)) {
                 ALOGI("Using module %d as the primary audio interface", module);
                 mPrimaryHardwareDev = playbackThread->getOutput()->audioHwDev;
 
                 mHardwareStatus = AUDIO_HW_SET_MODE;
-                mPrimaryHardwareDev->hwDevice()->setMode(mMode);
+                mPrimaryHardwareDev.load()->hwDevice()->setMode(mMode);
                 mHardwareStatus = AUDIO_HW_IDLE;
             }
         } else {
@@ -3159,7 +2974,7 @@
 audio_io_handle_t AudioFlinger::openDuplicateOutput(audio_io_handle_t output1,
         audio_io_handle_t output2)
 {
-    Mutex::Autolock _l(mLock);
+    audio_utils::lock_guard _l(mutex());
     IAfPlaybackThread* const thread1 = checkMixerThread_l(output1);
     IAfPlaybackThread* const thread2 = checkMixerThread_l(output2);
 
@@ -3191,7 +3006,7 @@
     sp<IAfPlaybackThread> playbackThread;
     sp<IAfMmapPlaybackThread> mmapThread;
     {
-        Mutex::Autolock _l(mLock);
+        audio_utils::lock_guard _l(mutex());
         playbackThread = checkPlaybackThread_l(output);
         if (playbackThread != NULL) {
             ALOGV("closeOutput() %d", output);
@@ -3216,11 +3031,11 @@
                         checkPlaybackThread_l(mPlaybackThreads.keyAt(0));
                 if (dstThread != NULL) {
                     // audioflinger lock is held so order of thread lock acquisition doesn't matter
-                    Mutex::Autolock _dl(dstThread->mutex());
-                    Mutex::Autolock _sl(playbackThread->mutex());
+                    // Use scoped_lock to avoid deadlock order issues with duplicating threads.
+                    audio_utils::scoped_lock sl(dstThread->mutex(), playbackThread->mutex());
                     Vector<sp<IAfEffectChain>> effectChains = playbackThread->getEffectChains_l();
                     for (size_t i = 0; i < effectChains.size(); i ++) {
-                        moveEffectChain_l(effectChains[i]->sessionId(), playbackThread.get(),
+                        moveEffectChain_ll(effectChains[i]->sessionId(), playbackThread.get(),
                                 dstThread);
                     }
                 }
@@ -3257,6 +3072,7 @@
     return NO_ERROR;
 }
 
+/* static */
 void AudioFlinger::closeOutputFinish(const sp<IAfPlaybackThread>& thread)
 {
     AudioStreamOut *out = thread->clearOutput();
@@ -3274,7 +3090,7 @@
 
 status_t AudioFlinger::suspendOutput(audio_io_handle_t output)
 {
-    Mutex::Autolock _l(mLock);
+    audio_utils::lock_guard _l(mutex());
     IAfPlaybackThread* const thread = checkPlaybackThread_l(output);
 
     if (thread == NULL) {
@@ -3289,7 +3105,7 @@
 
 status_t AudioFlinger::restoreOutput(audio_io_handle_t output)
 {
-    Mutex::Autolock _l(mLock);
+    audio_utils::lock_guard _l(mutex());
     IAfPlaybackThread* const thread = checkPlaybackThread_l(output);
 
     if (thread == NULL) {
@@ -3306,7 +3122,7 @@
 status_t AudioFlinger::openInput(const media::OpenInputRequest& request,
                                  media::OpenInputResponse* response)
 {
-    Mutex::Autolock _l(mLock);
+    audio_utils::lock_guard _l(mutex());
 
     AudioDeviceTypeAddr device = VALUE_OR_RETURN_STATUS(
             aidl2legacy_AudioDeviceTypeAddress(request.device));
@@ -3443,7 +3259,7 @@
     sp<IAfRecordThread> recordThread;
     sp<IAfMmapCaptureThread> mmapThread;
     {
-        Mutex::Autolock _l(mLock);
+        audio_utils::lock_guard _l(mutex());
         recordThread = checkRecordThread_l(input);
         if (recordThread != 0) {
             ALOGV("closeInput() %d", input);
@@ -3456,7 +3272,7 @@
             // new capture on the same session
             sp<IAfEffectChain> chain;
             {
-                Mutex::Autolock _sl(recordThread->mutex());
+                audio_utils::lock_guard _sl(recordThread->mutex());
                 const Vector<sp<IAfEffectChain>> effectChains = recordThread->getEffectChains_l();
                 // Note: maximum one chain per record thread
                 if (effectChains.size() != 0) {
@@ -3474,7 +3290,7 @@
                         continue;
                     }
                     if (t->hasAudioSession(chain->sessionId()) != 0) {
-                        Mutex::Autolock _l2(t->mutex());
+                        audio_utils::lock_guard _l2(t->mutex());
                         ALOGV("closeInput() found thread %d for effect session %d",
                               t->id(), chain->sessionId());
                         t->addEffectChain_l(chain);
@@ -3498,7 +3314,7 @@
         }
         ioConfigChanged(AUDIO_INPUT_CLOSED, sp<AudioIoDescriptor>::make(input));
     }
-    // FIXME: calling thread->exit() without mLock held should not be needed anymore now that
+    // FIXME: calling thread->exit() without mutex() held should not be needed anymore now that
     // we have a different lock for notification client
     if (recordThread != 0) {
         closeInputFinish(recordThread);
@@ -3528,7 +3344,7 @@
 }
 
 status_t AudioFlinger::invalidateTracks(const std::vector<audio_port_handle_t> &portIds) {
-    Mutex::Autolock _l(mLock);
+    audio_utils::lock_guard _l(mutex());
     ALOGV("%s", __func__);
 
     std::set<audio_port_handle_t> portIdSet(portIds.begin(), portIds.end());
@@ -3563,7 +3379,7 @@
 void AudioFlinger::acquireAudioSessionId(
         audio_session_t audioSession, pid_t pid, uid_t uid)
 {
-    Mutex::Autolock _l(mLock);
+    audio_utils::lock_guard _l(mutex());
     pid_t caller = IPCThreadState::self()->getCallingPid();
     ALOGV("acquiring %d from %d, for %d", audioSession, caller, pid);
     const uid_t callerUid = IPCThreadState::self()->getCallingUid();
@@ -3575,7 +3391,7 @@
     }
 
     {
-        Mutex::Autolock _cl(mClientLock);
+        audio_utils::lock_guard _cl(clientMutex());
         // Ignore requests received from processes not known as notification client. The request
         // is likely proxied by mediaserver (e.g CameraService) and releaseAudioSessionId() can be
         // called from a different pid leaving a stale session reference.  Also we don't know how
@@ -3603,7 +3419,7 @@
 {
     std::vector<sp<IAfEffectModule>> removedEffects;
     {
-        Mutex::Autolock _l(mLock);
+        audio_utils::lock_guard _l(mutex());
         pid_t caller = IPCThreadState::self()->getCallingPid();
         ALOGV("releasing %d from %d for %d", audioSession, caller, pid);
         const uid_t callerUid = IPCThreadState::self()->getCallingUid();
@@ -3658,7 +3474,7 @@
 
     for (size_t i = 0; i < mPlaybackThreads.size(); i++) {
         sp<IAfPlaybackThread> t = mPlaybackThreads.valueAt(i);
-        Mutex::Autolock _l(t->mutex());
+        audio_utils::lock_guard _l(t->mutex());
         const Vector<sp<IAfEffectChain>> threadChains = t->getEffectChains_l();
         for (size_t j = 0; j < threadChains.size(); j++) {
             sp<IAfEffectChain> ec = threadChains[j];
@@ -3670,7 +3486,7 @@
 
     for (size_t i = 0; i < mRecordThreads.size(); i++) {
         sp<IAfRecordThread> t = mRecordThreads.valueAt(i);
-        Mutex::Autolock _l(t->mutex());
+        audio_utils::lock_guard _l(t->mutex());
         const Vector<sp<IAfEffectChain>> threadChains = t->getEffectChains_l();
         for (size_t j = 0; j < threadChains.size(); j++) {
             sp<IAfEffectChain> ec = threadChains[j];
@@ -3680,7 +3496,7 @@
 
     for (size_t i = 0; i < mMmapThreads.size(); i++) {
         const sp<IAfMmapThread> t = mMmapThreads.valueAt(i);
-        Mutex::Autolock _l(t->mutex());
+        audio_utils::lock_guard _l(t->mutex());
         const Vector<sp<IAfEffectChain>> threadChains = t->getEffectChains_l();
         for (size_t j = 0; j < threadChains.size(); j++) {
             sp<IAfEffectChain> ec = threadChains[j];
@@ -3692,7 +3508,7 @@
          // clang-tidy suggests const ref
         sp<IAfEffectChain> ec = chains[i];  // NOLINT(performance-unnecessary-copy-initialization)
         int sessionid = ec->sessionId();
-        const auto t = sp<IAfThreadBase>::cast(ec->thread().promote()); // TODO(b/288339104)
+        const auto t = ec->thread().promote();
         if (t == 0) {
             continue;
         }
@@ -3708,7 +3524,7 @@
             }
         }
         if (!found) {
-            Mutex::Autolock _l(t->mutex());
+            audio_utils::lock_guard _l(t->mutex());
             // remove all effects from the chain
             while (ec->numberOfEffects()) {
                 sp<IAfEffectModule> effect = ec->getEffectModule(0);
@@ -3724,7 +3540,7 @@
     return removedEffects;
 }
 
-// dumpToThreadLog_l() must be called with AudioFlinger::mLock held
+// dumpToThreadLog_l() must be called with AudioFlinger::mutex() held
 void AudioFlinger::dumpToThreadLog_l(const sp<IAfThreadBase> &thread)
 {
     constexpr int THREAD_DUMP_TIMEOUT_MS = 2;
@@ -3736,7 +3552,7 @@
     }
 }
 
-// checkThread_l() must be called with AudioFlinger::mLock held
+// checkThread_l() must be called with AudioFlinger::mutex() held
 IAfThreadBase* AudioFlinger::checkThread_l(audio_io_handle_t ioHandle) const
 {
     IAfThreadBase* thread = checkMmapThread_l(ioHandle);
@@ -3755,7 +3571,7 @@
     return thread;
 }
 
-// checkOutputThread_l() must be called with AudioFlinger::mLock held
+// checkOutputThread_l() must be called with AudioFlinger::mutex() held
 sp<IAfThreadBase> AudioFlinger::checkOutputThread_l(audio_io_handle_t ioHandle) const
 {
     if (audio_unique_id_get_use(ioHandle) != AUDIO_UNIQUE_ID_USE_OUTPUT) {
@@ -3769,33 +3585,33 @@
     return thread;
 }
 
-// checkPlaybackThread_l() must be called with AudioFlinger::mLock held
+// checkPlaybackThread_l() must be called with AudioFlinger::mutex() held
 IAfPlaybackThread* AudioFlinger::checkPlaybackThread_l(audio_io_handle_t output) const
 {
     return mPlaybackThreads.valueFor(output).get();
 }
 
-// checkMixerThread_l() must be called with AudioFlinger::mLock held
+// checkMixerThread_l() must be called with AudioFlinger::mutex() held
 IAfPlaybackThread* AudioFlinger::checkMixerThread_l(audio_io_handle_t output) const
 {
     IAfPlaybackThread * const thread = checkPlaybackThread_l(output);
     return thread != nullptr && thread->type() != IAfThreadBase::DIRECT ? thread : nullptr;
 }
 
-// checkRecordThread_l() must be called with AudioFlinger::mLock held
+// checkRecordThread_l() must be called with AudioFlinger::mutex() held
 IAfRecordThread* AudioFlinger::checkRecordThread_l(audio_io_handle_t input) const
 {
     return mRecordThreads.valueFor(input).get();
 }
 
-// checkMmapThread_l() must be called with AudioFlinger::mLock held
+// checkMmapThread_l() must be called with AudioFlinger::mutex() held
 IAfMmapThread* AudioFlinger::checkMmapThread_l(audio_io_handle_t io) const
 {
     return mMmapThreads.valueFor(io).get();
 }
 
 
-// checkPlaybackThread_l() must be called with AudioFlinger::mLock held
+// checkPlaybackThread_l() must be called with AudioFlinger::mutex() held
 sp<VolumeInterface> AudioFlinger::getVolumeInterface_l(audio_io_handle_t output) const
 {
     sp<VolumeInterface> volumeInterface = mPlaybackThreads.valueFor(output).get();
@@ -3851,7 +3667,7 @@
 
 IAfPlaybackThread* AudioFlinger::primaryPlaybackThread_l() const
 {
-    AutoMutex lock(mHardwareLock);
+    audio_utils::lock_guard lock(hardwareMutex());
     if (mPrimaryHardwareDev == nullptr) {
         return nullptr;
     }
@@ -3940,7 +3756,7 @@
         // The frameCount should also not be smaller than the secondary thread min frame
         // count
         size_t minFrameCount = AudioSystem::calculateMinFrameCount(
-                    [&] { Mutex::Autolock _l(secondaryThread->mutex());
+                    [&] { audio_utils::lock_guard _l(secondaryThread->mutex());
                           return secondaryThread->latency_l(); }(),
                     secondaryThread->frameCount(), // normal frame count
                     secondaryThread->sampleRate(),
@@ -4008,7 +3824,7 @@
                                     const audioflinger::SyncEventCallback& callBack,
                                     const wp<IAfTrackBase>& cookie)
 {
-    Mutex::Autolock _l(mLock);
+    audio_utils::lock_guard _l(mutex());
 
     auto event = sp<audioflinger::SyncEvent>::make(
             type, triggerSession, listenerSession, callBack, cookie);
@@ -4045,7 +3861,7 @@
 
 status_t AudioFlinger::queryNumberEffects(uint32_t *numEffects) const
 {
-    Mutex::Autolock _l(mLock);
+    audio_utils::lock_guard _l(mutex());
     if (mEffectsFactoryHal.get()) {
         return mEffectsFactoryHal->queryNumberEffects(numEffects);
     } else {
@@ -4055,7 +3871,7 @@
 
 status_t AudioFlinger::queryEffect(uint32_t index, effect_descriptor_t *descriptor) const
 {
-    Mutex::Autolock _l(mLock);
+    audio_utils::lock_guard _l(mutex());
     if (mEffectsFactoryHal.get()) {
         return mEffectsFactoryHal->getDescriptor(index, descriptor);
     } else {
@@ -4072,7 +3888,7 @@
         return BAD_VALUE;
     }
 
-    Mutex::Autolock _l(mLock);
+    audio_utils::lock_guard _l(mutex());
 
     if (!mEffectsFactoryHal.get()) {
         return -ENODEV;
@@ -4167,7 +3983,7 @@
         adjAttributionSource.pid = VALUE_OR_RETURN_STATUS(legacy2aidl_pid_t_int32_t(callingPid));
         currentPid = callingPid;
     }
-    adjAttributionSource = AudioFlinger::checkAttributionSourcePackage(adjAttributionSource);
+    adjAttributionSource = afutils::checkAttributionSourcePackage(adjAttributionSource);
 
     ALOGV("createEffect pid %d, effectClient %p, priority %d, sessionId %d, io %d, factory %p",
           adjAttributionSource.pid, effectClient.get(), priority, sessionId, io,
@@ -4192,7 +4008,11 @@
             lStatus = BAD_VALUE;
             goto Exit;
         }
-        IAfPlaybackThread* const thread = checkPlaybackThread_l(io);
+        IAfPlaybackThread* thread;
+        {
+            audio_utils::lock_guard l(mutex());
+            thread = checkPlaybackThread_l(io);
+        }
         if (thread == nullptr) {
             ALOGE("%s: invalid output %d specified for AUDIO_SESSION_OUTPUT_STAGE", __func__, io);
             lStatus = BAD_VALUE;
@@ -4283,7 +4103,7 @@
             ALOGV("createEffect got output %d", io);
         }
 
-        Mutex::Autolock _l(mLock);
+        audio_utils::lock_guard _l(mutex());
 
         if (sessionId == AUDIO_SESSION_DEVICE) {
             sp<Client> client = registerPid(currentPid);
@@ -4292,8 +4112,8 @@
                     &descOut, device, client, effectClient, mPatchPanel->patches_l(),
                     &enabledOut, &lStatus, probe, request.notifyFramesProcessed);
             if (lStatus != NO_ERROR && lStatus != ALREADY_EXISTS) {
-                // remove local strong reference to Client with mClientLock held
-                Mutex::Autolock _cl(mClientLock);
+                // remove local strong reference to Client with clientMutex() held
+                audio_utils::lock_guard _cl(clientMutex());
                 client.clear();
             } else {
                 // handle must be valid here, but check again to be safe.
@@ -4386,7 +4206,7 @@
             // session and used it instead of creating a new one.
             sp<IAfEffectChain> chain = getOrphanEffectChain_l(sessionId);
             if (chain != 0) {
-                Mutex::Autolock _l2(thread->mutex());
+                audio_utils::lock_guard _l2(thread->mutex());
                 thread->addEffectChain_l(chain);
             }
         }
@@ -4413,8 +4233,8 @@
                                         &descOut, &enabledOut, &lStatus, pinned, probe,
                                         request.notifyFramesProcessed);
         if (lStatus != NO_ERROR && lStatus != ALREADY_EXISTS) {
-            // remove local strong reference to Client with mClientLock held
-            Mutex::Autolock _cl(mClientLock);
+            // remove local strong reference to Client with clientMutex() held
+            audio_utils::lock_guard _cl(clientMutex());
             client.clear();
         } else {
             // handle must be valid here, but check again to be safe.
@@ -4462,7 +4282,7 @@
 {
     ALOGV("%s() session %d, srcOutput %d, dstOutput %d",
             __func__, sessionId, srcOutput, dstOutput);
-    Mutex::Autolock _l(mLock);
+    audio_utils::lock_guard _l(mutex());
     if (srcOutput == dstOutput) {
         ALOGW("%s() same dst and src outputs %d", __func__, dstOutput);
         return NO_ERROR;
@@ -4478,9 +4298,8 @@
         return BAD_VALUE;
     }
 
-    Mutex::Autolock _dl(dstThread->mutex());
-    Mutex::Autolock _sl(srcThread->mutex());
-    return moveEffectChain_l(sessionId, srcThread, dstThread);
+    audio_utils::scoped_lock _ll(dstThread->mutex(), srcThread->mutex());
+    return moveEffectChain_ll(sessionId, srcThread, dstThread);
 }
 
 
@@ -4488,38 +4307,38 @@
                                 audio_session_t sessionId,
                                 bool suspended)
 {
-    Mutex::Autolock _l(mLock);
+    audio_utils::lock_guard _l(mutex());
 
     sp<IAfThreadBase> thread = getEffectThread_l(sessionId, effectId);
     if (thread == nullptr) {
       return;
     }
-    Mutex::Autolock _sl(thread->mutex());
+    audio_utils::lock_guard _sl(thread->mutex());
     sp<IAfEffectModule> effect = thread->getEffect_l(sessionId, effectId);
     thread->setEffectSuspended_l(&effect->desc().type, suspended, sessionId);
 }
 
 
-// moveEffectChain_l must be called with both srcThread and dstThread mLocks held
-status_t AudioFlinger::moveEffectChain_l(audio_session_t sessionId,
+// moveEffectChain_ll must be called with the AudioFlinger::mutex()
+// and both srcThread and dstThread mutex()s held
+status_t AudioFlinger::moveEffectChain_ll(audio_session_t sessionId,
         IAfPlaybackThread* srcThread, IAfPlaybackThread* dstThread)
-NO_THREAD_SAFETY_ANALYSIS // requires srcThread and dstThread locks
 {
-    ALOGV("moveEffectChain_l() session %d from thread %p to thread %p",
-            sessionId, srcThread, dstThread);
+    ALOGV("%s: session %d from thread %p to thread %p",
+            __func__, sessionId, srcThread, dstThread);
 
     sp<IAfEffectChain> chain = srcThread->getEffectChain_l(sessionId);
     if (chain == 0) {
-        ALOGW("moveEffectChain_l() effect chain for session %d not on source thread %p",
-                sessionId, srcThread);
+        ALOGW("%s: effect chain for session %d not on source thread %p",
+                __func__, sessionId, srcThread);
         return INVALID_OPERATION;
     }
 
     // Check whether the destination thread and all effects in the chain are compatible
     if (!chain->isCompatibleWithThread_l(dstThread)) {
-        ALOGW("moveEffectChain_l() effect chain failed because"
+        ALOGW("%s: effect chain failed because"
                 " destination thread %p is not compatible with effects in the chain",
-                dstThread);
+                __func__, dstThread);
         return INVALID_OPERATION;
     }
 
@@ -4541,7 +4360,7 @@
             effect = chain->getEffectFromId_l(0)) {
         srcThread->removeEffect_l(effect);
         removed.add(effect);
-        status = dstThread->addEffect_l(effect);
+        status = dstThread->addEffect_ll(effect);
         if (status != NO_ERROR) {
             errorString = StringPrintf(
                     "cannot add effect %p to destination thread", effect.get());
@@ -4567,7 +4386,7 @@
         for (const auto& effect : removed) {
             dstThread->removeEffect_l(effect); // Note: Depending on error location, the last
                                                // effect may not have been placed on dstThread.
-            if (srcThread->addEffect_l(effect) == NO_ERROR) {
+            if (srcThread->addEffect_ll(effect) == NO_ERROR) {
                 ++restored;
                 if (dstChain == nullptr) {
                     dstChain = effect->getCallback()->chain().promote();
@@ -4583,7 +4402,7 @@
         // If we do not take the dstChain lock, it is possible that processing is ongoing
         // while we are starting the effect.  This can cause glitches with volume,
         // see b/202360137.
-        dstChain->lock();
+        dstChain->mutex().lock();
         for (const auto& effect : removed) {
             if (effect->state() == IAfEffectModule::ACTIVE ||
                     effect->state() == IAfEffectModule::STOPPING) {
@@ -4591,7 +4410,7 @@
                 effect->start();
             }
         }
-        dstChain->unlock();
+        dstChain->mutex().unlock();
     }
 
     if (status != NO_ERROR) {
@@ -4615,13 +4434,12 @@
         const sp<IAfPlaybackThread>& dstThread, sp<IAfPlaybackThread>* srcThread)
 {
     status_t status = NO_ERROR;
-    Mutex::Autolock _l(mLock);
+    audio_utils::lock_guard _l(mutex());
     const sp<IAfThreadBase> threadBase = getEffectThread_l(AUDIO_SESSION_OUTPUT_MIX, EffectId);
     const sp<IAfPlaybackThread> thread = threadBase ? threadBase->asIAfPlaybackThread() : nullptr;
 
     if (EffectId != 0 && thread != 0 && dstThread != thread.get()) {
-        Mutex::Autolock _dl(dstThread->mutex());
-        Mutex::Autolock _sl(thread->mutex());
+        audio_utils::scoped_lock _ll(dstThread->mutex(), thread->mutex());
         sp<IAfEffectChain> srcChain = thread->getEffectChain_l(AUDIO_SESSION_OUTPUT_MIX);
         sp<IAfEffectChain> dstChain;
         if (srcChain == 0) {
@@ -4633,16 +4451,16 @@
             return INVALID_OPERATION;
         }
         thread->removeEffect_l(effect);
-        status = dstThread->addEffect_l(effect);
+        status = dstThread->addEffect_ll(effect);
         if (status != NO_ERROR) {
-            thread->addEffect_l(effect);
+            thread->addEffect_ll(effect);
             status = INVALID_OPERATION;
             goto Exit;
         }
 
         dstChain = effect->getCallback()->chain().promote();
         if (dstChain == 0) {
-            thread->addEffect_l(effect);
+            thread->addEffect_ll(effect);
             status = INVALID_OPERATION;
         }
 
@@ -4660,8 +4478,7 @@
     return status;
 }
 
-bool AudioFlinger::isNonOffloadableGlobalEffectEnabled_l()
-NO_THREAD_SAFETY_ANALYSIS  // thread lock for getEffectChain_l.
+bool AudioFlinger::isNonOffloadableGlobalEffectEnabled_l() const
 {
     if (mGlobalEffectEnableTime != 0 &&
             ((systemTime() - mGlobalEffectEnableTime) < kMinGlobalEffectEnabletimeNs)) {
@@ -4680,7 +4497,7 @@
 
 void AudioFlinger::onNonOffloadableGlobalEffectEnable()
 {
-    Mutex::Autolock _l(mLock);
+    audio_utils::lock_guard _l(mutex());
 
     mGlobalEffectEnableTime = systemTime();
 
@@ -4725,7 +4542,7 @@
 
 bool AudioFlinger::updateOrphanEffectChains(const sp<IAfEffectModule>& effect)
 {
-    Mutex::Autolock _l(mLock);
+    audio_utils::lock_guard _l(mutex());
     audio_session_t session = effect->sessionId();
     ssize_t index = mOrphanEffectChains.indexOfKey(session);
     ALOGV("updateOrphanEffectChains session %d index %zd", session, index);
@@ -4740,6 +4557,55 @@
     return false;
 }
 
+// ----------------------------------------------------------------------------
+// from PatchPanel
+
+/* List connected audio ports and their attributes */
+status_t AudioFlinger::listAudioPorts(unsigned int* num_ports,
+        struct audio_port* ports) const
+{
+    audio_utils::lock_guard _l(mutex());
+    return mPatchPanel->listAudioPorts_l(num_ports, ports);
+}
+
+/* Get supported attributes for a given audio port */
+status_t AudioFlinger::getAudioPort(struct audio_port_v7* port) const {
+    const status_t status = AudioValidator::validateAudioPort(*port);
+    if (status != NO_ERROR) {
+        return status;
+    }
+
+    audio_utils::lock_guard _l(mutex());
+    return mPatchPanel->getAudioPort_l(port);
+}
+
+/* Connect a patch between several source and sink ports */
+status_t AudioFlinger::createAudioPatch(
+        const struct audio_patch* patch, audio_patch_handle_t* handle)
+{
+    const status_t status = AudioValidator::validateAudioPatch(*patch);
+    if (status != NO_ERROR) {
+        return status;
+    }
+
+    audio_utils::lock_guard _l(mutex());
+    return mPatchPanel->createAudioPatch_l(patch, handle);
+}
+
+/* Disconnect a patch */
+status_t AudioFlinger::releaseAudioPatch(audio_patch_handle_t handle)
+{
+    audio_utils::lock_guard _l(mutex());
+    return mPatchPanel->releaseAudioPatch_l(handle);
+}
+
+/* List connected audio ports and they attributes */
+status_t AudioFlinger::listAudioPatches(
+        unsigned int* num_patches, struct audio_patch* patches) const
+{
+    audio_utils::lock_guard _l(mutex());
+    return mPatchPanel->listAudioPatches_l(num_patches, patches);
+}
 
 // ----------------------------------------------------------------------------
 
diff --git a/services/audioflinger/AudioFlinger.h b/services/audioflinger/AudioFlinger.h
index 9bc0ff9..2c34144 100644
--- a/services/audioflinger/AudioFlinger.h
+++ b/services/audioflinger/AudioFlinger.h
@@ -15,359 +15,395 @@
 ** limitations under the License.
 */
 
-#ifndef ANDROID_AUDIO_FLINGER_H
-#define ANDROID_AUDIO_FLINGER_H
+#pragma once
 
-#include "Configuration.h"
-#include <atomic>
-#include <mutex>
-#include <chrono>
-#include <deque>
-#include <map>
-#include <numeric>
-#include <optional>
-#include <set>
-#include <string>
-#include <vector>
-#include <stdint.h>
-#include <sys/types.h>
-#include <limits.h>
-
-#include <android/media/BnAudioTrack.h>
-#include <android/media/IAudioFlingerClient.h>
-#include <android/media/IAudioTrackCallback.h>
-#include <android/os/BnExternalVibrationController.h>
-#include <android/content/AttributionSourceState.h>
-
-
-#include <android-base/macros.h>
-#include <cutils/atomic.h>
-#include <cutils/compiler.h>
-
-#include <cutils/properties.h>
-#include <media/IAudioFlinger.h>
-#include <media/AudioSystem.h>
-#include <media/AudioTrack.h>
-#include <media/MmapStreamInterface.h>
-#include <media/MmapStreamCallback.h>
-
-#include <utils/Errors.h>
-#include <utils/threads.h>
-#include <utils/SortedVector.h>
-#include <utils/TypeHelpers.h>
-#include <utils/Vector.h>
-
-#include <binder/AppOpsManager.h>
-#include <binder/BinderService.h>
-#include <binder/IAppOpsCallback.h>
-#include <binder/MemoryDealer.h>
-
-#include <system/audio.h>
-#include <system/audio_policy.h>
-
-#include <media/audiohal/EffectBufferHalInterface.h>
-#include <media/audiohal/StreamHalInterface.h>
-#include <media/AudioBufferProvider.h>
-#include <media/AudioContainers.h>
-#include <media/AudioDeviceTypeAddr.h>
-#include <media/AudioMixer.h>
-#include <media/DeviceDescriptorBase.h>
-#include <media/ExtendedAudioBufferProvider.h>
-#include <media/VolumeShaper.h>
-#include <mediautils/ServiceUtilities.h>
-#include <mediautils/SharedMemoryAllocator.h>
-#include <mediautils/Synchronization.h>
-#include <mediautils/ThreadSnapshot.h>
-
-#include <afutils/AllocatorFactory.h>
-#include <afutils/AudioWatchdog.h>
-#include <afutils/NBAIO_Tee.h>
-
-#include <audio_utils/clock.h>
-#include <audio_utils/FdToString.h>
-#include <audio_utils/LinearMap.h>
-#include <audio_utils/MelAggregator.h>
-#include <audio_utils/MelProcessor.h>
-#include <audio_utils/SimpleLog.h>
-#include <audio_utils/TimestampVerifier.h>
-
-#include <sounddose/SoundDoseManager.h>
-#include <timing/MonotonicFrameCounter.h>
-#include <timing/SyncEvent.h>
-#include <timing/SynchronizedRecordState.h>
-
-#include <datapath/AudioHwDevice.h>
-#include <datapath/AudioStreamIn.h>
-#include <datapath/AudioStreamOut.h>
-#include <datapath/SpdifStreamOut.h>
-#include <datapath/ThreadMetrics.h>
-#include <datapath/TrackMetrics.h>
-#include <datapath/VolumeInterface.h>
-#include <fastpath/FastCapture.h>
-#include <fastpath/FastMixer.h>
-#include <media/nbaio/NBAIO.h>
-
-#include <android/os/IPowerManager.h>
-
-#include <media/nblog/NBLog.h>
-#include <private/media/AudioEffectShared.h>
-#include <private/media/AudioTrackShared.h>
-
-#include <vibrator/ExternalVibration.h>
-#include <vibrator/ExternalVibrationUtils.h>
-
-#include "android/media/BnAudioRecord.h"
-#include "android/media/BnEffect.h"
-
+// Classes and interfaces directly used.
 #include "Client.h"
-#include "ResamplerBufferProvider.h"
-
-// include AudioFlinger component interfaces
-#include "IAfPatchPanel.h"  // this should be listed before other IAf* interfaces.
+#include "DeviceEffectManager.h"
+#include "EffectConfiguration.h"
 #include "IAfEffect.h"
+#include "IAfPatchPanel.h"
 #include "IAfThread.h"
 #include "IAfTrack.h"
-
-// Classes that depend on IAf* interfaces but are not cross-dependent.
-#include "PatchCommandThread.h"
-#include "DeviceEffectManager.h"
 #include "MelReporter.h"
+#include "PatchCommandThread.h"
+
+// External classes
+#include <audio_utils/mutex.h>
+#include <audio_utils/FdToString.h>
+#include <audio_utils/SimpleLog.h>
+#include <media/IAudioFlinger.h>
+#include <media/MediaMetricsItem.h>
+#include <media/audiohal/DevicesFactoryHalInterface.h>
+#include <mediautils/ServiceUtilities.h>
+#include <mediautils/Synchronization.h>
+
+// not needed with the includes above, added to prevent transitive include dependency.
+#include <utils/KeyedVector.h>
+#include <utils/String16.h>
+#include <atomic>
+#include <functional>
+#include <map>
+#include <optional>
+#include <set>
 
 namespace android {
 
-class AudioMixer;
-class AudioBuffer;
-class AudioResampler;
-class DeviceHalInterface;
-class DevicesFactoryHalCallback;
-class DevicesFactoryHalInterface;
-class EffectsFactoryHalInterface;
-class FastMixer;
-class IAudioManager;
-class PassthruBufferProvider;
-class ServerProxy;
-
-// ----------------------------------------------------------------------------
-
-static const nsecs_t kDefaultStandbyTimeInNsecs = seconds(3);
-
-#define INCLUDING_FROM_AUDIOFLINGER_H
-
-using android::content::AttributionSourceState;
-
-struct stream_type_t {
-    float volume = 1.f;
-    bool mute = false;
-};
-
-class AudioFlinger : public AudioFlingerServerAdapter::Delegate
+class AudioFlinger
+    : public AudioFlingerServerAdapter::Delegate  // IAudioFlinger client interface
+    , public IAfClientCallback
+    , public IAfDeviceEffectManagerCallback
+    , public IAfMelReporterCallback
+    , public IAfPatchPanelCallback
+    , public IAfThreadCallback
 {
     friend class sp<AudioFlinger>;
-    friend class Client; // removeClient_l();
-    friend class DeviceEffectManager;
-    friend class DeviceEffectManagerCallback;
-    friend class MelReporter;
-    friend class PatchPanel;
-    // TODO(b/291012167) replace the Thread friends with an interface.
-    friend class DirectOutputThread;
-    friend class MixerThread;
-    friend class MmapPlaybackThread;
-    friend class MmapThread;
-    friend class PlaybackThread;
-    friend class RecordThread;
-    friend class ThreadBase;
-
 public:
     static void instantiate() ANDROID_API;
 
-    static AttributionSourceState checkAttributionSourcePackage(
-        const AttributionSourceState& attributionSource);
+private:
 
-    status_t dump(int fd, const Vector<String16>& args) override;
+    // ---- begin IAudioFlinger interface
 
-    // IAudioFlinger interface, in binder opcode order
+    status_t dump(int fd, const Vector<String16>& args) final EXCLUDES_AudioFlinger_Mutex;
+
     status_t createTrack(const media::CreateTrackRequest& input,
-                         media::CreateTrackResponse& output) override;
+            media::CreateTrackResponse& output) final EXCLUDES_AudioFlinger_Mutex;
 
     status_t createRecord(const media::CreateRecordRequest& input,
-                          media::CreateRecordResponse& output) override;
+            media::CreateRecordResponse& output) final EXCLUDES_AudioFlinger_Mutex;
 
-    virtual     uint32_t    sampleRate(audio_io_handle_t ioHandle) const;
-    virtual     audio_format_t format(audio_io_handle_t output) const;
-    virtual     size_t      frameCount(audio_io_handle_t ioHandle) const;
-    virtual     size_t      frameCountHAL(audio_io_handle_t ioHandle) const;
-    virtual     uint32_t    latency(audio_io_handle_t output) const;
+    uint32_t sampleRate(audio_io_handle_t ioHandle) const final EXCLUDES_AudioFlinger_Mutex;
+    audio_format_t format(audio_io_handle_t output) const final EXCLUDES_AudioFlinger_Mutex;
+    size_t frameCount(audio_io_handle_t ioHandle) const final EXCLUDES_AudioFlinger_Mutex;
+    size_t frameCountHAL(audio_io_handle_t ioHandle) const final EXCLUDES_AudioFlinger_Mutex;
+    uint32_t latency(audio_io_handle_t output) const final EXCLUDES_AudioFlinger_Mutex;
 
-    virtual     status_t    setMasterVolume(float value);
-    virtual     status_t    setMasterMute(bool muted);
-
-    virtual     float       masterVolume() const;
-    virtual     bool        masterMute() const;
+    status_t setMasterVolume(float value) final EXCLUDES_AudioFlinger_Mutex;
+    status_t setMasterMute(bool muted) final EXCLUDES_AudioFlinger_Mutex;
+    float masterVolume() const final EXCLUDES_AudioFlinger_Mutex;
+    bool masterMute() const final EXCLUDES_AudioFlinger_Mutex;
 
     // Balance value must be within -1.f (left only) to 1.f (right only) inclusive.
-                status_t    setMasterBalance(float balance) override;
-                status_t    getMasterBalance(float *balance) const override;
+    status_t setMasterBalance(float balance) final EXCLUDES_AudioFlinger_Mutex;
+    status_t getMasterBalance(float* balance) const final EXCLUDES_AudioFlinger_Mutex;
 
-    virtual     status_t    setStreamVolume(audio_stream_type_t stream, float value,
-                                            audio_io_handle_t output);
-    virtual     status_t    setStreamMute(audio_stream_type_t stream, bool muted);
+    status_t setStreamVolume(audio_stream_type_t stream, float value,
+            audio_io_handle_t output) final EXCLUDES_AudioFlinger_Mutex;
+    status_t setStreamMute(audio_stream_type_t stream, bool muted) final
+            EXCLUDES_AudioFlinger_Mutex;
 
-    virtual     float       streamVolume(audio_stream_type_t stream,
-                                         audio_io_handle_t output) const;
-    virtual     bool        streamMute(audio_stream_type_t stream) const;
+    float streamVolume(audio_stream_type_t stream,
+            audio_io_handle_t output) const final EXCLUDES_AudioFlinger_Mutex;
+    bool streamMute(audio_stream_type_t stream) const final EXCLUDES_AudioFlinger_Mutex;
 
-    virtual     status_t    setMode(audio_mode_t mode);
+    status_t setMode(audio_mode_t mode) final EXCLUDES_AudioFlinger_Mutex;
 
-    virtual     status_t    setMicMute(bool state);
-    virtual     bool        getMicMute() const;
+    status_t setMicMute(bool state) final EXCLUDES_AudioFlinger_Mutex;
+    bool getMicMute() const final EXCLUDES_AudioFlinger_Mutex;
 
-    virtual     void        setRecordSilenced(audio_port_handle_t portId, bool silenced);
+    void setRecordSilenced(audio_port_handle_t portId, bool silenced) final
+            EXCLUDES_AudioFlinger_Mutex;
 
-    virtual     status_t    setParameters(audio_io_handle_t ioHandle, const String8& keyValuePairs);
-    virtual     String8     getParameters(audio_io_handle_t ioHandle, const String8& keys) const;
+    status_t setParameters(audio_io_handle_t ioHandle, const String8& keyValuePairs) final
+            EXCLUDES_AudioFlinger_Mutex;
+    String8 getParameters(audio_io_handle_t ioHandle, const String8& keys) const final
+            EXCLUDES_AudioFlinger_Mutex;
 
-    virtual     void        registerClient(const sp<media::IAudioFlingerClient>& client);
+    void registerClient(const sp<media::IAudioFlingerClient>& client) final
+            EXCLUDES_AudioFlinger_Mutex;
+    size_t getInputBufferSize(uint32_t sampleRate, audio_format_t format,
+            audio_channel_mask_t channelMask) const final EXCLUDES_AudioFlinger_Mutex;
 
-    virtual     size_t      getInputBufferSize(uint32_t sampleRate, audio_format_t format,
-                                               audio_channel_mask_t channelMask) const;
+    status_t openOutput(const media::OpenOutputRequest& request,
+            media::OpenOutputResponse* response) final EXCLUDES_AudioFlinger_Mutex;
 
-    virtual status_t openOutput(const media::OpenOutputRequest& request,
-                                media::OpenOutputResponse* response);
+    audio_io_handle_t openDuplicateOutput(audio_io_handle_t output1,
+            audio_io_handle_t output2) final EXCLUDES_AudioFlinger_Mutex;
 
-    virtual audio_io_handle_t openDuplicateOutput(audio_io_handle_t output1,
-                                                  audio_io_handle_t output2);
+    status_t closeOutput(audio_io_handle_t output) final EXCLUDES_AudioFlinger_Mutex;
 
-    virtual status_t closeOutput(audio_io_handle_t output);
+    status_t suspendOutput(audio_io_handle_t output) final EXCLUDES_AudioFlinger_Mutex;
 
-    virtual status_t suspendOutput(audio_io_handle_t output);
+    status_t restoreOutput(audio_io_handle_t output) final EXCLUDES_AudioFlinger_Mutex;
 
-    virtual status_t restoreOutput(audio_io_handle_t output);
+    status_t openInput(const media::OpenInputRequest& request,
+            media::OpenInputResponse* response) final EXCLUDES_AudioFlinger_Mutex;
 
-    virtual status_t openInput(const media::OpenInputRequest& request,
-                               media::OpenInputResponse* response);
+    status_t closeInput(audio_io_handle_t input) final EXCLUDES_AudioFlinger_Mutex;
 
-    virtual status_t closeInput(audio_io_handle_t input);
+    status_t setVoiceVolume(float volume) final EXCLUDES_AudioFlinger_Mutex;
 
-    virtual status_t setVoiceVolume(float volume);
+    status_t getRenderPosition(uint32_t* halFrames, uint32_t* dspFrames,
+            audio_io_handle_t output) const final EXCLUDES_AudioFlinger_Mutex;
 
-    virtual status_t getRenderPosition(uint32_t *halFrames, uint32_t *dspFrames,
-                                       audio_io_handle_t output) const;
-
-    virtual uint32_t getInputFramesLost(audio_io_handle_t ioHandle) const;
+    uint32_t getInputFramesLost(audio_io_handle_t ioHandle) const final
+            EXCLUDES_AudioFlinger_Mutex;
 
     // This is the binder API.  For the internal API see nextUniqueId().
-    virtual audio_unique_id_t newAudioUniqueId(audio_unique_id_use_t use);
+    audio_unique_id_t newAudioUniqueId(audio_unique_id_use_t use) final
+            EXCLUDES_AudioFlinger_Mutex;
 
-    void acquireAudioSessionId(audio_session_t audioSession, pid_t pid, uid_t uid) override;
+    void acquireAudioSessionId(audio_session_t audioSession, pid_t pid, uid_t uid) final
+            EXCLUDES_AudioFlinger_Mutex;
 
-    virtual void releaseAudioSessionId(audio_session_t audioSession, pid_t pid);
+    void releaseAudioSessionId(audio_session_t audioSession, pid_t pid) final
+            EXCLUDES_AudioFlinger_Mutex;
 
-    virtual status_t queryNumberEffects(uint32_t *numEffects) const;
+    status_t queryNumberEffects(uint32_t* numEffects) const final EXCLUDES_AudioFlinger_Mutex;
 
-    virtual status_t queryEffect(uint32_t index, effect_descriptor_t *descriptor) const;
+    status_t queryEffect(uint32_t index, effect_descriptor_t* descriptor) const final
+            EXCLUDES_AudioFlinger_Mutex;
 
-    virtual status_t getEffectDescriptor(const effect_uuid_t *pUuid,
-                                         const effect_uuid_t *pTypeUuid,
-                                         uint32_t preferredTypeFlag,
-                                         effect_descriptor_t *descriptor) const;
+    status_t getEffectDescriptor(const effect_uuid_t* pUuid,
+            const effect_uuid_t* pTypeUuid,
+            uint32_t preferredTypeFlag,
+            effect_descriptor_t* descriptor) const final EXCLUDES_AudioFlinger_Mutex;
 
-    virtual status_t createEffect(const media::CreateEffectRequest& request,
-                                  media::CreateEffectResponse* response);
+    status_t createEffect(const media::CreateEffectRequest& request,
+            media::CreateEffectResponse* response) final EXCLUDES_AudioFlinger_Mutex;
 
-    virtual status_t moveEffects(audio_session_t sessionId, audio_io_handle_t srcOutput,
-                        audio_io_handle_t dstOutput);
+    status_t moveEffects(audio_session_t sessionId, audio_io_handle_t srcOutput,
+            audio_io_handle_t dstOutput) final EXCLUDES_AudioFlinger_Mutex;
 
-            void setEffectSuspended(int effectId,
-                                    audio_session_t sessionId,
-                                    bool suspended) override;
+    void setEffectSuspended(int effectId,
+            audio_session_t sessionId,
+            bool suspended) final EXCLUDES_AudioFlinger_Mutex;
 
-    virtual audio_module_handle_t loadHwModule(const char *name);
+    audio_module_handle_t loadHwModule(const char* name) final EXCLUDES_AudioFlinger_Mutex;
 
-    virtual uint32_t getPrimaryOutputSamplingRate();
-    virtual size_t getPrimaryOutputFrameCount();
+    uint32_t getPrimaryOutputSamplingRate() const final EXCLUDES_AudioFlinger_Mutex;
+    size_t getPrimaryOutputFrameCount() const final EXCLUDES_AudioFlinger_Mutex;
 
-    virtual status_t setLowRamDevice(bool isLowRamDevice, int64_t totalMemory) override;
-
-    /* List available audio ports and their attributes */
-    virtual status_t listAudioPorts(unsigned int *num_ports,
-                                    struct audio_port *ports);
+    status_t setLowRamDevice(bool isLowRamDevice, int64_t totalMemory) final
+            EXCLUDES_AudioFlinger_Mutex;
 
     /* Get attributes for a given audio port */
-    virtual status_t getAudioPort(struct audio_port_v7 *port);
+    status_t getAudioPort(struct audio_port_v7* port) const final EXCLUDES_AudioFlinger_Mutex;
 
     /* Create an audio patch between several source and sink ports */
-    virtual status_t createAudioPatch(const struct audio_patch *patch,
-                                       audio_patch_handle_t *handle);
+    status_t createAudioPatch(const struct audio_patch *patch,
+            audio_patch_handle_t* handle) final EXCLUDES_AudioFlinger_Mutex;
 
     /* Release an audio patch */
-    virtual status_t releaseAudioPatch(audio_patch_handle_t handle);
+    status_t releaseAudioPatch(audio_patch_handle_t handle) final EXCLUDES_AudioFlinger_Mutex;
 
     /* List existing audio patches */
-    virtual status_t listAudioPatches(unsigned int *num_patches,
-                                      struct audio_patch *patches);
+    status_t listAudioPatches(unsigned int* num_patches,
+            struct audio_patch* patches) const final EXCLUDES_AudioFlinger_Mutex;
 
     /* Set audio port configuration */
-    virtual status_t setAudioPortConfig(const struct audio_port_config *config);
+    status_t setAudioPortConfig(const struct audio_port_config* config) final
+            EXCLUDES_AudioFlinger_Mutex;
 
     /* Get the HW synchronization source used for an audio session */
-    virtual audio_hw_sync_t getAudioHwSyncForSession(audio_session_t sessionId);
+    audio_hw_sync_t getAudioHwSyncForSession(audio_session_t sessionId) final
+            EXCLUDES_AudioFlinger_Mutex;
 
     /* Indicate JAVA services are ready (scheduling, power management ...) */
-    virtual status_t systemReady();
-    virtual status_t audioPolicyReady() { mAudioPolicyReady.store(true); return NO_ERROR; }
-            bool isAudioPolicyReady() const { return mAudioPolicyReady.load(); }
+    status_t systemReady() final EXCLUDES_AudioFlinger_Mutex;
+    status_t audioPolicyReady() final { mAudioPolicyReady.store(true); return NO_ERROR; }
 
+    status_t getMicrophones(std::vector<media::MicrophoneInfoFw>* microphones) const final
+            EXCLUDES_AudioFlinger_Mutex;
 
-    virtual status_t getMicrophones(std::vector<media::MicrophoneInfoFw> *microphones);
+    status_t setAudioHalPids(const std::vector<pid_t>& pids) final
+            EXCLUDES_AudioFlinger_Mutex;
 
-    virtual status_t setAudioHalPids(const std::vector<pid_t>& pids);
+    status_t setVibratorInfos(const std::vector<media::AudioVibratorInfo>& vibratorInfos) final
+            EXCLUDES_AudioFlinger_Mutex;
 
-    virtual status_t setVibratorInfos(const std::vector<media::AudioVibratorInfo>& vibratorInfos);
+    status_t updateSecondaryOutputs(
+            const TrackSecondaryOutputsMap& trackSecondaryOutputs) final
+            EXCLUDES_AudioFlinger_Mutex;
 
-    virtual status_t updateSecondaryOutputs(
-            const TrackSecondaryOutputsMap& trackSecondaryOutputs);
-
-    virtual status_t getMmapPolicyInfos(
+    status_t getMmapPolicyInfos(
             media::audio::common::AudioMMapPolicyType policyType,
-            std::vector<media::audio::common::AudioMMapPolicyInfo> *policyInfos);
+            std::vector<media::audio::common::AudioMMapPolicyInfo>* policyInfos) final
+            EXCLUDES_AudioFlinger_Mutex;
 
-    virtual int32_t getAAudioMixerBurstCount();
+    int32_t getAAudioMixerBurstCount() const final EXCLUDES_AudioFlinger_Mutex;
 
-    virtual int32_t getAAudioHardwareBurstMinUsec();
+    int32_t getAAudioHardwareBurstMinUsec() const final EXCLUDES_AudioFlinger_Mutex;
 
-    virtual status_t setDeviceConnectedState(const struct audio_port_v7 *port,
-                                             media::DeviceConnectedState state);
+    status_t setDeviceConnectedState(const struct audio_port_v7* port,
+            media::DeviceConnectedState state) final EXCLUDES_AudioFlinger_Mutex;
 
-    virtual status_t setSimulateDeviceConnections(bool enabled);
+    status_t setSimulateDeviceConnections(bool enabled) final EXCLUDES_AudioFlinger_Mutex;
 
-    virtual status_t setRequestedLatencyMode(
-            audio_io_handle_t output, audio_latency_mode_t mode);
+    status_t setRequestedLatencyMode(
+            audio_io_handle_t output, audio_latency_mode_t mode) final
+            EXCLUDES_AudioFlinger_Mutex;
 
-    virtual status_t getSupportedLatencyModes(audio_io_handle_t output,
-            std::vector<audio_latency_mode_t>* modes);
+    status_t getSupportedLatencyModes(audio_io_handle_t output,
+            std::vector<audio_latency_mode_t>* modes) const final EXCLUDES_AudioFlinger_Mutex;
 
-    virtual status_t setBluetoothVariableLatencyEnabled(bool enabled);
+    status_t setBluetoothVariableLatencyEnabled(bool enabled) final EXCLUDES_AudioFlinger_Mutex;
 
-    virtual status_t isBluetoothVariableLatencyEnabled(bool* enabled);
+    status_t isBluetoothVariableLatencyEnabled(bool* enabled) const final
+            EXCLUDES_AudioFlinger_Mutex;
 
-    virtual status_t supportsBluetoothVariableLatency(bool* support);
+    status_t supportsBluetoothVariableLatency(bool* support) const final
+            EXCLUDES_AudioFlinger_Mutex;
 
-    virtual status_t getSoundDoseInterface(const sp<media::ISoundDoseCallback>& callback,
-                                           sp<media::ISoundDose>* soundDose);
+    status_t getSoundDoseInterface(const sp<media::ISoundDoseCallback>& callback,
+            sp<media::ISoundDose>* soundDose) const final EXCLUDES_AudioFlinger_Mutex;
 
-    status_t invalidateTracks(const std::vector<audio_port_handle_t>& portIds) override;
+    status_t invalidateTracks(const std::vector<audio_port_handle_t>& portIds) final
+            EXCLUDES_AudioFlinger_Mutex;
 
-    virtual status_t getAudioPolicyConfig(media::AudioPolicyConfig* config);
+    status_t getAudioPolicyConfig(media::AudioPolicyConfig* config) final
+            EXCLUDES_AudioFlinger_Mutex;
 
     status_t onTransactWrapper(TransactionCode code, const Parcel& data, uint32_t flags,
-        const std::function<status_t()>& delegate) override;
+            const std::function<status_t()>& delegate) final EXCLUDES_AudioFlinger_Mutex;
 
-    // end of IAudioFlinger interface
+    // ---- end of IAudioFlinger interface
 
-    sp<NBLog::Writer>   newWriter_l(size_t size, const char *name);
-    void                unregisterWriter(const sp<NBLog::Writer>& writer);
+    // ---- begin IAfClientCallback interface
+
+    audio_utils::mutex& clientMutex() const final
+            RETURN_CAPABILITY(audio_utils::AudioFlinger_ClientMutex) {
+        return mClientMutex;
+    }
+    void removeClient_l(pid_t pid) REQUIRES(clientMutex()) final;
+    void removeNotificationClient(pid_t pid) final EXCLUDES_AudioFlinger_Mutex;
+    status_t moveAuxEffectToIo(
+            int effectId,
+            const sp<IAfPlaybackThread>& dstThread,
+            sp<IAfPlaybackThread>* srcThread) final EXCLUDES_AudioFlinger_Mutex;
+
+    // ---- end of IAfClientCallback interface
+
+    // ---- begin IAfDeviceEffectManagerCallback interface
+
+    // also used by IAfThreadCallback
+    bool isAudioPolicyReady() const final { return mAudioPolicyReady.load(); }
+    // below also used by IAfMelReporterCallback, IAfPatchPanelCallback
+    const sp<PatchCommandThread>& getPatchCommandThread() final { return mPatchCommandThread; }
+    status_t addEffectToHal(
+            const struct audio_port_config* device, const sp<EffectHalInterface>& effect) final
+            EXCLUDES_AudioFlinger_HardwareMutex;
+    status_t removeEffectFromHal(
+            const struct audio_port_config* device, const sp<EffectHalInterface>& effect) final
+            EXCLUDES_AudioFlinger_HardwareMutex;
+
+    // ---- end of IAfDeviceEffectManagerCallback interface
+
+    // ---- begin IAfMelReporterCallback interface
+
+    // below also used by IAfThreadCallback
+    audio_utils::mutex& mutex() const final
+            RETURN_CAPABILITY(audio_utils::AudioFlinger_Mutex)
+            EXCLUDES_BELOW_AudioFlinger_Mutex { return mMutex; }
+    sp<IAfThreadBase> checkOutputThread_l(audio_io_handle_t ioHandle) const final
+            REQUIRES(mutex());
+
+    // ---- end of IAfMelReporterCallback interface
+
+    // ---- begin IAfPatchPanelCallback interface
+
+    void closeThreadInternal_l(const sp<IAfPlaybackThread>& thread) final REQUIRES(mutex());
+    void closeThreadInternal_l(const sp<IAfRecordThread>& thread) final REQUIRES(mutex());
+    // return thread associated with primary hardware device, or NULL
+    IAfPlaybackThread* primaryPlaybackThread_l() const final  REQUIRES(mutex());
+    IAfPlaybackThread* checkPlaybackThread_l(audio_io_handle_t output) const final
+            REQUIRES(mutex());
+    IAfRecordThread* checkRecordThread_l(audio_io_handle_t input) const final  REQUIRES(mutex());
+    IAfMmapThread* checkMmapThread_l(audio_io_handle_t io) const final REQUIRES(mutex());
+    sp<IAfThreadBase> openInput_l(audio_module_handle_t module,
+            audio_io_handle_t* input,
+            audio_config_t* config,
+            audio_devices_t device,
+            const char* address,
+            audio_source_t source,
+            audio_input_flags_t flags,
+            audio_devices_t outputDevice,
+            const String8& outputDeviceAddress) final REQUIRES(mutex());
+    sp<IAfThreadBase> openOutput_l(audio_module_handle_t module,
+            audio_io_handle_t* output,
+            audio_config_t* halConfig,
+            audio_config_base_t* mixerConfig,
+            audio_devices_t deviceType,
+            const String8& address,
+            audio_output_flags_t flags) final REQUIRES(mutex());
+    const DefaultKeyedVector<audio_module_handle_t, AudioHwDevice*>&
+            getAudioHwDevs_l() const final REQUIRES(mutex()) { return mAudioHwDevs; }
+    void updateDownStreamPatches_l(const struct audio_patch* patch,
+            const std::set<audio_io_handle_t>& streams) final REQUIRES(mutex());
+    void updateOutDevicesForRecordThreads_l(const DeviceDescriptorBaseVector& devices) final
+            REQUIRES(mutex());
+
+    // ---- end of IAfPatchPanelCallback interface
+
+    // ----- begin IAfThreadCallback interface
+
+    bool isNonOffloadableGlobalEffectEnabled_l() const final REQUIRES(mutex());
+    bool btNrecIsOff() const final { return mBtNrecIsOff.load(); }
+    float masterVolume_l() const final REQUIRES(mutex());
+    bool masterMute_l() const final REQUIRES(mutex());
+    float getMasterBalance_l() const REQUIRES(mutex());
+    // no range check, AudioFlinger::mutex() held
+    bool streamMute_l(audio_stream_type_t stream) const final REQUIRES(mutex()) {
+        return mStreamTypes[stream].mute;
+    }
+    audio_mode_t getMode() const final { return mMode; }
+    bool isLowRamDevice() const final { return mIsLowRamDevice; }
+    uint32_t getScreenState() const final { return mScreenState; }
+
+    std::optional<media::AudioVibratorInfo> getDefaultVibratorInfo_l() const final
+            REQUIRES(mutex());
+    const sp<IAfPatchPanel>& getPatchPanel() const final { return mPatchPanel; }
+    const sp<MelReporter>& getMelReporter() const final { return mMelReporter; }
+    const sp<EffectsFactoryHalInterface>& getEffectsFactoryHal() const final {
+        return mEffectsFactoryHal;
+    }
+    sp<IAudioManager> getOrCreateAudioManager() final;
+
+    // Called when the last effect handle on an effect instance is removed. If this
+    // effect belongs to an effect chain in mOrphanEffectChains, the chain is updated
+    // and removed from mOrphanEffectChains if it does not contain any effect.
+    // Return true if the effect was found in mOrphanEffectChains, false otherwise.
+    bool updateOrphanEffectChains(const sp<IAfEffectModule>& effect) final
+            EXCLUDES_AudioFlinger_Mutex;
+
+    status_t moveEffectChain_ll(audio_session_t sessionId,
+            IAfPlaybackThread* srcThread, IAfPlaybackThread* dstThread) final
+            REQUIRES(mutex(), audio_utils::ThreadBase_Mutex);
+
+    // This is a helper that is called during incoming binder calls.
+    // Requests media.log to start merging log buffers
+    void requestLogMerge() final;
+    sp<NBLog::Writer> newWriter_l(size_t size, const char *name) final REQUIRES(mutex());
+    void unregisterWriter(const sp<NBLog::Writer>& writer) final;
+
+    sp<audioflinger::SyncEvent> createSyncEvent(AudioSystem::sync_event_t type,
+            audio_session_t triggerSession,
+            audio_session_t listenerSession,
+            const audioflinger::SyncEventCallback& callBack,
+            const wp<IAfTrackBase>& cookie) final EXCLUDES_AudioFlinger_Mutex;
+
+    void ioConfigChanged(audio_io_config_event_t event,
+            const sp<AudioIoDescriptor>& ioDesc,
+            pid_t pid = 0) final EXCLUDES_AudioFlinger_ClientMutex;
+    void onNonOffloadableGlobalEffectEnable() final EXCLUDES_AudioFlinger_Mutex;
+    void onSupportedLatencyModesChanged(
+            audio_io_handle_t output, const std::vector<audio_latency_mode_t>& modes) final
+            EXCLUDES_AudioFlinger_ClientMutex;
+
+    // ---- end of IAfThreadCallback interface
+
+    /* List available audio ports and their attributes */
+    status_t listAudioPorts(unsigned int* num_ports, struct audio_port* ports) const
+            EXCLUDES_AudioFlinger_Mutex;
+
     sp<EffectsFactoryHalInterface> getEffectsFactory();
 
+public:
+    // TODO(b/292281786): Remove this when Oboeservice can get access to
+    // openMmapStream through an IAudioFlinger handle directly.
+    static inline std::atomic<AudioFlinger*> gAudioFlinger = nullptr;
+
     status_t openMmapStream(MmapStreamInterface::stream_direction_t direction,
                             const audio_attributes_t *attr,
                             audio_config_base_t *config,
@@ -376,22 +412,7 @@
                             audio_session_t *sessionId,
                             const sp<MmapStreamCallback>& callback,
                             sp<MmapStreamInterface>& interface,
-                            audio_port_handle_t *handle);
-
-    static os::HapticScale onExternalVibrationStart(
-        const sp<os::ExternalVibration>& externalVibration);
-    static void onExternalVibrationStop(const sp<os::ExternalVibration>& externalVibration);
-
-    status_t addEffectToHal(
-            const struct audio_port_config *device, const sp<EffectHalInterface>& effect);
-    status_t removeEffectFromHal(
-            const struct audio_port_config *device, const sp<EffectHalInterface>& effect);
-
-    void updateDownStreamPatches_l(const struct audio_patch *patch,
-                                   const std::set<audio_io_handle_t>& streams);
-
-    std::optional<media::AudioVibratorInfo> getDefaultVibratorInfo_l();
-
+            audio_port_handle_t *handle) EXCLUDES_AudioFlinger_Mutex;
 private:
     // FIXME The 400 is temporarily too high until a leak of writers in media.log is fixed.
     static const size_t kLogMemorySize = 400 * 1024;
@@ -399,130 +420,33 @@
     // When a log writer is unregistered, it is done lazily so that media.log can continue to see it
     // for as long as possible.  The memory is only freed when it is needed for another log writer.
     Vector< sp<NBLog::Writer> > mUnregisteredWriters;
-    Mutex               mUnregisteredWritersLock;
-
-public:
-    // Life cycle of gAudioFlinger and AudioFlinger:
-    //
-    // AudioFlinger is created once and survives until audioserver crashes
-    // irrespective of sp<> and wp<> as it is refcounted by ServiceManager and we
-    // don't issue a ServiceManager::tryUnregisterService().
-    //
-    // gAudioFlinger is an atomic pointer set on AudioFlinger::onFirstRef().
-    // After this is set, it is safe to obtain a wp<> or sp<> from it as the
-    // underlying object does not go away.
-    //
-    // Note: For most inner classes, it is acceptable to hold a reference to the outer
-    // AudioFlinger instance as creation requires AudioFlinger to exist in the first place.
-    //
-    // An atomic here ensures underlying writes have completed before setting
-    // the pointer. Access by memory_order_seq_cst.
-    //
-
-    static inline std::atomic<AudioFlinger *> gAudioFlinger = nullptr;
-
-    sp<audioflinger::SyncEvent> createSyncEvent(AudioSystem::sync_event_t type,
-                                        audio_session_t triggerSession,
-                                        audio_session_t listenerSession,
-                                        const audioflinger::SyncEventCallback& callBack,
-                                        const wp<IAfTrackBase>& cookie);
-
-    bool        btNrecIsOff() const { return mBtNrecIsOff.load(); }
-
-    void             lock() ACQUIRE(mLock) { mLock.lock(); }
-    void             unlock() RELEASE(mLock) { mLock.unlock(); }
-
-private:
-
-               audio_mode_t getMode() const { return mMode; }
+    audio_utils::mutex& unregisteredWritersMutex() const { return mUnregisteredWritersMutex; }
+    mutable audio_utils::mutex mUnregisteredWritersMutex;
 
                             AudioFlinger() ANDROID_API;
-    virtual                 ~AudioFlinger();
+    ~AudioFlinger() override;
 
     // call in any IAudioFlinger method that accesses mPrimaryHardwareDev
-    status_t                initCheck() const { return mPrimaryHardwareDev == NULL ?
+    status_t initCheck() const { return mPrimaryHardwareDev == NULL ?
                                                         NO_INIT : NO_ERROR; }
 
     // RefBase
-    virtual     void        onFirstRef();
+    void onFirstRef() override;
 
     AudioHwDevice*          findSuitableHwDev_l(audio_module_handle_t module,
-                                                audio_devices_t deviceType);
-
-    // Set kEnableExtendedChannels to true to enable greater than stereo output
-    // for the MixerThread and device sink.  Number of channels allowed is
-    // FCC_2 <= channels <= AudioMixer::MAX_NUM_CHANNELS.
-    static const bool kEnableExtendedChannels = true;
-
-    // Returns true if channel mask is permitted for the PCM sink in the MixerThread
-    static inline bool isValidPcmSinkChannelMask(audio_channel_mask_t channelMask) {
-        switch (audio_channel_mask_get_representation(channelMask)) {
-        case AUDIO_CHANNEL_REPRESENTATION_POSITION: {
-            // Haptic channel mask is only applicable for channel position mask.
-            const uint32_t channelCount = audio_channel_count_from_out_mask(
-                    static_cast<audio_channel_mask_t>(channelMask & ~AUDIO_CHANNEL_HAPTIC_ALL));
-            const uint32_t maxChannelCount = kEnableExtendedChannels
-                    ? AudioMixer::MAX_NUM_CHANNELS : FCC_2;
-            if (channelCount < FCC_2 // mono is not supported at this time
-                    || channelCount > maxChannelCount) {
-                return false;
-            }
-            // check that channelMask is the "canonical" one we expect for the channelCount.
-            return audio_channel_position_mask_is_out_canonical(channelMask);
-            }
-        case AUDIO_CHANNEL_REPRESENTATION_INDEX:
-            if (kEnableExtendedChannels) {
-                const uint32_t channelCount = audio_channel_count_from_out_mask(channelMask);
-                if (channelCount >= FCC_2 // mono is not supported at this time
-                        && channelCount <= AudioMixer::MAX_NUM_CHANNELS) {
-                    return true;
-                }
-            }
-            return false;
-        default:
-            return false;
-        }
-    }
-
-    // Set kEnableExtendedPrecision to true to use extended precision in MixerThread
-    static const bool kEnableExtendedPrecision = true;
-
-    // Returns true if format is permitted for the PCM sink in the MixerThread
-    static inline bool isValidPcmSinkFormat(audio_format_t format) {
-        switch (format) {
-        case AUDIO_FORMAT_PCM_16_BIT:
-            return true;
-        case AUDIO_FORMAT_PCM_FLOAT:
-        case AUDIO_FORMAT_PCM_24_BIT_PACKED:
-        case AUDIO_FORMAT_PCM_32_BIT:
-        case AUDIO_FORMAT_PCM_8_24_BIT:
-            return kEnableExtendedPrecision;
-        default:
-            return false;
-        }
-    }
-
-    // standby delay for MIXER and DUPLICATING playback threads is read from property
-    // ro.audio.flinger_standbytime_ms or defaults to kDefaultStandbyTimeInNsecs
-    static nsecs_t          mStandbyTimeInNsecs;
+            audio_devices_t deviceType) REQUIRES(mutex());
 
     // incremented by 2 when screen state changes, bit 0 == 1 means "off"
-    // AudioFlinger::setParameters() updates, other threads read w/o lock
-    static uint32_t         mScreenState;
+    // AudioFlinger::setParameters() updates with mutex().
+    std::atomic_uint32_t mScreenState{};
 
-    // Internal dump utilities.
-    static const int kDumpLockTimeoutNs = 1 * NANOS_PER_SECOND;
-public:
-    // TODO(b/288339104) extract to afutils
-    static bool dumpTryLock(Mutex& mutex);
-private:
     void dumpPermissionDenial(int fd, const Vector<String16>& args);
-    void dumpClients(int fd, const Vector<String16>& args);
-    void dumpInternals(int fd, const Vector<String16>& args);
+    void dumpClients_ll(int fd, const Vector<String16>& args) REQUIRES(mutex(), clientMutex());
+    void dumpInternals_l(int fd, const Vector<String16>& args) REQUIRES(mutex());
 
     SimpleLog mThreadLog{16}; // 16 Thread history limit
 
-    void dumpToThreadLog_l(const sp<IAfThreadBase>& thread);
+    void dumpToThreadLog_l(const sp<IAfThreadBase>& thread) REQUIRES(mutex());
 
     // --- Notification Client ---
     class NotificationClient : public IBinder::DeathRecipient {
@@ -569,25 +493,22 @@
         bool mPendingRequests;
 
         // Mutex and condition variable around mPendingRequests' value
-        Mutex       mMutex;
-        Condition   mCond;
+        audio_utils::mutex mMutex;
+        audio_utils::condition_variable mCondition;
 
         // Duration of the sleep period after a processed request
         static const int kPostTriggerSleepPeriod = 1000000;
     };
 
-    const sp<MediaLogNotifier> mMediaLogNotifier;
-
-    // This is a helper that is called during incoming binder calls.
-    // Requests media.log to start merging log buffers
-    void requestLogMerge();
+    const sp<MediaLogNotifier> mMediaLogNotifier = sp<MediaLogNotifier>::make();
 
     // Find io handle by session id.
     // Preference is given to an io handle with a matching effect chain to session id.
     // If none found, AUDIO_IO_HANDLE_NONE is returned.
     template <typename T>
     static audio_io_handle_t findIoHandleBySessionId_l(
-            audio_session_t sessionId, const T& threads) {
+            audio_session_t sessionId, const T& threads)
+            REQUIRES(audio_utils::AudioFlinger_Mutex) {
         audio_io_handle_t io = AUDIO_IO_HANDLE_NONE;
 
         for (size_t i = 0; i < threads.size(); i++) {
@@ -602,44 +523,16 @@
         return io;
     }
 
-    IAfThreadBase* checkThread_l(audio_io_handle_t ioHandle) const;
-    sp<IAfThreadBase> checkOutputThread_l(audio_io_handle_t ioHandle) const REQUIRES(mLock);
-    IAfPlaybackThread* checkPlaybackThread_l(audio_io_handle_t output) const;
-    IAfPlaybackThread* checkMixerThread_l(audio_io_handle_t output) const;
-    IAfRecordThread* checkRecordThread_l(audio_io_handle_t input) const;
-    IAfMmapThread* checkMmapThread_l(audio_io_handle_t io) const;
-              sp<VolumeInterface> getVolumeInterface_l(audio_io_handle_t output) const;
-              std::vector<sp<VolumeInterface>> getAllVolumeInterfaces_l() const;
+    IAfThreadBase* checkThread_l(audio_io_handle_t ioHandle) const REQUIRES(mutex());
+    IAfPlaybackThread* checkMixerThread_l(audio_io_handle_t output) const REQUIRES(mutex());
 
-    sp<IAfThreadBase> openInput_l(audio_module_handle_t module,
-                                           audio_io_handle_t *input,
-                                           audio_config_t *config,
-                                           audio_devices_t device,
-                                           const char* address,
-                                           audio_source_t source,
-                                           audio_input_flags_t flags,
-                                           audio_devices_t outputDevice,
-                                           const String8& outputDeviceAddress);
-    sp<IAfThreadBase> openOutput_l(audio_module_handle_t module,
-                                          audio_io_handle_t *output,
-                                          audio_config_t *halConfig,
-                                          audio_config_base_t *mixerConfig,
-                                          audio_devices_t deviceType,
-                                          const String8& address,
-                                          audio_output_flags_t flags);
+    sp<VolumeInterface> getVolumeInterface_l(audio_io_handle_t output) const REQUIRES(mutex());
+    std::vector<sp<VolumeInterface>> getAllVolumeInterfaces_l() const REQUIRES(mutex());
 
-    void closeOutputFinish(const sp<IAfPlaybackThread>& thread);
+
+    static void closeOutputFinish(const sp<IAfPlaybackThread>& thread);
     void closeInputFinish(const sp<IAfRecordThread>& thread);
 
-              // no range check, AudioFlinger::mLock held
-              bool streamMute_l(audio_stream_type_t stream) const
-                                { return mStreamTypes[stream].mute; }
-              void ioConfigChanged(audio_io_config_event_t event,
-                                   const sp<AudioIoDescriptor>& ioDesc,
-                                   pid_t pid = 0);
-              void onSupportedLatencyModesChanged(
-                    audio_io_handle_t output, const std::vector<audio_latency_mode_t>& modes);
-
               // Allocate an audio_unique_id_t.
               // Specific types are audio_io_handle_t, audio_session_t, effect ID (int),
               // audio_module_handle_t, and audio_patch_handle_t.
@@ -651,42 +544,26 @@
               //       Thus it may fail by returning an ID of the wrong sign,
               //       or by returning a non-unique ID.
               // This is the internal API.  For the binder API see newAudioUniqueId().
-              audio_unique_id_t nextUniqueId(audio_unique_id_use_t use);
-
-              status_t moveEffectChain_l(audio_session_t sessionId,
-            IAfPlaybackThread* srcThread, IAfPlaybackThread* dstThread);
-
-public:
-    // TODO(b/288339104) cluster together
-              status_t moveAuxEffectToIo(int EffectId,
-            const sp<IAfPlaybackThread>& dstThread, sp<IAfPlaybackThread>* srcThread);
-private:
+    // used by IAfDeviceEffectManagerCallback, IAfPatchPanelCallback, IAfThreadCallback
+    audio_unique_id_t nextUniqueId(audio_unique_id_use_t use) final;
 
               // return thread associated with primary hardware device, or NULL
-              IAfPlaybackThread* primaryPlaybackThread_l() const;
-              DeviceTypeSet primaryOutputDevice_l() const;
+    DeviceTypeSet primaryOutputDevice_l() const REQUIRES(mutex());
 
               // return the playback thread with smallest HAL buffer size, and prefer fast
-              IAfPlaybackThread* fastPlaybackThread_l() const;
+    IAfPlaybackThread* fastPlaybackThread_l() const REQUIRES(mutex());
 
-              sp<IAfThreadBase> getEffectThread_l(audio_session_t sessionId, int effectId);
+    sp<IAfThreadBase> getEffectThread_l(audio_session_t sessionId, int effectId)
+            REQUIRES(mutex());
 
-              IAfThreadBase* hapticPlaybackThread_l() const;
+    IAfThreadBase* hapticPlaybackThread_l() const REQUIRES(mutex());
 
               void updateSecondaryOutputsForTrack_l(
                       IAfTrack* track,
                       IAfPlaybackThread* thread,
-                      const std::vector<audio_io_handle_t>& secondaryOutputs) const;
+            const std::vector<audio_io_handle_t>& secondaryOutputs) const REQUIRES(mutex());
 
-
-                void        removeClient_l(pid_t pid);
-                void        removeNotificationClient(pid_t pid);
-public:
-    // TODO(b/288339104) cluster together
-                bool isNonOffloadableGlobalEffectEnabled_l();
-private:
-                void onNonOffloadableGlobalEffectEnable();
-                bool isSessionAcquired_l(audio_session_t audioSession);
+    bool isSessionAcquired_l(audio_session_t audioSession) REQUIRES(mutex());
 
                 // Store an effect chain to mOrphanEffectChains keyed vector.
                 // Called when a thread exits and effects are still attached to it.
@@ -695,25 +572,18 @@
                 // return ALREADY_EXISTS if a chain with the same session already exists in
                 // mOrphanEffectChains. Note that this should never happen as there is only one
                 // chain for a given session and it is attached to only one thread at a time.
-                status_t putOrphanEffectChain_l(const sp<IAfEffectChain>& chain);
+    status_t putOrphanEffectChain_l(const sp<IAfEffectChain>& chain) REQUIRES(mutex());
                 // Get an effect chain for the specified session in mOrphanEffectChains and remove
                 // it if found. Returns 0 if not found (this is the most common case).
-                sp<IAfEffectChain> getOrphanEffectChain_l(audio_session_t session);
-                // Called when the last effect handle on an effect instance is removed. If this
-                // effect belongs to an effect chain in mOrphanEffectChains, the chain is updated
-                // and removed from mOrphanEffectChains if it does not contain any effect.
-                // Return true if the effect was found in mOrphanEffectChains, false otherwise.
-public:
-// TODO(b/288339104) suggest better grouping
-                bool updateOrphanEffectChains(const sp<IAfEffectModule>& effect);
-private:
-                std::vector< sp<IAfEffectModule> > purgeStaleEffects_l();
+    sp<IAfEffectChain> getOrphanEffectChain_l(audio_session_t session) REQUIRES(mutex());
 
-                void broadcastParametersToRecordThreads_l(const String8& keyValuePairs);
-                void updateOutDevicesForRecordThreads_l(const DeviceDescriptorBaseVector& devices);
-                void forwardParametersToDownstreamPatches_l(
+    std::vector< sp<IAfEffectModule> > purgeStaleEffects_l() REQUIRES(mutex());
+
+    void broadcastParametersToRecordThreads_l(const String8& keyValuePairs) REQUIRES(mutex());
+    void forwardParametersToDownstreamPatches_l(
                         audio_io_handle_t upStream, const String8& keyValuePairs,
-            const std::function<bool(const sp<IAfPlaybackThread>&)>& useThread = nullptr);
+            const std::function<bool(const sp<IAfPlaybackThread>&)>& useThread = nullptr)
+            REQUIRES(mutex());
 
     // for mAudioSessionRefs only
     struct AudioSessionRef {
@@ -725,30 +595,28 @@
         int         mCnt;
     };
 
-public:
-    // TODO(b/288339104) access by getter,
-    mutable     Mutex                               mLock;
+    mutable audio_utils::mutex mMutex;
                 // protects mClients and mNotificationClients.
-                // must be locked after mLock and ThreadBase::mLock if both must be locked
-                // avoids acquiring AudioFlinger::mLock from inside thread loop.
+                // must be locked after mutex() and ThreadBase::mutex() if both must be locked
+                // avoids acquiring AudioFlinger::mutex() from inside thread loop.
 
-    // TODO(b/288339104) access by getter,
-    mutable     Mutex                               mClientLock;
-private:
-                // protected by mClientLock
-                DefaultKeyedVector< pid_t, wp<Client> >     mClients;   // see ~Client()
+    mutable audio_utils::mutex mClientMutex;
 
-                mutable     Mutex                   mHardwareLock;
-                // NOTE: If both mLock and mHardwareLock mutexes must be held,
-                // always take mLock before mHardwareLock
+    DefaultKeyedVector<pid_t, wp<Client>> mClients GUARDED_BY(clientMutex());   // see ~Client()
 
-                // guarded by mHardwareLock
-                AudioHwDevice* mPrimaryHardwareDev;
-                DefaultKeyedVector<audio_module_handle_t, AudioHwDevice*>  mAudioHwDevs;
+    audio_utils::mutex& hardwareMutex() const { return mHardwareMutex; }
 
-                // These two fields are immutable after onFirstRef(), so no lock needed to access
-                sp<DevicesFactoryHalInterface> mDevicesFactoryHal;
-                sp<DevicesFactoryHalCallback> mDevicesFactoryHalCallback;
+    mutable audio_utils::mutex mHardwareMutex;
+    // NOTE: If both mMutex and mHardwareMutex mutexes must be held,
+    // always take mMutex before mHardwareMutex
+
+    std::atomic<AudioHwDevice*> mPrimaryHardwareDev = nullptr;
+    DefaultKeyedVector<audio_module_handle_t, AudioHwDevice*> mAudioHwDevs
+            GUARDED_BY(hardwareMutex()) {nullptr /* defValue */};
+
+     const sp<DevicesFactoryHalInterface> mDevicesFactoryHal =
+             DevicesFactoryHalInterface::create();
+     /* const */ sp<DevicesFactoryHalCallback> mDevicesFactoryHalCallback;  // set onFirstRef().
 
     // for dump, indicates which hardware operation is currently in progress (but not stream ops)
     enum hardware_call_state {
@@ -778,135 +646,110 @@
         AUDIO_HW_SET_SIMULATE_CONNECTIONS, // setSimulateDeviceConnections
     };
 
-    mutable     hardware_call_state                 mHardwareStatus;    // for dump only
+    mutable hardware_call_state mHardwareStatus = AUDIO_HW_IDLE;  // for dump only
+    DefaultKeyedVector<audio_io_handle_t, sp<IAfPlaybackThread>> mPlaybackThreads
+            GUARDED_BY(mutex());
+    stream_type_t mStreamTypes[AUDIO_STREAM_CNT] GUARDED_BY(mutex());
 
+    float mMasterVolume GUARDED_BY(mutex()) = 1.f;
+    bool mMasterMute GUARDED_BY(mutex()) = false;
+    float mMasterBalance GUARDED_BY(mutex()) = 0.f;
 
-    DefaultKeyedVector<audio_io_handle_t, sp<IAfPlaybackThread>> mPlaybackThreads;
-                stream_type_t                       mStreamTypes[AUDIO_STREAM_CNT];
+    DefaultKeyedVector<audio_io_handle_t, sp<IAfRecordThread>> mRecordThreads GUARDED_BY(mutex());
 
-                // member variables below are protected by mLock
-                float                               mMasterVolume;
-                bool                                mMasterMute;
-                float                               mMasterBalance = 0.f;
-                // end of variables protected by mLock
-
-    DefaultKeyedVector<audio_io_handle_t, sp<IAfRecordThread>> mRecordThreads;
-
-                // protected by mClientLock
-                DefaultKeyedVector< pid_t, sp<NotificationClient> >    mNotificationClients;
+    DefaultKeyedVector<pid_t, sp<NotificationClient>> mNotificationClients
+            GUARDED_BY(clientMutex());
 
                 // updated by atomic_fetch_add_explicit
-                volatile atomic_uint_fast32_t       mNextUniqueIds[AUDIO_UNIQUE_ID_USE_MAX];
+    volatile atomic_uint_fast32_t mNextUniqueIds[AUDIO_UNIQUE_ID_USE_MAX];  // ctor init
 
-                audio_mode_t                        mMode;
-                std::atomic_bool                    mBtNrecIsOff;
+    std::atomic<audio_mode_t> mMode = AUDIO_MODE_INVALID;
+    std::atomic<bool> mBtNrecIsOff = false;
 
-                // protected by mLock
-                Vector<AudioSessionRef*> mAudioSessionRefs;
+    Vector<AudioSessionRef*> mAudioSessionRefs GUARDED_BY(mutex());
 
-                float       masterVolume_l() const;
-                float       getMasterBalance_l() const;
-                bool        masterMute_l() const;
-                AudioHwDevice* loadHwModule_l(const char *name);
+    AudioHwDevice* loadHwModule_ll(const char *name) REQUIRES(mutex(), hardwareMutex());
 
                 // sync events awaiting for a session to be created.
-                std::list<sp<audioflinger::SyncEvent>> mPendingSyncEvents;
+    std::list<sp<audioflinger::SyncEvent>> mPendingSyncEvents GUARDED_BY(mutex());
 
                 // Effect chains without a valid thread
-                DefaultKeyedVector<audio_session_t, sp<IAfEffectChain>> mOrphanEffectChains;
+    DefaultKeyedVector<audio_session_t, sp<IAfEffectChain>> mOrphanEffectChains
+            GUARDED_BY(mutex());
 
                 // list of sessions for which a valid HW A/V sync ID was retrieved from the HAL
-                DefaultKeyedVector< audio_session_t , audio_hw_sync_t >mHwAvSyncIds;
+    DefaultKeyedVector<audio_session_t, audio_hw_sync_t> mHwAvSyncIds GUARDED_BY(mutex());
 
                 // list of MMAP stream control threads. Those threads allow for wake lock, routing
                 // and volume control for activity on the associated MMAP stream at the HAL.
                 // Audio data transfer is directly handled by the client creating the MMAP stream
-    DefaultKeyedVector<audio_io_handle_t, sp<IAfMmapThread>> mMmapThreads;
+    DefaultKeyedVector<audio_io_handle_t, sp<IAfMmapThread>> mMmapThreads GUARDED_BY(mutex());
 
-private:
-    sp<Client>  registerPid(pid_t pid);    // always returns non-0
+    sp<Client> registerPid(pid_t pid) EXCLUDES_AudioFlinger_ClientMutex; // always returns non-0
 
     // for use from destructor
-    status_t    closeOutput_nonvirtual(audio_io_handle_t output);
-    void closeThreadInternal_l(const sp<IAfPlaybackThread>& thread);
-    status_t    closeInput_nonvirtual(audio_io_handle_t input);
-    void closeThreadInternal_l(const sp<IAfRecordThread>& thread);
-    void setAudioHwSyncForSession_l(IAfPlaybackThread* thread, audio_session_t sessionId);
+    status_t closeOutput_nonvirtual(audio_io_handle_t output) EXCLUDES_AudioFlinger_Mutex;
+    status_t closeInput_nonvirtual(audio_io_handle_t input) EXCLUDES_AudioFlinger_Mutex;
+    void setAudioHwSyncForSession_l(IAfPlaybackThread* thread, audio_session_t sessionId)
+            REQUIRES(mutex());
 
-    status_t    checkStreamType(audio_stream_type_t stream) const;
+    static status_t checkStreamType(audio_stream_type_t stream);
 
+    // no mutex needed.
     void        filterReservedParameters(String8& keyValuePairs, uid_t callingUid);
     void        logFilteredParameters(size_t originalKVPSize, const String8& originalKVPs,
                                       size_t rejectedKVPSize, const String8& rejectedKVPs,
                                       uid_t callingUid);
 
-public:
-    sp<IAudioManager> getOrCreateAudioManager();
-
     // These methods read variables atomically without mLock,
     // though the variables are updated with mLock.
-    bool    isLowRamDevice() const { return mIsLowRamDevice; }
     size_t getClientSharedHeapSize() const;
 
-private:
-    std::atomic<bool> mIsLowRamDevice;
-    bool    mIsDeviceTypeKnown;
-    int64_t mTotalMemory;
-    std::atomic<size_t> mClientSharedHeapSize;
+    std::atomic<bool> mIsLowRamDevice = true;
+    bool mIsDeviceTypeKnown GUARDED_BY(mutex()) = false;
+    int64_t mTotalMemory GUARDED_BY(mutex()) = 0;
+    std::atomic<size_t> mClientSharedHeapSize = kMinimumClientSharedHeapSizeBytes;
     static constexpr size_t kMinimumClientSharedHeapSizeBytes = 1024 * 1024; // 1MB
 
-    nsecs_t mGlobalEffectEnableTime;  // when a global effect was last enabled
+    // when a global effect was last enabled
+    nsecs_t mGlobalEffectEnableTime GUARDED_BY(mutex()) = 0;
 
-    // protected by mLock
-    const sp<IAfPatchPanel> mPatchPanel = IAfPatchPanel::create(this);
+    /* const */ sp<IAfPatchPanel> mPatchPanel;
 
-public:
-    // TODO(b/288339104) access by getter.
-    sp<EffectsFactoryHalInterface> mEffectsFactoryHal;
-private:
+    const sp<EffectsFactoryHalInterface> mEffectsFactoryHal =
+            audioflinger::EffectConfiguration::getEffectsFactoryHal();
 
-    const sp<PatchCommandThread> mPatchCommandThread;
-    sp<DeviceEffectManager> mDeviceEffectManager;
-    sp<MelReporter> mMelReporter;
+    const sp<PatchCommandThread> mPatchCommandThread = sp<PatchCommandThread>::make();
+    /* const */ sp<DeviceEffectManager> mDeviceEffectManager;  // set onFirstRef
+    /* const */ sp<MelReporter> mMelReporter;  // set onFirstRef
 
-    bool       mSystemReady;
-    std::atomic_bool mAudioPolicyReady{};
+    bool mSystemReady GUARDED_BY(mutex()) = false;
+    std::atomic<bool> mAudioPolicyReady = false;
 
-    mediautils::UidInfo mUidInfo;
+    mediautils::UidInfo mUidInfo GUARDED_BY(mutex());
 
+    // no mutex needed.
     SimpleLog  mRejectedSetParameterLog;
     SimpleLog  mAppSetParameterLog;
     SimpleLog  mSystemSetParameterLog;
 
-    std::vector<media::AudioVibratorInfo> mAudioVibratorInfos;
+    std::vector<media::AudioVibratorInfo> mAudioVibratorInfos GUARDED_BY(mutex());
 
     static inline constexpr const char *mMetricsId = AMEDIAMETRICS_KEY_AUDIO_FLINGER;
 
-    // Keep in sync with java definition in media/java/android/media/AudioRecord.java
-    static constexpr int32_t kMaxSharedAudioHistoryMs = 5000;
-
     std::map<media::audio::common::AudioMMapPolicyType,
-             std::vector<media::audio::common::AudioMMapPolicyInfo>> mPolicyInfos;
-    int32_t mAAudioBurstsPerBuffer = 0;
-    int32_t mAAudioHwBurstMinMicros = 0;
+             std::vector<media::audio::common::AudioMMapPolicyInfo>> mPolicyInfos
+             GUARDED_BY(mutex());
+    int32_t mAAudioBurstsPerBuffer GUARDED_BY(mutex()) = 0;
+    int32_t mAAudioHwBurstMinMicros GUARDED_BY(mutex()) = 0;
 
     /** Interface for interacting with the AudioService. */
-    mediautils::atomic_sp<IAudioManager>       mAudioManager;
+    mediautils::atomic_sp<IAudioManager> mAudioManager;
 
     // Bluetooth Variable latency control logic is enabled or disabled
-    std::atomic_bool mBluetoothLatencyModesEnabled;
+    std::atomic<bool> mBluetoothLatencyModesEnabled = true;
 };
 
-#undef INCLUDING_FROM_AUDIOFLINGER_H
-
-std::string formatToString(audio_format_t format);
-std::string inputFlagsToString(audio_input_flags_t flags);
-std::string outputFlagsToString(audio_output_flags_t flags);
-std::string devicesToString(audio_devices_t devices);
-const char *sourceToString(audio_source_t source);
-
 // ----------------------------------------------------------------------------
 
 } // namespace android
-
-#endif // ANDROID_AUDIO_FLINGER_H
diff --git a/services/audioflinger/Client.cpp b/services/audioflinger/Client.cpp
new file mode 100644
index 0000000..93599ac
--- /dev/null
+++ b/services/audioflinger/Client.cpp
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "Client.h"
+
+namespace android {
+
+Client::Client(const sp<IAfClientCallback>& afClientCallback, pid_t pid)
+    : mAfClientCallback(afClientCallback)
+    , mPid(pid)
+    , mClientAllocator(AllocatorFactory::getClientAllocator()) {}
+
+// Client destructor must be called with AudioFlinger::mClientLock held
+Client::~Client()
+{
+    mAfClientCallback->removeClient_l(mPid);
+}
+
+AllocatorFactory::ClientAllocator& Client::allocator()
+{
+    return mClientAllocator;
+}
+
+}   // namespace android
\ No newline at end of file
diff --git a/services/audioflinger/Client.h b/services/audioflinger/Client.h
index cb507fe..ff0d751 100644
--- a/services/audioflinger/Client.h
+++ b/services/audioflinger/Client.h
@@ -16,26 +16,45 @@
 
 #pragma once
 
-// TODO(b/288339104) Move to nested namespace
+#include <afutils/AllocatorFactory.h>
+#include <audio_utils/mutex.h>
+#include <android-base/macros.h>  // DISALLOW_COPY_AND_ASSIGN
+#include <utils/RefBase.h>        // avoid transitive dependency
+
+// TODO(b/291318727) Move to nested namespace
 namespace android {
 
-class AudioFlinger;
+class IAfPlaybackThread;
+
+class IAfClientCallback : public virtual RefBase {
+public:
+    virtual audio_utils::mutex& clientMutex() const
+            RETURN_CAPABILITY(audio_utils::AudioFlinger_ClientMutex) = 0;
+    virtual void removeClient_l(pid_t pid) REQUIRES(clientMutex()) = 0;
+    virtual void removeNotificationClient(pid_t pid) EXCLUDES_AudioFlinger_Mutex = 0;
+
+    // used indirectly by clients.
+    virtual status_t moveAuxEffectToIo(
+            int effectId,
+            const sp<IAfPlaybackThread>& dstThread,
+            sp<IAfPlaybackThread>* srcThread) EXCLUDES_AudioFlinger_Mutex = 0;
+};
 
 class Client : public RefBase {
 public:
-    Client(const sp<AudioFlinger>& audioFlinger, pid_t pid);
+    Client(const sp<IAfClientCallback>& audioFlinger, pid_t pid);
 
     // TODO(b/289139675) make Client container.
     // Client destructor must be called with AudioFlinger::mClientLock held
     ~Client() override;
     AllocatorFactory::ClientAllocator& allocator();
     pid_t pid() const { return mPid; }
-    sp<AudioFlinger> audioFlinger() const { return mAudioFlinger; }
+    const auto& afClientCallback() const { return mAfClientCallback; }
 
 private:
     DISALLOW_COPY_AND_ASSIGN(Client);
 
-    const sp<AudioFlinger> mAudioFlinger;
+    const sp<IAfClientCallback> mAfClientCallback;
     const pid_t mPid;
     AllocatorFactory::ClientAllocator mClientAllocator;
 };
diff --git a/services/audioflinger/DeviceEffectManager.cpp b/services/audioflinger/DeviceEffectManager.cpp
index c088c90..0a7be75 100644
--- a/services/audioflinger/DeviceEffectManager.cpp
+++ b/services/audioflinger/DeviceEffectManager.cpp
@@ -15,16 +15,17 @@
 ** limitations under the License.
 */
 
-
 #define LOG_TAG "DeviceEffectManager"
 //#define LOG_NDEBUG 0
 
-#include <utils/Log.h>
-#include <audio_utils/primitives.h>
+#include "DeviceEffectManager.h"
 
-#include "AudioFlinger.h"
 #include "EffectConfiguration.h"
+
+#include <afutils/DumpTryLock.h>
+#include <audio_utils/primitives.h>
 #include <media/audiohal/EffectsFactoryHalInterface.h>
+#include <utils/Log.h>
 
 // ----------------------------------------------------------------------------
 
@@ -34,22 +35,23 @@
 using detail::AudioHalVersionInfo;
 using media::IEffectClient;
 
-DeviceEffectManager::DeviceEffectManager(AudioFlinger& audioFlinger)
-    : mAudioFlinger(audioFlinger),
-      mMyCallback(new DeviceEffectManagerCallback(*this)) {}
+DeviceEffectManager::DeviceEffectManager(
+        const sp<IAfDeviceEffectManagerCallback>& afDeviceEffectManagerCallback)
+    : mAfDeviceEffectManagerCallback(afDeviceEffectManagerCallback),
+      mMyCallback(sp<DeviceEffectManagerCallback>::make(*this)) {}
 
 void DeviceEffectManager::onFirstRef() {
-    mAudioFlinger.mPatchCommandThread->addListener(this);
+    mAfDeviceEffectManagerCallback->getPatchCommandThread()->addListener(this);
 }
 
 status_t DeviceEffectManager::addEffectToHal(const struct audio_port_config* device,
         const sp<EffectHalInterface>& effect) {
-    return mAudioFlinger.addEffectToHal(device, effect);
+    return mAfDeviceEffectManagerCallback->addEffectToHal(device, effect);
 };
 
 status_t DeviceEffectManager::removeEffectFromHal(const struct audio_port_config* device,
         const sp<EffectHalInterface>& effect) {
-    return mAudioFlinger.removeEffectFromHal(device, effect);
+    return mAfDeviceEffectManagerCallback->removeEffectFromHal(device, effect);
 };
 
 void DeviceEffectManager::onCreateAudioPatch(audio_patch_handle_t handle,
@@ -57,7 +59,7 @@
     ALOGV("%s handle %d mHalHandle %d device sink %08x",
             __func__, handle, patch.mHalHandle,
             patch.mAudioPatch.num_sinks > 0 ? patch.mAudioPatch.sinks[0].ext.device.type : 0);
-    Mutex::Autolock _l(mLock);
+    audio_utils::lock_guard _l(mutex());
     for (auto& effect : mDeviceEffects) {
         status_t status = effect.second->onCreatePatch(handle, patch);
         ALOGV("%s Effect onCreatePatch status %d", __func__, status);
@@ -67,13 +69,13 @@
 
 void DeviceEffectManager::onReleaseAudioPatch(audio_patch_handle_t handle) {
     ALOGV("%s", __func__);
-    Mutex::Autolock _l(mLock);
+    audio_utils::lock_guard _l(mutex());
     for (auto& effect : mDeviceEffects) {
         effect.second->onReleasePatch(handle);
     }
 }
 
-// DeviceEffectManager::createEffect_l() must be called with AudioFlinger::mLock held
+// DeviceEffectManager::createEffect_l() must be called with AudioFlinger::mutex() held
 sp<IAfEffectHandle> DeviceEffectManager::createEffect_l(
         effect_descriptor_t *descriptor,
         const AudioDeviceTypeAddr& device,
@@ -95,13 +97,14 @@
     }
 
     {
-        Mutex::Autolock _l(mLock);
+        audio_utils::lock_guard _l(mutex());
         auto iter = mDeviceEffects.find(device);
         if (iter != mDeviceEffects.end()) {
             effect = iter->second;
         } else {
             effect = IAfDeviceEffectProxy::create(device, mMyCallback,
-                    descriptor, mAudioFlinger.nextUniqueId(AUDIO_UNIQUE_ID_USE_EFFECT),
+                    descriptor,
+                    mAfDeviceEffectManagerCallback->nextUniqueId(AUDIO_UNIQUE_ID_USE_EFFECT),
                     notifyFramesProcessed);
         }
         // create effect handle and connect it to effect module
@@ -128,6 +131,7 @@
     return handle;
 }
 
+/* static */
 status_t DeviceEffectManager::checkEffectCompatibility(
         const effect_descriptor_t *desc) {
     const sp<EffectsFactoryHalInterface> effectsFactory =
@@ -154,6 +158,7 @@
     return NO_ERROR;
 }
 
+/* static */
 status_t DeviceEffectManager::createEffectHal(
         const effect_uuid_t *pEffectUuid, int32_t sessionId, int32_t deviceId,
         sp<EffectHalInterface> *effect) {
@@ -170,7 +175,7 @@
 void DeviceEffectManager::dump(int fd)
 NO_THREAD_SAFETY_ANALYSIS  // conditional try lock
 {
-    const bool locked = AudioFlinger::dumpTryLock(mLock);
+    const bool locked = afutils::dumpTryLock(mutex());
     if (!locked) {
         String8 result("DeviceEffectManager may be deadlocked\n");
         write(fd, result.c_str(), result.size());
@@ -187,13 +192,13 @@
     }
 
     if (locked) {
-        mLock.unlock();
+        mutex().unlock();
     }
 }
 
 size_t DeviceEffectManager::removeEffect(const sp<IAfDeviceEffectProxy>& effect)
 {
-    Mutex::Autolock _l(mLock);
+    audio_utils::lock_guard _l(mutex());
     mDeviceEffects.erase(effect->device());
     return mDeviceEffects.size();
 }
@@ -221,11 +226,11 @@
 }
 
 bool DeviceEffectManagerCallback::isAudioPolicyReady() const {
-    return mManager.audioFlinger().isAudioPolicyReady();
+    return mManager.afDeviceEffectManagerCallback()->isAudioPolicyReady();
 }
 
 int DeviceEffectManagerCallback::newEffectId() const {
-    return mManager.audioFlinger().nextUniqueId(AUDIO_UNIQUE_ID_USE_EFFECT);
+    return mManager.afDeviceEffectManagerCallback()->nextUniqueId(AUDIO_UNIQUE_ID_USE_EFFECT);
 }
 
 } // namespace android
diff --git a/services/audioflinger/DeviceEffectManager.h b/services/audioflinger/DeviceEffectManager.h
index b09de77..6a5c889 100644
--- a/services/audioflinger/DeviceEffectManager.h
+++ b/services/audioflinger/DeviceEffectManager.h
@@ -17,14 +17,31 @@
 
 #pragma once
 
+#include "IAfEffect.h"
+#include "PatchCommandThread.h"
+
 namespace android {
 
+class IAfDeviceEffectManagerCallback : public virtual RefBase {
+public:
+    virtual bool isAudioPolicyReady() const = 0;
+    virtual audio_unique_id_t nextUniqueId(audio_unique_id_use_t use) = 0;
+    virtual const sp<PatchCommandThread>& getPatchCommandThread() = 0;
+    virtual status_t addEffectToHal(
+            const struct audio_port_config* device, const sp<EffectHalInterface>& effect)
+            EXCLUDES_AudioFlinger_HardwareMutex = 0;
+    virtual status_t removeEffectFromHal(
+            const struct audio_port_config* device, const sp<EffectHalInterface>& effect)
+            EXCLUDES_AudioFlinger_HardwareMutex= 0;
+};
+
 class DeviceEffectManagerCallback;
 
 // DeviceEffectManager is concealed within AudioFlinger, their lifetimes are the same.
 class DeviceEffectManager : public PatchCommandThread::PatchCommandListener {
 public:
-    explicit DeviceEffectManager(AudioFlinger& audioFlinger);
+    explicit DeviceEffectManager(
+            const sp<IAfDeviceEffectManagerCallback>& afDeviceEffectManagerCallback);
 
     void onFirstRef() override;
 
@@ -36,10 +53,10 @@
                 int *enabled,
                 status_t *status,
                 bool probe,
-                bool notifyFramesProcessed);
+                bool notifyFramesProcessed) REQUIRES(audio_utils::AudioFlinger_Mutex);
 
     size_t removeEffect(const sp<IAfDeviceEffectProxy>& effect);
-    status_t createEffectHal(const effect_uuid_t *pEffectUuid,
+    static status_t createEffectHal(const effect_uuid_t *pEffectUuid,
            int32_t sessionId, int32_t deviceId,
            sp<EffectHalInterface> *effect);
     status_t addEffectToHal(const struct audio_port_config *device,
@@ -47,23 +64,28 @@
     status_t removeEffectFromHal(const struct audio_port_config *device,
             const sp<EffectHalInterface>& effect);
 
-    AudioFlinger& audioFlinger() const { return mAudioFlinger; }
+    const auto& afDeviceEffectManagerCallback() const { return mAfDeviceEffectManagerCallback; }
 
     void dump(int fd);
 
     // PatchCommandThread::PatchCommandListener implementation
 
     void onCreateAudioPatch(audio_patch_handle_t handle,
-            const IAfPatchPanel::Patch& patch) final;
-    void onReleaseAudioPatch(audio_patch_handle_t handle) final;
+            const IAfPatchPanel::Patch& patch) final
+            EXCLUDES_DeviceEffectManager_Mutex;
+    void onReleaseAudioPatch(audio_patch_handle_t handle) final
+            EXCLUDES_DeviceEffectManager_Mutex;
 
 private:
-    status_t checkEffectCompatibility(const effect_descriptor_t *desc);
+    static status_t checkEffectCompatibility(const effect_descriptor_t *desc);
 
-    Mutex mLock;
-    AudioFlinger &mAudioFlinger;
+    audio_utils::mutex& mutex() const RETURN_CAPABILITY(audio_utils::DeviceEffectManager_Mutex) {
+       return mMutex;
+   }
+    mutable audio_utils::mutex mMutex;
+    const sp<IAfDeviceEffectManagerCallback> mAfDeviceEffectManagerCallback;
     const sp<DeviceEffectManagerCallback> mMyCallback;
-    std::map<AudioDeviceTypeAddr, sp<IAfDeviceEffectProxy>> mDeviceEffects;
+    std::map<AudioDeviceTypeAddr, sp<IAfDeviceEffectProxy>> mDeviceEffects GUARDED_BY(mutex());
 };
 
 class DeviceEffectManagerCallback : public EffectCallbackInterface {
@@ -72,55 +94,54 @@
         : mManager(manager) {}
 
     status_t createEffectHal(const effect_uuid_t *pEffectUuid,
-           int32_t sessionId, int32_t deviceId,
-           sp<EffectHalInterface> *effect) override {
+            int32_t sessionId, int32_t deviceId, sp<EffectHalInterface> *effect) final {
                 return mManager.createEffectHal(pEffectUuid, sessionId, deviceId, effect);
             }
     status_t allocateHalBuffer(size_t size __unused,
-            sp<EffectBufferHalInterface>* buffer __unused) override { return NO_ERROR; }
-    bool updateOrphanEffectChains(const sp<IAfEffectBase>& effect __unused) override {
+            sp<EffectBufferHalInterface>* buffer __unused) final { return NO_ERROR; }
+    bool updateOrphanEffectChains(const sp<IAfEffectBase>& effect __unused) final {
         return false;
     }
 
-    audio_io_handle_t io() const override  { return AUDIO_IO_HANDLE_NONE; }
-    bool isOutput() const override { return false; }
-    bool isOffload() const override { return false; }
-    bool isOffloadOrDirect() const override { return false; }
-    bool isOffloadOrMmap() const override { return false; }
-    bool isSpatializer() const override { return false; }
+    audio_io_handle_t io() const final { return AUDIO_IO_HANDLE_NONE; }
+    bool isOutput() const final { return false; }
+    bool isOffload() const final { return false; }
+    bool isOffloadOrDirect() const final { return false; }
+    bool isOffloadOrMmap() const final { return false; }
+    bool isSpatializer() const final { return false; }
 
-    uint32_t  sampleRate() const override { return 0; }
-    audio_channel_mask_t inChannelMask(int id __unused) const override {
+    uint32_t sampleRate() const final { return 0; }
+    audio_channel_mask_t inChannelMask(int id __unused) const final {
         return AUDIO_CHANNEL_NONE;
     }
-    uint32_t inChannelCount(int id __unused) const override { return 0; }
-    audio_channel_mask_t outChannelMask() const override { return AUDIO_CHANNEL_NONE; }
-    uint32_t outChannelCount() const override { return 0; }
+    uint32_t inChannelCount(int id __unused) const final { return 0; }
+    audio_channel_mask_t outChannelMask() const final { return AUDIO_CHANNEL_NONE; }
+    uint32_t outChannelCount() const final { return 0; }
 
-    audio_channel_mask_t hapticChannelMask() const override { return AUDIO_CHANNEL_NONE; }
-    size_t    frameCount() const override  { return 0; }
-    uint32_t  latency() const override  { return 0; }
+    audio_channel_mask_t hapticChannelMask() const final { return AUDIO_CHANNEL_NONE; }
+    size_t frameCount() const final { return 0; }
+    uint32_t latency() const final { return 0; }
 
-    status_t addEffectToHal(const sp<EffectHalInterface>& /* effect */) override {
+    status_t addEffectToHal(const sp<EffectHalInterface>& /* effect */) final {
         return NO_ERROR;
     }
-    status_t removeEffectFromHal(const sp<EffectHalInterface>& /* effect */) override {
+    status_t removeEffectFromHal(const sp<EffectHalInterface>& /* effect */) final {
         return NO_ERROR;
     }
 
-    bool disconnectEffectHandle(IAfEffectHandle *handle, bool unpinIfLast) override;
-    void setVolumeForOutput(float left __unused, float right __unused) const override {}
+    bool disconnectEffectHandle(IAfEffectHandle *handle, bool unpinIfLast) final;
+    void setVolumeForOutput(float left __unused, float right __unused) const final {}
 
     // check if effects should be suspended or restored when a given effect is enable or disabled
     void checkSuspendOnEffectEnabled(const sp<IAfEffectBase>& effect __unused,
-                          bool enabled __unused, bool threadLocked __unused) override {}
-    void resetVolume() override {}
-    product_strategy_t strategy() const override  { return static_cast<product_strategy_t>(0); }
-    int32_t activeTrackCnt() const override { return 0; }
-    void onEffectEnable(const sp<IAfEffectBase>& effect __unused) override {}
-    void onEffectDisable(const sp<IAfEffectBase>& effect __unused) override {}
+                          bool enabled __unused, bool threadLocked __unused) final {}
+    void resetVolume() final {}
+    product_strategy_t strategy() const final { return static_cast<product_strategy_t>(0); }
+    int32_t activeTrackCnt() const final { return 0; }
+    void onEffectEnable(const sp<IAfEffectBase>& effect __unused) final {}
+    void onEffectDisable(const sp<IAfEffectBase>& effect __unused) final {}
 
-    wp<IAfEffectChain> chain() const override { return nullptr; }
+    wp<IAfEffectChain> chain() const final { return nullptr; }
 
     bool isAudioPolicyReady() const final;
 
diff --git a/services/audioflinger/Effects.cpp b/services/audioflinger/Effects.cpp
index 563a3e3..0f3e130 100644
--- a/services/audioflinger/Effects.cpp
+++ b/services/audioflinger/Effects.cpp
@@ -19,10 +19,25 @@
 #define LOG_TAG "AudioFlinger"
 //#define LOG_NDEBUG 0
 
-#include <algorithm>
+#include "Effects.h"
 
-#include "Configuration.h"
-#include <utils/Log.h>
+#include "Client.h"
+#include "EffectConfiguration.h"
+
+#include <afutils/DumpTryLock.h>
+#include <audio_utils/channels.h>
+#include <audio_utils/primitives.h>
+#include <media/AudioCommonTypes.h>
+#include <media/AudioContainers.h>
+#include <media/AudioDeviceTypeAddr.h>
+#include <media/AudioEffect.h>
+#include <media/ShmemCompat.h>
+#include <media/TypeConverter.h>
+#include <media/audiohal/EffectHalInterface.h>
+#include <media/audiohal/EffectsFactoryHalInterface.h>
+#include <mediautils/MethodStatistics.h>
+#include <mediautils/ServiceUtilities.h>
+#include <mediautils/TimeCheck.h>
 #include <system/audio_effects/effect_aec.h>
 #include <system/audio_effects/effect_downmix.h>
 #include <system/audio_effects/effect_dynamicsprocessing.h>
@@ -30,22 +45,9 @@
 #include <system/audio_effects/effect_ns.h>
 #include <system/audio_effects/effect_spatializer.h>
 #include <system/audio_effects/effect_visualizer.h>
-#include <audio_utils/channels.h>
-#include <audio_utils/primitives.h>
-#include <media/AudioCommonTypes.h>
-#include <media/AudioContainers.h>
-#include <media/AudioEffect.h>
-#include <media/AudioDeviceTypeAddr.h>
-#include <media/ShmemCompat.h>
-#include <media/audiohal/EffectHalInterface.h>
-#include <media/audiohal/EffectsFactoryHalInterface.h>
-#include <mediautils/MethodStatistics.h>
-#include <mediautils/ServiceUtilities.h>
-#include <mediautils/TimeCheck.h>
+#include <utils/Log.h>
 
-#include "AudioFlinger.h"
-#include "EffectConfiguration.h"
-#include "Effects.h"
+#include <algorithm>
 
 // ----------------------------------------------------------------------------
 
@@ -107,7 +109,7 @@
 {
 }
 
-// must be called with EffectModule::mLock held
+// must be called with EffectModule::mutex() held
 status_t EffectBase::setEnabled_l(bool enabled)
 {
 
@@ -153,7 +155,7 @@
 {
     status_t status;
     {
-        Mutex::Autolock _l(mLock);
+        audio_utils::lock_guard _l(mutex());
         status = setEnabled_l(enabled);
     }
     if (fromHandle) {
@@ -188,13 +190,13 @@
 
 void EffectBase::setSuspended(bool suspended)
 {
-    Mutex::Autolock _l(mLock);
+    audio_utils::lock_guard _l(mutex());
     mSuspended = suspended;
 }
 
 bool EffectBase::suspended() const
 {
-    Mutex::Autolock _l(mLock);
+    audio_utils::lock_guard _l(mutex());
     return mSuspended;
 }
 
@@ -202,7 +204,7 @@
 {
     status_t status;
 
-    Mutex::Autolock _l(mLock);
+    audio_utils::lock_guard _l(mutex());
     int priority = handle->priority();
     size_t size = mHandles.size();
     IAfEffectHandle *controlHandle = nullptr;
@@ -248,7 +250,7 @@
     product_strategy_t strategy = PRODUCT_STRATEGY_NONE;
 
     {
-        Mutex::Autolock _l(mLock);
+        audio_utils::lock_guard _l(mutex());
 
         if ((isInternal_l() && !mPolicyRegistered)
                 || !getCallback()->isAudioPolicyReady()) {
@@ -282,7 +284,7 @@
             return NO_ERROR;
         }
     }
-    mPolicyLock.lock();
+    policyMutex().lock();
     ALOGV("%s name %s id %d session %d doRegister %d registered %d doEnable %d enabled %d",
         __func__, mDescriptor.name, mId, mSessionId, doRegister, registered, doEnable, enabled);
     if (doRegister) {
@@ -300,7 +302,7 @@
     if (registered && doEnable) {
         status = AudioSystem::setEffectEnabled(mId, enabled);
     }
-    mPolicyLock.unlock();
+    policyMutex().unlock();
 
     return status;
 }
@@ -308,7 +310,7 @@
 
 ssize_t EffectBase::removeHandle(IAfEffectHandle *handle)
 {
-    Mutex::Autolock _l(mLock);
+    audio_utils::lock_guard _l(mutex());
     return removeHandle_l(handle);
 }
 
@@ -346,7 +348,7 @@
     return mHandles.size();
 }
 
-// must be called with EffectModule::mLock held
+// must be called with EffectModule::mutex() held
 IAfEffectHandle *EffectBase::controlHandle_l()
 {
     // the first valid handle in the list has control over the module
@@ -369,12 +371,12 @@
         return mHandles.size();
     }
 
-    Mutex::Autolock _l(mLock);
+    audio_utils::lock_guard _l(mutex());
     ssize_t numHandles = removeHandle_l(handle);
     if ((numHandles == 0) && (!mPinned || unpinIfLast)) {
-        mLock.unlock();
+        mutex().unlock();
         callback->updateOrphanEffectChains(this);
-        mLock.lock();
+        mutex().lock();
     }
     return numHandles;
 }
@@ -382,7 +384,7 @@
 bool EffectBase::purgeHandles()
 {
     bool enabled = false;
-    Mutex::Autolock _l(mLock);
+    audio_utils::lock_guard _l(mutex());
     IAfEffectHandle *handle = controlHandle_l();
     if (handle != NULL) {
         enabled = handle->enabled();
@@ -507,7 +509,7 @@
 
     result.appendFormat("\tEffect ID %d:\n", mId);
 
-    bool locked = AudioFlinger::dumpTryLock(mLock);
+    const bool locked = afutils::dumpTryLock(mutex());
     // failed to lock - AudioFlinger is probably deadlocked
     if (!locked) {
         result.append("\t\tCould not lock Fx mutex:\n");
@@ -545,7 +547,7 @@
         }
     }
     if (locked) {
-        mLock.unlock();
+        mutex().unlock();
     }
 
     write(fd, result.c_str(), result.length());
@@ -614,7 +616,7 @@
 }
 
 bool EffectModule::updateState() {
-    Mutex::Autolock _l(mLock);
+    audio_utils::lock_guard _l(mutex());
 
     bool started = false;
     switch (mState) {
@@ -670,7 +672,7 @@
 
 void EffectModule::process()
 {
-    Mutex::Autolock _l(mLock);
+    audio_utils::lock_guard _l(mutex());
 
     if (mState == DESTROYED || mEffectInterface == 0 || mInBuffer == 0 || mOutBuffer == 0) {
         return;
@@ -1014,7 +1016,7 @@
 
 status_t EffectModule::init()
 {
-    Mutex::Autolock _l(mLock);
+    audio_utils::lock_guard _l(mutex());
     if (mEffectInterface == 0) {
         return NO_INIT;
     }
@@ -1044,12 +1046,12 @@
     }
 }
 
-// start() must be called with PlaybackThread::mLock or EffectChain::mLock held
+// start() must be called with PlaybackThread::mutex() or EffectChain::mutex() held
 status_t EffectModule::start()
 {
     status_t status;
     {
-        Mutex::Autolock _l(mLock);
+        audio_utils::lock_guard _l(mutex());
         status = start_l();
     }
     if (status == NO_ERROR) {
@@ -1084,7 +1086,7 @@
 
 status_t EffectModule::stop()
 {
-    Mutex::Autolock _l(mLock);
+    audio_utils::lock_guard _l(mutex());
     return stop_l();
 }
 
@@ -1121,7 +1123,7 @@
     return status;
 }
 
-// must be called with EffectChain::mLock held
+// must be called with EffectChain::mutex() held
 void EffectModule::release_l()
 {
     if (mEffectInterface != 0) {
@@ -1157,7 +1159,7 @@
                      int32_t maxReplySize,
                      std::vector<uint8_t>* reply)
 {
-    Mutex::Autolock _l(mLock);
+    audio_utils::lock_guard _l(mutex());
     ALOGVV("command(), cmdCode: %d, mEffectInterface: %p", cmdCode, mEffectInterface.get());
 
     if (mState == DESTROYED || mEffectInterface == 0) {
@@ -1354,7 +1356,7 @@
 
 status_t EffectModule::setVolume(uint32_t *left, uint32_t *right, bool controller)
 {
-    AutoLockReentrant _l(mLock, mSetVolumeReentrantTid);
+    AutoLockReentrant _l(mutex(), mSetVolumeReentrantTid);
     if (mStatus != NO_ERROR) {
         return mStatus;
     }
@@ -1408,7 +1410,7 @@
         return NO_ERROR;
     }
 
-    Mutex::Autolock _l(mLock);
+    audio_utils::lock_guard _l(mutex());
     if (mStatus != NO_ERROR) {
         return mStatus;
     }
@@ -1438,7 +1440,7 @@
 
 status_t EffectModule::setMode(audio_mode_t mode)
 {
-    Mutex::Autolock _l(mLock);
+    audio_utils::lock_guard _l(mutex());
     if (mStatus != NO_ERROR) {
         return mStatus;
     }
@@ -1460,7 +1462,7 @@
 
 status_t EffectModule::setAudioSource(audio_source_t source)
 {
-    Mutex::Autolock _l(mLock);
+    audio_utils::lock_guard _l(mutex());
     if (mStatus != NO_ERROR) {
         return mStatus;
     }
@@ -1478,7 +1480,7 @@
 
 status_t EffectModule::setOffloaded(bool offloaded, audio_io_handle_t io)
 {
-    Mutex::Autolock _l(mLock);
+    audio_utils::lock_guard _l(mutex());
     if (mStatus != NO_ERROR) {
         return mStatus;
     }
@@ -1511,7 +1513,7 @@
 
 bool EffectModule::isOffloaded() const
 {
-    Mutex::Autolock _l(mLock);
+    audio_utils::lock_guard _l(mutex());
     return mOffloaded;
 }
 
@@ -1582,7 +1584,7 @@
 
 status_t EffectModule::getConfigs(
         audio_config_base_t* inputCfg, audio_config_base_t* outputCfg, bool* isOutput) const {
-    Mutex::Autolock _l(mLock);
+    audio_utils::lock_guard _l(mutex());
     if (mConfig.inputCfg.mask == 0 || mConfig.outputCfg.mask == 0) {
         return NO_INIT;
     }
@@ -1617,7 +1619,7 @@
     EffectBase::dump(fd, args);
 
     String8 result;
-    bool locked = AudioFlinger::dumpTryLock(mLock);
+    const bool locked = afutils::dumpTryLock(mutex());
 
     result.append("\t\tStatus Engine:\n");
     result.appendFormat("\t\t%03d    %p\n",
@@ -1633,7 +1635,7 @@
             mConfig.inputCfg.samplingRate,
             mConfig.inputCfg.channels,
             mConfig.inputCfg.format,
-            formatToString((audio_format_t)mConfig.inputCfg.format).c_str());
+            toString(static_cast<audio_format_t>(mConfig.inputCfg.format)).c_str());
 
     result.append("\t\t- Output configuration:\n");
     result.append("\t\t\tBuffer     Frames  Smp rate Channels Format\n");
@@ -1643,7 +1645,7 @@
             mConfig.outputCfg.samplingRate,
             mConfig.outputCfg.channels,
             mConfig.outputCfg.format,
-            formatToString((audio_format_t)mConfig.outputCfg.format).c_str());
+            toString(static_cast<audio_format_t>(mConfig.outputCfg.format)).c_str());
 
     result.appendFormat("\t\t- HAL buffers:\n"
             "\t\t\tIn(%s) InConversion(%s) Out(%s) OutConversion(%s)\n",
@@ -1660,7 +1662,7 @@
     }
 
     if (locked) {
-        mLock.unlock();
+        mutex().unlock();
     }
 }
 
@@ -1783,7 +1785,7 @@
 
 Status EffectHandle::enable(int32_t* _aidl_return)
 {
-    AutoMutex _l(mLock);
+    audio_utils::lock_guard _l(mutex());
     ALOGV("enable %p", this);
     sp<IAfEffectBase> effect = mEffect.promote();
     if (effect == 0 || mDisconnected) {
@@ -1822,7 +1824,7 @@
 Status EffectHandle::disable(int32_t* _aidl_return)
 {
     ALOGV("disable %p", this);
-    AutoMutex _l(mLock);
+    audio_utils::lock_guard _l(mutex());
     sp<IAfEffectBase> effect = mEffect.promote();
     if (effect == 0 || mDisconnected) {
         RETURN(DEAD_OBJECT);
@@ -1855,7 +1857,7 @@
 
 void EffectHandle::disconnect(bool unpinIfLast)
 {
-    AutoMutex _l(mLock);
+    audio_utils::lock_guard _l(mutex());
     ALOGV("disconnect(%s) %p", unpinIfLast ? "true" : "false", this);
     if (mDisconnected) {
         if (unpinIfLast) {
@@ -1882,7 +1884,7 @@
         }
         mCblkMemory.clear();    // free the shared memory before releasing the heap it belongs to
         // Client destructor must run with AudioFlinger client mutex locked
-        Mutex::Autolock _l2(mClient->audioFlinger()->mClientLock);
+        audio_utils::lock_guard _l2(mClient->afClientCallback()->clientMutex());
         mClient.clear();
     }
 }
@@ -1894,7 +1896,7 @@
 
 Status EffectHandle::getConfig(
         media::EffectConfig* _config, int32_t* _aidl_return) {
-    AutoMutex _l(mLock);
+    audio_utils::lock_guard _l(mutex());
     sp<IAfEffectBase> effect = mEffect.promote();
     if (effect == nullptr || mDisconnected) {
         RETURN(DEAD_OBJECT);
@@ -1961,7 +1963,7 @@
         return disable(_aidl_return);
     }
 
-    AutoMutex _l(mLock);
+    audio_utils::lock_guard _l(mutex());
     sp<IAfEffectBase> effect = mEffect.promote();
     if (effect == 0 || mDisconnected) {
         RETURN(DEAD_OBJECT);
@@ -2091,7 +2093,7 @@
 void EffectHandle::dumpToBuffer(char* buffer, size_t size) const
 NO_THREAD_SAFETY_ANALYSIS  // conditional try lock
 {
-    bool locked = mCblk != NULL && AudioFlinger::dumpTryLock(mCblk->lock);
+    const bool locked = mCblk != nullptr && afutils::dumpTryLock(mCblk->lock);
 
     snprintf(buffer, size, "\t\t\t%5d    %5d  %3s    %3s  %5u  %5u\n",
             (mClient == 0) ? getpid() : mClient->pid(),
@@ -2112,31 +2114,22 @@
 
 /* static */
 sp<IAfEffectChain> IAfEffectChain::create(
-        const wp<IAfThreadBase>& wThread,
+        const sp<IAfThreadBase>& thread,
         audio_session_t sessionId)
 {
-    // TODO(b/288339104) no weak pointer cast.
-    return sp<EffectChain>::make(wThread, sessionId);
+    return sp<EffectChain>::make(thread, sessionId);
 }
 
-EffectChain::EffectChain(const wp<IAfThreadBase>& thread,
+EffectChain::EffectChain(const sp<IAfThreadBase>& thread,
                                        audio_session_t sessionId)
     : mSessionId(sessionId), mActiveTrackCnt(0), mTrackCnt(0), mTailBufferCount(0),
       mLeftVolume(UINT_MAX), mRightVolume(UINT_MAX),
       mNewLeftVolume(UINT_MAX), mNewRightVolume(UINT_MAX),
       mEffectCallback(new EffectCallback(wp<EffectChain>(this), thread))
 {
-    const sp<IAfThreadBase> p = thread.promote();
-    if (p == nullptr) {
-        return;
-    }
-    mStrategy = p->getStrategyForStream(AUDIO_STREAM_MUSIC);
-    mMaxTailBuffers = ((kProcessTailDurationMs * p->sampleRate()) / 1000) /
-                                    p->frameCount();
-}
-
-EffectChain::~EffectChain()
-{
+    mStrategy = thread->getStrategyForStream(AUDIO_STREAM_MUSIC);
+    mMaxTailBuffers = ((kProcessTailDurationMs * thread->sampleRate()) / 1000) /
+                                    thread->frameCount();
 }
 
 // getEffectFromDesc_l() must be called with IAfThreadBase::mutex() held
@@ -2184,7 +2177,7 @@
 std::vector<int> EffectChain::getEffectIds() const
 {
     std::vector<int> ids;
-    Mutex::Autolock _l(mLock);
+    audio_utils::lock_guard _l(mutex());
     for (size_t i = 0; i < mEffects.size(); i++) {
         ids.push_back(mEffects[i]->id());
     }
@@ -2193,11 +2186,11 @@
 
 void EffectChain::clearInputBuffer()
 {
-    Mutex::Autolock _l(mLock);
+    audio_utils::lock_guard _l(mutex());
     clearInputBuffer_l();
 }
 
-// Must be called with EffectChain::mLock locked
+// Must be called with EffectChain::mutex() locked
 void EffectChain::clearInputBuffer_l()
 {
     if (mInBuffer == NULL) {
@@ -2210,7 +2203,7 @@
     mInBuffer->commit();
 }
 
-// Must be called with EffectChain::mLock locked
+// Must be called with EffectChain::mutex() locked
 void EffectChain::process_l()
 {
     // never process effects when:
@@ -2269,7 +2262,7 @@
                                                    audio_session_t sessionId,
                                                    bool pinned)
 {
-    Mutex::Autolock _l(mLock);
+    audio_utils::lock_guard _l(mutex());
     effect = new EffectModule(mEffectCallback, desc, id, sessionId, pinned, AUDIO_PORT_HANDLE_NONE);
     status_t lStatus = effect->status();
     if (lStatus == NO_ERROR) {
@@ -2284,10 +2277,10 @@
 // addEffect_l() must be called with IAfThreadBase::mutex() held
 status_t EffectChain::addEffect_l(const sp<IAfEffectModule>& effect)
 {
-    Mutex::Autolock _l(mLock);
+    audio_utils::lock_guard _l(mutex());
     return addEffect_ll(effect);
 }
-// addEffect_l() must be called with IAfThreadBase::mLock and EffectChain::mutex() held
+// addEffect_l() must be called with IAfThreadBase::mutex() and EffectChain::mutex() held
 status_t EffectChain::addEffect_ll(const sp<IAfEffectModule>& effect)
 {
     effect->setCallback(mEffectCallback);
@@ -2454,7 +2447,7 @@
 size_t EffectChain::removeEffect_l(const sp<IAfEffectModule>& effect,
                                                  bool release)
 {
-    Mutex::Autolock _l(mLock);
+    audio_utils::lock_guard _l(mutex());
     size_t size = mEffects.size();
     uint32_t type = effect->desc().flags & EFFECT_FLAG_TYPE_MASK;
 
@@ -2541,7 +2534,7 @@
     return false;
 }
 
-// setVolume_l() must be called with IAfThreadBase::mLock or EffectChain::mLock held
+// setVolume_l() must be called with IAfThreadBase::mutex() or EffectChain::mutex() held
 bool EffectChain::setVolume_l(uint32_t *left, uint32_t *right, bool force)
 {
     uint32_t newLeft = *left;
@@ -2617,7 +2610,7 @@
     return volumeControlIndex.has_value();
 }
 
-// resetVolume_l() must be called with IAfThreadBase::mutex() or EffectChain::mLock held
+// resetVolume_l() must be called with IAfThreadBase::mutex() or EffectChain::mutex() held
 void EffectChain::resetVolume_l()
 {
     if ((mLeftVolume != UINT_MAX) && (mRightVolume != UINT_MAX)) {
@@ -2628,7 +2621,7 @@
 }
 
 // containsHapticGeneratingEffect_l must be called with
-// IAfThreadBase::mutex() or EffectChain::mLock held
+// IAfThreadBase::mutex() or EffectChain::mutex() held
 bool EffectChain::containsHapticGeneratingEffect_l()
 {
     for (size_t i = 0; i < mEffects.size(); ++i) {
@@ -2641,7 +2634,7 @@
 
 void EffectChain::setHapticIntensity_l(int id, os::HapticScale intensity)
 {
-    Mutex::Autolock _l(mLock);
+    audio_utils::lock_guard _l(mutex());
     for (size_t i = 0; i < mEffects.size(); ++i) {
         mEffects[i]->setHapticIntensity(id, intensity);
     }
@@ -2649,7 +2642,7 @@
 
 void EffectChain::syncHalEffectsState()
 {
-    Mutex::Autolock _l(mLock);
+    audio_utils::lock_guard _l(mutex());
     for (size_t i = 0; i < mEffects.size(); i++) {
         if (mEffects[i]->state() == EffectModule::ACTIVE ||
                 mEffects[i]->state() == EffectModule::STOPPING) {
@@ -2667,7 +2660,7 @@
     result.appendFormat("    %zu effects for session %d\n", numEffects, mSessionId);
 
     if (numEffects) {
-        bool locked = AudioFlinger::dumpTryLock(mLock);
+        const bool locked = afutils::dumpTryLock(mutex());
         // failed to lock - AudioFlinger is probably deadlocked
         if (!locked) {
             result.append("\tCould not lock mutex:\n");
@@ -2690,7 +2683,7 @@
         }
 
         if (locked) {
-            mLock.unlock();
+            mutex().unlock();
         }
     } else {
         write(fd, result.c_str(), result.size());
@@ -2739,12 +2732,12 @@
                 sp<IAfEffectModule> effect = desc->mEffect.promote();
                 if (effect != 0) {
                     effect->setSuspended(false);
-                    effect->lock();
+                    effect->mutex().lock();
                     IAfEffectHandle *handle = effect->controlHandle_l();
                     if (handle != NULL && !handle->disconnected()) {
                         effect->setEnabled_l(handle->enabled());
                     }
-                    effect->unlock();
+                    effect->mutex().unlock();
                 }
                 desc->mEffect.clear();
             }
@@ -2894,7 +2887,7 @@
 
 bool EffectChain::isNonOffloadableEnabled() const
 {
-    Mutex::Autolock _l(mLock);
+    audio_utils::lock_guard _l(mutex());
     return isNonOffloadableEnabled_l();
 }
 
@@ -2911,7 +2904,7 @@
 
 void EffectChain::setThread(const sp<IAfThreadBase>& thread)
 {
-    Mutex::Autolock _l(mLock);
+    audio_utils::lock_guard _l(mutex());
     mEffectCallback->setThread(thread);
 }
 
@@ -2940,7 +2933,7 @@
 
 bool EffectChain::isRawCompatible() const
 {
-    Mutex::Autolock _l(mLock);
+    audio_utils::lock_guard _l(mutex());
     for (const auto &effect : mEffects) {
         if (effect->isProcessImplemented()) {
             return false;
@@ -2952,7 +2945,7 @@
 
 bool EffectChain::isFastCompatible() const
 {
-    Mutex::Autolock _l(mLock);
+    audio_utils::lock_guard _l(mutex());
     for (const auto &effect : mEffects) {
         if (effect->isProcessImplemented()
                 && effect->isImplementationSoftware()) {
@@ -2964,7 +2957,7 @@
 }
 
 bool EffectChain::isBitPerfectCompatible() const {
-    Mutex::Autolock _l(mLock);
+    audio_utils::lock_guard _l(mutex());
     for (const auto &effect : mEffects) {
         if (effect->isProcessImplemented()
                 && effect->isImplementationSoftware()) {
@@ -2975,10 +2968,10 @@
     return true;
 }
 
-// isCompatibleWithThread_l() must be called with thread->mLock held
+// isCompatibleWithThread_l() must be called with thread->mutex() held
 bool EffectChain::isCompatibleWithThread_l(const sp<IAfThreadBase>& thread) const
 {
-    Mutex::Autolock _l(mLock);
+    audio_utils::lock_guard _l(mutex());
     for (size_t i = 0; i < mEffects.size(); i++) {
         if (thread->checkEffectCompatibility_l(&(mEffects[i]->desc()), mSessionId) != NO_ERROR) {
             return false;
@@ -3003,12 +2996,12 @@
 bool EffectChain::EffectCallback::updateOrphanEffectChains(
         const sp<IAfEffectBase>& effect) {
     // in EffectChain context, an EffectBase is always from an EffectModule so static cast is safe
-    return mAudioFlinger.updateOrphanEffectChains(effect->asEffectModule());
+    return mAfThreadCallback->updateOrphanEffectChains(effect->asEffectModule());
 }
 
 status_t EffectChain::EffectCallback::allocateHalBuffer(
         size_t size, sp<EffectBufferHalInterface>* buffer) {
-    return mAudioFlinger.mEffectsFactoryHal->allocateBuffer(size, buffer);
+    return mAfThreadCallback->getEffectsFactoryHal()->allocateBuffer(size, buffer);
 }
 
 status_t EffectChain::EffectCallback::addEffectToHal(
@@ -3282,7 +3275,7 @@
 status_t DeviceEffectProxy::setEnabled(bool enabled, bool fromHandle)
 {
     status_t status = EffectBase::setEnabled(enabled, fromHandle);
-    Mutex::Autolock _l(mProxyLock);
+    audio_utils::lock_guard _l(proxyMutex());
     if (status == NO_ERROR) {
         for (auto& handle : mEffectHandles) {
             Status bs;
@@ -3335,7 +3328,7 @@
         ALOGV("%s sink %d checkPort status %d", __func__, i, status);
     }
     if (status == NO_ERROR || status == ALREADY_EXISTS) {
-        Mutex::Autolock _l(mProxyLock);
+        audio_utils::lock_guard _l(proxyMutex());
         mEffectHandles.emplace(patchHandle, handle);
     }
     ALOGW_IF(status == BAD_VALUE,
@@ -3345,7 +3338,10 @@
 }
 
 status_t DeviceEffectProxy::checkPort(const IAfPatchPanel::Patch& patch,
-        const struct audio_port_config *port, sp<IAfEffectHandle> *handle) {
+        const struct audio_port_config *port, sp<IAfEffectHandle> *handle)
+NO_THREAD_SAFETY_ANALYSIS
+// calling function 'createEffect_l' requires holding mutex 'AudioFlinger_Mutex' exclusively
+{
 
     ALOGV("%s type %d device type %d address %s device ID %d patch.isSoftware() %d",
             __func__, port->type, port->ext.device.type,
@@ -3367,7 +3363,7 @@
     status_t status = NAME_NOT_FOUND;
 
     if (mDescriptor.flags & EFFECT_FLAG_HW_ACC_TUNNEL) {
-        Mutex::Autolock _l(mProxyLock);
+        audio_utils::lock_guard _l(proxyMutex());
         mDevicePort = *port;
         mHalEffect = new EffectModule(mMyCallback,
                                       const_cast<effect_descriptor_t *>(&mDescriptor),
@@ -3431,7 +3427,7 @@
 void DeviceEffectProxy::onReleasePatch(audio_patch_handle_t patchHandle) {
     sp<IAfEffectHandle> effect;
     {
-        Mutex::Autolock _l(mProxyLock);
+        audio_utils::lock_guard _l(proxyMutex());
         if (mEffectHandles.find(patchHandle) != mEffectHandles.end()) {
             effect = mEffectHandles.at(patchHandle);
             mEffectHandles.erase(patchHandle);
@@ -3442,7 +3438,7 @@
 
 size_t DeviceEffectProxy::removeEffect(const sp<IAfEffectModule>& effect)
 {
-    Mutex::Autolock _l(mProxyLock);
+    audio_utils::lock_guard _l(proxyMutex());
     if (effect == mHalEffect) {
         mHalEffect->release_l();
         mHalEffect.clear();
@@ -3503,7 +3499,7 @@
     const Vector<String16> args;
     EffectBase::dump(fd, args);
 
-    const bool locked = AudioFlinger::dumpTryLock(mProxyLock);
+    const bool locked = afutils::dumpTryLock(proxyMutex());
     if (!locked) {
         String8 result("DeviceEffectProxy may be deadlocked\n");
         write(fd, result.c_str(), result.size());
@@ -3533,7 +3529,7 @@
     }
 
     if (locked) {
-        mLock.unlock();
+        proxyMutex().unlock();
     }
 }
 
diff --git a/services/audioflinger/Effects.h b/services/audioflinger/Effects.h
index 1a894e3..6b1d9cf 100644
--- a/services/audioflinger/Effects.h
+++ b/services/audioflinger/Effects.h
@@ -15,6 +15,17 @@
 ** limitations under the License.
 */
 
+#pragma once
+
+#include "DeviceEffectManager.h"
+#include "IAfEffect.h"
+
+#include <android-base/macros.h>  // DISALLOW_COPY_AND_ASSIGN
+#include <mediautils/Synchronization.h>
+#include <private/media/AudioEffectShared.h>
+
+#include <map>  // avoid transitive dependency
+
 namespace android {
 
 //--- Audio Effect Management
@@ -100,8 +111,7 @@
     bool             isPinned() const final { return mPinned; }
     void             unPin() final { mPinned = false; }
 
-    void             lock() ACQUIRE(mLock) final { mLock.lock(); }
-    void             unlock() RELEASE(mLock) final { mLock.unlock(); }
+    audio_utils::mutex& mutex() const final { return mMutex; }
 
     status_t         updatePolicyState() final;
 
@@ -124,7 +134,8 @@
 
     DISALLOW_COPY_AND_ASSIGN(EffectBase);
 
-    mutable Mutex mLock;      // mutex for process, commands and handles list protection
+    // mutex for process, commands and handles list protection
+    mutable audio_utils::mutex mMutex;
     mediautils::atomic_sp<EffectCallbackInterface> mCallback; // parent effect chain
     const int                 mId;        // this instance unique ID
     const audio_session_t     mSessionId; // audio session ID
@@ -137,9 +148,10 @@
                 // First handle in mHandles has highest priority and controls the effect module
 
     // Audio policy effect state management
-    // Mutex protecting transactions with audio policy manager as mLock cannot
+    // Mutex protecting transactions with audio policy manager as mutex() cannot
     // be held to avoid cross deadlocks with audio policy mutex
-    Mutex                     mPolicyLock;
+    audio_utils::mutex& policyMutex() const { return mPolicyMutex; }
+    mutable audio_utils::mutex mPolicyMutex;
     // Effect is registered in APM or not
     bool                      mPolicyRegistered = false;
     // Effect enabled state communicated to APM. Enabled state corresponds to
@@ -261,9 +273,10 @@
     uint32_t mInChannelCountRequested;
     uint32_t mOutChannelCountRequested;
 
+    template <typename MUTEX>
     class AutoLockReentrant {
     public:
-        AutoLockReentrant(Mutex& mutex, pid_t allowedTid)
+        AutoLockReentrant(MUTEX& mutex, pid_t allowedTid)
             : mMutex(gettid() == allowedTid ? nullptr : &mutex)
         {
             if (mMutex != nullptr) mMutex->lock();
@@ -272,7 +285,7 @@
             if (mMutex != nullptr) mMutex->unlock();
         }
     private:
-        Mutex * const mMutex;
+        MUTEX * const mMutex;
     };
 
     static constexpr pid_t INVALID_PID = (pid_t)-1;
@@ -353,7 +366,8 @@
 private:
     DISALLOW_COPY_AND_ASSIGN(EffectHandle);
 
-    Mutex mLock;                             // protects IEffect method calls
+    audio_utils::mutex& mutex() const { return mMutex; }
+    mutable audio_utils::mutex mMutex; // protects IEffect method calls
     const wp<IAfEffectBase> mEffect;               // pointer to controlled EffectModule
     const sp<media::IEffectClient> mEffectClient;  // callback interface for client notifications
     /*const*/ sp<Client> mClient;            // client for shared memory allocation, see
@@ -382,17 +396,12 @@
 // it also provide it's own input buffer used by the track as accumulation buffer.
 class EffectChain : public IAfEffectChain {
 public:
-    EffectChain(const wp<IAfThreadBase>& wThread, audio_session_t sessionId);
-    ~EffectChain() override;
+    EffectChain(const sp<IAfThreadBase>& thread, audio_session_t sessionId);
 
     void process_l() final;
 
-    void lock() ACQUIRE(mLock) final {
-        mLock.lock();
-    }
-    void unlock() RELEASE(mLock) final {
-        mLock.unlock();
-    }
+    audio_utils::mutex& mutex() const final { return mMutex; }
+
     status_t createEffect_l(sp<IAfEffectModule>& effect,
                             effect_descriptor_t *desc,
                             int id,
@@ -478,7 +487,7 @@
     // Is this EffectChain compatible with the bit-perfect audio flag.
     bool isBitPerfectCompatible() const final;
 
-    // isCompatibleWithThread_l() must be called with thread->mLock held
+    // isCompatibleWithThread_l() must be called with thread->mutex() held
     bool isCompatibleWithThread_l(const sp<IAfThreadBase>& thread) const final;
 
     bool containsHapticGeneratingEffect_l() final;
@@ -516,16 +525,11 @@
         // Note: ctors taking a weak pointer to their owner must not promote it
         // during construction (but may keep a reference for later promotion).
         EffectCallback(const wp<EffectChain>& owner,
-                const wp<IAfThreadBase>& thread)
+                const sp<IAfThreadBase>& thread)  // we take a sp<> but store a wp<>.
             : mChain(owner)
-            , mThread(thread)
-            , mAudioFlinger(*AudioFlinger::gAudioFlinger) {
-            const sp<IAfThreadBase> base = thread.promote();
-            if (base != nullptr) {
-                mThreadType = base->type();
-            } else {
-                mThreadType = IAfThreadBase::MIXER;  // assure a consistent value.
-            }
+            , mThread(thread) {
+            mThreadType = thread->type();
+            mAfThreadCallback = thread->afThreadCallback();
         }
 
         status_t createEffectHal(const effect_uuid_t *pEffectUuid,
@@ -566,7 +570,7 @@
         wp<IAfEffectChain> chain() const final { return mChain; }
 
         bool isAudioPolicyReady() const final {
-            return mAudioFlinger.isAudioPolicyReady();
+            return mAfThreadCallback->isAudioPolicyReady();
         }
 
         wp<IAfThreadBase> thread() const { return mThread.load(); }
@@ -574,12 +578,13 @@
         void setThread(const sp<IAfThreadBase>& thread) {
             mThread = thread;
             mThreadType = thread->type();
+            mAfThreadCallback = thread->afThreadCallback();
         }
 
     private:
         const wp<IAfEffectChain> mChain;
         mediautils::atomic_wp<IAfThreadBase> mThread;
-        AudioFlinger &mAudioFlinger;  // implementation detail: outer instance always exists.
+        sp<IAfThreadCallback> mAfThreadCallback;
         IAfThreadBase::type_t mThreadType;
     };
 
@@ -618,7 +623,7 @@
 
     std::optional<size_t> findVolumeControl_l(size_t from, size_t to) const;
 
-    mutable  Mutex mLock;        // mutex protecting effect list
+    mutable audio_utils::mutex mMutex; // mutex protecting effect list
              Vector<sp<IAfEffectModule>> mEffects; // list of effect modules
              audio_session_t mSessionId; // audio session ID
              sp<EffectBufferHalInterface> mInBuffer;  // chain input buffer
@@ -643,7 +648,7 @@
 
              const sp<EffectCallback> mEffectCallback;
 
-             wp<EffectModule> mVolumeControlEffect;
+             wp<IAfEffectModule> mVolumeControlEffect;
 };
 
 class DeviceEffectProxy : public IAfDeviceEffectProxy, public EffectBase {
@@ -748,9 +753,10 @@
     const sp<DeviceEffectManagerCallback> mManagerCallback;
     const sp<ProxyCallback> mMyCallback;
 
-    mutable Mutex mProxyLock;
-    std::map<audio_patch_handle_t, sp<IAfEffectHandle>> mEffectHandles; // protected by mProxyLock
-    sp<IAfEffectModule> mHalEffect; // protected by mProxyLock
+    audio_utils::mutex& proxyMutex() const { return mProxyMutex; }
+    mutable audio_utils::mutex mProxyMutex;
+    std::map<audio_patch_handle_t, sp<IAfEffectHandle>> mEffectHandles; // protected by mProxyMutex
+    sp<IAfEffectModule> mHalEffect; // protected by mProxyMutex
     struct audio_port_config mDevicePort = { .id = AUDIO_PORT_HANDLE_NONE };
     const bool mNotifyFramesProcessed;
 };
diff --git a/services/audioflinger/IAfEffect.h b/services/audioflinger/IAfEffect.h
index 6937fd9..ea0c6d9 100644
--- a/services/audioflinger/IAfEffect.h
+++ b/services/audioflinger/IAfEffect.h
@@ -16,9 +16,23 @@
 
 #pragma once
 
+#include "IAfPatchPanel.h"  // full class Patch definition needed
+
+#include <android/media/AudioVibratorInfo.h>
+#include <android/media/BnEffect.h>
+#include <android/media/BnEffectClient.h>
+#include <audio_utils/mutex.h>
+#include <media/AudioCommonTypes.h>  // product_strategy_t
+#include <media/AudioDeviceTypeAddr.h>
+#include <media/audiohal/EffectHalInterface.h>
+#include <utils/RefBase.h>
+#include <vibrator/ExternalVibration.h>
+
 namespace android {
 
+class Client;
 class DeviceEffectManagerCallback;
+
 class IAfDeviceEffectProxy;
 class IAfEffectBase;
 class IAfEffectChain;
@@ -128,8 +142,7 @@
     virtual ssize_t removeHandle_l(IAfEffectHandle *handle) = 0;
     virtual IAfEffectHandle* controlHandle_l() = 0;
 
-    virtual void lock() = 0;
-    virtual void unlock() = 0;
+    virtual audio_utils::mutex& mutex() const = 0;
 };
 
 class IAfEffectModule : public virtual IAfEffectBase {
@@ -192,7 +205,7 @@
     // Most of these methods are accessed from AudioFlinger::Thread
 public:
     static sp<IAfEffectChain> create(
-            const wp<IAfThreadBase>& wThread,
+            const sp<IAfThreadBase>& thread,
             audio_session_t sessionId);
 
     // special key used for an entry in mSuspendedEffects keyed vector
@@ -205,8 +218,7 @@
 
     virtual void process_l() = 0;
 
-    virtual void lock() = 0;
-    virtual void unlock() = 0;
+    virtual audio_utils::mutex& mutex() const = 0;
 
     virtual status_t createEffect_l(sp<IAfEffectModule>& effect,
                             effect_descriptor_t *desc,
@@ -350,7 +362,7 @@
             const IAfPatchPanel::Patch& patch) = 0;
     virtual void onReleasePatch(audio_patch_handle_t patchHandle) = 0;
 
-    virtual void dump2(int fd, int spaces) const = 0; // TODO(b/288339104) naming?
+    virtual void dump2(int fd, int spaces) const = 0; // TODO(b/291319101) naming?
 
 private:
     // used by DeviceEffectProxy
diff --git a/services/audioflinger/IAfPatchPanel.h b/services/audioflinger/IAfPatchPanel.h
index 29bd4ab..5a6621e 100644
--- a/services/audioflinger/IAfPatchPanel.h
+++ b/services/audioflinger/IAfPatchPanel.h
@@ -16,14 +16,21 @@
 
 #pragma once
 
+// The following includes are required because we have class definitions below
+// for EndPoint and Patch, which precludes using a forward declaration only.
+#include "IAfThread.h"  // IAfThreadBase IAfMmapThread IAfPlaybackThread IAfRecordThread
+#include "IAfTrack.h"   // IAfPatchRecord IAfPatchTrack
+
+#include <datapath/AudioHwDevice.h>
+#include <media/DeviceDescriptorBase.h>
+#include <utils/Log.h>      // ALOG used in this file
+#include <utils/RefBase.h>  // avoid transitive dependency
+#include <utils/Thread.h>
+
 namespace android {
 
 class IAfPatchPanel;
-class IAfPatchRecord;
-class IAfPatchTrack;
-class IAfPlaybackThread;
-class IAfRecordThread;
-class IAfThreadBase;
+class PatchCommandThread;
 
 class SoftwarePatch {
 public:
@@ -38,8 +45,7 @@
           mRecordThreadHandle(recordThreadHandle) {}
     SoftwarePatch(const SoftwarePatch&) = default;
 
-    // Must be called under AudioFlinger::mLock
-    status_t getLatencyMs_l(double* latencyMs) const;
+    status_t getLatencyMs_l(double* latencyMs) const REQUIRES(audio_utils::AudioFlinger_Mutex);
     audio_patch_handle_t getPatchHandle() const { return mPatchHandle; };
     audio_io_handle_t getPlaybackThreadHandle() const { return mPlaybackThreadHandle; };
     audio_io_handle_t getRecordThreadHandle() const { return mRecordThreadHandle; };
@@ -51,9 +57,48 @@
     const audio_io_handle_t mRecordThreadHandle;
 };
 
+class IAfPatchPanelCallback : public virtual RefBase {
+public:
+    virtual void closeThreadInternal_l(const sp<IAfPlaybackThread>& thread) REQUIRES(mutex()) = 0;
+    virtual void closeThreadInternal_l(const sp<IAfRecordThread>& thread) REQUIRES(mutex()) = 0;
+    virtual IAfPlaybackThread* primaryPlaybackThread_l() const REQUIRES(mutex()) = 0;
+    virtual IAfPlaybackThread* checkPlaybackThread_l(audio_io_handle_t output) const
+            REQUIRES(mutex()) = 0;
+    virtual IAfRecordThread* checkRecordThread_l(audio_io_handle_t input) const
+            REQUIRES(mutex()) = 0;
+    virtual IAfMmapThread* checkMmapThread_l(audio_io_handle_t io) const REQUIRES(mutex()) = 0;
+    virtual sp<IAfThreadBase> openInput_l(audio_module_handle_t module,
+            audio_io_handle_t* input,
+            audio_config_t* config,
+            audio_devices_t device,
+            const char* address,
+            audio_source_t source,
+            audio_input_flags_t flags,
+            audio_devices_t outputDevice,
+            const String8& outputDeviceAddress) REQUIRES(mutex()) = 0;
+    virtual sp<IAfThreadBase> openOutput_l(audio_module_handle_t module,
+            audio_io_handle_t* output,
+            audio_config_t* halConfig,
+            audio_config_base_t* mixerConfig,
+            audio_devices_t deviceType,
+            const String8& address,
+            audio_output_flags_t flags) REQUIRES(mutex()) = 0;
+    virtual audio_utils::mutex& mutex() const
+            RETURN_CAPABILITY(audio_utils::AudioFlinger_Mutex) = 0;
+    virtual const DefaultKeyedVector<audio_module_handle_t, AudioHwDevice*>&
+            getAudioHwDevs_l() const REQUIRES(mutex()) = 0;
+    virtual audio_unique_id_t nextUniqueId(audio_unique_id_use_t use) = 0;
+    virtual const sp<PatchCommandThread>& getPatchCommandThread() = 0;
+    virtual void updateDownStreamPatches_l(
+            const struct audio_patch* patch, const std::set<audio_io_handle_t>& streams)
+            REQUIRES(mutex()) = 0;
+    virtual void updateOutDevicesForRecordThreads_l(const DeviceDescriptorBaseVector& devices)
+            REQUIRES(mutex()) = 0;
+};
+
 class IAfPatchPanel : public virtual RefBase {
 public:
-    static sp<IAfPatchPanel> create(AudioFlinger* audioFlinger);
+    static sp<IAfPatchPanel> create(const sp<IAfPatchPanelCallback>& afPatchPanelCallback);
 
     // Extraction of inner Endpoint and Patch classes would require interfaces
     // (in the Endpoint case a templated interface) but that seems
@@ -92,9 +137,12 @@
         sp<const ThreadType> const_thread() const { return mThread; }
         sp<const TrackType> const_track() const { return mTrack; }
 
-        void closeConnections(const sp<IAfPatchPanel>& panel) {
+        void closeConnections_l(const sp<IAfPatchPanel>& panel)
+                REQUIRES(audio_utils::AudioFlinger_Mutex)
+                NO_THREAD_SAFETY_ANALYSIS // this is broken in clang
+        {
             if (mHandle != AUDIO_PATCH_HANDLE_NONE) {
-                panel->releaseAudioPatch(mHandle);
+                panel->releaseAudioPatch_l(mHandle);
                 mHandle = AUDIO_PATCH_HANDLE_NONE;
             }
             if (mThread != nullptr) {
@@ -176,8 +224,10 @@
 
         friend void swap(Patch& a, Patch& b) noexcept { a.swap(b); }
 
-        status_t createConnections(const sp<IAfPatchPanel>& panel);
-        void clearConnections(const sp<IAfPatchPanel>& panel);
+        status_t createConnections_l(const sp<IAfPatchPanel>& panel)
+                REQUIRES(audio_utils::AudioFlinger_Mutex);
+        void clearConnections_l(const sp<IAfPatchPanel>& panel)
+                REQUIRES(audio_utils::AudioFlinger_Mutex);
         bool isSoftware() const {
             return mRecord.handle() != AUDIO_PATCH_HANDLE_NONE ||
                    mPlayback.handle() != AUDIO_PATCH_HANDLE_NONE;
@@ -209,22 +259,27 @@
     };
 
     /* List connected audio ports and their attributes */
-    virtual status_t listAudioPorts(unsigned int* num_ports, struct audio_port* ports) = 0;
+    virtual status_t listAudioPorts_l(unsigned int* num_ports, struct audio_port* ports)
+            REQUIRES(audio_utils::AudioFlinger_Mutex) = 0;
 
     /* Get supported attributes for a given audio port */
-    virtual status_t getAudioPort(struct audio_port_v7* port) = 0;
+    virtual status_t getAudioPort_l(struct audio_port_v7* port)
+            REQUIRES(audio_utils::AudioFlinger_Mutex) = 0;
 
     /* Create a patch between several source and sink ports */
-    virtual status_t createAudioPatch(
+    virtual status_t createAudioPatch_l(
             const struct audio_patch* patch,
             audio_patch_handle_t* handle,
-            bool endpointPatch = false) = 0;
+            bool endpointPatch = false)
+            REQUIRES(audio_utils::AudioFlinger_Mutex) = 0;
 
     /* Release a patch */
-    virtual status_t releaseAudioPatch(audio_patch_handle_t handle) = 0;
+    virtual status_t releaseAudioPatch_l(audio_patch_handle_t handle)
+            REQUIRES(audio_utils::AudioFlinger_Mutex) = 0;
 
     /* List connected audio devices and they attributes */
-    virtual status_t listAudioPatches(unsigned int* num_patches, struct audio_patch* patches) = 0;
+    virtual status_t listAudioPatches_l(unsigned int* num_patches, struct audio_patch* patches)
+            REQUIRES(audio_utils::AudioFlinger_Mutex) = 0;
 
     // Retrieves all currently estrablished software patches for a stream
     // opened on an intermediate module.
@@ -239,13 +294,14 @@
 
     virtual void dump(int fd) const = 0;
 
-    // Must be called under AudioFlinger::mLock
+    virtual const std::map<audio_patch_handle_t, Patch>& patches_l() const
+            REQUIRES(audio_utils::AudioFlinger_Mutex) = 0;
 
-    virtual const std::map<audio_patch_handle_t, Patch>& patches_l() const = 0;
+    virtual status_t getLatencyMs_l(audio_patch_handle_t patchHandle, double* latencyMs) const
+            REQUIRES(audio_utils::AudioFlinger_Mutex) = 0;
 
-    virtual status_t getLatencyMs_l(audio_patch_handle_t patchHandle, double* latencyMs) const = 0;
-
-    virtual void closeThreadInternal_l(const sp<IAfThreadBase>& thread) const = 0;
+    virtual void closeThreadInternal_l(const sp<IAfThreadBase>& thread) const
+            REQUIRES(audio_utils::AudioFlinger_Mutex) = 0;
 };
 
 }  // namespace android
diff --git a/services/audioflinger/IAfThread.h b/services/audioflinger/IAfThread.h
index 8b87ed7..fc2f805 100644
--- a/services/audioflinger/IAfThread.h
+++ b/services/audioflinger/IAfThread.h
@@ -16,7 +16,25 @@
 
 #pragma once
 
-#include "IAfTrack.h"
+#include <android/media/IAudioTrackCallback.h>
+#include <android/media/IEffectClient.h>
+#include <audiomanager/IAudioManager.h>
+#include <audio_utils/mutex.h>
+#include <audio_utils/MelProcessor.h>
+#include <binder/MemoryDealer.h>
+#include <datapath/AudioStreamIn.h>
+#include <datapath/AudioStreamOut.h>
+#include <datapath/VolumeInterface.h>
+#include <fastpath/FastMixerDumpState.h>
+#include <media/DeviceDescriptorBase.h>
+#include <media/MmapStreamInterface.h>
+#include <media/audiohal/StreamHalInterface.h>
+#include <media/nblog/NBLog.h>
+#include <timing/SyncEvent.h>
+#include <utils/RefBase.h>
+#include <vibrator/ExternalVibration.h>
+
+#include <optional>
 
 namespace android {
 
@@ -27,6 +45,80 @@
 class IAfPlaybackThread;
 class IAfRecordThread;
 
+class IAfEffectChain;
+class IAfEffectHandle;
+class IAfEffectModule;
+class IAfPatchPanel;
+class IAfPatchRecord;
+class IAfPatchTrack;
+class IAfRecordTrack;
+class IAfTrack;
+class IAfTrackBase;
+class Client;
+class MelReporter;
+
+// Used internally for Threads.cpp and AudioFlinger.cpp
+struct stream_type_t {
+    float volume = 1.f;
+    bool mute = false;
+};
+
+// Note this is exposed through IAfThreadBase::afThreadCallback()
+// and hence may be used by the Effect / Track framework.
+class IAfThreadCallback : public virtual RefBase {
+public:
+    virtual audio_utils::mutex& mutex() const
+            RETURN_CAPABILITY(audio_utils::AudioFlinger_Mutex) = 0;
+    virtual bool isNonOffloadableGlobalEffectEnabled_l() const
+            REQUIRES(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
+            REQUIRES(mutex()) = 0;
+    virtual bool masterMute_l() const
+            REQUIRES(mutex()) = 0;
+    virtual float getMasterBalance_l() const
+            REQUIRES(mutex()) = 0;
+    virtual bool streamMute_l(audio_stream_type_t stream) const
+            REQUIRES(mutex()) = 0;
+    virtual audio_mode_t getMode() const = 0;
+    virtual bool isLowRamDevice() const = 0;
+    virtual bool isAudioPolicyReady() const = 0;  // Effects
+    virtual uint32_t getScreenState() const = 0;
+    virtual std::optional<media::AudioVibratorInfo> getDefaultVibratorInfo_l() const
+            REQUIRES(mutex()) = 0;
+    virtual const sp<IAfPatchPanel>& getPatchPanel() const = 0;
+    virtual const sp<MelReporter>& getMelReporter() const = 0;
+    virtual const sp<EffectsFactoryHalInterface>& getEffectsFactoryHal() const = 0;
+    virtual sp<IAudioManager> getOrCreateAudioManager() = 0;  // Tracks
+
+    virtual bool updateOrphanEffectChains(const sp<IAfEffectModule>& effect)
+            EXCLUDES_AudioFlinger_Mutex = 0;
+    virtual status_t moveEffectChain_ll(audio_session_t sessionId,
+            IAfPlaybackThread* srcThread, IAfPlaybackThread* dstThread)
+            REQUIRES(mutex(), audio_utils::ThreadBase_Mutex) = 0;
+
+    virtual void requestLogMerge() = 0;
+    virtual sp<NBLog::Writer> newWriter_l(size_t size, const char *name)
+            REQUIRES(mutex()) = 0;
+    virtual void unregisterWriter(const sp<NBLog::Writer>& writer) = 0;
+
+    virtual sp<audioflinger::SyncEvent> createSyncEvent(AudioSystem::sync_event_t type,
+            audio_session_t triggerSession,
+            audio_session_t listenerSession,
+            const audioflinger::SyncEventCallback& callBack,
+            const wp<IAfTrackBase>& cookie)
+            EXCLUDES_AudioFlinger_Mutex = 0;
+
+    virtual void ioConfigChanged(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;
+    virtual void onSupportedLatencyModesChanged(
+            audio_io_handle_t output, const std::vector<audio_latency_mode_t>& modes)
+            EXCLUDES_AudioFlinger_ClientMutex = 0;
+};
+
 class IAfThreadBase : public virtual RefBase {
 public:
     enum type_t {
@@ -43,6 +135,10 @@
     };
 
     static const char* threadTypeToString(type_t type);
+    static std::string formatToString(audio_format_t format);  // compliant for MediaMetrics
+    static bool isValidPcmSinkChannelMask(audio_channel_mask_t channelMask);
+    static bool isValidPcmSinkFormat(audio_format_t format);
+
     virtual status_t readyToRun() = 0;
     virtual void clearPowerManager() = 0;
     virtual status_t initCheck() const = 0;
@@ -129,7 +225,8 @@
             status_t* status /*non-NULL*/,
             bool pinned,
             bool probe,
-            bool notifyFramesProcessed) = 0;
+            bool notifyFramesProcessed)
+            REQUIRES(audio_utils::AudioFlinger_Mutex) = 0;
 
     // return values for hasAudioSession (bit field)
     enum effect_state {
@@ -171,7 +268,8 @@
     // 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
-    virtual status_t addEffect_l(const sp<IAfEffectModule>& effect) = 0;
+    virtual status_t addEffect_ll(const sp<IAfEffectModule>& effect)
+            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;
@@ -226,7 +324,8 @@
     // deliver stats to mediametrics.
     virtual void sendStatistics(bool force) = 0;
 
-    virtual Mutex& mutex() const = 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;
@@ -237,8 +336,10 @@
     virtual void invalidateTracksForAudioSession(audio_session_t sessionId) const = 0;
 
     virtual bool isStreamInitialized() const = 0;
-    virtual void startMelComputation_l(const sp<audio_utils::MelProcessor>& processor) = 0;
-    virtual void stopMelComputation_l() = 0;
+    virtual void startMelComputation_l(const sp<audio_utils::MelProcessor>& processor)
+            REQUIRES(audio_utils::AudioFlinger_Mutex) = 0;
+    virtual void stopMelComputation_l()
+            REQUIRES(audio_utils::AudioFlinger_Mutex) = 0;
 
     virtual product_strategy_t getStrategyForStream(audio_stream_type_t stream) const = 0;
 
@@ -250,30 +351,31 @@
     virtual sp<IAfDuplicatingThread> asIAfDuplicatingThread() { return nullptr; }
     virtual sp<IAfPlaybackThread> asIAfPlaybackThread() { return nullptr; }
     virtual sp<IAfRecordThread> asIAfRecordThread() { return nullptr; }
-    virtual AudioFlinger* audioFlinger() const = 0;
+    virtual IAfThreadCallback* afThreadCallback() const = 0;
 };
 
 class IAfPlaybackThread : public virtual IAfThreadBase, public virtual VolumeInterface {
 public:
     static sp<IAfPlaybackThread> createBitPerfectThread(
-            const sp<AudioFlinger>& audioflinger, AudioStreamOut* output, audio_io_handle_t id,
-            bool systemReady);
+            const sp<IAfThreadCallback>& afThreadCallback, AudioStreamOut* output,
+            audio_io_handle_t id, bool systemReady);
 
     static sp<IAfPlaybackThread> createDirectOutputThread(
-            const sp<AudioFlinger>& audioFlinger, AudioStreamOut* output, audio_io_handle_t id,
-            bool systemReady, const audio_offload_info_t& offloadInfo);
+            const sp<IAfThreadCallback>& afThreadCallback, AudioStreamOut* output,
+            audio_io_handle_t id, bool systemReady, const audio_offload_info_t& offloadInfo);
 
     static sp<IAfPlaybackThread> createMixerThread(
-            const sp<AudioFlinger>& audioFlinger, AudioStreamOut* output, audio_io_handle_t id,
-            bool systemReady, type_t type = MIXER, audio_config_base_t* mixerConfig = nullptr);
+            const sp<IAfThreadCallback>& afThreadCallback, AudioStreamOut* output,
+            audio_io_handle_t id, bool systemReady, type_t type = MIXER,
+            audio_config_base_t* mixerConfig = nullptr);
 
     static sp<IAfPlaybackThread> createOffloadThread(
-            const sp<AudioFlinger>& audioFlinger, AudioStreamOut* output, audio_io_handle_t id,
-            bool systemReady, const audio_offload_info_t& offloadInfo);
+            const sp<IAfThreadCallback>& afThreadCallback, AudioStreamOut* output,
+            audio_io_handle_t id, bool systemReady, const audio_offload_info_t& offloadInfo);
 
     static sp<IAfPlaybackThread> createSpatializerThread(
-            const sp<AudioFlinger>& audioFlinger, AudioStreamOut* output, audio_io_handle_t id,
-            bool systemReady, audio_config_base_t* mixerConfig);
+            const sp<IAfThreadCallback>& afThreadCallback, AudioStreamOut* output,
+            audio_io_handle_t id, bool systemReady, audio_config_base_t* mixerConfig);
 
     static constexpr int8_t kMaxTrackStopRetriesOffload = 2;
 
@@ -313,7 +415,8 @@
             audio_port_handle_t portId,
             const sp<media::IAudioTrackCallback>& callback,
             bool isSpatialized,
-            bool isBitPerfect) = 0;
+            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;
@@ -388,7 +491,7 @@
 class IAfDuplicatingThread : public virtual IAfPlaybackThread {
 public:
     static sp<IAfDuplicatingThread> create(
-            const sp<AudioFlinger>& audioFlinger, IAfPlaybackThread* mainThread,
+            const sp<IAfThreadCallback>& afThreadCallback, IAfPlaybackThread* mainThread,
             audio_io_handle_t id, bool systemReady);
 
     virtual void addOutputTrack(IAfPlaybackThread* thread) = 0;
@@ -399,8 +502,8 @@
 class IAfRecordThread : public virtual IAfThreadBase {
 public:
     static sp<IAfRecordThread> create(
-            const sp<AudioFlinger>& audioFlinger, AudioStreamIn* input, audio_io_handle_t id,
-            bool systemReady);
+            const sp<IAfThreadCallback>& afThreadCallback, AudioStreamIn* input,
+            audio_io_handle_t id, bool systemReady);
 
     virtual sp<IAfRecordTrack> createRecordTrack_l(
             const sp<Client>& client,
@@ -417,7 +520,8 @@
             pid_t tid,
             status_t* status /*non-NULL*/,
             audio_port_handle_t portId,
-            int32_t maxSharedAudioHistoryMs) = 0;
+            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;
 
@@ -486,10 +590,10 @@
     virtual status_t getExternalPosition(uint64_t* position, int64_t* timeNanos) const = 0;
     virtual status_t reportData(const void* buffer, size_t frameCount) = 0;
 
-    // TODO(b/288339104)  move to IAfThreadBase?
+    // TODO(b/291317898)  move to IAfThreadBase?
     virtual void invalidateTracks(std::set<audio_port_handle_t>& portIds) = 0;
 
-    // Sets the UID records silence - TODO(b/288339104)  move to IAfMmapCaptureThread
+    // Sets the UID records silence - TODO(b/291317898)  move to IAfMmapCaptureThread
     virtual void setRecordSilenced(audio_port_handle_t portId, bool silenced) = 0;
 
     virtual sp<IAfMmapPlaybackThread> asIAfMmapPlaybackThread() { return nullptr; }
@@ -499,8 +603,8 @@
 class IAfMmapPlaybackThread : public virtual IAfMmapThread, public virtual VolumeInterface {
 public:
     static sp<IAfMmapPlaybackThread> create(
-            const sp<AudioFlinger>& audioFlinger, audio_io_handle_t id, AudioHwDevice* hwDev,
-            AudioStreamOut* output, bool systemReady);
+            const sp<IAfThreadCallback>& afThreadCallback, audio_io_handle_t id,
+            AudioHwDevice* hwDev, AudioStreamOut* output, bool systemReady);
 
     virtual AudioStreamOut* clearOutput() = 0;
 };
@@ -508,8 +612,8 @@
 class IAfMmapCaptureThread : public virtual IAfMmapThread {
 public:
     static sp<IAfMmapCaptureThread> create(
-            const sp<AudioFlinger>& audioFlinger, audio_io_handle_t id, AudioHwDevice* hwDev,
-            AudioStreamIn* input, bool systemReady);
+            const sp<IAfThreadCallback>& afThreadCallback, audio_io_handle_t id,
+            AudioHwDevice* hwDev, AudioStreamIn* input, bool systemReady);
 
     virtual AudioStreamIn* clearInput() = 0;
 };
diff --git a/services/audioflinger/IAfTrack.h b/services/audioflinger/IAfTrack.h
index 35338fa..cf30ded 100644
--- a/services/audioflinger/IAfTrack.h
+++ b/services/audioflinger/IAfTrack.h
@@ -16,8 +16,27 @@
 
 #pragma once
 
+#include <android/media/BnAudioRecord.h>
+#include <android/media/BnAudioTrack.h>
+#include <audiomanager/IAudioManager.h>
+#include <binder/IMemory.h>
+#include <fastpath/FastMixerDumpState.h>
+#include <media/AudioSystem.h>
+#include <media/VolumeShaper.h>
+#include <private/media/AudioTrackShared.h>
+#include <timing/SyncEvent.h>
+#include <timing/SynchronizedRecordState.h>
+#include <utils/RefBase.h>
+#include <vibrator/ExternalVibration.h>
+
+#include <vector>
+
 namespace android {
 
+class Client;
+class ResamplerBufferProvider;
+struct Source;
+
 class IAfDuplicatingThread;
 class IAfPatchRecord;
 class IAfPatchTrack;
@@ -209,12 +228,12 @@
 
     /**
      * For RecordTrack
-     * TODO(b/288339104) either use this or add asRecordTrack or asTrack etc.
+     * TODO(b/291317964) either use this or add asRecordTrack or asTrack etc.
      */
     virtual void handleSyncStartEvent(const sp<audioflinger::SyncEvent>& event __unused){};
 
     // For Thread use, fast tracks and offloaded tracks only
-    // TODO(b/288339104) rearrange to IAfTrack.
+    // TODO(b/291317964) rearrange to IAfTrack.
     virtual bool isStopped() const = 0;
     virtual bool isStopping() const = 0;
     virtual bool isStopping_1() const = 0;
@@ -388,7 +407,7 @@
     virtual ExtendedAudioBufferProvider* asExtendedAudioBufferProvider() = 0;
     virtual VolumeProvider* asVolumeProvider() = 0;
 
-    // TODO(b/288339104) split into getter/setter
+    // TODO(b/291317964) split into getter/setter
     virtual FillingStatus& fillingStatus() = 0;
     virtual int8_t& retryCount() = 0;
     virtual FastTrackUnderruns& fastTrackUnderruns() = 0;
@@ -397,7 +416,6 @@
 // playback track, used by DuplicatingThread
 class IAfOutputTrack : public virtual IAfTrack {
 public:
-    // TODO(b/288339104) void*
     static sp<IAfOutputTrack> create(
             IAfPlaybackThread* playbackThread,
             IAfDuplicatingThread* sourceThread, uint32_t sampleRate,
@@ -416,7 +434,6 @@
 
 class IAfMmapTrack : public virtual IAfTrackBase {
 public:
-    // TODO(b/288339104) void*
     static sp<IAfMmapTrack> create(IAfThreadBase* thread,
             const audio_attributes_t& attr,
             uint32_t sampleRate,
@@ -454,7 +471,6 @@
     // Only one AIDL IAudioRecord interface adapter should be created per RecordTrack.
     static sp<media::IAudioRecord> createIAudioRecordAdapter(const sp<IAfRecordTrack>& recordTrack);
 
-    // TODO(b/288339104) void*
     static sp<IAfRecordTrack> create(IAfRecordThread* thread,
             const sp<Client>& client,
             const audio_attributes_t& attr,
@@ -477,7 +493,7 @@
     // set the buffer overflow flag and return previous value
     virtual bool setOverflow() = 0;
 
-    // TODO(b/288339104) handleSyncStartEvent in IAfTrackBase should move here.
+    // TODO(b/291317964) handleSyncStartEvent in IAfTrackBase should move here.
     virtual void clearSyncStartEvent() = 0;
     virtual void updateTrackFrameInfo(
             int64_t trackFramesReleased, int64_t sourceFramesRead, uint32_t halSampleRate,
diff --git a/services/audioflinger/MelReporter.cpp b/services/audioflinger/MelReporter.cpp
index 5c580cd..add453f 100644
--- a/services/audioflinger/MelReporter.cpp
+++ b/services/audioflinger/MelReporter.cpp
@@ -18,7 +18,7 @@
 // #define LOG_NDEBUG 0
 #define LOG_TAG "MelReporter"
 
-#include "AudioFlinger.h"
+#include "MelReporter.h"
 
 #include <android/media/ISoundDoseCallback.h>
 #include <audio_utils/power.h>
@@ -65,7 +65,7 @@
 
 void MelReporter::activateInternalSoundDoseComputation() {
     {
-        std::lock_guard _l(mLock);
+        audio_utils::lock_guard _l(mutex());
         if (!mUseHalSoundDoseInterface) {
             // no need to start internal MEL on active patches
             return;
@@ -77,7 +77,7 @@
 }
 
 void MelReporter::onFirstRef() {
-    mAudioFlinger.mPatchCommandThread->addListener(this);
+    mAfMelReporterCallback->getPatchCommandThread()->addListener(this);
 }
 
 bool MelReporter::shouldComputeMelForDeviceType(audio_devices_t device) {
@@ -111,8 +111,8 @@
         return;
     }
 
-    std::lock_guard _laf(mAudioFlinger.mLock);
-    std::lock_guard _l(mLock);
+    audio_utils::lock_guard _laf(mAfMelReporterCallback->mutex());  // AudioFlinger_Mutex
+    audio_utils::lock_guard _l(mutex());
     auto activeMelPatchId = activePatchStreamHandle_l(streamHandle);
     if (!activeMelPatchId) {
         ALOGV("%s stream handle %d does not have an active patch", __func__, streamHandle);
@@ -171,8 +171,8 @@
     }
 
     if (!newPatch.deviceHandles.empty()) {
-        std::lock_guard _afl(mAudioFlinger.mLock);
-        std::lock_guard _l(mLock);
+        audio_utils::lock_guard _afl(mAfMelReporterCallback->mutex());  // AudioFlinger_Mutex
+        audio_utils::lock_guard _l(mutex());
         ALOGV("%s add patch handle %d to active devices", __func__, handle);
         startMelComputationForActivePatch_l(newPatch);
         newPatch.csdActive = true;
@@ -183,7 +183,7 @@
 void MelReporter::startMelComputationForActivePatch_l(const ActiveMelPatch& patch)
 NO_THREAD_SAFETY_ANALYSIS  // access of AudioFlinger::checkOutputThread_l
 {
-    auto outputThread = mAudioFlinger.checkOutputThread_l(patch.streamHandle);
+    auto outputThread = mAfMelReporterCallback->checkOutputThread_l(patch.streamHandle);
     if (outputThread == nullptr) {
         ALOGE("%s cannot find thread for stream handle %d", __func__, patch.streamHandle);
         return;
@@ -213,7 +213,7 @@
 
     ActiveMelPatch melPatch;
     {
-        std::lock_guard _l(mLock);
+        audio_utils::lock_guard _l(mutex());
 
         auto patchIt = mActiveMelPatches.find(handle);
         if (patchIt == mActiveMelPatches.end()) {
@@ -226,8 +226,8 @@
         mActiveMelPatches.erase(patchIt);
     }
 
-    std::lock_guard _afl(mAudioFlinger.mLock);
-    std::lock_guard _l(mLock);
+    audio_utils::lock_guard _afl(mAfMelReporterCallback->mutex());  // AudioFlinger_Mutex
+    audio_utils::lock_guard _l(mutex());
     stopMelComputationForPatch_l(melPatch);
 }
 
@@ -239,7 +239,7 @@
 
 void MelReporter::stopInternalMelComputation() {
     ALOGV("%s", __func__);
-    std::lock_guard _l(mLock);
+    audio_utils::lock_guard _l(mutex());
     mActiveMelPatches.clear();
     mUseHalSoundDoseInterface = true;
 }
@@ -252,7 +252,7 @@
         return;
     }
 
-    auto outputThread = mAudioFlinger.checkOutputThread_l(patch.streamHandle);
+    auto outputThread = mAfMelReporterCallback->checkOutputThread_l(patch.streamHandle);
 
     ALOGV("%s: stop MEL for stream id: %d", __func__, patch.streamHandle);
     for (const auto& deviceId : patch.deviceHandles) {
@@ -286,7 +286,7 @@
 }
 
 std::string MelReporter::dump() {
-    std::lock_guard _l(mLock);
+    audio_utils::lock_guard _l(mutex());
     std::string output("\nSound Dose:\n");
     output.append(mSoundDoseManager->dump());
     return output;
diff --git a/services/audioflinger/MelReporter.h b/services/audioflinger/MelReporter.h
index 50fa24b..07ab94d 100644
--- a/services/audioflinger/MelReporter.h
+++ b/services/audioflinger/MelReporter.h
@@ -17,23 +17,36 @@
 
 #pragma once
 
-#include <mutex>
+#include "IAfPatchPanel.h"
+#include "PatchCommandThread.h"
+
+#include <audio_utils/mutex.h>
 #include <sounddose/SoundDoseManager.h>
+
 #include <unordered_map>
 
 namespace android {
 
 constexpr static int kMaxTimestampDeltaInSec = 120;
 
+class IAfMelReporterCallback : public virtual RefBase {
+public:
+    virtual audio_utils::mutex& mutex() const
+            RETURN_CAPABILITY(audio_utils::AudioFlinger_Mutex) = 0;
+    virtual const sp<PatchCommandThread>& getPatchCommandThread() = 0;
+    virtual sp<IAfThreadBase> checkOutputThread_l(audio_io_handle_t ioHandle) const
+            REQUIRES(mutex()) = 0;
+};
+
 /**
  * Class for listening to new patches and starting the MEL computation. MelReporter is
  * concealed within AudioFlinger, their lifetimes are the same.
  */
 class MelReporter : public PatchCommandThread::PatchCommandListener {
 public:
-    explicit MelReporter(AudioFlinger& audioFlinger)
-        : mAudioFlinger(audioFlinger),
-          mSoundDoseManager(sp<SoundDoseManager>::make()) {}
+    explicit MelReporter(const sp<IAfMelReporterCallback>& afMelReporterCallback)
+        : mAfMelReporterCallback(afMelReporterCallback),
+         mSoundDoseManager(sp<SoundDoseManager>::make()) {}
 
     void onFirstRef() override;
 
@@ -51,7 +64,7 @@
      * implementation, false otherwise.
      */
     bool activateHalSoundDoseComputation(const std::string& module,
-                                         const sp<DeviceHalInterface>& device);
+            const sp<DeviceHalInterface>& device) EXCLUDES_MelReporter_Mutex;
 
     /**
      * Activates the MEL reporting from internal framework values. These are used
@@ -59,7 +72,7 @@
      * Note: the internal CSD computation does not guarantee a certification with
      * IEC62368-1 3rd edition or EN50332-3
      */
-    void activateInternalSoundDoseComputation();
+    void activateInternalSoundDoseComputation() EXCLUDES_MelReporter_Mutex;
 
     sp<media::ISoundDose> getSoundDoseInterface(const sp<media::ISoundDoseCallback>& callback);
 
@@ -67,8 +80,9 @@
 
     // PatchCommandListener methods
     void onCreateAudioPatch(audio_patch_handle_t handle,
-        const IAfPatchPanel::Patch& patch) final;
-    void onReleaseAudioPatch(audio_patch_handle_t handle) final;
+            const IAfPatchPanel::Patch& patch) final
+            EXCLUDES_AudioFlinger_Mutex;
+    void onReleaseAudioPatch(audio_patch_handle_t handle) final EXCLUDES_AudioFlinger_Mutex;
 
     /**
      * The new metadata can determine whether we should compute MEL for the given thread.
@@ -76,7 +90,9 @@
      * Otherwise, this method will disable CSD.
      **/
     void updateMetadataForCsd(audio_io_handle_t streamHandle,
-                              const std::vector<playback_track_metadata_v7_t>& metadataVec);
+            const std::vector<playback_track_metadata_v7_t>& metadataVec)
+            EXCLUDES_AudioFlinger_Mutex;
+
 private:
     struct ActiveMelPatch {
         audio_io_handle_t streamHandle{AUDIO_IO_HANDLE_NONE};
@@ -88,30 +104,34 @@
     bool shouldComputeMelForDeviceType(audio_devices_t device);
 
     void stopInternalMelComputation();
+    audio_utils::mutex& mutex() const RETURN_CAPABILITY(audio_utils::MelReporter_Mutex) {
+        return mMutex;
+    }
 
-    /** Should be called with the following order of locks: mAudioFlinger.mLock -> mLock. */
-    void stopMelComputationForPatch_l(const ActiveMelPatch& patch) REQUIRES(mLock);
+    /** Should be called with the following order of locks: mAudioFlinger.mutex() -> mutex(). */
+    void stopMelComputationForPatch_l(const ActiveMelPatch& patch) REQUIRES(mutex());
 
-    /** Should be called with the following order of locks: mAudioFlinger.mLock -> mLock. */
-    void startMelComputationForActivePatch_l(const ActiveMelPatch& patch) REQUIRES(mLock);
+    /** Should be called with the following order of locks: mAudioFlinger.mutex() -> mutex(). */
+    void startMelComputationForActivePatch_l(const ActiveMelPatch& patch) REQUIRES(mutex());
 
     std::optional<audio_patch_handle_t>
-    activePatchStreamHandle_l(audio_io_handle_t streamHandle) REQUIRES(mLock);
+    activePatchStreamHandle_l(audio_io_handle_t streamHandle) REQUIRES(mutex());
 
-    bool useHalSoundDoseInterface_l() REQUIRES(mLock);
+    bool useHalSoundDoseInterface_l() REQUIRES(mutex());
 
-    AudioFlinger& mAudioFlinger;  // does not own the object
+    const sp<IAfMelReporterCallback> mAfMelReporterCallback;
 
-    sp<SoundDoseManager> mSoundDoseManager;
+    /* const */ sp<SoundDoseManager> mSoundDoseManager;  // set onFirstRef
 
     /**
      * Lock for protecting the active mel patches. Do not mix with the AudioFlinger lock.
-     * Locking order AudioFlinger::mLock -> PatchCommandThread::mLock -> MelReporter::mLock.
+     * Locking order AudioFlinger::mutex() -> PatchCommandThread::mutex() -> MelReporter::mutex().
      */
-    std::mutex mLock;
-    std::unordered_map<audio_patch_handle_t, ActiveMelPatch> mActiveMelPatches GUARDED_BY(mLock);
-    std::unordered_map<audio_port_handle_t, int> mActiveDevices GUARDED_BY(mLock);
-    bool mUseHalSoundDoseInterface GUARDED_BY(mLock) = false;
+    mutable audio_utils::mutex mMutex;
+    std::unordered_map<audio_patch_handle_t, ActiveMelPatch> mActiveMelPatches
+            GUARDED_BY(mutex());
+    std::unordered_map<audio_port_handle_t, int> mActiveDevices GUARDED_BY(mutex());
+    bool mUseHalSoundDoseInterface GUARDED_BY(mutex()) = false;
 };
 
 }  // namespace android
diff --git a/services/audioflinger/MmapTracks.h b/services/audioflinger/MmapTracks.h
index 16c141f..85ce142 100644
--- a/services/audioflinger/MmapTracks.h
+++ b/services/audioflinger/MmapTracks.h
@@ -17,6 +17,10 @@
 
 #pragma once
 
+#include "TrackBase.h"
+
+#include <android/content/AttributionSourceState.h>
+
 namespace android {
 
 // playback track
@@ -62,8 +66,6 @@
                             mute_state_t muteState)
                             /* REQUIRES(MmapPlaybackThread::mLock) */ final;
 private:
-    friend class MmapThread;
-
     DISALLOW_COPY_AND_ASSIGN(MmapTrack);
 
     // AudioBufferProvider interface
diff --git a/services/audioflinger/PatchCommandThread.cpp b/services/audioflinger/PatchCommandThread.cpp
index 46d6549..f4c76d6 100644
--- a/services/audioflinger/PatchCommandThread.cpp
+++ b/services/audioflinger/PatchCommandThread.cpp
@@ -18,7 +18,9 @@
 #define LOG_TAG "AudioFlinger::PatchCommandThread"
 //#define LOG_NDEBUG 0
 
-#include "AudioFlinger.h"
+#include "PatchCommandThread.h"
+
+#include <utils/Log.h>
 
 namespace android {
 
@@ -27,7 +29,7 @@
 PatchCommandThread::~PatchCommandThread() {
     exit();
 
-    std::lock_guard _l(mLock);
+    audio_utils::lock_guard _l(mutex());
     mCommands.clear();
 }
 
@@ -37,7 +39,7 @@
 
 void PatchCommandThread::addListener(const sp<PatchCommandListener>& listener) {
     ALOGV("%s add listener %p", __func__, static_cast<void*>(listener.get()));
-    std::lock_guard _l(mListenerLock);
+    audio_utils::lock_guard _l(listenerMutex());
     mListeners.emplace_back(listener);
 }
 
@@ -57,9 +59,8 @@
 }
 
 bool PatchCommandThread::threadLoop()
-NO_THREAD_SAFETY_ANALYSIS  // bug in clang compiler.
 {
-    std::unique_lock _l(mLock);
+    audio_utils::unique_lock _l(mutex());
 
     while (!exitPending()) {
         while (!mCommands.empty() && !exitPending()) {
@@ -69,7 +70,7 @@
 
             std::vector<wp<PatchCommandListener>> listenersCopy;
             {
-                std::lock_guard _ll(mListenerLock);
+                audio_utils::lock_guard _ll(listenerMutex());
                 listenersCopy = mListeners;
             }
 
@@ -120,7 +121,7 @@
 }
 
 void PatchCommandThread::sendCommand(const sp<Command>& command) {
-    std::lock_guard _l(mLock);
+    audio_utils::lock_guard _l(mutex());
     mCommands.emplace_back(command);
     mWaitWorkCV.notify_one();
 }
@@ -146,7 +147,7 @@
 void PatchCommandThread::exit() {
     ALOGV("%s", __func__);
     {
-        std::lock_guard _l(mLock);
+        audio_utils::lock_guard _l(mutex());
         requestExit();
         mWaitWorkCV.notify_one();
     }
diff --git a/services/audioflinger/PatchCommandThread.h b/services/audioflinger/PatchCommandThread.h
index fe16675..8ca96f1 100644
--- a/services/audioflinger/PatchCommandThread.h
+++ b/services/audioflinger/PatchCommandThread.h
@@ -17,6 +17,14 @@
 
 #pragma once
 
+#include "IAfPatchPanel.h"
+
+#include <utils/RefBase.h>  // avoid transitive dependency
+#include <utils/Thread.h>  // avoid transitive dependency
+
+#include <deque>
+#include <mutex>  // avoid transitive dependency
+
 namespace android {
 
 class Command;
@@ -42,10 +50,12 @@
     PatchCommandThread() : Thread(false /* canCallJava */) {}
     ~PatchCommandThread() override;
 
-    void addListener(const sp<PatchCommandListener>& listener);
+    void addListener(const sp<PatchCommandListener>& listener)
+            EXCLUDES_PatchCommandThread_ListenerMutex;
 
-    void createAudioPatch(audio_patch_handle_t handle, const IAfPatchPanel::Patch& patch);
-    void releaseAudioPatch(audio_patch_handle_t handle);
+    void createAudioPatch(audio_patch_handle_t handle, const IAfPatchPanel::Patch& patch)
+            EXCLUDES_PatchCommandThread_Mutex;
+    void releaseAudioPatch(audio_patch_handle_t handle) EXCLUDES_PatchCommandThread_Mutex;
 
     // Thread virtuals
     void onFirstRef() override;
@@ -54,9 +64,8 @@
     void exit();
 
     void createAudioPatchCommand(audio_patch_handle_t handle,
-            const IAfPatchPanel::Patch& patch);
-    void releaseAudioPatchCommand(audio_patch_handle_t handle);
-
+            const IAfPatchPanel::Patch& patch) EXCLUDES_PatchCommandThread_Mutex;
+    void releaseAudioPatchCommand(audio_patch_handle_t handle) EXCLUDES_PatchCommandThread_Mutex;
 private:
     class CommandData;
 
@@ -90,15 +99,22 @@
         audio_patch_handle_t mHandle;
     };
 
-    void sendCommand(const sp<Command>& command);
+    void sendCommand(const sp<Command>& command) EXCLUDES_PatchCommandThread_Mutex;
 
-    std::string mThreadName;
-    std::mutex mLock;
-    std::condition_variable mWaitWorkCV;
-    std::deque<sp<Command>> mCommands GUARDED_BY(mLock); // list of pending commands
+    audio_utils::mutex& mutex() const RETURN_CAPABILITY(audio_utils::PatchCommandThread_Mutex) {
+        return mMutex;
+    }
+    audio_utils::mutex& listenerMutex() const
+            RETURN_CAPABILITY(audio_utils::PatchCommandThread_ListenerMutex) {
+        return mListenerMutex;
+    }
 
-    std::mutex mListenerLock;
-    std::vector<wp<PatchCommandListener>> mListeners GUARDED_BY(mListenerLock);
+    mutable audio_utils::mutex mMutex;
+    audio_utils::condition_variable mWaitWorkCV;
+    std::deque<sp<Command>> mCommands GUARDED_BY(mutex()); // list of pending commands
+
+    mutable audio_utils::mutex mListenerMutex;
+    std::vector<wp<PatchCommandListener>> mListeners GUARDED_BY(listenerMutex());
 };
 
 }  // namespace android
diff --git a/services/audioflinger/PatchPanel.cpp b/services/audioflinger/PatchPanel.cpp
index 2302bd8..7d3900b 100644
--- a/services/audioflinger/PatchPanel.cpp
+++ b/services/audioflinger/PatchPanel.cpp
@@ -19,17 +19,16 @@
 #define LOG_TAG "AudioFlinger::PatchPanel"
 //#define LOG_NDEBUG 0
 
-#include "Configuration.h"
-#include <utils/Log.h>
-#include <audio_utils/primitives.h>
-
-#include "AudioFlinger.h"
 #include "PatchPanel.h"
+#include "PatchCommandThread.h"
+
+#include <audio_utils/primitives.h>
 #include <media/AudioParameter.h>
 #include <media/AudioValidator.h>
 #include <media/DeviceDescriptorBase.h>
 #include <media/PatchBuilder.h>
 #include <mediautils/ServiceUtilities.h>
+#include <utils/Log.h>
 
 // ----------------------------------------------------------------------------
 
@@ -48,56 +47,9 @@
 
 namespace android {
 
-/* List connected audio ports and their attributes */
-status_t AudioFlinger::listAudioPorts(unsigned int *num_ports,
-                                struct audio_port *ports)
-{
-    Mutex::Autolock _l(mLock);
-    return mPatchPanel->listAudioPorts(num_ports, ports);
-}
-
-/* Get supported attributes for a given audio port */
-status_t AudioFlinger::getAudioPort(struct audio_port_v7 *port) {
-    status_t status = AudioValidator::validateAudioPort(*port);
-    if (status != NO_ERROR) {
-        return status;
-    }
-
-    Mutex::Autolock _l(mLock);
-    return mPatchPanel->getAudioPort(port);
-}
-
-/* Connect a patch between several source and sink ports */
-status_t AudioFlinger::createAudioPatch(const struct audio_patch *patch,
-                                   audio_patch_handle_t *handle)
-{
-    status_t status = AudioValidator::validateAudioPatch(*patch);
-    if (status != NO_ERROR) {
-        return status;
-    }
-
-    Mutex::Autolock _l(mLock);
-    return mPatchPanel->createAudioPatch(patch, handle);
-}
-
-/* Disconnect a patch */
-status_t AudioFlinger::releaseAudioPatch(audio_patch_handle_t handle)
-{
-    Mutex::Autolock _l(mLock);
-    return mPatchPanel->releaseAudioPatch(handle);
-}
-
-/* List connected audio ports and they attributes */
-status_t AudioFlinger::listAudioPatches(unsigned int *num_patches,
-                                  struct audio_patch *patches)
-{
-    Mutex::Autolock _l(mLock);
-    return mPatchPanel->listAudioPatches(num_patches, patches);
-}
-
 /* static */
-sp<IAfPatchPanel> IAfPatchPanel::create(AudioFlinger* audioFlinger) {
-    return sp<PatchPanel>::make(audioFlinger);
+sp<IAfPatchPanel> IAfPatchPanel::create(const sp<IAfPatchPanelCallback>& afPatchPanelCallback) {
+    return sp<PatchPanel>::make(afPatchPanelCallback);
 }
 
 status_t SoftwarePatch::getLatencyMs_l(double* latencyMs) const {
@@ -119,10 +71,10 @@
 {
     if (const auto recordThread = thread->asIAfRecordThread();
             recordThread) {
-        mAudioFlinger.closeThreadInternal_l(recordThread);
+        mAfPatchPanelCallback->closeThreadInternal_l(recordThread);
     } else if (const auto playbackThread = thread->asIAfPlaybackThread();
             playbackThread) {
-        mAudioFlinger.closeThreadInternal_l(playbackThread);
+        mAfPatchPanelCallback->closeThreadInternal_l(playbackThread);
     } else {
         LOG_ALWAYS_FATAL("%s: Endpoints only accept IAfPlayback and IAfRecord threads, "
                 "invalid thread, id: %d  type: %d",
@@ -131,7 +83,7 @@
 }
 
 /* List connected audio ports and their attributes */
-status_t PatchPanel::listAudioPorts(unsigned int* /* num_ports */,
+status_t PatchPanel::listAudioPorts_l(unsigned int* /* num_ports */,
                                 struct audio_port *ports __unused)
 {
     ALOGV(__func__);
@@ -139,14 +91,14 @@
 }
 
 /* Get supported attributes for a given audio port */
-status_t PatchPanel::getAudioPort(struct audio_port_v7* port)
+status_t PatchPanel::getAudioPort_l(struct audio_port_v7* port)
 {
     if (port->type != AUDIO_PORT_TYPE_DEVICE) {
         // Only query the HAL when the port is a device.
         // TODO: implement getAudioPort for mix.
         return INVALID_OPERATION;
     }
-    AudioHwDevice* hwDevice = findAudioHwDeviceByModule(port->ext.device.hw_module);
+    AudioHwDevice* hwDevice = findAudioHwDeviceByModule_l(port->ext.device.hw_module);
     if (hwDevice == nullptr) {
         ALOGW("%s cannot find hw module %d", __func__, port->ext.device.hw_module);
         return BAD_VALUE;
@@ -158,7 +110,7 @@
 }
 
 /* Connect a patch between several source and sink ports */
-status_t PatchPanel::createAudioPatch(const struct audio_patch* patch,
+status_t PatchPanel::createAudioPatch_l(const struct audio_patch* patch,
                                    audio_patch_handle_t *handle,
                                    bool endpointPatch)
  //unlocks AudioFlinger::mLock when calling IAfThreadBase::sendCreateAudioPatchConfigEvent
@@ -192,7 +144,7 @@
             // 1) if a software patch is present, release the playback and capture threads and
             // tracks created. This will also release the corresponding audio HAL patches
             if (removedPatch.isSoftware()) {
-                removedPatch.clearConnections(this);
+                removedPatch.clearConnections_l(this);
             }
             // 2) if the new patch and old patch source or sink are devices from different
             // hw modules,  clear the audio HAL patches now because they will not be updated
@@ -217,7 +169,7 @@
                     // removedPatch.mHalHandle would be AUDIO_PATCH_HANDLE_NONE in this case.
                     hwModule = oldPatch.sinks[0].ext.device.hw_module;
                 }
-                sp<DeviceHalInterface> hwDevice = findHwDeviceByModule(hwModule);
+                sp<DeviceHalInterface> hwDevice = findHwDeviceByModule_l(hwModule);
                 if (hwDevice != 0) {
                     hwDevice->releaseAudioPatch(removedPatch.mHalHandle);
                 }
@@ -233,7 +185,7 @@
     switch (patch->sources[0].type) {
         case AUDIO_PORT_TYPE_DEVICE: {
             audio_module_handle_t srcModule = patch->sources[0].ext.device.hw_module;
-            AudioHwDevice *audioHwDevice = findAudioHwDeviceByModule(srcModule);
+            AudioHwDevice *audioHwDevice = findAudioHwDeviceByModule_l(srcModule);
             if (!audioHwDevice) {
                 status = BAD_VALUE;
                 goto exit;
@@ -275,8 +227,8 @@
                         status = INVALID_OPERATION;
                         goto exit;
                     }
-                    const sp<IAfThreadBase> thread =
-                            mAudioFlinger.checkPlaybackThread_l(patch->sources[1].ext.mix.handle);
+                    const sp<IAfThreadBase> thread = mAfPatchPanelCallback->checkPlaybackThread_l(
+                            patch->sources[1].ext.mix.handle);
                     if (thread == 0) {
                         ALOGW("%s() cannot get playback thread", __func__);
                         status = INVALID_OPERATION;
@@ -302,7 +254,7 @@
                     if (patch->sinks[0].config_mask & AUDIO_PORT_CONFIG_FLAGS) {
                         flags = patch->sinks[0].flags.output;
                     }
-                    const sp<IAfThreadBase> thread = mAudioFlinger.openOutput_l(
+                    const sp<IAfThreadBase> thread = mAfPatchPanelCallback->openOutput_l(
                                                             patch->sinks[0].ext.device.hw_module,
                                                             &output,
                                                             &config,
@@ -310,7 +262,7 @@
                                                             outputDevice,
                                                             outputDeviceAddress,
                                                             flags);
-                    ALOGV("mAudioFlinger.openOutput_l() returned %p", thread.get());
+                    ALOGV("mAfPatchPanelCallback->openOutput_l() returned %p", thread.get());
                     if (thread == 0) {
                         status = NO_MEMORY;
                         goto exit;
@@ -349,7 +301,7 @@
                                 == AUDIO_STREAM_VOICE_CALL) {
                     source = AUDIO_SOURCE_VOICE_COMMUNICATION;
                 }
-                const sp<IAfThreadBase> thread = mAudioFlinger.openInput_l(srcModule,
+                const sp<IAfThreadBase> thread = mAfPatchPanelCallback->openInput_l(srcModule,
                                                                     &input,
                                                                     &config,
                                                                     device,
@@ -358,14 +310,14 @@
                                                                     flags,
                                                                     outputDevice,
                                                                     outputDeviceAddress);
-                ALOGV("mAudioFlinger.openInput_l() returned %p inChannelMask %08x",
+                ALOGV("mAfPatchPanelCallback->openInput_l() returned %p inChannelMask %08x",
                       thread.get(), config.channel_mask);
                 if (thread == 0) {
                     status = NO_MEMORY;
                     goto exit;
                 }
                 newPatch.mRecord.setThread(thread->asIAfRecordThread().get());
-                status = newPatch.createConnections(this);
+                status = newPatch.createConnections_l(this);
                 if (status != NO_ERROR) {
                     goto exit;
                 }
@@ -374,10 +326,11 @@
                 }
             } else {
                 if (patch->sinks[0].type == AUDIO_PORT_TYPE_MIX) {
-                    sp<IAfThreadBase> thread = mAudioFlinger.checkRecordThread_l(
+                    sp<IAfThreadBase> thread = mAfPatchPanelCallback->checkRecordThread_l(
                                                               patch->sinks[0].ext.mix.handle);
                     if (thread == 0) {
-                        thread = mAudioFlinger.checkMmapThread_l(patch->sinks[0].ext.mix.handle);
+                        thread = mAfPatchPanelCallback->checkMmapThread_l(
+                                patch->sinks[0].ext.mix.handle);
                         if (thread == 0) {
                             ALOGW("%s() bad capture I/O handle %d",
                                     __func__, patch->sinks[0].ext.mix.handle);
@@ -385,9 +338,9 @@
                             goto exit;
                         }
                     }
-                    mAudioFlinger.unlock();
+                    mAfPatchPanelCallback->mutex().unlock();
                     status = thread->sendCreateAudioPatchConfigEvent(patch, &halHandle);
-                    mAudioFlinger.lock();
+                    mAfPatchPanelCallback->mutex().lock();
                     if (status == NO_ERROR) {
                         newPatch.setThread(thread);
                     }
@@ -411,7 +364,7 @@
         } break;
         case AUDIO_PORT_TYPE_MIX: {
             audio_module_handle_t srcModule =  patch->sources[0].ext.mix.hw_module;
-            ssize_t index = mAudioFlinger.mAudioHwDevs.indexOfKey(srcModule);
+            ssize_t index = mAfPatchPanelCallback->getAudioHwDevs_l().indexOfKey(srcModule);
             if (index < 0) {
                 ALOGW("%s() bad src hw module %d", __func__, srcModule);
                 status = BAD_VALUE;
@@ -437,10 +390,11 @@
                 device->applyAudioPortConfig(&patch->sinks[i]);
                 devices.push_back(device);
             }
-            sp<IAfThreadBase> thread =
-                            mAudioFlinger.checkPlaybackThread_l(patch->sources[0].ext.mix.handle);
+            sp<IAfThreadBase> thread = mAfPatchPanelCallback->checkPlaybackThread_l(
+                    patch->sources[0].ext.mix.handle);
             if (thread == 0) {
-                thread = mAudioFlinger.checkMmapThread_l(patch->sources[0].ext.mix.handle);
+                thread = mAfPatchPanelCallback->checkMmapThread_l(
+                        patch->sources[0].ext.mix.handle);
                 if (thread == 0) {
                     ALOGW("%s() bad playback I/O handle %d",
                             __func__, patch->sources[0].ext.mix.handle);
@@ -448,13 +402,13 @@
                     goto exit;
                 }
             }
-            if (thread == mAudioFlinger.primaryPlaybackThread_l()) {
-                mAudioFlinger.updateOutDevicesForRecordThreads_l(devices);
+            if (thread == mAfPatchPanelCallback->primaryPlaybackThread_l()) {
+                mAfPatchPanelCallback->updateOutDevicesForRecordThreads_l(devices);
             }
 
-            mAudioFlinger.unlock();
+            mAfPatchPanelCallback->mutex().unlock();
             status = thread->sendCreateAudioPatchConfigEvent(patch, &halHandle);
-            mAudioFlinger.lock();
+            mAfPatchPanelCallback->mutex().lock();
             if (status == NO_ERROR) {
                 newPatch.setThread(thread);
             }
@@ -479,15 +433,16 @@
 exit:
     ALOGV("%s() status %d", __func__, status);
     if (status == NO_ERROR) {
-        *handle = (audio_patch_handle_t) mAudioFlinger.nextUniqueId(AUDIO_UNIQUE_ID_USE_PATCH);
+        *handle = static_cast<audio_patch_handle_t>(
+                mAfPatchPanelCallback->nextUniqueId(AUDIO_UNIQUE_ID_USE_PATCH));
         newPatch.mHalHandle = halHandle;
-        mAudioFlinger.mPatchCommandThread->createAudioPatch(*handle, newPatch);
+        mAfPatchPanelCallback->getPatchCommandThread()->createAudioPatch(*handle, newPatch);
         if (insertedModule != AUDIO_MODULE_HANDLE_NONE) {
-            addSoftwarePatchToInsertedModules(insertedModule, *handle, &newPatch.mAudioPatch);
+            addSoftwarePatchToInsertedModules_l(insertedModule, *handle, &newPatch.mAudioPatch);
         }
         mPatches.insert(std::make_pair(*handle, std::move(newPatch)));
     } else {
-        newPatch.clearConnections(this);
+        newPatch.clearConnections_l(this);
     }
     return status;
 }
@@ -498,10 +453,10 @@
             mRecord.handle(), mPlayback.handle());
 }
 
-status_t PatchPanel::Patch::createConnections(const sp<IAfPatchPanel>& panel)
+status_t PatchPanel::Patch::createConnections_l(const sp<IAfPatchPanel>& panel)
 {
     // create patch from source device to record thread input
-    status_t status = panel->createAudioPatch(
+    status_t status = panel->createAudioPatch_l(
             PatchBuilder().addSource(mAudioPatch.sources[0]).
                 addSink(mRecord.thread(), { .source = AUDIO_SOURCE_MIC }).patch(),
             mRecord.handlePtr(),
@@ -513,7 +468,7 @@
 
     // create patch from playback thread output to sink device
     if (mAudioPatch.num_sinks != 0) {
-        status = panel->createAudioPatch(
+        status = panel->createAudioPatch_l(
                 PatchBuilder().addSource(mPlayback.thread()).addSink(mAudioPatch.sinks[0]).patch(),
                 mPlayback.handlePtr(),
                 true /*endpointPatch*/);
@@ -662,15 +617,15 @@
     return status;
 }
 
-void PatchPanel::Patch::clearConnections(const sp<IAfPatchPanel>& panel)
+void PatchPanel::Patch::clearConnections_l(const sp<IAfPatchPanel>& panel)
 {
     ALOGV("%s() mRecord.handle %d mPlayback.handle %d",
             __func__, mRecord.handle(), mPlayback.handle());
     mRecord.stopTrack();
     mPlayback.stopTrack();
     mRecord.clearTrackPeer(); // mRecord stop is synchronous. Break PeerProxy sp<> cycle.
-    mRecord.closeConnections(panel);
-    mPlayback.closeConnections(panel);
+    mRecord.closeConnections_l(panel);
+    mPlayback.closeConnections_l(panel);
 }
 
 status_t PatchPanel::Patch::getLatencyMs(double* latencyMs) const
@@ -760,7 +715,7 @@
 }
 
 /* Disconnect a patch */
-status_t PatchPanel::releaseAudioPatch(audio_patch_handle_t handle)
+status_t PatchPanel::releaseAudioPatch_l(audio_patch_handle_t handle)
  //unlocks AudioFlinger::mLock when calling IAfThreadBase::sendReleaseAudioPatchConfigEvent
  //to avoid deadlocks if the thread loop needs to acquire AudioFlinger::mLock
  //before processing the release patch request.
@@ -779,7 +734,7 @@
     const struct audio_port_config &src = patch.sources[0];
     switch (src.type) {
         case AUDIO_PORT_TYPE_DEVICE: {
-            sp<DeviceHalInterface> hwDevice = findHwDeviceByModule(src.ext.device.hw_module);
+            sp<DeviceHalInterface> hwDevice = findHwDeviceByModule_l(src.ext.device.hw_module);
             if (hwDevice == 0) {
                 ALOGW("%s() bad src hw module %d", __func__, src.ext.device.hw_module);
                 status = BAD_VALUE;
@@ -787,47 +742,47 @@
             }
 
             if (removedPatch.isSoftware()) {
-                removedPatch.clearConnections(this);
+                removedPatch.clearConnections_l(this);
                 break;
             }
 
             if (patch.sinks[0].type == AUDIO_PORT_TYPE_MIX) {
                 audio_io_handle_t ioHandle = patch.sinks[0].ext.mix.handle;
-                sp<IAfThreadBase> thread = mAudioFlinger.checkRecordThread_l(ioHandle);
+                sp<IAfThreadBase> thread = mAfPatchPanelCallback->checkRecordThread_l(ioHandle);
                 if (thread == 0) {
-                    thread = mAudioFlinger.checkMmapThread_l(ioHandle);
+                    thread = mAfPatchPanelCallback->checkMmapThread_l(ioHandle);
                     if (thread == 0) {
                         ALOGW("%s() bad capture I/O handle %d", __func__, ioHandle);
                         status = BAD_VALUE;
                         break;
                     }
                 }
-                mAudioFlinger.unlock();
+                mAfPatchPanelCallback->mutex().unlock();
                 status = thread->sendReleaseAudioPatchConfigEvent(removedPatch.mHalHandle);
-                mAudioFlinger.lock();
+                mAfPatchPanelCallback->mutex().lock();
             } else {
                 status = hwDevice->releaseAudioPatch(removedPatch.mHalHandle);
             }
         } break;
         case AUDIO_PORT_TYPE_MIX: {
-            if (findHwDeviceByModule(src.ext.mix.hw_module) == 0) {
+            if (findHwDeviceByModule_l(src.ext.mix.hw_module) == 0) {
                 ALOGW("%s() bad src hw module %d", __func__, src.ext.mix.hw_module);
                 status = BAD_VALUE;
                 break;
             }
             audio_io_handle_t ioHandle = src.ext.mix.handle;
-            sp<IAfThreadBase> thread = mAudioFlinger.checkPlaybackThread_l(ioHandle);
+            sp<IAfThreadBase> thread = mAfPatchPanelCallback->checkPlaybackThread_l(ioHandle);
             if (thread == 0) {
-                thread = mAudioFlinger.checkMmapThread_l(ioHandle);
+                thread = mAfPatchPanelCallback->checkMmapThread_l(ioHandle);
                 if (thread == 0) {
                     ALOGW("%s() bad playback I/O handle %d", __func__, ioHandle);
                     status = BAD_VALUE;
                     break;
                 }
             }
-            mAudioFlinger.unlock();
+            mAfPatchPanelCallback->mutex().unlock();
             status = thread->sendReleaseAudioPatchConfigEvent(removedPatch.mHalHandle);
-            mAudioFlinger.lock();
+            mAfPatchPanelCallback->mutex().lock();
         } break;
         default:
             status = BAD_VALUE;
@@ -840,11 +795,11 @@
 void PatchPanel::erasePatch(audio_patch_handle_t handle) {
     mPatches.erase(handle);
     removeSoftwarePatchFromInsertedModules(handle);
-    mAudioFlinger.mPatchCommandThread->releaseAudioPatch(handle);
+    mAfPatchPanelCallback->getPatchCommandThread()->releaseAudioPatch(handle);
 }
 
 /* List connected audio ports and they attributes */
-status_t PatchPanel::listAudioPatches(unsigned int* /* num_patches */,
+status_t PatchPanel::listAudioPatches_l(unsigned int* /* num_patches */,
                                   struct audio_patch *patches __unused)
 {
     ALOGV(__func__);
@@ -901,30 +856,30 @@
     }
 }
 
-AudioHwDevice* PatchPanel::findAudioHwDeviceByModule(audio_module_handle_t module)
+AudioHwDevice* PatchPanel::findAudioHwDeviceByModule_l(audio_module_handle_t module)
 {
     if (module == AUDIO_MODULE_HANDLE_NONE) return nullptr;
-    ssize_t index = mAudioFlinger.mAudioHwDevs.indexOfKey(module);
+    ssize_t index = mAfPatchPanelCallback->getAudioHwDevs_l().indexOfKey(module);
     if (index < 0) {
         ALOGW("%s() bad hw module %d", __func__, module);
         return nullptr;
     }
-    return mAudioFlinger.mAudioHwDevs.valueAt(index);
+    return mAfPatchPanelCallback->getAudioHwDevs_l().valueAt(index);
 }
 
-sp<DeviceHalInterface> PatchPanel::findHwDeviceByModule(audio_module_handle_t module)
+sp<DeviceHalInterface> PatchPanel::findHwDeviceByModule_l(audio_module_handle_t module)
 {
-    AudioHwDevice *audioHwDevice = findAudioHwDeviceByModule(module);
+    AudioHwDevice *audioHwDevice = findAudioHwDeviceByModule_l(module);
     return audioHwDevice ? audioHwDevice->hwDevice() : nullptr;
 }
 
-void PatchPanel::addSoftwarePatchToInsertedModules(
+void PatchPanel::addSoftwarePatchToInsertedModules_l(
         audio_module_handle_t module, audio_patch_handle_t handle,
         const struct audio_patch *patch)
 {
     mInsertedModules[module].sw_patches.insert(handle);
     if (!mInsertedModules[module].streams.empty()) {
-        mAudioFlinger.updateDownStreamPatches_l(patch, mInsertedModules[module].streams);
+        mAfPatchPanelCallback->updateDownStreamPatches_l(patch, mInsertedModules[module].streams);
     }
 }
 
diff --git a/services/audioflinger/PatchPanel.h b/services/audioflinger/PatchPanel.h
index 14b96c9..1ff8fff 100644
--- a/services/audioflinger/PatchPanel.h
+++ b/services/audioflinger/PatchPanel.h
@@ -17,32 +17,42 @@
 
 #pragma once
 
+#include "IAfPatchPanel.h"
+
+#include <map>  // avoid transitive dependency
+#include <set>  // avoid transitive dependency
+
 namespace android {
 
 class PatchPanel : public IAfPatchPanel {
 public:
-    explicit PatchPanel(AudioFlinger* audioFlinger) : mAudioFlinger(*audioFlinger) {}
+    explicit PatchPanel(const sp<IAfPatchPanelCallback>& afPatchPanelCallback)
+        : mAfPatchPanelCallback(afPatchPanelCallback) {}
 
     /* List connected audio ports and their attributes */
-    status_t listAudioPorts(unsigned int *num_ports,
-        struct audio_port* ports) final;
+    status_t listAudioPorts_l(unsigned int *num_ports,
+            struct audio_port* ports) final REQUIRES(audio_utils::AudioFlinger_Mutex);
 
     /* Get supported attributes for a given audio port */
-    status_t getAudioPort(struct audio_port_v7* port) final;
+    status_t getAudioPort_l(struct audio_port_v7* port) final
+            REQUIRES(audio_utils::AudioFlinger_Mutex);
 
     /* Create a patch between several source and sink ports */
-    status_t createAudioPatch(const struct audio_patch *patch,
+    status_t createAudioPatch_l(const struct audio_patch *patch,
                               audio_patch_handle_t *handle,
-                              bool endpointPatch = false) final;
+                              bool endpointPatch = false) final
+            REQUIRES(audio_utils::AudioFlinger_Mutex);
 
     /* Release a patch */
-    status_t releaseAudioPatch(audio_patch_handle_t handle) final;
+    status_t releaseAudioPatch_l(audio_patch_handle_t handle) final
+            REQUIRES(audio_utils::AudioFlinger_Mutex);
 
     /* List connected audio devices and they attributes */
-    status_t listAudioPatches(unsigned int *num_patches,
-            struct audio_patch* patches) final;
+    status_t listAudioPatches_l(unsigned int *num_patches,
+            struct audio_patch* patches) final
+            REQUIRES(audio_utils::AudioFlinger_Mutex);
 
-    // Retrieves all currently estrablished software patches for a stream
+    // Retrieves all currently established software patches for a stream
     // opened on an intermediate module.
     status_t getDownstreamSoftwarePatches(audio_io_handle_t stream,
             std::vector<SoftwarePatch>* patches) const final;
@@ -54,24 +64,28 @@
 
     void dump(int fd) const final;
 
-    // Call with AudioFlinger mLock held
-    const std::map<audio_patch_handle_t, Patch>& patches_l() const final { return mPatches; }
+    const std::map<audio_patch_handle_t, Patch>& patches_l() const final
+            REQUIRES(audio_utils::AudioFlinger_Mutex) { return mPatches; }
 
-    // Must be called under AudioFlinger::mLock
-    status_t getLatencyMs_l(audio_patch_handle_t patchHandle, double* latencyMs) const final;
+    status_t getLatencyMs_l(audio_patch_handle_t patchHandle, double* latencyMs) const final
+            REQUIRES(audio_utils::AudioFlinger_Mutex);
 
-    void closeThreadInternal_l(const sp<IAfThreadBase>& thread) const final;
+    void closeThreadInternal_l(const sp<IAfThreadBase>& thread) const final
+            REQUIRES(audio_utils::AudioFlinger_Mutex);
 
 private:
-    AudioHwDevice* findAudioHwDeviceByModule(audio_module_handle_t module);
-    sp<DeviceHalInterface> findHwDeviceByModule(audio_module_handle_t module);
-    void addSoftwarePatchToInsertedModules(
+    AudioHwDevice* findAudioHwDeviceByModule_l(audio_module_handle_t module)
+            REQUIRES(audio_utils::AudioFlinger_Mutex);
+    sp<DeviceHalInterface> findHwDeviceByModule_l(audio_module_handle_t module)
+            REQUIRES(audio_utils::AudioFlinger_Mutex);
+    void addSoftwarePatchToInsertedModules_l(
             audio_module_handle_t module, audio_patch_handle_t handle,
-            const struct audio_patch *patch);
+            const struct audio_patch *patch)
+            REQUIRES(audio_utils::AudioFlinger_Mutex);
     void removeSoftwarePatchFromInsertedModules(audio_patch_handle_t handle);
     void erasePatch(audio_patch_handle_t handle);
 
-    AudioFlinger &mAudioFlinger;
+    const sp<IAfPatchPanelCallback> mAfPatchPanelCallback;
     std::map<audio_patch_handle_t, Patch> mPatches;
 
     // This map allows going from a thread to "downstream" software patches
diff --git a/services/audioflinger/PlaybackTracks.h b/services/audioflinger/PlaybackTracks.h
index de6fc32..15e85f9 100644
--- a/services/audioflinger/PlaybackTracks.h
+++ b/services/audioflinger/PlaybackTracks.h
@@ -16,8 +16,13 @@
 */
 
 #pragma once
-#include <math.h>
-#include <sys/types.h>
+
+#include "TrackBase.h"
+
+#include <android/os/BnExternalVibrationController.h>
+#include <audio_utils/mutex.h>
+#include <audio_utils/LinearMap.h>
+#include <binder/AppOpsManager.h>
 
 namespace android {
 
@@ -214,11 +219,6 @@
     void processMuteEvent_l(const sp<IAudioManager>& audioManager, mute_state_t muteState) final;
 
 protected:
-    // for numerous
-    friend class PlaybackThread;
-    friend class MixerThread;
-    friend class DirectOutputThread;
-    friend class OffloadThread;
 
     DISALLOW_COPY_AND_ASSIGN(Track);
 
@@ -468,7 +468,8 @@
      */
     SourceMetadatas mTrackMetadatas;
     /** Protects mTrackMetadatas against concurrent access. */
-    mutable std::mutex mTrackMetadatasMutex;
+    audio_utils::mutex& trackMetadataMutex() const { return mTrackMetadataMutex; }
+    mutable audio_utils::mutex mTrackMetadataMutex;
 };  // end of OutputTrack
 
 // playback track, used by PatchPanel
diff --git a/services/audioflinger/RecordTracks.h b/services/audioflinger/RecordTracks.h
index 5cf09c5..8d3de38 100644
--- a/services/audioflinger/RecordTracks.h
+++ b/services/audioflinger/RecordTracks.h
@@ -17,7 +17,11 @@
 
 #pragma once
 
+#include "TrackBase.h"
+
 #include <android/content/AttributionSourceState.h>
+#include <audio_utils/mutex.h>
+#include <datapath/AudioStreamIn.h> // struct Source
 
 namespace android {
 
@@ -95,8 +99,6 @@
     }
 
 private:
-    friend class AudioFlinger;  // for mState
-
     DISALLOW_COPY_AND_ASSIGN(RecordTrack);
 
 protected:
@@ -213,15 +215,16 @@
     };
 
     sp<StreamInHalInterface> obtainStream(sp<IAfThreadBase>* thread);
+    audio_utils::mutex& readMutex() const { return mReadMutex; }
 
     PatchRecordAudioBufferProvider mPatchRecordAudioBufferProvider;
     std::unique_ptr<void, decltype(free)*> mSinkBuffer;  // frame size aligned continuous buffer
     std::unique_ptr<void, decltype(free)*> mStubBuffer;  // buffer used for AudioBufferProvider
     size_t mUnconsumedFrames = 0;
-    std::mutex mReadLock;
-    std::condition_variable mReadCV;
-    size_t mReadBytes = 0; // GUARDED_BY(mReadLock)
-    status_t mReadError = NO_ERROR; // GUARDED_BY(mReadLock)
+    mutable audio_utils::mutex mReadMutex;
+    audio_utils::condition_variable mReadCV;
+    size_t mReadBytes = 0; // GUARDED_BY(readMutex())
+    status_t mReadError = NO_ERROR; // GUARDED_BY(readMutex())
     int64_t mLastReadFrames = 0;  // accessed on RecordThread only
 };
 
diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp
index a3bd53d..0b73fba 100644
--- a/services/audioflinger/Threads.cpp
+++ b/services/audioflinger/Threads.cpp
@@ -20,45 +20,49 @@
 // #define LOG_NDEBUG 0
 #define ATRACE_TAG ATRACE_TAG_AUDIO
 
-#include "Configuration.h"
-#include <math.h>
-#include <fcntl.h>
-#include <memory>
-#include <sstream>
-#include <string>
-#include <linux/futex.h>
-#include <sys/stat.h>
-#include <sys/syscall.h>
+#include "Threads.h"
+
+#include "Client.h"
+#include "IAfEffect.h"
+#include "MelReporter.h"
+#include "ResamplerBufferProvider.h"
+
+#include <afutils/DumpTryLock.h>
+#include <afutils/Permission.h>
+#include <afutils/TypedLogger.h>
+#include <afutils/Vibrator.h>
+#include <audio_utils/MelProcessor.h>
+#include <audio_utils/Metadata.h>
+#ifdef DEBUG_CPU_USAGE
+#include <audio_utils/Statistics.h>
+#include <cpustats/ThreadCpuUsage.h>
+#endif
+#include <audio_utils/channels.h>
+#include <audio_utils/format.h>
+#include <audio_utils/minifloat.h>
+#include <audio_utils/mono_blend.h>
+#include <audio_utils/primitives.h>
+#include <audio_utils/safe_math.h>
+#include <audiomanager/AudioManager.h>
+#include <binder/IPCThreadState.h>
+#include <binder/IServiceManager.h>
+#include <binder/PersistableBundle.h>
 #include <cutils/bitops.h>
 #include <cutils/properties.h>
-#include <binder/PersistableBundle.h>
+#include <fastpath/AutoPark.h>
 #include <media/AudioContainers.h>
 #include <media/AudioDeviceTypeAddr.h>
 #include <media/AudioParameter.h>
 #include <media/AudioResamplerPublic.h>
+#ifdef ADD_BATTERY_DATA
+#include <media/IMediaPlayerService.h>
+#include <media/IMediaDeathNotifier.h>
+#endif
+#include <media/MmapStreamCallback.h>
 #include <media/RecordBufferConverter.h>
 #include <media/TypeConverter.h>
-#include <utils/Log.h>
-#include <utils/Trace.h>
-
-#include <private/media/AudioTrackShared.h>
-#include <private/android_filesystem_config.h>
-#include <audio_utils/Balance.h>
-#include <audio_utils/MelProcessor.h>
-#include <audio_utils/Metadata.h>
-#include <audio_utils/channels.h>
-#include <audio_utils/mono_blend.h>
-#include <audio_utils/primitives.h>
-#include <audio_utils/format.h>
-#include <audio_utils/minifloat.h>
-#include <audio_utils/safe_math.h>
-#include <system/audio_effects/effect_aec.h>
-#include <system/audio_effects/effect_downmix.h>
-#include <system/audio_effects/effect_ns.h>
-#include <system/audio_effects/effect_spatializer.h>
-#include <system/audio.h>
-
-// NBAIO implementations
+#include <media/audiohal/EffectsFactoryHalInterface.h>
+#include <media/audiohal/StreamHalInterface.h>
 #include <media/nbaio/AudioStreamInSource.h>
 #include <media/nbaio/AudioStreamOutSink.h>
 #include <media/nbaio/MonoPipe.h>
@@ -68,33 +72,27 @@
 #include <media/nbaio/SourceAudioBufferProvider.h>
 #include <mediautils/BatteryNotifier.h>
 #include <mediautils/Process.h>
-
-#include <audiomanager/AudioManager.h>
-#include <powermanager/PowerManager.h>
-
-#include <media/audiohal/EffectsFactoryHalInterface.h>
-#include <media/audiohal/StreamHalInterface.h>
-
-#include "AudioFlinger.h"
-#include "Threads.h"
-
 #include <mediautils/SchedulingPolicyService.h>
 #include <mediautils/ServiceUtilities.h>
+#include <powermanager/PowerManager.h>
+#include <private/android_filesystem_config.h>
+#include <private/media/AudioTrackShared.h>
+#include <system/audio_effects/effect_aec.h>
+#include <system/audio_effects/effect_downmix.h>
+#include <system/audio_effects/effect_ns.h>
+#include <system/audio_effects/effect_spatializer.h>
+#include <utils/Log.h>
+#include <utils/Trace.h>
 
-#ifdef ADD_BATTERY_DATA
-#include <media/IMediaPlayerService.h>
-#include <media/IMediaDeathNotifier.h>
-#endif
-
-#ifdef DEBUG_CPU_USAGE
-#include <audio_utils/Statistics.h>
-#include <cpustats/ThreadCpuUsage.h>
-#endif
-
-#include <fastpath/AutoPark.h>
-
+#include <fcntl.h>
+#include <linux/futex.h>
+#include <math.h>
+#include <memory>
 #include <pthread.h>
-#include <afutils/TypedLogger.h>
+#include <sstream>
+#include <string>
+#include <sys/stat.h>
+#include <sys/syscall.h>
 
 // ----------------------------------------------------------------------------
 
@@ -126,6 +124,9 @@
 using media::IEffectClient;
 using content::AttributionSourceState;
 
+// Keep in sync with java definition in media/java/android/media/AudioRecord.java
+static constexpr int32_t kMaxSharedAudioHistoryMs = 5000;
+
 // retry counts for buffer fill timeout
 // 50 * ~20msecs = 1 second
 static const int8_t kMaxTrackRetries = 50;
@@ -242,8 +243,84 @@
 // and that all "fast" AudioRecord clients read from.  In either case, the size can be small.
 static const size_t kRecordThreadReadOnlyHeapSize = 0xD000;
 
+static const nsecs_t kDefaultStandbyTimeInNsecs = seconds(3);
+
+static nsecs_t getStandbyTimeInNanos() {
+    static nsecs_t standbyTimeInNanos = []() {
+        const int ms = property_get_int32("ro.audio.flinger_standbytime_ms",
+                    kDefaultStandbyTimeInNsecs / NANOS_PER_MILLISECOND);
+        ALOGI("%s: Using %d ms as standby time", __func__, ms);
+        return milliseconds(ms);
+    }();
+    return standbyTimeInNanos;
+}
+
+// Set kEnableExtendedChannels to true to enable greater than stereo output
+// for the MixerThread and device sink.  Number of channels allowed is
+// FCC_2 <= channels <= FCC_LIMIT.
+constexpr bool kEnableExtendedChannels = true;
+
+// Returns true if channel mask is permitted for the PCM sink in the MixerThread
+/* static */
+bool IAfThreadBase::isValidPcmSinkChannelMask(audio_channel_mask_t channelMask) {
+    switch (audio_channel_mask_get_representation(channelMask)) {
+    case AUDIO_CHANNEL_REPRESENTATION_POSITION: {
+        // Haptic channel mask is only applicable for channel position mask.
+        const uint32_t channelCount = audio_channel_count_from_out_mask(
+                static_cast<audio_channel_mask_t>(channelMask & ~AUDIO_CHANNEL_HAPTIC_ALL));
+        const uint32_t maxChannelCount = kEnableExtendedChannels
+                ? FCC_LIMIT : FCC_2;
+        if (channelCount < FCC_2 // mono is not supported at this time
+                || channelCount > maxChannelCount) {
+            return false;
+        }
+        // check that channelMask is the "canonical" one we expect for the channelCount.
+        return audio_channel_position_mask_is_out_canonical(channelMask);
+        }
+    case AUDIO_CHANNEL_REPRESENTATION_INDEX:
+        if (kEnableExtendedChannels) {
+            const uint32_t channelCount = audio_channel_count_from_out_mask(channelMask);
+            if (channelCount >= FCC_2 // mono is not supported at this time
+                    && channelCount <= FCC_LIMIT) {
+                return true;
+            }
+        }
+        return false;
+    default:
+        return false;
+    }
+}
+
+// Set kEnableExtendedPrecision to true to use extended precision in MixerThread
+constexpr bool kEnableExtendedPrecision = true;
+
+// Returns true if format is permitted for the PCM sink in the MixerThread
+/* static */
+bool IAfThreadBase::isValidPcmSinkFormat(audio_format_t format) {
+    switch (format) {
+    case AUDIO_FORMAT_PCM_16_BIT:
+        return true;
+    case AUDIO_FORMAT_PCM_FLOAT:
+    case AUDIO_FORMAT_PCM_24_BIT_PACKED:
+    case AUDIO_FORMAT_PCM_32_BIT:
+    case AUDIO_FORMAT_PCM_8_24_BIT:
+        return kEnableExtendedPrecision;
+    default:
+        return false;
+    }
+}
+
 // ----------------------------------------------------------------------------
 
+// formatToString() needs to be exact for MediaMetrics purposes.
+// Do not use media/TypeConverter.h toString().
+/* static */
+std::string IAfThreadBase::formatToString(audio_format_t format) {
+    std::string result;
+    FormatConverter::toString(format, result);
+    return result;
+}
+
 // TODO: move all toString helpers to audio.h
 // under  #ifdef __cplusplus #endif
 static std::string patchSinksToString(const struct audio_patch *patch)
@@ -544,11 +621,11 @@
     }
 }
 
-ThreadBase::ThreadBase(const sp<AudioFlinger>& audioFlinger, audio_io_handle_t id,
+ThreadBase::ThreadBase(const sp<IAfThreadCallback>& afThreadCallback, audio_io_handle_t id,
         type_t type, bool systemReady, bool isOut)
     :   Thread(false /*canCallJava*/),
         mType(type),
-        mAudioFlinger(audioFlinger),
+        mAfThreadCallback(afThreadCallback),
         mThreadMetrics(std::string(AMEDIAMETRICS_KEY_PREFIX_AUDIO_THREAD) + std::to_string(id),
                isOut),
         mIsOut(isOut),
@@ -608,9 +685,9 @@
         //      mWaitWorkCV.wait(...);
         //      // now thread is hung
         //  }
-        AutoMutex lock(mLock);
+        audio_utils::lock_guard lock(mutex());
         requestExit();
-        mWaitWorkCV.broadcast();
+        mWaitWorkCV.notify_all();
     }
     // When Thread::requestExitAndWait is made virtual and this method is renamed to
     // "virtual status_t requestExitAndWait()", replace by "return Thread::requestExitAndWait();"
@@ -620,7 +697,7 @@
 status_t ThreadBase::setParameters(const String8& keyValuePairs)
 {
     ALOGV("ThreadBase::setParameters() %s", keyValuePairs.c_str());
-    Mutex::Autolock _l(mLock);
+    audio_utils::lock_guard _l(mutex());
 
     return sendSetParameterConfigEvent_l(keyValuePairs);
 }
@@ -639,30 +716,31 @@
     }
     mConfigEvents.add(event);
     ALOGV("sendConfigEvent_l() num events %zu event %d", mConfigEvents.size(), event->mType);
-    mWaitWorkCV.signal();
-    mLock.unlock();
+    mWaitWorkCV.notify_one();
+    mutex().unlock();
     {
-        Mutex::Autolock _l(event->mLock);
+        audio_utils::unique_lock _l(event->mutex());
         while (event->mWaitStatus) {
-            if (event->mCond.waitRelative(event->mLock, kConfigEventTimeoutNs) != NO_ERROR) {
+            if (event->mCondition.wait_for(_l, std::chrono::nanoseconds(kConfigEventTimeoutNs))
+                        == std::cv_status::timeout) {
                 event->mStatus = TIMED_OUT;
                 event->mWaitStatus = false;
             }
         }
         status = event->mStatus;
     }
-    mLock.lock();
+    mutex().lock();
     return status;
 }
 
 void ThreadBase::sendIoConfigEvent(audio_io_config_event_t event, pid_t pid,
                                                  audio_port_handle_t portId)
 {
-    Mutex::Autolock _l(mLock);
+    audio_utils::lock_guard _l(mutex());
     sendIoConfigEvent_l(event, pid, portId);
 }
 
-// sendIoConfigEvent_l() must be called with ThreadBase::mLock held
+// sendIoConfigEvent_l() must be called with ThreadBase::mutex() held
 void ThreadBase::sendIoConfigEvent_l(audio_io_config_event_t event, pid_t pid,
                                                    audio_port_handle_t portId)
 {
@@ -682,11 +760,11 @@
 
 void ThreadBase::sendPrioConfigEvent(pid_t pid, pid_t tid, int32_t prio, bool forApp)
 {
-    Mutex::Autolock _l(mLock);
+    audio_utils::lock_guard _l(mutex());
     sendPrioConfigEvent_l(pid, tid, prio, forApp);
 }
 
-// sendPrioConfigEvent_l() must be called with ThreadBase::mLock held
+// sendPrioConfigEvent_l() must be called with ThreadBase::mutex() held
 void ThreadBase::sendPrioConfigEvent_l(
         pid_t pid, pid_t tid, int32_t prio, bool forApp)
 {
@@ -694,7 +772,7 @@
     sendConfigEvent_l(configEvent);
 }
 
-// sendSetParameterConfigEvent_l() must be called with ThreadBase::mLock held
+// sendSetParameterConfigEvent_l() must be called with ThreadBase::mutex() held
 status_t ThreadBase::sendSetParameterConfigEvent_l(const String8& keyValuePair)
 {
     sp<ConfigEvent> configEvent;
@@ -717,7 +795,7 @@
                                                         const struct audio_patch *patch,
                                                         audio_patch_handle_t *handle)
 {
-    Mutex::Autolock _l(mLock);
+    audio_utils::lock_guard _l(mutex());
     sp<ConfigEvent> configEvent = (ConfigEvent *)new CreateAudioPatchConfigEvent(*patch, *handle);
     status_t status = sendConfigEvent_l(configEvent);
     if (status == NO_ERROR) {
@@ -731,7 +809,7 @@
 status_t ThreadBase::sendReleaseAudioPatchConfigEvent(
                                                                 const audio_patch_handle_t handle)
 {
-    Mutex::Autolock _l(mLock);
+    audio_utils::lock_guard _l(mutex());
     sp<ConfigEvent> configEvent = (ConfigEvent *)new ReleaseAudioPatchConfigEvent(handle);
     return sendConfigEvent_l(configEvent);
 }
@@ -743,7 +821,7 @@
         // The update out device operation is only for record thread.
         return INVALID_OPERATION;
     }
-    Mutex::Autolock _l(mLock);
+    audio_utils::lock_guard _l(mutex());
     sp<ConfigEvent> configEvent = (ConfigEvent *)new UpdateOutDevicesConfigEvent(outDevices);
     return sendConfigEvent_l(configEvent);
 }
@@ -758,7 +836,7 @@
 
 void ThreadBase::sendCheckOutputStageEffectsEvent()
 {
-    Mutex::Autolock _l(mLock);
+    audio_utils::lock_guard _l(mutex());
     sendCheckOutputStageEffectsEvent_l();
 }
 
@@ -853,10 +931,10 @@
             break;
         }
         {
-            Mutex::Autolock _l(event->mLock);
+            audio_utils::lock_guard _l(event->mutex());
             if (event->mWaitStatus) {
                 event->mWaitStatus = false;
-                event->mCond.signal();
+                event->mCondition.notify_one();
             }
         }
         ALOGV_IF(mConfigEvents.isEmpty(), "processConfigEvents_l() DONE thread %p", this);
@@ -949,7 +1027,7 @@
     dprintf(fd, "\n%s thread %p, name %s, tid %d, type %d (%s):\n", isOutput() ? "Output" : "Input",
             this, mThreadName, getTid(), type(), threadTypeToString(type()));
 
-    bool locked = AudioFlinger::dumpTryLock(mLock);
+    const bool locked = afutils::dumpTryLock(mutex());
     if (!locked) {
         dprintf(fd, "  Thread may be deadlocked\n");
     }
@@ -960,7 +1038,7 @@
     dumpEffectChains_l(fd, args);
 
     if (locked) {
-        mLock.unlock();
+        mutex().unlock();
     }
 
     dprintf(fd, "  Local log:\n");
@@ -987,12 +1065,14 @@
     dprintf(fd, "  Standby: %s\n", mStandby ? "yes" : "no");
     dprintf(fd, "  Sample rate: %u Hz\n", mSampleRate);
     dprintf(fd, "  HAL frame count: %zu\n", mFrameCount);
-    dprintf(fd, "  HAL format: 0x%x (%s)\n", mHALFormat, formatToString(mHALFormat).c_str());
+    dprintf(fd, "  HAL format: 0x%x (%s)\n", mHALFormat,
+            IAfThreadBase::formatToString(mHALFormat).c_str());
     dprintf(fd, "  HAL buffer size: %zu bytes\n", mBufferSize);
     dprintf(fd, "  Channel count: %u\n", mChannelCount);
     dprintf(fd, "  Channel mask: 0x%08x (%s)\n", mChannelMask,
             channelMaskToString(mChannelMask, mType != RECORD).c_str());
-    dprintf(fd, "  Processing format: 0x%x (%s)\n", mFormat, formatToString(mFormat).c_str());
+    dprintf(fd, "  Processing format: 0x%x (%s)\n", mFormat,
+            IAfThreadBase::formatToString(mFormat).c_str());
     dprintf(fd, "  Processing frame size: %zu bytes\n", mFrameSize);
     dprintf(fd, "  Pending config events:");
     size_t numConfig = mConfigEvents.size();
@@ -1073,7 +1153,7 @@
 
 void ThreadBase::acquireWakeLock()
 {
-    Mutex::Autolock _l(mLock);
+    audio_utils::lock_guard _l(mutex());
     acquireWakeLock_l();
 }
 
@@ -1127,7 +1207,7 @@
 
 void ThreadBase::releaseWakeLock()
 {
-    Mutex::Autolock _l(mLock);
+    audio_utils::lock_guard _l(mutex());
     releaseWakeLock_l();
 }
 
@@ -1186,7 +1266,7 @@
 
 void ThreadBase::clearPowerManager()
 {
-    Mutex::Autolock _l(mLock);
+    audio_utils::lock_guard _l(mutex());
     releaseWakeLock_l();
     mPowerManager.clear();
 }
@@ -1317,7 +1397,7 @@
 NO_THREAD_SAFETY_ANALYSIS  // manual locking
 {
     if (!threadLocked) {
-        mLock.lock();
+        mutex().lock();
     }
 
     if (mType != RECORD) {
@@ -1332,11 +1412,11 @@
     }
 
     if (!threadLocked) {
-        mLock.unlock();
+        mutex().unlock();
     }
 }
 
-// checkEffectCompatibility_l() must be called with ThreadBase::mLock held
+// checkEffectCompatibility_l() must be called with ThreadBase::mutex() held
 status_t RecordThread::checkEffectCompatibility_l(
         const effect_descriptor_t *desc, audio_session_t sessionId)
 {
@@ -1380,7 +1460,7 @@
     return NO_ERROR;
 }
 
-// checkEffectCompatibility_l() must be called with ThreadBase::mLock held
+// checkEffectCompatibility_l() must be called with ThreadBase::mutex() held
 status_t PlaybackThread::checkEffectCompatibility_l(
         const effect_descriptor_t *desc, audio_session_t sessionId)
 {
@@ -1535,7 +1615,7 @@
     return NO_ERROR;
 }
 
-// ThreadBase::createEffect_l() must be called with AudioFlinger::mLock held
+// ThreadBase::createEffect_l() must be called with AudioFlinger::mutex() held
 sp<IAfEffectHandle> ThreadBase::createEffect_l(
         const sp<Client>& client,
         const sp<IEffectClient>& effectClient,
@@ -1564,8 +1644,8 @@
 
     ALOGV("createEffect_l() thread %p effect %s on session %d", this, desc->name, sessionId);
 
-    { // scope for mLock
-        Mutex::Autolock _l(mLock);
+    { // scope for mutex()
+        audio_utils::lock_guard _l(mutex());
 
         lStatus = checkEffectCompatibility_l(desc, sessionId);
         if (probe || lStatus != NO_ERROR) {
@@ -1588,7 +1668,7 @@
         ALOGV("createEffect_l() got effect %p on chain %p", effect.get(), chain.get());
 
         if (effect == 0) {
-            effectId = mAudioFlinger->nextUniqueId(AUDIO_UNIQUE_ID_USE_EFFECT);
+            effectId = mAfThreadCallback->nextUniqueId(AUDIO_UNIQUE_ID_USE_EFFECT);
             // create a new effect module if none present in the chain
             lStatus = chain->createEffect_l(effect, desc, effectId, sessionId, pinned);
             if (lStatus != NO_ERROR) {
@@ -1599,14 +1679,14 @@
             // FIXME: use vector of device and address when effect interface is ready.
             effect->setDevices(outDeviceTypeAddrs());
             effect->setInputDevice(inDeviceTypeAddr());
-            effect->setMode(mAudioFlinger->getMode());
+            effect->setMode(mAfThreadCallback->getMode());
             effect->setAudioSource(mAudioSource);
         }
         if (effect->isHapticGenerator()) {
             // TODO(b/184194057): Use the vibrator information from the vibrator that will be used
             // for the HapticGenerator.
             const std::optional<media::AudioVibratorInfo> defaultVibratorInfo =
-                    std::move(mAudioFlinger->getDefaultVibratorInfo_l());
+                    std::move(mAfThreadCallback->getDefaultVibratorInfo_l());
             if (defaultVibratorInfo) {
                 // Only set the vibrator info when it is a valid one.
                 effect->setVibratorInfo(*defaultVibratorInfo);
@@ -1627,7 +1707,7 @@
 
 Exit:
     if (!probe && lStatus != NO_ERROR && lStatus != ALREADY_EXISTS) {
-        Mutex::Autolock _l(mLock);
+        audio_utils::lock_guard _l(mutex());
         if (effectCreated) {
             chain->removeEffect_l(effect);
         }
@@ -1647,7 +1727,7 @@
     bool remove = false;
     sp<IAfEffectModule> effect;
     {
-        Mutex::Autolock _l(mLock);
+        audio_utils::lock_guard _l(mutex());
         sp<IAfEffectBase> effectBase = handle->effect().promote();
         if (effectBase == nullptr) {
             return;
@@ -1664,7 +1744,7 @@
         sendCheckOutputStageEffectsEvent_l();
     }
     if (remove) {
-        mAudioFlinger->updateOrphanEffectChains(effect);
+        mAfThreadCallback->updateOrphanEffectChains(effect);
         if (handle->enabled()) {
             effect->checkSuspendOnEffectEnabled(false, false /*threadLocked*/);
         }
@@ -1673,7 +1753,7 @@
 
 void ThreadBase::onEffectEnable(const sp<IAfEffectModule>& effect) {
     if (isOffloadOrMmap()) {
-        Mutex::Autolock _l(mLock);
+        audio_utils::lock_guard _l(mutex());
         broadcast_l();
     }
     if (!effect->isOffloadable()) {
@@ -1682,14 +1762,14 @@
             t->invalidateTracks(AUDIO_STREAM_MUSIC);
         }
         if (effect->sessionId() == AUDIO_SESSION_OUTPUT_MIX) {
-            mAudioFlinger->onNonOffloadableGlobalEffectEnable();
+            mAfThreadCallback->onNonOffloadableGlobalEffectEnable();
         }
     }
 }
 
 void ThreadBase::onEffectDisable() {
     if (isOffloadOrMmap()) {
-        Mutex::Autolock _l(mLock);
+        audio_utils::lock_guard _l(mutex());
         broadcast_l();
     }
 }
@@ -1697,7 +1777,7 @@
 sp<IAfEffectModule> ThreadBase::getEffect(audio_session_t sessionId,
         int effectId) const
 {
-    Mutex::Autolock _l(mLock);
+    audio_utils::lock_guard _l(mutex());
     return getEffect_l(sessionId, effectId);
 }
 
@@ -1714,9 +1794,9 @@
     return chain != nullptr ? chain->getEffectIds() : std::vector<int>{};
 }
 
-// PlaybackThread::addEffect_l() must be called with AudioFlinger::mLock and
-// PlaybackThread::mLock held
-status_t ThreadBase::addEffect_l(const sp<IAfEffectModule>& effect)
+// PlaybackThread::addEffect_ll() must be called with AudioFlinger::mutex() and
+// ThreadBase::mutex() held
+status_t ThreadBase::addEffect_ll(const sp<IAfEffectModule>& effect)
 {
     // check for existing effect chain with the requested audio session
     audio_session_t sessionId = effect->sessionId();
@@ -1724,22 +1804,22 @@
     bool chainCreated = false;
 
     ALOGD_IF((mType == OFFLOAD) && !effect->isOffloadable(),
-             "addEffect_l() on offloaded thread %p: effect %s does not support offload flags %#x",
-                    this, effect->desc().name, effect->desc().flags);
+             "%s: on offloaded thread %p: effect %s does not support offload flags %#x",
+             __func__, this, effect->desc().name, effect->desc().flags);
 
     if (chain == 0) {
         // create a new chain for this session
-        ALOGV("addEffect_l() new effect chain for session %d", sessionId);
+        ALOGV("%s: new effect chain for session %d", __func__, sessionId);
         chain = IAfEffectChain::create(this, sessionId);
         addEffectChain_l(chain);
         chain->setStrategy(getStrategyForSession_l(sessionId));
         chainCreated = true;
     }
-    ALOGV("addEffect_l() %p chain %p effect %p", this, chain.get(), effect.get());
+    ALOGV("%s: %p chain %p effect %p", __func__, this, chain.get(), effect.get());
 
     if (chain->getEffectFromId_l(effect->id()) != 0) {
-        ALOGW("addEffect_l() %p effect %s already present in chain %p",
-                this, effect->desc().name, chain.get());
+        ALOGW("%s: %p effect %s already present in chain %p",
+                __func__, this, effect->desc().name, chain.get());
         return BAD_VALUE;
     }
 
@@ -1755,7 +1835,7 @@
 
     effect->setDevices(outDeviceTypeAddrs());
     effect->setInputDevice(inDeviceTypeAddr());
-    effect->setMode(mAudioFlinger->getMode());
+    effect->setMode(mAfThreadCallback->getMode());
     effect->setAudioSource(mAudioSource);
 
     return NO_ERROR;
@@ -1786,7 +1866,7 @@
 {
     effectChains = mEffectChains;
     for (size_t i = 0; i < mEffectChains.size(); i++) {
-        mEffectChains[i]->lock();
+        mEffectChains[i]->mutex().lock();
     }
 }
 
@@ -1795,13 +1875,13 @@
 NO_THREAD_SAFETY_ANALYSIS  // calls EffectChain::unlock()
 {
     for (size_t i = 0; i < effectChains.size(); i++) {
-        effectChains[i]->unlock();
+        effectChains[i]->mutex().unlock();
     }
 }
 
 sp<IAfEffectChain> ThreadBase::getEffectChain(audio_session_t sessionId) const
 {
-    Mutex::Autolock _l(mLock);
+    audio_utils::lock_guard _l(mutex());
     return getEffectChain_l(sessionId);
 }
 
@@ -1819,7 +1899,7 @@
 
 void ThreadBase::setMode(audio_mode_t mode)
 {
-    Mutex::Autolock _l(mLock);
+    audio_utils::lock_guard _l(mutex());
     size_t size = mEffectChains.size();
     for (size_t i = 0; i < size; i++) {
         mEffectChains[i]->setMode_l(mode);
@@ -1839,7 +1919,7 @@
 
 void ThreadBase::systemReady()
 {
-    Mutex::Autolock _l(mLock);
+    audio_utils::lock_guard _l(mutex());
     if (mSystemReady) {
         return;
     }
@@ -1959,7 +2039,7 @@
     // If threadLoop is currently unlocked a signal of mWaitWorkCV will
     // be lost so we also flag to prevent it blocking on mWaitWorkCV
     mSignalPending = true;
-    mWaitWorkCV.broadcast();
+    mWaitWorkCV.notify_all();
 }
 
 // Call only from threadLoop() or when it is idle.
@@ -2029,13 +2109,13 @@
 
 product_strategy_t ThreadBase::getStrategyForStream(audio_stream_type_t stream) const
 {
-    if (!mAudioFlinger->isAudioPolicyReady()) {
+    if (!mAfThreadCallback->isAudioPolicyReady()) {
         return PRODUCT_STRATEGY_NONE;
     }
     return AudioSystem::getStrategyForStream(stream);
 }
 
-// startMelComputation_l() must be called with AudioFlinger::mLock held
+// startMelComputation_l() must be called with AudioFlinger::mutex() held
 void ThreadBase::startMelComputation_l(
         const sp<audio_utils::MelProcessor>& /*processor*/)
 {
@@ -2043,7 +2123,7 @@
     ALOGW("%s: ThreadBase does not support CSD", __func__);
 }
 
-// stopMelComputation_l() must be called with AudioFlinger::mLock held
+// stopMelComputation_l() must be called with AudioFlinger::mutex() held
 void ThreadBase::stopMelComputation_l()
 {
     // Do nothing
@@ -2054,20 +2134,20 @@
 //      Playback
 // ----------------------------------------------------------------------------
 
-PlaybackThread::PlaybackThread(const sp<AudioFlinger>& audioFlinger,
+PlaybackThread::PlaybackThread(const sp<IAfThreadCallback>& afThreadCallback,
                                              AudioStreamOut* output,
                                              audio_io_handle_t id,
                                              type_t type,
                                              bool systemReady,
                                              audio_config_base_t *mixerConfig)
-    :   ThreadBase(audioFlinger, id, type, systemReady, true /* isOut */),
+    :   ThreadBase(afThreadCallback, id, type, systemReady, true /* isOut */),
         mNormalFrameCount(0), mSinkBuffer(NULL),
-        mMixerBufferEnabled(AudioFlinger::kEnableExtendedPrecision || type == SPATIALIZER),
+        mMixerBufferEnabled(kEnableExtendedPrecision || type == SPATIALIZER),
         mMixerBuffer(NULL),
         mMixerBufferSize(0),
         mMixerBufferFormat(AUDIO_FORMAT_INVALID),
         mMixerBufferValid(false),
-        mEffectBufferEnabled(AudioFlinger::kEnableExtendedPrecision || type == SPATIALIZER),
+        mEffectBufferEnabled(kEnableExtendedPrecision || type == SPATIALIZER),
         mEffectBuffer(NULL),
         mEffectBufferSize(0),
         mEffectBufferFormat(AUDIO_FORMAT_INVALID),
@@ -2082,13 +2162,13 @@
         mNumWrites(0), mNumDelayedWrites(0), mInWrite(false),
         mMixerStatus(MIXER_IDLE),
         mMixerStatusIgnoringFastTracks(MIXER_IDLE),
-        mStandbyDelayNs(AudioFlinger::mStandbyTimeInNsecs),
+        mStandbyDelayNs(getStandbyTimeInNanos()),
         mBytesRemaining(0),
         mCurrentWriteLength(0),
         mUseAsyncWrite(false),
         mWriteAckSequence(0),
         mDrainSequence(0),
-        mScreenState(AudioFlinger::mScreenState),
+        mScreenState(mAfThreadCallback->getScreenState()),
         // index 0 is reserved for normal mixer's submix
         mFastTrackAvailMask(((1 << FastMixerState::sMaxFastTracks) - 1) & ~1),
         mHwSupportsPause(false), mHwPaused(false), mFlushPending(false),
@@ -2097,17 +2177,17 @@
         mIsTimestampAdvancing(kMinimumTimeBetweenTimestampChecksNs)
 {
     snprintf(mThreadName, kThreadNameLength, "AudioOut_%X", id);
-    mNBLogWriter = audioFlinger->newWriter_l(kLogSize, mThreadName);
+    mNBLogWriter = afThreadCallback->newWriter_l(kLogSize, mThreadName);
 
-    // Assumes constructor is called by AudioFlinger with it's mLock held, but
+    // Assumes constructor is called by AudioFlinger with its mutex() held, but
     // it would be safer to explicitly pass initial masterVolume/masterMute as
     // parameter.
     //
     // If the HAL we are using has support for master volume or master mute,
     // then do not attenuate or mute during mixing (just leave the volume at 1.0
     // and the mute set to false).
-    mMasterVolume = audioFlinger->masterVolume_l();
-    mMasterMute = audioFlinger->masterMute_l();
+    mMasterVolume = afThreadCallback->masterVolume_l();
+    mMasterMute = afThreadCallback->masterMute_l();
     if (mOutput->audioHwDev) {
         if (mOutput->audioHwDev->canSetMasterVolume()) {
             mMasterVolume = 1.0;
@@ -2145,7 +2225,7 @@
     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 = mAudioFlinger->streamMute_l(stream);
+        mStreamTypes[stream].mute = mAfThreadCallback->streamMute_l(stream);
     }
     // Audio patch and call assistant volume are always max
     mStreamTypes[AUDIO_STREAM_PATCH].volume = 1.0f;
@@ -2156,7 +2236,7 @@
 
 PlaybackThread::~PlaybackThread()
 {
-    mAudioFlinger->unregisterWriter(mNBLogWriter);
+    mAfThreadCallback->unregisterWriter(mNBLogWriter);
     free(mSinkBuffer);
     free(mMixerBuffer);
     free(mEffectBuffer);
@@ -2299,7 +2379,7 @@
     }
 }
 
-// PlaybackThread::createTrack_l() must be called with AudioFlinger::mLock held
+// PlaybackThread::createTrack_l() must be called with AudioFlinger::mutex() held
 sp<IAfTrack> PlaybackThread::createTrack_l(
         const sp<Client>& client,
         audio_stream_type_t streamType,
@@ -2403,8 +2483,8 @@
         }
 
         // check compatibility with audio effects.
-        { // scope for mLock
-            Mutex::Autolock _l(mLock);
+        { // scope for mutex()
+            audio_utils::lock_guard _l(mutex());
             for (audio_session_t session : {
                     AUDIO_SESSION_DEVICE,
                     AUDIO_SESSION_OUTPUT_STAGE,
@@ -2610,8 +2690,8 @@
         goto Exit;
     }
 
-    { // scope for mLock
-        Mutex::Autolock _l(mLock);
+    { // scope for mutex()
+        audio_utils::lock_guard _l(mutex());
 
         // all tracks in same audio session must share the same routing strategy otherwise
         // conflicts will happen when tracks are moved from one output to another by audio policy
@@ -2655,7 +2735,7 @@
         }
         mTracks.add(track);
         {
-            Mutex::Autolock _atCbL(mAudioTrackCbLock);
+            audio_utils::lock_guard _atCbL(audioTrackCbMutex());
             if (callback.get() != nullptr) {
                 mAudioTrackCallbacks.emplace(track, callback);
             }
@@ -2707,7 +2787,7 @@
 
 uint32_t PlaybackThread::latency() const
 {
-    Mutex::Autolock _l(mLock);
+    audio_utils::lock_guard _l(mutex());
     return latency_l();
 }
 uint32_t PlaybackThread::latency_l() const
@@ -2721,7 +2801,7 @@
 
 void PlaybackThread::setMasterVolume(float value)
 {
-    Mutex::Autolock _l(mLock);
+    audio_utils::lock_guard _l(mutex());
     // Don't apply master volume in SW if our HAL can do it for us.
     if (mOutput && mOutput->audioHwDev &&
         mOutput->audioHwDev->canSetMasterVolume()) {
@@ -2741,7 +2821,7 @@
     if (isDuplicating()) {
         return;
     }
-    Mutex::Autolock _l(mLock);
+    audio_utils::lock_guard _l(mutex());
     // Don't apply master mute in SW if our HAL can do it for us.
     if (mOutput && mOutput->audioHwDev &&
         mOutput->audioHwDev->canSetMasterMute()) {
@@ -2753,21 +2833,21 @@
 
 void PlaybackThread::setStreamVolume(audio_stream_type_t stream, float value)
 {
-    Mutex::Autolock _l(mLock);
+    audio_utils::lock_guard _l(mutex());
     mStreamTypes[stream].volume = value;
     broadcast_l();
 }
 
 void PlaybackThread::setStreamMute(audio_stream_type_t stream, bool muted)
 {
-    Mutex::Autolock _l(mLock);
+    audio_utils::lock_guard _l(mutex());
     mStreamTypes[stream].mute = muted;
     broadcast_l();
 }
 
 float PlaybackThread::streamVolume(audio_stream_type_t stream) const
 {
-    Mutex::Autolock _l(mLock);
+    audio_utils::lock_guard _l(mutex());
     return mStreamTypes[stream].volume;
 }
 
@@ -2776,9 +2856,9 @@
     mOutput->stream->setVolume(left, right);
 }
 
-// addTrack_l() must be called with ThreadBase::mLock held
+// addTrack_l() must be called with ThreadBase::mutex() held
 status_t PlaybackThread::addTrack_l(const sp<IAfTrack>& track)
-NO_THREAD_SAFETY_ANALYSIS  // release and re-acquire mLock
+NO_THREAD_SAFETY_ANALYSIS  // release and re-acquire mutex()
 {
     status_t status = ALREADY_EXISTS;
 
@@ -2788,15 +2868,15 @@
         // effectively get the latency it requested.
         if (track->isExternalTrack()) {
             IAfTrackBase::track_state state = track->state();
-            mLock.unlock();
+            mutex().unlock();
             status = AudioSystem::startOutput(track->portId());
-            mLock.lock();
+            mutex().lock();
             // abort track was stopped/paused while we released the lock
             if (state != track->state()) {
                 if (status == NO_ERROR) {
-                    mLock.unlock();
+                    mutex().unlock();
                     AudioSystem::stopOutput(track->portId());
-                    mLock.lock();
+                    mutex().lock();
                 }
                 return INVALID_OPERATION;
             }
@@ -2835,17 +2915,17 @@
                         || (chain != nullptr && chain->containsHapticGeneratingEffect_l()))) {
             // Unlock due to VibratorService will lock for this call and will
             // call Tracks.mute/unmute which also require thread's lock.
-            mLock.unlock();
-            const os::HapticScale intensity = AudioFlinger::onExternalVibrationStart(
+            mutex().unlock();
+            const os::HapticScale intensity = afutils::onExternalVibrationStart(
                     track->getExternalVibration());
             std::optional<media::AudioVibratorInfo> vibratorInfo;
             {
                 // TODO(b/184194780): Use the vibrator information from the vibrator that will be
                 // used to play this track.
-                Mutex::Autolock _l(mAudioFlinger->mLock);
-                vibratorInfo = std::move(mAudioFlinger->getDefaultVibratorInfo_l());
+                 audio_utils::lock_guard _l(mAfThreadCallback->mutex());
+                vibratorInfo = std::move(mAfThreadCallback->getDefaultVibratorInfo_l());
             }
-            mLock.lock();
+            mutex().lock();
             track->setHapticIntensity(intensity);
             if (vibratorInfo) {
                 track->setHapticMaxAmplitude(vibratorInfo->maxAmplitude);
@@ -2911,7 +2991,7 @@
 
     mTracks.remove(track);
     {
-        Mutex::Autolock _atCbL(mAudioTrackCbLock);
+        audio_utils::lock_guard _atCbL(audioTrackCbMutex());
         mAudioTrackCallbacks.erase(track);
     }
     if (track->isFastTrack()) {
@@ -2930,7 +3010,7 @@
 
 String8 PlaybackThread::getParameters(const String8& keys)
 {
-    Mutex::Autolock _l(mLock);
+    audio_utils::lock_guard _l(mutex());
     String8 out_s8;
     if (initCheck() == NO_ERROR && mOutput->stream->getParameters(keys, &out_s8) == OK) {
         return out_s8;
@@ -2939,7 +3019,7 @@
 }
 
 status_t DirectOutputThread::selectPresentation(int presentationId, int programId) {
-    Mutex::Autolock _l(mLock);
+    audio_utils::lock_guard _l(mutex());
     if (!isStreamInitialized()) {
         return NO_INIT;
     }
@@ -2968,7 +3048,7 @@
         desc = sp<AudioIoDescriptor>::make(mId);
         break;
     }
-    mAudioFlinger->ioConfigChanged(event, desc, pid);
+    mAfThreadCallback->ioConfigChanged(event, desc, pid);
 }
 
 void PlaybackThread::onWriteReady()
@@ -3009,7 +3089,7 @@
             audio_utils::metadata::ByteString metaDataStr =
                     audio_utils::metadata::byteStringFromData(metadata);
             std::vector metadataVec(metaDataStr.begin(), metaDataStr.end());
-            Mutex::Autolock _l(mAudioTrackCbLock);
+            audio_utils::lock_guard _l(audioTrackCbMutex());
             for (const auto& callbackPair : mAudioTrackCallbacks) {
                 callbackPair.second->onCodecFormatChanged(metadataVec);
             }
@@ -3018,17 +3098,17 @@
 
 void PlaybackThread::resetWriteBlocked(uint32_t sequence)
 {
-    Mutex::Autolock _l(mLock);
+    audio_utils::lock_guard _l(mutex());
     // reject out of sequence requests
     if ((mWriteAckSequence & 1) && (sequence == mWriteAckSequence)) {
         mWriteAckSequence &= ~1;
-        mWaitWorkCV.signal();
+        mWaitWorkCV.notify_one();
     }
 }
 
 void PlaybackThread::resetDraining(uint32_t sequence)
 {
-    Mutex::Autolock _l(mLock);
+    audio_utils::lock_guard _l(mutex());
     // reject out of sequence requests
     if ((mDrainSequence & 1) && (sequence == mDrainSequence)) {
         // Register discontinuity when HW drain is completed because that can cause
@@ -3037,11 +3117,13 @@
         // elsewhere, e.g. in flush).
         mTimestampVerifier.discontinuity(mTimestampVerifier.DISCONTINUITY_MODE_ZERO);
         mDrainSequence &= ~1;
-        mWaitWorkCV.signal();
+        mWaitWorkCV.notify_one();
     }
 }
 
 void PlaybackThread::readOutputParameters_l()
+NO_THREAD_SAFETY_ANALYSIS
+// 'moveEffectChain_ll' requires holding mutex 'AudioFlinger_Mutex' exclusively
 {
     // unfortunately we have no way of recovering from errors here, hence the LOG_ALWAYS_FATAL
     const audio_config_base_t audioConfig = mOutput->getAudioProperties();
@@ -3050,7 +3132,7 @@
     if (!audio_is_output_channel(mChannelMask)) {
         LOG_ALWAYS_FATAL("HAL channel mask %#x not valid for output", mChannelMask);
     }
-    if (hasMixer() && !AudioFlinger::isValidPcmSinkChannelMask(mChannelMask)) {
+    if (hasMixer() && !isValidPcmSinkChannelMask(mChannelMask)) {
         LOG_ALWAYS_FATAL("HAL channel mask %#x not supported for mixed output",
                 mChannelMask);
     }
@@ -3073,7 +3155,7 @@
     if (!audio_is_valid_format(mFormat)) {
         LOG_ALWAYS_FATAL("HAL format %#x not valid for output", mFormat);
     }
-    if (hasMixer() && !AudioFlinger::isValidPcmSinkFormat(mFormat)) {
+    if (hasMixer() && !isValidPcmSinkFormat(mFormat)) {
         LOG_FATAL("HAL format %#x not supported for mixed output",
                 mFormat);
     }
@@ -3206,20 +3288,21 @@
 
     // force reconfiguration of effect chains and engines to take new buffer size and audio
     // parameters into account
-    // Note that mLock is not held when readOutputParameters_l() is called from the constructor
+    // Note that mutex() is not held when readOutputParameters_l() is called from the constructor
     // but in this case nothing is done below as no audio sessions have effect yet so it doesn't
     // matter.
-    // create a copy of mEffectChains as calling moveEffectChain_l() can reorder some effect chains
+    // create a copy of mEffectChains as calling moveEffectChain_ll()
+    // can reorder some effect chains
     Vector<sp<IAfEffectChain>> effectChains = mEffectChains;
     for (size_t i = 0; i < effectChains.size(); i ++) {
-        mAudioFlinger->moveEffectChain_l(effectChains[i]->sessionId(),
+        mAfThreadCallback->moveEffectChain_ll(effectChains[i]->sessionId(),
             this/* srcThread */, this/* dstThread */);
     }
 
     audio_output_flags_t flags = mOutput->flags;
     mediametrics::LogItem item(mThreadMetrics.getMetricsId()); // TODO: method in ThreadMetrics?
     item.set(AMEDIAMETRICS_PROP_EVENT, AMEDIAMETRICS_PROP_EVENT_VALUE_READPARAMETERS)
-        .set(AMEDIAMETRICS_PROP_ENCODING, formatToString(mFormat).c_str())
+        .set(AMEDIAMETRICS_PROP_ENCODING, IAfThreadBase::formatToString(mFormat).c_str())
         .set(AMEDIAMETRICS_PROP_SAMPLERATE, (int32_t)mSampleRate)
         .set(AMEDIAMETRICS_PROP_CHANNELMASK, (int32_t)mChannelMask)
         .set(AMEDIAMETRICS_PROP_CHANNELCOUNT, (int32_t)mChannelCount)
@@ -3230,7 +3313,7 @@
         .set(AMEDIAMETRICS_PROP_PREFIX_HAPTIC AMEDIAMETRICS_PROP_CHANNELCOUNT,
                 (int32_t)mHapticChannelCount)
         .set(AMEDIAMETRICS_PROP_PREFIX_HAL    AMEDIAMETRICS_PROP_ENCODING,
-                formatToString(mHALFormat).c_str())
+                IAfThreadBase::formatToString(mHALFormat).c_str())
         .set(AMEDIAMETRICS_PROP_PREFIX_HAL    AMEDIAMETRICS_PROP_FRAMECOUNT,
                 (int32_t)mFrameCount) // sic - added HAL
         ;
@@ -3270,7 +3353,7 @@
     if (halFrames == NULL || dspFrames == NULL) {
         return BAD_VALUE;
     }
-    Mutex::Autolock _l(mLock);
+    audio_utils::lock_guard _l(mutex());
     if (initCheck() != NO_ERROR) {
         return INVALID_OPERATION;
     }
@@ -3311,13 +3394,13 @@
 
 AudioStreamOut* PlaybackThread::getOutput() const
 {
-    Mutex::Autolock _l(mLock);
+    audio_utils::lock_guard _l(mutex());
     return mOutput;
 }
 
 AudioStreamOut* PlaybackThread::clearOutput()
 {
-    Mutex::Autolock _l(mLock);
+    audio_utils::lock_guard _l(mutex());
     AudioStreamOut *output = mOutput;
     mOutput = NULL;
     // FIXME FastMixer might also have a raw ptr to mOutputSink;
@@ -3328,7 +3411,7 @@
     return output;
 }
 
-// this method must always be called either with ThreadBase mLock held or inside the thread loop
+// this method must always be called either with ThreadBase mutex() held or inside the thread loop
 sp<StreamHalInterface> PlaybackThread::stream() const
 {
     if (mOutput == NULL) {
@@ -3348,7 +3431,7 @@
         return BAD_VALUE;
     }
 
-    Mutex::Autolock _l(mLock);
+    audio_utils::lock_guard _l(mutex());
 
     for (size_t i = 0; i < mTracks.size(); ++i) {
         sp<IAfTrack> track = mTracks[i];
@@ -3421,7 +3504,7 @@
 
         ATRACE_BEGIN("write");
         // update the setpoint when AudioFlinger::mScreenState changes
-        uint32_t screenState = AudioFlinger::mScreenState;
+        const uint32_t screenState = mAfThreadCallback->getScreenState();
         if (screenState != mScreenState) {
             mScreenState = screenState;
             MonoPipe *pipe = (MonoPipe *)mPipeSink.get();
@@ -3478,7 +3561,7 @@
     return bytesWritten;
 }
 
-// startMelComputation_l() must be called with AudioFlinger::mLock held
+// startMelComputation_l() must be called with AudioFlinger::mutex() held
 void PlaybackThread::startMelComputation_l(
         const sp<audio_utils::MelProcessor>& processor)
 {
@@ -3488,7 +3571,7 @@
     }
 }
 
-// stopMelComputation_l() must be called with AudioFlinger::mLock held
+// stopMelComputation_l() must be called with AudioFlinger::mutex() held
 void PlaybackThread::stopMelComputation_l()
 {
     auto outputSink = static_cast<AudioStreamOutSink*>(mOutputSink.get());
@@ -3516,7 +3599,7 @@
 void PlaybackThread::threadLoop_exit()
 {
     {
-        Mutex::Autolock _l(mLock);
+        audio_utils::lock_guard _l(mutex());
         for (size_t i = 0; i < mTracks.size(); i++) {
             sp<IAfTrack> track = mTracks[i];
             track->invalidate();
@@ -3555,7 +3638,7 @@
     mActiveSleepTimeUs = activeSleepTimeUs();
     mIdleSleepTimeUs = idleSleepTimeUs();
 
-    mStandbyDelayNs = AudioFlinger::mStandbyTimeInNsecs;
+    mStandbyDelayNs = getStandbyTimeInNanos();
 
     // make sure standby delay is not too short when connected to an A2DP sink to avoid
     // truncating audio when going to standby.
@@ -3584,12 +3667,12 @@
 
 void PlaybackThread::invalidateTracks(audio_stream_type_t streamType)
 {
-    Mutex::Autolock _l(mLock);
+    audio_utils::lock_guard _l(mutex());
     invalidateTracks_l(streamType);
 }
 
 void PlaybackThread::invalidateTracks(std::set<audio_port_handle_t>& portIds) {
-    Mutex::Autolock _l(mLock);
+    audio_utils::lock_guard _l(mutex());
     invalidateTracks_l(portIds);
 }
 
@@ -3642,12 +3725,12 @@
             }
             size_t numSamples = mNormalFrameCount
                     * (audio_channel_count_from_out_mask(channelMask) + mHapticChannelCount);
-            status_t result = mAudioFlinger->mEffectsFactoryHal->allocateBuffer(
+            status_t result = mAfThreadCallback->getEffectsFactoryHal()->allocateBuffer(
                     numSamples * sizeof(float),
                     &halInBuffer);
             if (result != OK) return result;
 
-            result = mAudioFlinger->mEffectsFactoryHal->mirrorBuffer(
+            result = mAfThreadCallback->getEffectsFactoryHal()->mirrorBuffer(
                     isSessionSpatialized ? mEffectBuffer : mPostSpatializerBuffer,
                     isSessionSpatialized ? mEffectBufferSize : mPostSpatializerBufferSize,
                     &halOutBuffer);
@@ -3662,10 +3745,10 @@
             // - OUTPUT_STAGE session uses the mEffectBuffer as input buffer and
             // mPostSpatializerBuffer as output buffer
             // - DEVICE session uses the mPostSpatializerBuffer as input and output buffer.
-            status_t result = mAudioFlinger->mEffectsFactoryHal->mirrorBuffer(
+            status_t result = mAfThreadCallback->getEffectsFactoryHal()->mirrorBuffer(
                     mEffectBuffer, mEffectBufferSize, &halInBuffer);
             if (result != OK) return result;
-            result = mAudioFlinger->mEffectsFactoryHal->mirrorBuffer(
+            result = mAfThreadCallback->getEffectsFactoryHal()->mirrorBuffer(
                     mPostSpatializerBuffer, mPostSpatializerBufferSize, &halOutBuffer);
             if (result != OK) return result;
 
@@ -3674,7 +3757,7 @@
             }
         }
     } else {
-        status_t result = mAudioFlinger->mEffectsFactoryHal->mirrorBuffer(
+        status_t result = mAfThreadCallback->getEffectsFactoryHal()->mirrorBuffer(
                 mEffectBufferEnabled ? mEffectBuffer : mSinkBuffer,
                 mEffectBufferEnabled ? mEffectBufferSize : mSinkBufferSize,
                 &halInBuffer);
@@ -3690,7 +3773,8 @@
                 size_t numSamples = mNormalFrameCount
                         * (audio_channel_count_from_out_mask(mMixerChannelMask)
                                                              + mHapticChannelCount);
-                const status_t allocateStatus = mAudioFlinger->mEffectsFactoryHal->allocateBuffer(
+                const status_t allocateStatus =
+                        mAfThreadCallback->getEffectsFactoryHal()->allocateBuffer(
                         numSamples * sizeof(float),
                         &halInBuffer);
                 if (allocateStatus != OK) return allocateStatus;
@@ -3792,7 +3876,7 @@
 status_t PlaybackThread::attachAuxEffect(
         const sp<IAfTrack>& track, int EffectId)
 {
-    Mutex::Autolock _l(mLock);
+    audio_utils::lock_guard _l(mutex());
     return attachAuxEffect_l(track, EffectId);
 }
 
@@ -3834,6 +3918,18 @@
 {
     aflog::setThreadWriter(mNBLogWriter.get());
 
+    if (mType == SPATIALIZER) {
+        const pid_t tid = getTid();
+        if (tid == -1) {  // odd: we are here, we must be a running thread.
+            ALOGW("%s: Cannot update Spatializer mixer thread priority, no tid", __func__);
+        } else {
+            const int priorityBoost = requestSpatializerPriority(getpid(), tid);
+            if (priorityBoost > 0) {
+                stream()->setHalThreadPriority(priorityBoost);
+            }
+        }
+    }
+
     Vector<sp<IAfTrack>> tracksToRemove;
 
     mStandbyTimeNs = systemTime();
@@ -3882,7 +3978,7 @@
     {
         // Log merge requests are performed during AudioFlinger binder transactions, but
         // that does not cover audio playback. It's requested here for that reason.
-        mAudioFlinger->requestLogMerge();
+        mAfThreadCallback->requestLogMerge();
 
         cpuStats.sample(myName);
 
@@ -3893,16 +3989,16 @@
 
         // If the device is AUDIO_DEVICE_OUT_BUS, check for downstream latency.
         //
-        // Note: we access outDeviceTypes() outside of mLock.
+        // Note: we access outDeviceTypes() outside of mutex().
         if (isMsdDevice() && outDeviceTypes().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 (mAudioFlinger->mLock.tryLock() == NO_ERROR) {
+            if (mAfThreadCallback->mutex().try_lock()) {
                 std::vector<SoftwarePatch> swPatches;
                 double latencyMs = 0.; // not required; initialized for clang-tidy
                 status_t status = INVALID_OPERATION;
                 audio_patch_handle_t downstreamPatchHandle = AUDIO_PATCH_HANDLE_NONE;
-                if (mAudioFlinger->mPatchPanel->getDownstreamSoftwarePatches(
+                if (mAfThreadCallback->getPatchPanel()->getDownstreamSoftwarePatches(
                                 id(), &swPatches) == OK
                         && swPatches.size() > 0) {
                         status = swPatches[0].getLatencyMs_l(&latencyMs);
@@ -3924,7 +4020,7 @@
                     }
                     mDownstreamLatencyStatMs.add(latencyMs);
                 }
-                mAudioFlinger->mLock.unlock();
+                mAfThreadCallback->mutex().unlock();
             }
         } else {
             if (lastDownstreamPatchHandle != AUDIO_PATCH_HANDLE_NONE) {
@@ -3939,16 +4035,16 @@
         }
 
         MetadataUpdate metadataUpdate;
-        { // scope for mLock
+        { // scope for mutex()
 
-            Mutex::Autolock _l(mLock);
+            audio_utils::unique_lock _l(mutex());
 
             processConfigEvents_l();
             if (mCheckOutputStageEffects.load()) {
                 continue;
             }
 
-            // See comment at declaration of logString for why this is done under mLock
+            // See comment at declaration of logString for why this is done under mutex()
             if (logString != NULL) {
                 mNBLogWriter->logTimestamp();
                 mNBLogWriter->log(logString);
@@ -3973,8 +4069,9 @@
 
                 const int64_t waitNs = computeWaitTimeNs_l();
                 ALOGV("wait async completion (wait time: %lld)", (long long)waitNs);
-                status_t status = mWaitWorkCV.waitRelative(mLock, waitNs);
-                if (status == TIMED_OUT) {
+                std::cv_status cvstatus =
+                        mWaitWorkCV.wait_for(_l, std::chrono::nanoseconds(waitNs));
+                if (cvstatus == std::cv_status::timeout) {
                     mSignalPending = true; // if timeout recheck everything
                 }
                 ALOGV("async completion/wake");
@@ -4016,7 +4113,7 @@
                     releaseWakeLock_l();
                     // wait until we have something to do...
                     ALOGV("%s going to sleep", myName.c_str());
-                    mWaitWorkCV.wait(mLock);
+                    mWaitWorkCV.wait(_l);
                     ALOGV("%s waking up", myName.c_str());
                     acquireWakeLock_l();
 
@@ -4089,9 +4186,9 @@
                     && (mKernelPositionOnStandby
                             != mTimestamp.mPosition[ExtendedTimestamp::LOCATION_KERNEL])))) {
                 mHalStarted = true;
-                mWaitHalStartCV.broadcast();
+                mWaitHalStartCV.notify_all();
             }
-        } // mLock scope ends
+        } // mutex() scope ends
 
         if (mBytesRemaining == 0) {
             mCurrentWriteLength = 0;
@@ -4285,7 +4382,7 @@
         unlockEffectChains(effectChains);
 
         if (!metadataUpdate.playbackMetadataUpdate.empty()) {
-            mAudioFlinger->mMelReporter->updateMetadataForCsd(id(),
+            mAfThreadCallback->getMelReporter()->updateMetadataForCsd(id(),
                     metadataUpdate.playbackMetadataUpdate);
         }
 
@@ -4322,7 +4419,7 @@
                                 const double processMs =
                                        (lastIoBeginNs - mLastIoEndNs) * 1e-6;
 
-                                Mutex::Autolock _l(mLock);
+                                audio_utils::lock_guard _l(mutex());
                                 mIoJitterMs.add(jitterMs);
                                 mProcessTimeMs.add(processMs);
 
@@ -4423,7 +4520,7 @@
 
             } else {
                 ATRACE_BEGIN("sleep");
-                Mutex::Autolock _l(mLock);
+                audio_utils::unique_lock _l(mutex());
                 // suspended requires accurate metering of sleep time.
                 if (isSuspended()) {
                     // advance by expected sleepTime
@@ -4448,7 +4545,7 @@
                     mSleepTimeUs = deltaNs / 1000;
                 }
                 if (!mSignalPending && mConfigEvents.isEmpty() && !exitPending()) {
-                    mWaitWorkCV.waitRelative(mLock, microseconds((nsecs_t)mSleepTimeUs));
+                    mWaitWorkCV.wait_for(_l, std::chrono::microseconds(mSleepTimeUs));
                 }
                 ATRACE_END();
             }
@@ -4621,9 +4718,9 @@
 #endif
 }
 
-// removeTracks_l() must be called with ThreadBase::mLock held
+// removeTracks_l() must be called with ThreadBase::mutex() held
 void PlaybackThread::removeTracks_l(const Vector<sp<IAfTrack>>& tracksToRemove)
-NO_THREAD_SAFETY_ANALYSIS  // release and re-acquire mLock
+NO_THREAD_SAFETY_ANALYSIS  // release and re-acquire mutex()
 {
     for (const auto& track : tracksToRemove) {
         mActiveTracks.remove(track);
@@ -4649,11 +4746,11 @@
         if (mHapticChannelCount > 0 &&
                 ((track->channelMask() & AUDIO_CHANNEL_HAPTIC_ALL) != AUDIO_CHANNEL_NONE
                         || (chain != nullptr && chain->containsHapticGeneratingEffect_l()))) {
-            mLock.unlock();
+            mutex().unlock();
             // Unlock due to VibratorService will lock for this call and will
             // call Tracks.mute/unmute which also require thread's lock.
-            AudioFlinger::onExternalVibrationStop(track->getExternalVibration());
-            mLock.lock();
+            afutils::onExternalVibrationStop(track->getExternalVibration());
+            mutex().lock();
 
             // When the track is stop, set the haptic intensity as MUTE
             // for the HapticGenerator effect.
@@ -4851,13 +4948,13 @@
 
 void PlaybackThread::addPatchTrack(const sp<IAfPatchTrack>& track)
 {
-    Mutex::Autolock _l(mLock);
+    audio_utils::lock_guard _l(mutex());
     mTracks.add(track);
 }
 
 void PlaybackThread::deletePatchTrack(const sp<IAfPatchTrack>& track)
 {
-    Mutex::Autolock _l(mLock);
+    audio_utils::lock_guard _l(mutex());
     destroyTrack_l(track);
 }
 
@@ -4877,14 +4974,14 @@
 
 /* static */
 sp<IAfPlaybackThread> IAfPlaybackThread::createMixerThread(
-        const sp<AudioFlinger>& audioFlinger, AudioStreamOut* output,
+        const sp<IAfThreadCallback>& afThreadCallback, AudioStreamOut* output,
         audio_io_handle_t id, bool systemReady, type_t type, audio_config_base_t* mixerConfig) {
-    return sp<MixerThread>::make(audioFlinger, output, id, systemReady, type, mixerConfig);
+    return sp<MixerThread>::make(afThreadCallback, output, id, systemReady, type, mixerConfig);
 }
 
-MixerThread::MixerThread(const sp<AudioFlinger>& audioFlinger, AudioStreamOut* output,
+MixerThread::MixerThread(const sp<IAfThreadCallback>& afThreadCallback, AudioStreamOut* output,
         audio_io_handle_t id, bool systemReady, type_t type, audio_config_base_t *mixerConfig)
-    :   PlaybackThread(audioFlinger, output, id, type, systemReady, mixerConfig),
+    :   PlaybackThread(afThreadCallback, output, id, type, systemReady, mixerConfig),
         // mAudioMixer below
         // mFastMixer below
         mBluetoothLatencyModesEnabled(false),
@@ -4894,7 +4991,7 @@
         // mPipeSink below
         // mNormalSink below
 {
-    setMasterBalance(audioFlinger->getMasterBalance_l());
+    setMasterBalance(afThreadCallback->getMasterBalance_l());
     ALOGV("MixerThread() id=%d type=%d", id, type);
     ALOGV("mSampleRate=%u, mChannelMask=%#x, mChannelCount=%u, mFormat=%#x, mFrameSize=%zu, "
             "mFrameCount=%zu, mNormalFrameCount=%zu",
@@ -5021,7 +5118,7 @@
         state->mColdFutexAddr = &mFastMixerFutex;
         state->mColdGen++;
         state->mDumpState = &mFastMixerDumpState;
-        mFastMixerNBLogWriter = audioFlinger->newWriter_l(kFastMixerLogSize, "FastMixer");
+        mFastMixerNBLogWriter = afThreadCallback->newWriter_l(kFastMixerLogSize, "FastMixer");
         state->mNBLogWriter = mFastMixerNBLogWriter.get();
         sq->end();
         sq->push(FastMixerStateQueue::BLOCK_UNTIL_PUSHED);
@@ -5100,14 +5197,14 @@
         }
 #endif
     }
-    mAudioFlinger->unregisterWriter(mFastMixerNBLogWriter);
+    mAfThreadCallback->unregisterWriter(mFastMixerNBLogWriter);
     delete mAudioMixer;
 }
 
 void MixerThread::onFirstRef() {
     PlaybackThread::onFirstRef();
 
-    Mutex::Autolock _l(mLock);
+    audio_utils::lock_guard _l(mutex());
     if (mOutput != nullptr && mOutput->stream != nullptr) {
         status_t status = mOutput->stream->setLatencyModeCallback(this);
         if (status != INVALID_OPERATION) {
@@ -5157,7 +5254,7 @@
             }
             state->mCommand = FastMixerState::MIX_WRITE;
 #ifdef FAST_THREAD_STATISTICS
-            mFastMixerDumpState.increaseSamplingN(mAudioFlinger->isLowRamDevice() ?
+            mFastMixerDumpState.increaseSamplingN(mAfThreadCallback->isLowRamDevice() ?
                 FastThreadDumpState::kSamplingNforLowRamDevice : FastThreadDumpState::kSamplingN);
 #endif
             sq->end();
@@ -5222,7 +5319,7 @@
 
 bool PlaybackThread::waitingAsyncCallback()
 {
-    Mutex::Autolock _l(mLock);
+    audio_utils::lock_guard _l(mutex());
     return waitingAsyncCallback_l();
 }
 
@@ -5327,7 +5424,7 @@
     // TODO add standby time extension fct of effect tail
 }
 
-// prepareTracks_l() must be called with ThreadBase::mLock held
+// prepareTracks_l() must be called with ThreadBase::mutex() held
 PlaybackThread::mixer_state MixerThread::prepareTracks_l(
         Vector<sp<IAfTrack>>* tracksToRemove)
 {
@@ -5585,7 +5682,7 @@
                 float vlf = float_from_gain(gain_minifloat_unpack_left(vlr));
                 float vrf = float_from_gain(gain_minifloat_unpack_right(vlr));
 
-                track->processMuteEvent_l(mAudioFlinger->getOrCreateAudioManager(),
+                track->processMuteEvent_l(mAfThreadCallback->getOrCreateAudioManager(),
                     /*muteState=*/{masterVolume == 0.f,
                                    mStreamTypes[track->streamType()].volume == 0.f,
                                    mStreamTypes[track->streamType()].mute,
@@ -5768,7 +5865,7 @@
                     vrf = GAIN_FLOAT_UNITY;
                 }
 
-                track->processMuteEvent_l(mAudioFlinger->getOrCreateAudioManager(),
+                track->processMuteEvent_l(mAfThreadCallback->getOrCreateAudioManager(),
                     /*muteState=*/{masterVolume == 0.f,
                                    mStreamTypes[track->streamType()].volume == 0.f,
                                    mStreamTypes[track->streamType()].mute,
@@ -6123,7 +6220,7 @@
     return mixerStatus;
 }
 
-// trackCountForUid_l() must be called with ThreadBase::mLock held
+// trackCountForUid_l() must be called with ThreadBase::mutex() held
 uint32_t PlaybackThread::trackCountForUid_l(uid_t uid) const
 {
     uint32_t trackCount = 0;
@@ -6166,7 +6263,7 @@
     mPreviousNs = 0;
 }
 
-// isTrackAllowed_l() must be called with ThreadBase::mLock held
+// isTrackAllowed_l() must be called with ThreadBase::mutex() held
 bool MixerThread::isTrackAllowed_l(
         audio_channel_mask_t channelMask, audio_format_t format,
         audio_session_t sessionId, uid_t uid) const
@@ -6186,7 +6283,7 @@
     return true;
 }
 
-// checkForNewParameter_l() must be called with ThreadBase::mLock held
+// checkForNewParameter_l() must be called with ThreadBase::mutex() held
 bool MixerThread::checkForNewParameter_l(const String8& keyValuePair,
                                                        status_t& status)
 {
@@ -6201,7 +6298,7 @@
         reconfig = true;
     }
     if (param.getInt(String8(AudioParameter::keyFormat), value) == NO_ERROR) {
-        if (!AudioFlinger::isValidPcmSinkFormat(static_cast<audio_format_t>(value))) {
+        if (!isValidPcmSinkFormat(static_cast<audio_format_t>(value))) {
             status = BAD_VALUE;
         } else {
             // no need to save value, since it's constant
@@ -6209,7 +6306,7 @@
         }
     }
     if (param.getInt(String8(AudioParameter::keyChannels), value) == NO_ERROR) {
-        if (!AudioFlinger::isValidPcmSinkChannelMask(static_cast<audio_channel_mask_t>(value))) {
+        if (!isValidPcmSinkChannelMask(static_cast<audio_channel_mask_t>(value))) {
             status = BAD_VALUE;
         } else {
             // no need to save value, since it's constant
@@ -6336,7 +6433,7 @@
 }
 
 void MixerThread::onHalLatencyModesChanged_l() {
-    mAudioFlinger->onSupportedLatencyModesChanged(mId, mSupportedLatencyModes);
+    mAfThreadCallback->onSupportedLatencyModesChanged(mId, mSupportedLatencyModes);
 }
 
 void MixerThread::setHalLatencyMode_l() {
@@ -6404,14 +6501,14 @@
     if (modes == nullptr) {
         return BAD_VALUE;
     }
-    Mutex::Autolock _l(mLock);
+    audio_utils::lock_guard _l(mutex());
     *modes = mSupportedLatencyModes;
     return NO_ERROR;
 }
 
 void MixerThread::onRecommendedLatencyModeChanged(
         std::vector<audio_latency_mode_t> modes) {
-    Mutex::Autolock _l(mLock);
+    audio_utils::lock_guard _l(mutex());
     if (modes != mSupportedLatencyModes) {
         ALOGD("%s: thread(%d) supported latency modes: %s",
             __func__, mId, toString(modes).c_str());
@@ -6433,20 +6530,20 @@
 
 /* static */
 sp<IAfPlaybackThread> IAfPlaybackThread::createDirectOutputThread(
-        const sp<AudioFlinger>& audioFlinger,
+        const sp<IAfThreadCallback>& afThreadCallback,
         AudioStreamOut* output, audio_io_handle_t id, bool systemReady,
         const audio_offload_info_t& offloadInfo) {
     return sp<DirectOutputThread>::make(
-            audioFlinger, output, id, systemReady, offloadInfo);
+            afThreadCallback, output, id, systemReady, offloadInfo);
 }
 
-DirectOutputThread::DirectOutputThread(const sp<AudioFlinger>& audioFlinger,
+DirectOutputThread::DirectOutputThread(const sp<IAfThreadCallback>& afThreadCallback,
         AudioStreamOut* output, audio_io_handle_t id, ThreadBase::type_t type, bool systemReady,
         const audio_offload_info_t& offloadInfo)
-    :   PlaybackThread(audioFlinger, output, id, type, systemReady)
+    :   PlaybackThread(afThreadCallback, output, id, type, systemReady)
     , mOffloadInfo(offloadInfo)
 {
-    setMasterBalance(audioFlinger->getMasterBalance_l());
+    setMasterBalance(afThreadCallback->getMasterBalance_l());
 }
 
 DirectOutputThread::~DirectOutputThread()
@@ -6462,7 +6559,7 @@
 
 void DirectOutputThread::setMasterBalance(float balance)
 {
-    Mutex::Autolock _l(mLock);
+    audio_utils::lock_guard _l(mutex());
     if (mMasterBalance != balance) {
         mMasterBalance.store(balance);
         mBalance.computeStereoBalance(balance, &mMasterBalanceLeft, &mMasterBalanceRight);
@@ -6509,14 +6606,14 @@
         }
         left *= v;
         right *= v;
-        if (mAudioFlinger->getMode() != AUDIO_MODE_IN_COMMUNICATION
+        if (mAfThreadCallback->getMode() != AUDIO_MODE_IN_COMMUNICATION
                 || audio_channel_count_from_out_mask(mChannelMask) > 1) {
             left *= mMasterBalanceLeft; // DirectOutputThread balance applied as track volume
             right *= mMasterBalanceRight;
         }
     }
 
-    track->processMuteEvent_l(mAudioFlinger->getOrCreateAudioManager(),
+    track->processMuteEvent_l(mAfThreadCallback->getOrCreateAudioManager(),
         /*muteState=*/{mMasterMute,
                        mStreamTypes[track->streamType()].volume == 0.f,
                        mStreamTypes[track->streamType()].mute,
@@ -6842,7 +6939,7 @@
 void DirectOutputThread::threadLoop_exit()
 {
     {
-        Mutex::Autolock _l(mLock);
+        audio_utils::lock_guard _l(mutex());
         for (size_t i = 0; i < mTracks.size(); i++) {
             if (mTracks[i]->isFlushPending()) {
                 mTracks[i]->flushAck();
@@ -6873,7 +6970,7 @@
     return !mStandby && !(trackPaused || (mHwPaused && !trackStopped));
 }
 
-// checkForNewParameter_l() must be called with ThreadBase::mLock held
+// checkForNewParameter_l() must be called with ThreadBase::mutex() held
 bool DirectOutputThread::checkForNewParameter_l(const String8& keyValuePair,
                                                               status_t& status)
 {
@@ -7008,12 +7105,12 @@
         bool asyncError;
 
         {
-            Mutex::Autolock _l(mLock);
+            audio_utils::unique_lock _l(mutex());
             while (!((mWriteAckSequence & 1) ||
                      (mDrainSequence & 1) ||
                      mAsyncError ||
                      exitPending())) {
-                mWaitWorkCV.wait(mLock);
+                mWaitWorkCV.wait(_l);
             }
 
             if (exitPending()) {
@@ -7049,50 +7146,50 @@
 void AsyncCallbackThread::exit()
 {
     ALOGV("AsyncCallbackThread::exit");
-    Mutex::Autolock _l(mLock);
+    audio_utils::lock_guard _l(mutex());
     requestExit();
-    mWaitWorkCV.broadcast();
+    mWaitWorkCV.notify_all();
 }
 
 void AsyncCallbackThread::setWriteBlocked(uint32_t sequence)
 {
-    Mutex::Autolock _l(mLock);
+    audio_utils::lock_guard _l(mutex());
     // bit 0 is cleared
     mWriteAckSequence = sequence << 1;
 }
 
 void AsyncCallbackThread::resetWriteBlocked()
 {
-    Mutex::Autolock _l(mLock);
+    audio_utils::lock_guard _l(mutex());
     // ignore unexpected callbacks
     if (mWriteAckSequence & 2) {
         mWriteAckSequence |= 1;
-        mWaitWorkCV.signal();
+        mWaitWorkCV.notify_one();
     }
 }
 
 void AsyncCallbackThread::setDraining(uint32_t sequence)
 {
-    Mutex::Autolock _l(mLock);
+    audio_utils::lock_guard _l(mutex());
     // bit 0 is cleared
     mDrainSequence = sequence << 1;
 }
 
 void AsyncCallbackThread::resetDraining()
 {
-    Mutex::Autolock _l(mLock);
+    audio_utils::lock_guard _l(mutex());
     // ignore unexpected callbacks
     if (mDrainSequence & 2) {
         mDrainSequence |= 1;
-        mWaitWorkCV.signal();
+        mWaitWorkCV.notify_one();
     }
 }
 
 void AsyncCallbackThread::setAsyncError()
 {
-    Mutex::Autolock _l(mLock);
+    audio_utils::lock_guard _l(mutex());
     mAsyncError = true;
-    mWaitWorkCV.signal();
+    mWaitWorkCV.notify_one();
 }
 
 
@@ -7100,16 +7197,16 @@
 
 /* static */
 sp<IAfPlaybackThread> IAfPlaybackThread::createOffloadThread(
-        const sp<AudioFlinger>& audioFlinger,
+        const sp<IAfThreadCallback>& afThreadCallback,
         AudioStreamOut* output, audio_io_handle_t id, bool systemReady,
         const audio_offload_info_t& offloadInfo) {
-    return sp<OffloadThread>::make(audioFlinger, output, id, systemReady, offloadInfo);
+    return sp<OffloadThread>::make(afThreadCallback, output, id, systemReady, offloadInfo);
 }
 
-OffloadThread::OffloadThread(const sp<AudioFlinger>& audioFlinger,
+OffloadThread::OffloadThread(const sp<IAfThreadCallback>& afThreadCallback,
         AudioStreamOut* output, audio_io_handle_t id, bool systemReady,
         const audio_offload_info_t& offloadInfo)
-    :   DirectOutputThread(audioFlinger, output, id, OFFLOAD, systemReady, offloadInfo),
+    :   DirectOutputThread(afThreadCallback, output, id, OFFLOAD, systemReady, offloadInfo),
         mPausedWriteLength(0), mPausedBytesRemaining(0), mKeepWakeLock(true)
 {
     //FIXME: mStandby should be set to true by ThreadBase constructo
@@ -7388,7 +7485,7 @@
 
 bool OffloadThread::waitingAsyncCallback()
 {
-    Mutex::Autolock _l(mLock);
+    audio_utils::lock_guard _l(mutex());
     return waitingAsyncCallback_l();
 }
 
@@ -7415,14 +7512,14 @@
 
 void OffloadThread::invalidateTracks(audio_stream_type_t streamType)
 {
-    Mutex::Autolock _l(mLock);
+    audio_utils::lock_guard _l(mutex());
     if (PlaybackThread::invalidateTracks_l(streamType)) {
         mFlushPending = true;
     }
 }
 
 void OffloadThread::invalidateTracks(std::set<audio_port_handle_t>& portIds) {
-    Mutex::Autolock _l(mLock);
+    audio_utils::lock_guard _l(mutex());
     if (PlaybackThread::invalidateTracks_l(portIds)) {
         mFlushPending = true;
     }
@@ -7432,14 +7529,14 @@
 
 /* static */
 sp<IAfDuplicatingThread> IAfDuplicatingThread::create(
-        const sp<AudioFlinger>& audioFlinger,
+        const sp<IAfThreadCallback>& afThreadCallback,
         IAfPlaybackThread* mainThread, audio_io_handle_t id, bool systemReady) {
-    return sp<DuplicatingThread>::make(audioFlinger, mainThread, id, systemReady);
+    return sp<DuplicatingThread>::make(afThreadCallback, mainThread, id, systemReady);
 }
 
-DuplicatingThread::DuplicatingThread(const sp<AudioFlinger>& audioFlinger,
+DuplicatingThread::DuplicatingThread(const sp<IAfThreadCallback>& afThreadCallback,
        IAfPlaybackThread* mainThread, audio_io_handle_t id, bool systemReady)
-    :   MixerThread(audioFlinger, mainThread->getOutput(), id,
+    :   MixerThread(afThreadCallback, mainThread->getOutput(), id,
                     systemReady, DUPLICATING),
         mWaitTimeMs(UINT_MAX)
 {
@@ -7537,7 +7634,6 @@
     if (numTracks > 0) {
         ss << ":";
         for (const auto &track : mOutputTracks) {
-            // TODO(b/288339104) type
             const auto thread = track->thread().promote();
             ss << " (" << track->id() << " : ";
             if (thread.get() != nullptr) {
@@ -7565,7 +7661,7 @@
 
 void DuplicatingThread::addOutputTrack(IAfPlaybackThread* thread)
 {
-    Mutex::Autolock _l(mLock);
+    audio_utils::lock_guard _l(mutex());
     // The downstream MixerThread consumes thread->frameCount() amount of frames per mix pass.
     // Adjust for thread->sampleRate() to determine minimum buffer frame count.
     // Then triple buffer because Threads do not run synchronously and may not be clock locked.
@@ -7602,7 +7698,7 @@
 
 void DuplicatingThread::removeOutputTrack(IAfPlaybackThread* thread)
 {
-    Mutex::Autolock _l(mLock);
+    audio_utils::lock_guard _l(mutex());
     for (size_t i = 0; i < mOutputTracks.size(); i++) {
         if (mOutputTracks[i]->thread() == thread) {
             mOutputTracks[i]->destroy();
@@ -7617,12 +7713,11 @@
     ALOGV("removeOutputTrack(): unknown thread: %p", thread);
 }
 
-// caller must hold mLock
+// caller must hold mutex()
 void DuplicatingThread::updateWaitTime_l()
 {
     mWaitTimeMs = UINT_MAX;
     for (size_t i = 0; i < mOutputTracks.size(); i++) {
-        // TODO(b/288339104) type
         const auto strong = mOutputTracks[i]->thread().promote();
         if (strong != 0) {
             uint32_t waitTimeMs = (strong->frameCount() * 2 * 1000) / strong->sampleRate();
@@ -7678,38 +7773,23 @@
 
 /* static */
 sp<IAfPlaybackThread> IAfPlaybackThread::createSpatializerThread(
-        const sp<AudioFlinger>& audioFlinger,
+        const sp<IAfThreadCallback>& afThreadCallback,
         AudioStreamOut* output,
         audio_io_handle_t id,
         bool systemReady,
         audio_config_base_t* mixerConfig) {
-    return sp<SpatializerThread>::make(audioFlinger, output, id, systemReady, mixerConfig);
+    return sp<SpatializerThread>::make(afThreadCallback, output, id, systemReady, mixerConfig);
 }
 
-SpatializerThread::SpatializerThread(const sp<AudioFlinger>& audioFlinger,
+SpatializerThread::SpatializerThread(const sp<IAfThreadCallback>& afThreadCallback,
                                                              AudioStreamOut* output,
                                                              audio_io_handle_t id,
                                                              bool systemReady,
                                                              audio_config_base_t *mixerConfig)
-    : MixerThread(audioFlinger, output, id, systemReady, SPATIALIZER, mixerConfig)
+    : MixerThread(afThreadCallback, output, id, systemReady, SPATIALIZER, mixerConfig)
 {
 }
 
-void SpatializerThread::onFirstRef() {
-    MixerThread::onFirstRef();
-
-    const pid_t tid = getTid();
-    if (tid == -1) {
-        // Unusual: PlaybackThread::onFirstRef() should set the threadLoop running.
-        ALOGW("%s: Cannot update Spatializer mixer thread priority, not running", __func__);
-    } else {
-        const int priorityBoost = requestSpatializerPriority(getpid(), tid);
-        if (priorityBoost > 0) {
-            stream()->setHalThreadPriority(priorityBoost);
-        }
-    }
-}
-
 void SpatializerThread::setHalLatencyMode_l() {
     // if mSupportedLatencyModes is empty, the HAL stream does not support
     // latency mode control and we can exit.
@@ -7752,18 +7832,20 @@
     if (mode != AUDIO_LATENCY_MODE_LOW && mode != AUDIO_LATENCY_MODE_FREE) {
         return BAD_VALUE;
     }
-    Mutex::Autolock _l(mLock);
+    audio_utils::lock_guard _l(mutex());
     mRequestedLatencyMode = mode;
     return NO_ERROR;
 }
 
 void SpatializerThread::checkOutputStageEffects()
+NO_THREAD_SAFETY_ANALYSIS
+//  'createEffect_l' requires holding mutex 'AudioFlinger_Mutex' exclusively
 {
     bool hasVirtualizer = false;
     bool hasDownMixer = false;
     sp<IAfEffectHandle> finalDownMixer;
     {
-        Mutex::Autolock _l(mLock);
+        audio_utils::lock_guard _l(mutex());
         sp<IAfEffectChain> chain = getEffectChain_l(AUDIO_SESSION_OUTPUT_STAGE);
         if (chain != 0) {
             hasVirtualizer = chain->getEffectFromType_l(FX_IID_SPATIALIZER) != nullptr;
@@ -7782,7 +7864,7 @@
         finalDownMixer.clear();
     } else if (!hasDownMixer) {
         std::vector<effect_descriptor_t> descriptors;
-        status_t status = mAudioFlinger->mEffectsFactoryHal->getDescriptors(
+        status_t status = mAfThreadCallback->getEffectsFactoryHal()->getDescriptors(
                                                         EFFECT_UIID_DOWNMIX, &descriptors);
         if (status != NO_ERROR) {
             return;
@@ -7804,7 +7886,7 @@
     }
 
     {
-        Mutex::Autolock _l(mLock);
+        audio_utils::lock_guard _l(mutex());
         mFinalDownMixer = finalDownMixer;
     }
 }
@@ -7813,19 +7895,19 @@
 //      Record
 // ----------------------------------------------------------------------------
 
-sp<IAfRecordThread> IAfRecordThread::create(const sp<AudioFlinger>& audioFlinger,
+sp<IAfRecordThread> IAfRecordThread::create(const sp<IAfThreadCallback>& afThreadCallback,
         AudioStreamIn* input,
         audio_io_handle_t id,
         bool systemReady) {
-    return sp<RecordThread>::make(audioFlinger, input, id, systemReady);
+    return sp<RecordThread>::make(afThreadCallback, input, id, systemReady);
 }
 
-RecordThread::RecordThread(const sp<AudioFlinger>& audioFlinger,
+RecordThread::RecordThread(const sp<IAfThreadCallback>& afThreadCallback,
                                          AudioStreamIn *input,
                                          audio_io_handle_t id,
                                          bool systemReady
                                          ) :
-    ThreadBase(audioFlinger, id, RECORD, systemReady, false /* isOut */),
+    ThreadBase(afThreadCallback, id, RECORD, systemReady, false /* isOut */),
     mInput(input),
     mSource(mInput),
     mActiveTracks(&this->mLocalLog),
@@ -7846,7 +7928,7 @@
     , mBtNrecSuspended(false)
 {
     snprintf(mThreadName, kThreadNameLength, "AudioIn_%X", id);
-    mNBLogWriter = audioFlinger->newWriter_l(kLogSize, mThreadName);
+    mNBLogWriter = afThreadCallback->newWriter_l(kLogSize, mThreadName);
 
     if (mInput->audioHwDev != nullptr) {
         mIsMsdDevice = strcmp(
@@ -7954,7 +8036,8 @@
 #ifdef TEE_SINK
         // FIXME
 #endif
-        mFastCaptureNBLogWriter = audioFlinger->newWriter_l(kFastCaptureLogSize, "FastCapture");
+        mFastCaptureNBLogWriter =
+                afThreadCallback->newWriter_l(kFastCaptureLogSize, "FastCapture");
         state->mNBLogWriter = mFastCaptureNBLogWriter.get();
         sq->end();
         sq->push(FastCaptureStateQueue::BLOCK_UNTIL_PUSHED);
@@ -7996,8 +8079,8 @@
         mFastCapture->join();
         mFastCapture.clear();
     }
-    mAudioFlinger->unregisterWriter(mFastCaptureNBLogWriter);
-    mAudioFlinger->unregisterWriter(mNBLogWriter);
+    mAfThreadCallback->unregisterWriter(mFastCaptureNBLogWriter);
+    mAfThreadCallback->unregisterWriter(mNBLogWriter);
     free(mRsmpInBuffer);
 }
 
@@ -8009,13 +8092,13 @@
 void RecordThread::preExit()
 {
     ALOGV("  preExit()");
-    Mutex::Autolock _l(mLock);
+    audio_utils::lock_guard _l(mutex());
     for (size_t i = 0; i < mTracks.size(); i++) {
         sp<IAfRecordTrack> track = mTracks[i];
         track->invalidate();
     }
     mActiveTracks.clear();
-    mStartStopCond.broadcast();
+    mStartStopCV.notify_all();
 }
 
 bool RecordThread::threadLoop()
@@ -8027,7 +8110,7 @@
 reacquire_wakelock:
     sp<IAfRecordTrack> activeTrack;
     {
-        Mutex::Autolock _l(mLock);
+        audio_utils::lock_guard _l(mutex());
         acquireWakeLock_l();
     }
 
@@ -8051,13 +8134,13 @@
 
         bool silenceFastCapture = false;
 
-        { // scope for mLock
-            Mutex::Autolock _l(mLock);
+        { // scope for mutex()
+            audio_utils::unique_lock _l(mutex());
 
             processConfigEvents_l();
 
             // check exitPending here because checkForNewParameters_l() and
-            // checkForNewParameters_l() can temporarily release mLock
+            // checkForNewParameters_l() can temporarily release mutex()
             if (exitPending()) {
                 break;
             }
@@ -8065,7 +8148,7 @@
             // sleep with mutex unlocked
             if (sleepUs > 0) {
                 ATRACE_BEGIN("sleepC");
-                mWaitWorkCV.waitRelative(mLock, microseconds((nsecs_t)sleepUs));
+                (void)mWaitWorkCV.wait_for(_l, std::chrono::microseconds(sleepUs));
                 ATRACE_END();
                 sleepUs = 0;
                 continue;
@@ -8079,7 +8162,7 @@
                 releaseWakeLock_l();
                 ALOGV("RecordThread: loop stopping");
                 // go to sleep
-                mWaitWorkCV.wait(mLock);
+                mWaitWorkCV.wait(_l);
                 ALOGV("RecordThread: loop starting");
                 goto reacquire_wakelock;
             }
@@ -8186,7 +8269,7 @@
                 standbyIfNotAlreadyInStandby();
             }
             if (doBroadcast) {
-                mStartStopCond.broadcast();
+                mStartStopCV.notify_all();
             }
 
             // sleep if there are no active tracks to process
@@ -8225,7 +8308,7 @@
                 }
                 state->mCommand = FastCaptureState::READ_WRITE;
 #if 0   // FIXME
-                mFastCaptureDumpState.increaseSamplingN(mAudioFlinger->isLowRamDevice() ?
+                mFastCaptureDumpState.increaseSamplingN(mAfThreadCallback->isLowRamDevice() ?
                         FastThreadDumpState::kSamplingNforLowRamDevice :
                         FastThreadDumpState::kSamplingN);
 #endif
@@ -8555,7 +8638,7 @@
                     {0, 0} /* lastTimestamp */, mSampleRate);
             const double processMs = (lastIoBeginNs - mLastIoEndNs) * 1e-6;
 
-            Mutex::Autolock _l(mLock);
+            audio_utils::lock_guard _l(mutex());
             mIoJitterMs.add(jitterMs);
             mProcessTimeMs.add(processMs);
         }
@@ -8568,13 +8651,13 @@
     standbyIfNotAlreadyInStandby();
 
     {
-        Mutex::Autolock _l(mLock);
+        audio_utils::lock_guard _l(mutex());
         for (size_t i = 0; i < mTracks.size(); i++) {
             sp<IAfRecordTrack> track = mTracks[i];
             track->invalidate();
         }
         mActiveTracks.clear();
-        mStartStopCond.broadcast();
+        mStartStopCV.notify_all();
     }
 
     releaseWakeLock();
@@ -8633,7 +8716,7 @@
     }
 }
 
-// RecordThread::createRecordTrack_l() must be called with AudioFlinger::mLock held
+// RecordThread::createRecordTrack_l() must be called with AudioFlinger::mutex() held
 sp<IAfRecordTrack> RecordThread::createRecordTrack_l(
         const sp<Client>& client,
         const audio_attributes_t& attr,
@@ -8677,7 +8760,7 @@
             goto Exit;
         }
         if (maxSharedAudioHistoryMs < 0
-                || maxSharedAudioHistoryMs > AudioFlinger::kMaxSharedAudioHistoryMs) {
+                || maxSharedAudioHistoryMs > kMaxSharedAudioHistoryMs) {
             lStatus = BAD_VALUE;
             goto Exit;
         }
@@ -8725,7 +8808,7 @@
             mFastTrackAvail
         ) {
           // check compatibility with audio effects.
-          Mutex::Autolock _l(mLock);
+          audio_utils::lock_guard _l(mutex());
           // Do not accept FAST flag if the session has software effects
           sp<IAfEffectChain> chain = getEffectChain_l(sessionId);
           if (chain != 0) {
@@ -8789,8 +8872,8 @@
     *pFrameCount = frameCount;
     *pNotificationFrameCount = notificationFrameCount;
 
-    { // scope for mLock
-        Mutex::Autolock _l(mLock);
+    { // scope for mutex()
+        audio_utils::lock_guard _l(mutex());
         int32_t startFrames = -1;
         if (!mSharedAudioPackageName.empty()
                 && mSharedAudioPackageName == attributionSource.packageName
@@ -8844,14 +8927,14 @@
         recordTrack->clearSyncStartEvent();
     } else if (event != AudioSystem::SYNC_EVENT_SAME) {
         recordTrack->synchronizedRecordState().startRecording(
-                mAudioFlinger->createSyncEvent(
+                mAfThreadCallback->createSyncEvent(
                         event, triggerSession,
                         recordTrack->sessionId(), syncStartEventCallback, recordTrack));
     }
 
     {
         // This section is a rendezvous between binder thread executing start() and RecordThread
-        AutoMutex lock(mLock);
+         audio_utils::lock_guard lock(mutex());
         if (recordTrack->isInvalid()) {
             recordTrack->clearSyncStartEvent();
             ALOGW("%s track %d: invalidated before startInput", __func__, recordTrack->portId());
@@ -8875,9 +8958,9 @@
         recordTrack->setState(IAfTrackBase::STARTING_1);
         mActiveTracks.add(recordTrack);
         if (recordTrack->isExternalTrack()) {
-            mLock.unlock();
+            mutex().unlock();
             status = AudioSystem::startInput(recordTrack->portId());
-            mLock.lock();
+            mutex().lock();
             if (recordTrack->isInvalid()) {
                 recordTrack->clearSyncStartEvent();
                 if (status == NO_ERROR && recordTrack->state() == IAfTrackBase::STARTING_1) {
@@ -8923,7 +9006,7 @@
         }
         recordTrack->setState(IAfTrackBase::STARTING_2);
         // signal thread to start
-        mWaitWorkCV.broadcast();
+        mWaitWorkCV.notify_all();
         return status;
     }
 }
@@ -8936,7 +9019,7 @@
         sp<IAfTrackBase> ptr =
                 std::any_cast<const wp<IAfTrackBase>>(strongEvent->cookie()).promote();
         if (ptr != nullptr) {
-            // TODO(b/288339104) handleSyncStartEvent is in IAfTrackBase not IAfRecordTrack.
+            // TODO(b/291317898) handleSyncStartEvent is in IAfTrackBase not IAfRecordTrack.
             ptr->handleSyncStartEvent(strongEvent);
         }
     }
@@ -8944,7 +9027,7 @@
 
 bool RecordThread::stop(IAfRecordTrack* recordTrack) {
     ALOGV("RecordThread::stop");
-    AutoMutex _l(mLock);
+    audio_utils::unique_lock _l(mutex());
     // if we're invalid, we can't be on the ActiveTracks.
     if (mActiveTracks.indexOf(recordTrack) < 0 || recordTrack->state() == IAfTrackBase::PAUSING) {
         return false;
@@ -8955,8 +9038,8 @@
     // NOTE: Waiting here is important to keep stop synchronous.
     // This is needed for proper patchRecord peer release.
     while (recordTrack->state() == IAfTrackBase::PAUSING && !recordTrack->isInvalid()) {
-        mWaitWorkCV.broadcast(); // signal thread to stop
-        mStartStopCond.wait(mLock);
+        mWaitWorkCV.notify_all(); // signal thread to stop
+        mStartStopCV.wait(_l);
     }
 
     if (recordTrack->state() == IAfTrackBase::PAUSED) { // successful stop
@@ -8985,7 +9068,7 @@
     audio_session_t eventSession = event->triggerSession();
     status_t ret = NAME_NOT_FOUND;
 
-    Mutex::Autolock _l(mLock);
+    audio_utils::lock_guard _l(mutex());
 
     for (size_t i = 0; i < mTracks.size(); i++) {
         sp<IAfRecordTrack> track = mTracks[i];
@@ -9004,7 +9087,7 @@
         std::vector<media::MicrophoneInfoFw>* activeMicrophones) const
 {
     ALOGV("RecordThread::getActiveMicrophones");
-    AutoMutex _l(mLock);
+     audio_utils::lock_guard _l(mutex());
     if (!isStreamInitialized()) {
         return NO_INIT;
     }
@@ -9016,7 +9099,7 @@
             audio_microphone_direction_t direction)
 {
     ALOGV("setPreferredMicrophoneDirection(%d)", direction);
-    AutoMutex _l(mLock);
+     audio_utils::lock_guard _l(mutex());
     if (!isStreamInitialized()) {
         return NO_INIT;
     }
@@ -9026,7 +9109,7 @@
 status_t RecordThread::setPreferredMicrophoneFieldDimension(float zoom)
 {
     ALOGV("setPreferredMicrophoneFieldDimension(%f)", zoom);
-    AutoMutex _l(mLock);
+     audio_utils::lock_guard _l(mutex());
     if (!isStreamInitialized()) {
         return NO_INIT;
     }
@@ -9036,7 +9119,7 @@
 status_t RecordThread::shareAudioHistory(
         const std::string& sharedAudioPackageName, audio_session_t sharedSessionId,
         int64_t sharedAudioStartMs) {
-    AutoMutex _l(mLock);
+     audio_utils::lock_guard _l(mutex());
     return shareAudioHistory_l(sharedAudioPackageName, sharedSessionId, sharedAudioStartMs);
 }
 
@@ -9102,7 +9185,7 @@
     return change;
 }
 
-// destroyTrack_l() must be called with ThreadBase::mLock held
+// destroyTrack_l() must be called with ThreadBase::mutex() held
 void RecordThread::destroyTrack_l(const sp<IAfRecordTrack>& track)
 {
     track->terminate();
@@ -9202,7 +9285,7 @@
 
 void RecordThread::setRecordSilenced(audio_port_handle_t portId, bool silenced)
 {
-    Mutex::Autolock _l(mLock);
+    audio_utils::lock_guard _l(mutex());
     for (size_t i = 0; i < mTracks.size() ; i++) {
         sp<IAfRecordTrack> track = mTracks[i];
         if (track != 0 && track->portId() == portId) {
@@ -9327,7 +9410,7 @@
 
 void RecordThread::checkBtNrec()
 {
-    Mutex::Autolock _l(mLock);
+    audio_utils::lock_guard _l(mutex());
     checkBtNrec_l();
 }
 
@@ -9336,7 +9419,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()) &&
-                        mAudioFlinger->btNrecIsOff();
+                        mAfThreadCallback->btNrecIsOff();
     if (mBtNrecSuspended.exchange(suspend) != suspend) {
         for (size_t i = 0; i < mEffectChains.size(); i++) {
             setEffectSuspended_l(FX_IID_AEC, suspend, mEffectChains[i]->sessionId());
@@ -9436,7 +9519,7 @@
 
 String8 RecordThread::getParameters(const String8& keys)
 {
-    Mutex::Autolock _l(mLock);
+    audio_utils::lock_guard _l(mutex());
     if (initCheck() == NO_ERROR) {
         String8 out_s8;
         if (mInput->stream->getParameters(keys, &out_s8) == OK) {
@@ -9464,7 +9547,7 @@
         desc = sp<AudioIoDescriptor>::make(mId);
         break;
     }
-    mAudioFlinger->ioConfigChanged(event, desc, pid);
+    mAfThreadCallback->ioConfigChanged(event, desc, pid);
 }
 
 void RecordThread::readInputParameters_l()
@@ -9501,7 +9584,7 @@
     audio_input_flags_t flags = mInput->flags;
     mediametrics::LogItem item(mThreadMetrics.getMetricsId());
     item.set(AMEDIAMETRICS_PROP_EVENT, AMEDIAMETRICS_PROP_EVENT_VALUE_READPARAMETERS)
-        .set(AMEDIAMETRICS_PROP_ENCODING, formatToString(mFormat).c_str())
+        .set(AMEDIAMETRICS_PROP_ENCODING, IAfThreadBase::formatToString(mFormat).c_str())
         .set(AMEDIAMETRICS_PROP_FLAGS, toString(flags).c_str())
         .set(AMEDIAMETRICS_PROP_SAMPLERATE, (int32_t)mSampleRate)
         .set(AMEDIAMETRICS_PROP_CHANNELMASK, (int32_t)mChannelMask)
@@ -9512,7 +9595,7 @@
 
 uint32_t RecordThread::getInputFramesLost() const
 {
-    Mutex::Autolock _l(mLock);
+    audio_utils::lock_guard _l(mutex());
     uint32_t result;
     if (initCheck() == NO_ERROR && mInput->stream->getInputFramesLost(&result) == OK) {
         return result;
@@ -9523,7 +9606,7 @@
 KeyedVector<audio_session_t, bool> RecordThread::sessionIds() const
 {
     KeyedVector<audio_session_t, bool> ids;
-    Mutex::Autolock _l(mLock);
+    audio_utils::lock_guard _l(mutex());
     for (size_t j = 0; j < mTracks.size(); ++j) {
         sp<IAfRecordTrack> track = mTracks[j];
         audio_session_t sessionId = track->sessionId();
@@ -9536,14 +9619,14 @@
 
 AudioStreamIn* RecordThread::clearInput()
 {
-    Mutex::Autolock _l(mLock);
+    audio_utils::lock_guard _l(mutex());
     AudioStreamIn *input = mInput;
     mInput = NULL;
     mInputSource.clear();
     return input;
 }
 
-// this method must always be called either with ThreadBase mLock held or inside the thread loop
+// this method must always be called either with ThreadBase mutex() held or inside the thread loop
 sp<StreamHalInterface> RecordThread::stream() const
 {
     if (mInput == NULL) {
@@ -9661,7 +9744,7 @@
 
 void RecordThread::updateOutDevices(const DeviceDescriptorBaseVector& outDevices)
 {
-    Mutex::Autolock _l(mLock);
+    audio_utils::lock_guard _l(mutex());
     mOutDevices = outDevices;
     mOutDeviceTypeAddrs = deviceTypeAddrsFromDescriptors(mOutDevices);
     for (size_t i = 0; i < mEffectChains.size(); i++) {
@@ -9798,7 +9881,7 @@
 
 void RecordThread::addPatchTrack(const sp<IAfPatchRecord>& record)
 {
-    Mutex::Autolock _l(mLock);
+    audio_utils::lock_guard _l(mutex());
     mTracks.add(record);
     if (record->getSource()) {
         mSource = record->getSource();
@@ -9807,7 +9890,7 @@
 
 void RecordThread::deletePatchTrack(const sp<IAfPatchRecord>& record)
 {
-    Mutex::Autolock _l(mLock);
+    audio_utils::lock_guard _l(mutex());
     if (mSource == record->getSource()) {
         mSource = mInput;
     }
@@ -9909,9 +9992,9 @@
 
 
 MmapThread::MmapThread(
-        const sp<AudioFlinger>& audioFlinger, audio_io_handle_t id,
+        const sp<IAfThreadCallback>& afThreadCallback, audio_io_handle_t id,
         AudioHwDevice *hwDev, const sp<StreamHalInterface>& stream, bool systemReady, bool isOut)
-    : ThreadBase(audioFlinger, id, (isOut ? MMAP_PLAYBACK : MMAP_CAPTURE), systemReady, isOut),
+    : ThreadBase(afThreadCallback, id, (isOut ? MMAP_PLAYBACK : MMAP_CAPTURE), systemReady, isOut),
       mSessionId(AUDIO_SESSION_NONE),
       mPortId(AUDIO_PORT_HANDLE_NONE),
       mHalStream(stream), mHalDevice(hwDev->hwDevice()), mAudioHwDev(hwDev),
@@ -9932,7 +10015,7 @@
 {
     ActiveTracks<IAfMmapTrack> activeTracks;
     {
-        Mutex::Autolock _l(mLock);
+        audio_utils::lock_guard _l(mutex());
         for (const sp<IAfMmapTrack>& t : mActiveTracks) {
             activeTracks.add(t);
         }
@@ -10019,7 +10102,7 @@
     audio_port_handle_t portId = AUDIO_PORT_HANDLE_NONE;
 
     audio_io_handle_t io = mId;
-    AttributionSourceState adjAttributionSource = AudioFlinger::checkAttributionSourcePackage(
+    const AttributionSourceState adjAttributionSource = afutils::checkAttributionSourcePackage(
             client.attributionSource);
 
     if (isOutput()) {
@@ -10076,24 +10159,24 @@
         {
             // Add the track record before starting input so that the silent status for the
             // client can be cached.
-            Mutex::Autolock _l(mLock);
+            audio_utils::lock_guard _l(mutex());
             setClientSilencedState_l(portId, false /*silenced*/);
         }
         ret = AudioSystem::startInput(portId);
     }
 
-    Mutex::Autolock _l(mLock);
+    audio_utils::lock_guard _l(mutex());
     // abort if start is rejected by audio policy manager
     if (ret != NO_ERROR) {
         ALOGE("%s: error start rejected by AudioPolicyManager = %d", __FUNCTION__, ret);
         if (!mActiveTracks.isEmpty()) {
-            mLock.unlock();
+            mutex().unlock();
             if (isOutput()) {
                 AudioSystem::releaseOutput(portId);
             } else {
                 AudioSystem::releaseInput(portId);
             }
-            mLock.lock();
+            mutex().lock();
         } else {
             mHalStream->stop();
         }
@@ -10158,7 +10241,7 @@
         return NO_ERROR;
     }
 
-    Mutex::Autolock _l(mLock);
+    audio_utils::lock_guard _l(mutex());
 
     sp<IAfMmapTrack> track;
     for (const sp<IAfMmapTrack>& t : mActiveTracks) {
@@ -10174,7 +10257,7 @@
     mActiveTracks.remove(track);
     eraseClientSilencedState_l(track->portId());
 
-    mLock.unlock();
+    mutex().unlock();
     if (isOutput()) {
         AudioSystem::stopOutput(track->portId());
         AudioSystem::releaseOutput(track->portId());
@@ -10182,7 +10265,7 @@
         AudioSystem::stopInput(track->portId());
         AudioSystem::releaseInput(track->portId());
     }
-    mLock.lock();
+    mutex().lock();
 
     sp<IAfEffectChain> chain = getEffectChain_l(track->sessionId());
     if (chain != 0) {
@@ -10241,7 +10324,7 @@
     // TODO: make a readHalParameters call?
     mediametrics::LogItem item(mThreadMetrics.getMetricsId());
     item.set(AMEDIAMETRICS_PROP_EVENT, AMEDIAMETRICS_PROP_EVENT_VALUE_READPARAMETERS)
-        .set(AMEDIAMETRICS_PROP_ENCODING, formatToString(mFormat).c_str())
+        .set(AMEDIAMETRICS_PROP_ENCODING, IAfThreadBase::formatToString(mFormat).c_str())
         .set(AMEDIAMETRICS_PROP_SAMPLERATE, (int32_t)mSampleRate)
         .set(AMEDIAMETRICS_PROP_CHANNELMASK, (int32_t)mChannelMask)
         .set(AMEDIAMETRICS_PROP_CHANNELCOUNT, (int32_t)mChannelCount)
@@ -10254,7 +10337,7 @@
                 (int32_t)mHapticChannelCount)
         */
         .set(AMEDIAMETRICS_PROP_PREFIX_HAL    AMEDIAMETRICS_PROP_ENCODING,
-                formatToString(mHALFormat).c_str())
+                IAfThreadBase::formatToString(mHALFormat).c_str())
         .set(AMEDIAMETRICS_PROP_PREFIX_HAL    AMEDIAMETRICS_PROP_FRAMECOUNT,
                 (int32_t)mFrameCount) // sic - added HAL
         .record();
@@ -10271,7 +10354,7 @@
         Vector<sp<IAfEffectChain>> effectChains;
 
         { // under Thread lock
-        Mutex::Autolock _l(mLock);
+        audio_utils::unique_lock _l(mutex());
 
         if (mSignalPending) {
             // A signal was raised while we were unlocked
@@ -10287,7 +10370,7 @@
 
                 // wait until we have something to do...
                 ALOGV("%s going to sleep", myName.c_str());
-                mWaitWorkCV.wait(mLock);
+                mWaitWorkCV.wait(_l);
                 ALOGV("%s waking up", myName.c_str());
 
                 checkSilentMode_l();
@@ -10330,7 +10413,7 @@
     return false;
 }
 
-// checkForNewParameter_l() must be called with ThreadBase::mLock held
+// checkForNewParameter_l() must be called with ThreadBase::mutex() held
 bool MmapThread::checkForNewParameter_l(const String8& keyValuePair,
                                                               status_t& status)
 {
@@ -10351,7 +10434,7 @@
 
 String8 MmapThread::getParameters(const String8& keys)
 {
-    Mutex::Autolock _l(mLock);
+    audio_utils::lock_guard _l(mutex());
     String8 out_s8;
     if (initCheck() == NO_ERROR && mHalStream->getParameters(keys, &out_s8) == OK) {
         return out_s8;
@@ -10381,12 +10464,12 @@
         desc = sp<AudioIoDescriptor>::make(mId);
         break;
     }
-    mAudioFlinger->ioConfigChanged(event, desc, pid);
+    mAfThreadCallback->ioConfigChanged(event, desc, pid);
 }
 
 status_t MmapThread::createAudioPatch_l(const struct audio_patch* patch,
                                                           audio_patch_handle_t *handle)
-NO_THREAD_SAFETY_ANALYSIS  // elease and re-acquire mLock
+NO_THREAD_SAFETY_ANALYSIS  // elease and re-acquire mutex()
 {
     status_t status = NO_ERROR;
 
@@ -10462,9 +10545,9 @@
         }
         sp<MmapStreamCallback> callback = mCallback.promote();
         if (mDeviceId != deviceId && callback != 0) {
-            mLock.unlock();
+            mutex().unlock();
             callback->onRoutingChanged(deviceId);
-            mLock.lock();
+            mutex().lock();
         }
         mPatch = *patch;
         mDeviceId = deviceId;
@@ -10615,7 +10698,7 @@
 }
 
 void MmapThread::checkInvalidTracks_l()
-NO_THREAD_SAFETY_ANALYSIS  // release and re-acquire mLock
+NO_THREAD_SAFETY_ANALYSIS  // release and re-acquire mutex()
 {
     sp<MmapStreamCallback> callback;
     for (const sp<IAfMmapTrack>& track : mActiveTracks) {
@@ -10629,9 +10712,9 @@
         }
     }
     if (callback != 0) {
-        mLock.unlock();
+        mutex().unlock();
         callback->onRoutingChanged(AUDIO_PORT_HANDLE_NONE);
-        mLock.lock();
+        mutex().lock();
     }
 }
 
@@ -10667,15 +10750,15 @@
 
 /* static */
 sp<IAfMmapPlaybackThread> IAfMmapPlaybackThread::create(
-        const sp<AudioFlinger>& audioFlinger, audio_io_handle_t id,
+        const sp<IAfThreadCallback>& afThreadCallback, audio_io_handle_t id,
         AudioHwDevice* hwDev,  AudioStreamOut* output, bool systemReady) {
-    return sp<MmapPlaybackThread>::make(audioFlinger, id, hwDev, output, systemReady);
+    return sp<MmapPlaybackThread>::make(afThreadCallback, id, hwDev, output, systemReady);
 }
 
 MmapPlaybackThread::MmapPlaybackThread(
-        const sp<AudioFlinger>& audioFlinger, audio_io_handle_t id,
+        const sp<IAfThreadCallback>& afThreadCallback, audio_io_handle_t id,
         AudioHwDevice *hwDev,  AudioStreamOut *output, bool systemReady)
-    : MmapThread(audioFlinger, id, hwDev, output->stream, systemReady, true /* isOut */),
+    : MmapThread(afThreadCallback, id, hwDev, output->stream, systemReady, true /* isOut */),
       mStreamType(AUDIO_STREAM_MUSIC),
       mStreamVolume(1.0),
       mStreamMute(false),
@@ -10683,8 +10766,8 @@
 {
     snprintf(mThreadName, kThreadNameLength, "AudioMmapOut_%X", id);
     mChannelCount = audio_channel_count_from_out_mask(mChannelMask);
-    mMasterVolume = audioFlinger->masterVolume_l();
-    mMasterMute = audioFlinger->masterMute_l();
+    mMasterVolume = afThreadCallback->masterVolume_l();
+    mMasterMute = afThreadCallback->masterMute_l();
     if (mAudioHwDev) {
         if (mAudioHwDev->canSetMasterVolume()) {
             mMasterVolume = 1.0;
@@ -10709,7 +10792,7 @@
 
 AudioStreamOut* MmapPlaybackThread::clearOutput()
 {
-    Mutex::Autolock _l(mLock);
+    audio_utils::lock_guard _l(mutex());
     AudioStreamOut *output = mOutput;
     mOutput = NULL;
     return output;
@@ -10717,7 +10800,7 @@
 
 void MmapPlaybackThread::setMasterVolume(float value)
 {
-    Mutex::Autolock _l(mLock);
+    audio_utils::lock_guard _l(mutex());
     // Don't apply master volume in SW if our HAL can do it for us.
     if (mAudioHwDev &&
             mAudioHwDev->canSetMasterVolume()) {
@@ -10729,7 +10812,7 @@
 
 void MmapPlaybackThread::setMasterMute(bool muted)
 {
-    Mutex::Autolock _l(mLock);
+    audio_utils::lock_guard _l(mutex());
     // Don't apply master mute in SW if our HAL can do it for us.
     if (mAudioHwDev && mAudioHwDev->canSetMasterMute()) {
         mMasterMute = false;
@@ -10740,7 +10823,7 @@
 
 void MmapPlaybackThread::setStreamVolume(audio_stream_type_t stream, float value)
 {
-    Mutex::Autolock _l(mLock);
+    audio_utils::lock_guard _l(mutex());
     if (stream == mStreamType) {
         mStreamVolume = value;
         broadcast_l();
@@ -10749,7 +10832,7 @@
 
 float MmapPlaybackThread::streamVolume(audio_stream_type_t stream) const
 {
-    Mutex::Autolock _l(mLock);
+    audio_utils::lock_guard _l(mutex());
     if (stream == mStreamType) {
         return mStreamVolume;
     }
@@ -10758,7 +10841,7 @@
 
 void MmapPlaybackThread::setStreamMute(audio_stream_type_t stream, bool muted)
 {
-    Mutex::Autolock _l(mLock);
+    audio_utils::lock_guard _l(mutex());
     if (stream == mStreamType) {
         mStreamMute= muted;
         broadcast_l();
@@ -10767,7 +10850,7 @@
 
 void MmapPlaybackThread::invalidateTracks(audio_stream_type_t streamType)
 {
-    Mutex::Autolock _l(mLock);
+    audio_utils::lock_guard _l(mutex());
     if (streamType == mStreamType) {
         for (const sp<IAfMmapTrack>& track : mActiveTracks) {
             track->invalidate();
@@ -10778,7 +10861,7 @@
 
 void MmapPlaybackThread::invalidateTracks(std::set<audio_port_handle_t>& portIds)
 {
-    Mutex::Autolock _l(mLock);
+    audio_utils::lock_guard _l(mutex());
     bool trackMatch = false;
     for (const sp<IAfMmapTrack>& track : mActiveTracks) {
         if (portIds.find(track->portId()) != portIds.end()) {
@@ -10827,9 +10910,9 @@
             if (callback != 0) {
                 mHalVolFloat = volume; // SW volume control worked, so update value.
                 mNoCallbackWarningCount = 0;
-                mLock.unlock();
+                mutex().unlock();
                 callback->onVolumeChanged(volume);
-                mLock.lock();
+                mutex().lock();
             } else {
                 if (mNoCallbackWarningCount < kMaxNoCallbackWarnings) {
                     ALOGW("Could not set MMAP stream volume: no volume callback!");
@@ -10839,7 +10922,7 @@
         }
         for (const sp<IAfMmapTrack>& track : mActiveTracks) {
             track->setMetadataHasChanged();
-            track->processMuteEvent_l(mAudioFlinger->getOrCreateAudioManager(),
+            track->processMuteEvent_l(mAfThreadCallback->getOrCreateAudioManager(),
                 /*muteState=*/{mMasterMute,
                                mStreamVolume == 0.f,
                                mStreamMute,
@@ -10926,7 +11009,7 @@
     return NO_ERROR;
 }
 
-// startMelComputation_l() must be called with AudioFlinger::mLock held
+// startMelComputation_l() must be called with AudioFlinger::mutex() held
 void MmapPlaybackThread::startMelComputation_l(
         const sp<audio_utils::MelProcessor>& processor)
 {
@@ -10940,7 +11023,7 @@
     // assigned constant for each thread
 }
 
-// stopMelComputation_l() must be called with AudioFlinger::mLock held
+// stopMelComputation_l() must be called with AudioFlinger::mutex() held
 void MmapPlaybackThread::stopMelComputation_l()
 {
     ALOGV("%s: pausing mel processor for thread %d", __func__, id());
@@ -10961,15 +11044,15 @@
 
 /* static */
 sp<IAfMmapCaptureThread> IAfMmapCaptureThread::create(
-        const sp<AudioFlinger>& audioFlinger, audio_io_handle_t id,
+        const sp<IAfThreadCallback>& afThreadCallback, audio_io_handle_t id,
         AudioHwDevice* hwDev,  AudioStreamIn* input, bool systemReady) {
-    return sp<MmapCaptureThread>::make(audioFlinger, id, hwDev, input, systemReady);
+    return sp<MmapCaptureThread>::make(afThreadCallback, id, hwDev, input, systemReady);
 }
 
 MmapCaptureThread::MmapCaptureThread(
-        const sp<AudioFlinger>& audioFlinger, audio_io_handle_t id,
+        const sp<IAfThreadCallback>& afThreadCallback, audio_io_handle_t id,
         AudioHwDevice *hwDev,  AudioStreamIn *input, bool systemReady)
-    : MmapThread(audioFlinger, id, hwDev, input->stream, systemReady, false /* isOut */),
+    : MmapThread(afThreadCallback, id, hwDev, input->stream, systemReady, false /* isOut */),
       mInput(input)
 {
     snprintf(mThreadName, kThreadNameLength, "AudioMmapIn_%X", id);
@@ -10989,7 +11072,7 @@
 
 AudioStreamIn* MmapCaptureThread::clearInput()
 {
-    Mutex::Autolock _l(mLock);
+    audio_utils::lock_guard _l(mutex());
     AudioStreamIn *input = mInput;
     mInput = NULL;
     return input;
@@ -11047,7 +11130,7 @@
 
 void MmapCaptureThread::setRecordSilenced(audio_port_handle_t portId, bool silenced)
 {
-    Mutex::Autolock _l(mLock);
+    audio_utils::lock_guard _l(mutex());
     for (size_t i = 0; i < mActiveTracks.size() ; i++) {
         if (mActiveTracks[i]->portId() == portId) {
             mActiveTracks[i]->setSilenced_l(silenced);
@@ -11079,14 +11162,14 @@
 
 /* static */
 sp<IAfPlaybackThread> IAfPlaybackThread::createBitPerfectThread(
-        const sp<AudioFlinger>& audioflinger,
+        const sp<IAfThreadCallback>& afThreadCallback,
         AudioStreamOut* output, audio_io_handle_t id, bool systemReady) {
-    return sp<BitPerfectThread>::make(audioflinger, output, id, systemReady);
+    return sp<BitPerfectThread>::make(afThreadCallback, output, id, systemReady);
 }
 
-BitPerfectThread::BitPerfectThread(const sp<AudioFlinger> &audioflinger,
+BitPerfectThread::BitPerfectThread(const sp<IAfThreadCallback> &afThreadCallback,
         AudioStreamOut *output, audio_io_handle_t id, bool systemReady)
-        : MixerThread(audioflinger, output, id, systemReady, BIT_PERFECT) {}
+        : MixerThread(afThreadCallback, output, id, systemReady, BIT_PERFECT) {}
 
 PlaybackThread::mixer_state BitPerfectThread::prepareTracks_l(
         Vector<sp<IAfTrack>>* tracksToRemove) {
diff --git a/services/audioflinger/Threads.h b/services/audioflinger/Threads.h
index 8d80382..3105ad7 100644
--- a/services/audioflinger/Threads.h
+++ b/services/audioflinger/Threads.h
@@ -17,21 +17,36 @@
 
 #pragma once
 
+// ADD_BATTERY_DATA AUDIO_WATCHDOG FAST_THREAD_STATISTICS STATE_QUEUE_DUMP TEE_SINK
+#include "Configuration.h"
+#include "IAfThread.h"
+#include "IAfTrack.h"
+
+#include <android-base/macros.h>  // DISALLOW_COPY_AND_ASSIGN
+#include <android/os/IPowerManager.h>
+#include <afutils/AudioWatchdog.h>
+#include <afutils/NBAIO_Tee.h>
+#include <audio_utils/Balance.h>
+#include <audio_utils/SimpleLog.h>
+#include <datapath/ThreadMetrics.h>
+#include <fastpath/FastCapture.h>
+#include <fastpath/FastMixer.h>
+#include <mediautils/Synchronization.h>
+#include <mediautils/ThreadSnapshot.h>
+#include <timing/MonotonicFrameCounter.h>
+#include <utils/Log.h>
+
 namespace android {
 
 class AsyncCallbackThread;
 
 class ThreadBase : public virtual IAfThreadBase, public Thread {
-    // TODO(b/288339104) remove friends
-    friend class RecordTrack;
-    friend class Track;
-    friend class TrackBase;
 public:
     static const char *threadTypeToString(type_t type);
 
-    AudioFlinger* audioFlinger() const final { return mAudioFlinger.get(); }
+    IAfThreadCallback* afThreadCallback() const final { return mAfThreadCallback.get(); }
 
-    ThreadBase(const sp<AudioFlinger>& audioFlinger, audio_io_handle_t id,
+    ThreadBase(const sp<IAfThreadCallback>& afThreadCallback, audio_io_handle_t id,
                type_t type, bool systemReady, bool isOut);
     ~ThreadBase() override;
 
@@ -62,20 +77,20 @@
 
     // Config event sequence by client if status needed (e.g binder thread calling setParameters()):
     //  1. create SetParameterConfigEvent. This sets mWaitStatus in config event
-    //  2. Lock mLock
+    //  2. Lock mutex()
     //  3. Call sendConfigEvent_l(): Append to mConfigEvents and mWaitWorkCV.signal
     //  4. sendConfigEvent_l() reads status from event->mStatus;
     //  5. sendConfigEvent_l() returns status
     //  6. Unlock
     //
     // Parameter sequence by server: threadLoop calling processConfigEvents_l():
-    // 1. Lock mLock
+    // 1. Lock mutex()
     // 2. If there is an entry in mConfigEvents proceed ...
     // 3. Read first entry in mConfigEvents
     // 4. Remove first entry from mConfigEvents
     // 5. Process
     // 6. Set event->mStatus
-    // 7. event->mCond.signal
+    // 7. event->mCondition.notify_one()
     // 8. Unlock
 
     class ConfigEvent: public RefBase {
@@ -88,9 +103,10 @@
             }
         }
 
+        audio_utils::mutex& mutex() const { return mMutex; }
         const int mType; // event type e.g. CFG_EVENT_IO
-        Mutex mLock;     // mutex associated with mCond
-        Condition mCond; // condition for status return
+        mutable audio_utils::mutex mMutex; // mutex associated with mCondition
+        audio_utils::condition_variable mCondition; // condition for status return
         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
@@ -307,7 +323,7 @@
     void exit() final;
     status_t setParameters(const String8& keyValuePairs) final;
 
-                // sendConfigEvent_l() must be called with ThreadBase::mLock held
+                // 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);
@@ -374,7 +390,8 @@
                                     status_t *status /*non-NULL*/,
                                     bool pinned,
                                     bool probe,
-                                    bool notifyFramesProcessed) final;
+                                    bool notifyFramesProcessed) final
+            REQUIRES(audio_utils::AudioFlinger_Mutex);
 
                 // return values for hasAudioSession (bit field)
                 enum effect_state {
@@ -413,7 +430,8 @@
                 // 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
-    status_t addEffect_l(const sp<IAfEffectModule>& effect) final;
+    status_t addEffect_ll(const sp<IAfEffectModule>& effect) final
+            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;
@@ -421,10 +439,10 @@
     void disconnectEffectHandle(IAfEffectHandle* handle, bool unpinIfLast) final;
                 // detach all tracks connected to an auxiliary effect
     void detachAuxEffect_l(int /* effectId */) override {}
-    // TODO(b/288339104) - remove hasAudioSession_l below.
+    // 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 {
-                    Mutex::Autolock _l(mLock);
+                    std::lock_guard _l(mutex());
                     return hasAudioSession_l(sessionId);
                 }
 
@@ -492,19 +510,19 @@
                 // deliver stats to mediametrics.
     void sendStatistics(bool force) final;
 
-    Mutex& mutex() const final {
-        return mLock;
+    audio_utils::mutex& mutex() const final RETURN_CAPABILITY(audio_utils::ThreadBase_Mutex) {
+        return mMutex;
     }
-    mutable     Mutex                   mLock;
+    mutable audio_utils::mutex mMutex;
 
     void onEffectEnable(const sp<IAfEffectModule>& effect) final;
     void onEffectDisable() final;
 
-                // invalidateTracksForAudioSession_l must be called with holding mLock.
+                // invalidateTracksForAudioSession_l must be called with holding mutex().
     void invalidateTracksForAudioSession_l(audio_session_t /* sessionId */) const override {}
                 // Invalidate all the tracks with the given audio session.
     void invalidateTracksForAudioSession(audio_session_t sessionId) const final {
-                    Mutex::Autolock _l(mLock);
+                    std::lock_guard _l(mutex());
                     invalidateTracksForAudioSession_l(sessionId);
                 }
 
@@ -519,8 +537,10 @@
                     }
                 }
 
-    void startMelComputation_l(const sp<audio_utils::MelProcessor>& processor) override;
-    void stopMelComputation_l() override;
+    void startMelComputation_l(const sp<audio_utils::MelProcessor>& processor) override
+            REQUIRES(audio_utils::AudioFlinger_Mutex);
+    void stopMelComputation_l() override
+            REQUIRES(audio_utils::AudioFlinger_Mutex);
 
 protected:
 
@@ -571,7 +591,7 @@
                                 return INVALID_OPERATION;
                             }
 public:
-// TODO(b/288339104) organize with publics
+// TODO(b/291317898) organize with publics
                 product_strategy_t getStrategyForStream(audio_stream_type_t stream) const;
 protected:
 
@@ -581,15 +601,12 @@
                             { }
     virtual     void        dumpTracks_l(int fd __unused, const Vector<String16>& args __unused) { }
 
-
-    friend class AudioFlinger;      // for mEffectChains and mAudioManager
-
                 const type_t            mType;
 
                 // Used by parameters, config events, addTrack_l, exit
-                Condition               mWaitWorkCV;
+                audio_utils::condition_variable mWaitWorkCV;
 
-                const sp<AudioFlinger>  mAudioFlinger;
+                const sp<IAfThreadCallback>  mAfThreadCallback;
                 ThreadMetrics           mThreadMetrics;
                 const bool              mIsOut;
 
@@ -793,9 +810,6 @@
 class PlaybackThread : public ThreadBase, public virtual IAfPlaybackThread,
                        public StreamOutHalInterfaceCallback,
                        public virtual VolumeInterface, public StreamOutHalInterfaceEventCallback {
-    // TODO(b/288339104) remove friends
-    friend class OutputTrack;
-    friend class Track;
 public:
     sp<IAfPlaybackThread> asIAfPlaybackThread() final {
         return sp<IAfPlaybackThread>::fromExisting(this);
@@ -816,7 +830,7 @@
     // for initial conditions or large delays.
     static const nsecs_t kMaxNextBufferDelayNs = 100000000;
 
-    PlaybackThread(const sp<AudioFlinger>& audioFlinger, AudioStreamOut* output,
+    PlaybackThread(const sp<IAfThreadCallback>& afThreadCallback, AudioStreamOut* output,
                    audio_io_handle_t id, type_t type, bool systemReady,
                    audio_config_base_t *mixerConfig = nullptr);
     ~PlaybackThread() override;
@@ -928,7 +942,8 @@
                                 audio_port_handle_t portId,
                                 const sp<media::IAudioTrackCallback>& callback,
                                 bool isSpatialized,
-                                bool isBitPerfect) final;
+                                bool isBitPerfect) final
+            REQUIRES(audio_utils::AudioFlinger_Mutex);
 
     bool isTrackActive(const sp<IAfTrack>& track) const final {
         return mActiveTracks.indexOf(track) >= 0;
@@ -1032,7 +1047,7 @@
                 }
 
     void setDownStreamPatch(const struct audio_patch* patch) final {
-                    Mutex::Autolock _l(mLock);
+                    std::lock_guard _l(mutex());
                     mDownStreamPatch = *patch;
                 }
 
@@ -1054,11 +1069,13 @@
                     return INVALID_OPERATION;
                 }
 
-    void startMelComputation_l(const sp<audio_utils::MelProcessor>& processor) override;
-    void stopMelComputation_l() override;
+    void startMelComputation_l(const sp<audio_utils::MelProcessor>& processor) override
+            REQUIRES(audio_utils::AudioFlinger_Mutex);
+    void stopMelComputation_l() override
+            REQUIRES(audio_utils::AudioFlinger_Mutex);
 
     void setStandby() final {
-                    Mutex::Autolock _l(mLock);
+                    std::lock_guard _l(mutex());
                     setStandby_l();
                 }
 
@@ -1070,7 +1087,7 @@
                 }
 
     bool waitForHalStart() final {
-                    Mutex::Autolock _l(mLock);
+                    audio_utils::unique_lock _l(mutex());
                     static const nsecs_t kWaitHalTimeoutNs = seconds(2);
                     nsecs_t endWaitTimetNs = systemTime() + kWaitHalTimeoutNs;
                     while (!mHalStarted) {
@@ -1079,7 +1096,7 @@
                             break;
                         }
                         nsecs_t waitTimeLeftNs = endWaitTimetNs - timeNs;
-                        mWaitHalStartCV.waitRelative(mLock, waitTimeLeftNs);
+                        mWaitHalStartCV.wait_for(_l, std::chrono::nanoseconds(waitTimeLeftNs));
                     }
                     return mHalStarted;
                 }
@@ -1236,8 +1253,6 @@
                                 ThreadBase::invalidateTracksForAudioSession_l(sessionId, mTracks);
                             }
 
-    friend class AudioFlinger;      // for numerous
-
     DISALLOW_COPY_AND_ASSIGN(PlaybackThread);
 
     status_t addTrack_l(const sp<IAfTrack>& track) final;
@@ -1362,7 +1377,8 @@
 
     sp<AsyncCallbackThread>         mCallbackThread;
 
-    Mutex                                    mAudioTrackCbLock;
+    audio_utils::mutex& audioTrackCbMutex() const { return mAudioTrackCbMutex; }
+    mutable audio_utils::mutex mAudioTrackCbMutex;
     // Record of IAudioTrackCallback
     std::map<sp<IAfTrack>, sp<media::IAudioTrackCallback>> mAudioTrackCallbacks;
 
@@ -1383,7 +1399,7 @@
 
     // output stream start detection based on render position returned by the kernel
     // condition signalled when the output stream has started
-    Condition                mWaitHalStartCV;
+    audio_utils::condition_variable mWaitHalStartCV;
     // true when the output stream render position has moved, reset to false in standby
     bool                     mHalStarted = false;
     // last kernel render position saved when entering standby
@@ -1448,7 +1464,7 @@
 class MixerThread : public PlaybackThread,
                     public StreamOutHalInterfaceLatencyModeCallback  {
 public:
-    MixerThread(const sp<AudioFlinger>& audioFlinger,
+    MixerThread(const sp<IAfThreadCallback>& afThreadCallback,
                 AudioStreamOut* output,
                 audio_io_handle_t id,
                 bool systemReady,
@@ -1578,10 +1594,10 @@
         return sp<IAfDirectOutputThread>::fromExisting(this);
     }
 
-    DirectOutputThread(const sp<AudioFlinger>& audioFlinger, AudioStreamOut* output,
+    DirectOutputThread(const sp<IAfThreadCallback>& afThreadCallback, AudioStreamOut* output,
                        audio_io_handle_t id, bool systemReady,
                        const audio_offload_info_t& offloadInfo)
-        : DirectOutputThread(audioFlinger, output, id, DIRECT, systemReady, offloadInfo) { }
+        : DirectOutputThread(afThreadCallback, output, id, DIRECT, systemReady, offloadInfo) { }
 
     virtual                 ~DirectOutputThread();
 
@@ -1618,7 +1634,7 @@
     audioflinger::MonotonicFrameCounter mMonotonicFrameCounter;  // for VolumeShaper
     bool mVolumeShaperActive = false;
 
-    DirectOutputThread(const sp<AudioFlinger>& audioFlinger, AudioStreamOut* output,
+    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);
@@ -1659,7 +1675,7 @@
 class OffloadThread : public DirectOutputThread {
 public:
 
-    OffloadThread(const sp<AudioFlinger>& audioFlinger, AudioStreamOut* output,
+    OffloadThread(const sp<IAfThreadCallback>& afThreadCallback, AudioStreamOut* output,
                   audio_io_handle_t id, bool systemReady,
                   const audio_offload_info_t& offloadInfo);
     virtual                 ~OffloadThread() {};
@@ -1710,14 +1726,17 @@
     // setDraining(). The sequence is shifted one bit to the left and the lsb is used
     // to indicate that the callback has been received via resetDraining()
     uint32_t                   mDrainSequence;
-    Condition                  mWaitWorkCV;
-    Mutex                      mLock;
+    audio_utils::condition_variable mWaitWorkCV;
+    mutable audio_utils::mutex mMutex;
     bool                       mAsyncError;
+
+    audio_utils::mutex& mutex() const { return mMutex; }
 };
 
 class DuplicatingThread : public MixerThread, public IAfDuplicatingThread {
 public:
-    DuplicatingThread(const sp<AudioFlinger>& audioFlinger, IAfPlaybackThread* mainThread,
+    DuplicatingThread(const sp<IAfThreadCallback>& afThreadCallback,
+            IAfPlaybackThread* mainThread,
                       audio_io_handle_t id, bool systemReady);
     ~DuplicatingThread() override;
 
@@ -1779,7 +1798,7 @@
 
 class SpatializerThread : public MixerThread {
 public:
-    SpatializerThread(const sp<AudioFlinger>& audioFlinger,
+    SpatializerThread(const sp<IAfThreadCallback>& afThreadCallback,
                            AudioStreamOut* output,
                            audio_io_handle_t id,
                            bool systemReady,
@@ -1787,9 +1806,6 @@
 
     bool hasFastMixer() const final { return false; }
 
-            // RefBase
-    void onFirstRef() final;
-
     status_t setRequestedLatencyMode(audio_latency_mode_t mode) final;
 
 protected:
@@ -1806,16 +1822,13 @@
 // record thread
 class RecordThread : public IAfRecordThread, public ThreadBase
 {
-    // TODO(b/288339104) remove friends
-    friend class PassthruPatchRecord;
-    friend class RecordTrack;
     friend class ResamplerBufferProvider;
 public:
     sp<IAfRecordThread> asIAfRecordThread() final {
         return sp<IAfRecordThread>::fromExisting(this);
     }
 
-            RecordThread(const sp<AudioFlinger>& audioFlinger,
+            RecordThread(const sp<IAfThreadCallback>& afThreadCallback,
                     AudioStreamIn *input,
                     audio_io_handle_t id,
                     bool systemReady
@@ -1854,7 +1867,8 @@
                     pid_t tid,
                     status_t *status /*non-NULL*/,
                     audio_port_handle_t portId,
-                    int32_t maxSharedAudioHistoryMs) final;
+                    int32_t maxSharedAudioHistoryMs) final
+            REQUIRES(audio_utils::AudioFlinger_Mutex);
 
             status_t start(IAfRecordTrack* recordTrack,
                               AudioSystem::sync_event_t event,
@@ -1866,7 +1880,7 @@
     AudioStreamIn* getInput() const final { return mInput; }
     AudioStreamIn* clearInput() final;
 
-            // TODO(b/288339104) Unify with IAfThreadBase
+            // TODO(b/291317898) Unify with IAfThreadBase
             virtual sp<StreamHalInterface> stream() const;
 
 
@@ -1971,10 +1985,10 @@
             Source                              *mSource;
             SortedVector <sp<IAfRecordTrack>>    mTracks;
             // mActiveTracks has dual roles:  it indicates the current active track(s), and
-            // is used together with mStartStopCond to indicate start()/stop() progress
+            // is used together with mStartStopCV to indicate start()/stop() progress
             ActiveTracks<IAfRecordTrack>           mActiveTracks;
 
-            Condition                           mStartStopCond;
+            audio_utils::condition_variable mStartStopCV;
 
             // resampler converts input at HAL Hz to output at AudioRecord client Hz
             void                               *mRsmpInBuffer;  // size = mRsmpInFramesOA
@@ -2042,7 +2056,7 @@
 class MmapThread : public ThreadBase, public virtual IAfMmapThread
 {
  public:
-    MmapThread(const sp<AudioFlinger>& audioFlinger, audio_io_handle_t id,
+    MmapThread(const sp<IAfThreadCallback>& afThreadCallback, audio_io_handle_t id,
                AudioHwDevice *hwDev, const sp<StreamHalInterface>& stream, bool systemReady,
                bool isOut);
 
@@ -2076,7 +2090,7 @@
     virtual void threadLoop_exit() final;
     virtual void threadLoop_standby() final;
     virtual bool shouldStandby_l() final { return false; }
-    virtual status_t exitStandby_l() REQUIRES(mLock);
+    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; }
@@ -2167,7 +2181,7 @@
 class MmapPlaybackThread : public MmapThread, public IAfMmapPlaybackThread,
         public virtual VolumeInterface {
 public:
-    MmapPlaybackThread(const sp<AudioFlinger>& audioFlinger, audio_io_handle_t id,
+    MmapPlaybackThread(const sp<IAfThreadCallback>& afThreadCallback, audio_io_handle_t id,
                        AudioHwDevice *hwDev, AudioStreamOut *output, bool systemReady);
 
     sp<IAfMmapPlaybackThread> asIAfMmapPlaybackThread() final {
@@ -2212,8 +2226,10 @@
 
     status_t reportData(const void* buffer, size_t frameCount) final;
 
-    void startMelComputation_l(const sp<audio_utils::MelProcessor>& processor) final;
-    void stopMelComputation_l() final;
+    void startMelComputation_l(const sp<audio_utils::MelProcessor>& processor) final
+            REQUIRES(audio_utils::AudioFlinger_Mutex);
+    void stopMelComputation_l() final
+            REQUIRES(audio_utils::AudioFlinger_Mutex);
 
 protected:
     void dumpInternals_l(int fd, const Vector<String16>& args) final;
@@ -2231,7 +2247,7 @@
 class MmapCaptureThread : public MmapThread, public IAfMmapCaptureThread
 {
 public:
-    MmapCaptureThread(const sp<AudioFlinger>& audioFlinger, audio_io_handle_t id,
+    MmapCaptureThread(const sp<IAfThreadCallback>& afThreadCallback, audio_io_handle_t id,
                       AudioHwDevice *hwDev, AudioStreamIn *input, bool systemReady);
 
     sp<IAfMmapCaptureThread> asIAfMmapCaptureThread() final {
@@ -2240,7 +2256,7 @@
 
     AudioStreamIn* clearInput() final;
 
-    status_t exitStandby_l() REQUIRES(mLock) final;
+    status_t exitStandby_l() REQUIRES(mutex()) final;
 
     MetadataUpdate updateMetadata_l() final;
     void processVolume_l() final;
@@ -2261,7 +2277,7 @@
 
 class BitPerfectThread : public MixerThread {
 public:
-    BitPerfectThread(const sp<AudioFlinger>& audioflinger, AudioStreamOut *output,
+    BitPerfectThread(const sp<IAfThreadCallback>& afThreadCallback, AudioStreamOut *output,
                      audio_io_handle_t id, bool systemReady);
 
 protected:
diff --git a/services/audioflinger/TrackBase.h b/services/audioflinger/TrackBase.h
index 43a62e1..4e37953 100644
--- a/services/audioflinger/TrackBase.h
+++ b/services/audioflinger/TrackBase.h
@@ -17,6 +17,18 @@
 
 #pragma once
 
+#include "Configuration.h"  // TEE_SINK
+#include "IAfTrack.h"
+
+#include <afutils/NBAIO_Tee.h>
+#include <android-base/macros.h>  // DISALLOW_COPY_AND_ASSIGN
+#include <datapath/TrackMetrics.h>
+#include <mediautils/BatteryNotifier.h>
+
+#include <atomic>    // avoid transitive dependency
+#include <list>      // avoid transitive dependency
+#include <optional>  // avoid transitive dependency
+
 namespace android {
 
 // base for record and playback
diff --git a/services/audioflinger/Tracks.cpp b/services/audioflinger/Tracks.cpp
index bd4804c..31246ec 100644
--- a/services/audioflinger/Tracks.cpp
+++ b/services/audioflinger/Tracks.cpp
@@ -15,32 +15,33 @@
 ** limitations under the License.
 */
 
-
 #define LOG_TAG "AudioFlinger"
 //#define LOG_NDEBUG 0
 #define ATRACE_TAG ATRACE_TAG_AUDIO
 
-#include "Configuration.h"
-#include <linux/futex.h>
-#include <math.h>
-#include <sys/syscall.h>
+#include "MmapTracks.h"
+#include "PlaybackTracks.h"
+#include "RecordTracks.h"
+
+#include "Client.h"
+#include "IAfEffect.h"
+#include "IAfThread.h"
+#include "ResamplerBufferProvider.h"
+
+#include <audio_utils/minifloat.h>
+#include <media/AudioValidator.h>
+#include <media/RecordBufferConverter.h>
+#include <media/nbaio/Pipe.h>
+#include <media/nbaio/PipeReader.h>
+#include <mediautils/ServiceUtilities.h>
+#include <mediautils/SharedMemoryAllocator.h>
+#include <private/media/AudioTrackShared.h>
 #include <utils/Log.h>
 #include <utils/Trace.h>
 
-#include <private/media/AudioTrackShared.h>
-
-#include "AudioFlinger.h"
-#include "TrackBase.h"
-#include "PlaybackTracks.h"
-#include "RecordTracks.h"
-#include "MmapTracks.h"
-
-#include <media/nbaio/Pipe.h>
-#include <media/nbaio/PipeReader.h>
-#include <media/AudioValidator.h>
-#include <media/RecordBufferConverter.h>
-#include <mediautils/ServiceUtilities.h>
-#include <audio_utils/minifloat.h>
+#include <linux/futex.h>
+#include <math.h>
+#include <sys/syscall.h>
 
 // ----------------------------------------------------------------------------
 
@@ -276,7 +277,7 @@
     mCblkMemory.clear();    // free the shared memory before releasing the heap it belongs to
     if (mClient != 0) {
         // Client destructor must run with AudioFlinger client mutex locked
-        Mutex::Autolock _l(mClient->audioFlinger()->mClientLock);
+        audio_utils::lock_guard _l(mClient->afClientCallback()->clientMutex());
         // If the client's reference count drops to zero, the associated destructor
         // must run with AudioFlinger lock held. Thus the explicit clear() rather than
         // relying on the automatic clear() at end of scope.
@@ -388,7 +389,6 @@
     : BnAudioTrack(),
       mTrack(track)
 {
-    // TODO(b/288339104) binder thread priority change not needed.
     setMinSchedulerPolicy(SCHED_NORMAL, ANDROID_PRIORITY_AUDIO);
 }
 
@@ -642,7 +642,7 @@
             auto thread = mThread.promote();
             if (thread != nullptr && thread->type() == IAfThreadBase::OFFLOAD) {
                 // Wake up Thread if offloaded, otherwise it may be several seconds for update.
-                Mutex::Autolock _l(thread->mutex());
+                audio_utils::lock_guard _l(thread->mutex());
                 thread->broadcast_l();
             }
         }
@@ -889,7 +889,7 @@
         bool wasActive = false;
         const sp<IAfThreadBase> thread = mThread.promote();
         if (thread != 0) {
-            Mutex::Autolock _l(thread->mutex());
+            audio_utils::lock_guard _l(thread->mutex());
             auto* const playbackThread = thread->asIAfPlaybackThread().get();
             wasActive = playbackThread->destroyTrack_l(this);
         }
@@ -1169,16 +1169,16 @@
     const sp<IAfThreadBase> thread = mThread.promote();
     if (thread != 0) {
         if (isOffloaded()) {
-            Mutex::Autolock _laf(thread->audioFlinger()->mLock);
-            Mutex::Autolock _lth(thread->mutex());
+            audio_utils::lock_guard _laf(thread->afThreadCallback()->mutex());
+            audio_utils::lock_guard _lth(thread->mutex());
             sp<IAfEffectChain> ec = thread->getEffectChain_l(mSessionId);
-            if (thread->audioFlinger()->isNonOffloadableGlobalEffectEnabled_l() ||
+            if (thread->afThreadCallback()->isNonOffloadableGlobalEffectEnabled_l() ||
                     (ec != 0 && ec->isNonOffloadableEnabled())) {
                 invalidate();
                 return PERMISSION_DENIED;
             }
         }
-        Mutex::Autolock _lth(thread->mutex());
+        audio_utils::lock_guard _lth(thread->mutex());
         track_state state = mState;
         // here the track could be either new, or restarted
         // in both cases "unstop" the track
@@ -1277,7 +1277,8 @@
         forEachTeePatchTrack([](auto patchTrack) { patchTrack->start(); });
 
         // send format to AudioManager for playback activity monitoring
-        const sp<IAudioManager> audioManager = thread->audioFlinger()->getOrCreateAudioManager();
+        const sp<IAudioManager> audioManager =
+                thread->afThreadCallback()->getOrCreateAudioManager();
         if (audioManager && mPortId != AUDIO_PORT_HANDLE_NONE) {
             std::unique_ptr<os::PersistableBundle> bundle =
                     std::make_unique<os::PersistableBundle>();
@@ -1301,7 +1302,7 @@
     ALOGV("%s(%d): calling pid %d", __func__, mId, IPCThreadState::self()->getCallingPid());
     const sp<IAfThreadBase> thread = mThread.promote();
     if (thread != 0) {
-        Mutex::Autolock _l(thread->mutex());
+        audio_utils::lock_guard _l(thread->mutex());
         track_state state = mState;
         if (state == RESUMING || state == ACTIVE || state == PAUSING || state == PAUSED) {
             // If the track is not active (PAUSED and buffers full), flush buffers
@@ -1334,7 +1335,7 @@
     ALOGV("%s(%d): calling pid %d", __func__, mId, IPCThreadState::self()->getCallingPid());
     const sp<IAfThreadBase> thread = mThread.promote();
     if (thread != 0) {
-        Mutex::Autolock _l(thread->mutex());
+        audio_utils::lock_guard _l(thread->mutex());
         auto* const playbackThread = thread->asIAfPlaybackThread().get();
         switch (mState) {
         case STOPPING_1:
@@ -1371,7 +1372,7 @@
     ALOGV("%s(%d)", __func__, mId);
     const sp<IAfThreadBase> thread = mThread.promote();
     if (thread != 0) {
-        Mutex::Autolock _l(thread->mutex());
+        audio_utils::lock_guard _l(thread->mutex());
         auto* const playbackThread = thread->asIAfPlaybackThread().get();
 
         // Flush the ring buffer now if the track is not active in the PlaybackThread.
@@ -1502,7 +1503,7 @@
         // Signal thread to fetch new volume.
         const sp<IAfThreadBase> thread = mThread.promote();
         if (thread != 0) {
-            Mutex::Autolock _l(thread->mutex());
+            audio_utils::lock_guard _l(thread->mutex());
             thread->broadcast_l();
         }
     }
@@ -1666,7 +1667,7 @@
         return INVALID_OPERATION;
     }
 
-    Mutex::Autolock _l(thread->mutex());
+    audio_utils::lock_guard _l(thread->mutex());
     auto* const playbackThread = thread->asIAfPlaybackThread().get();
     return playbackThread->getTimestamp_l(timestamp);
 }
@@ -1681,7 +1682,7 @@
     auto dstThread = thread->asIAfPlaybackThread();
     // srcThread is initialized by call to moveAuxEffectToIo()
     sp<IAfPlaybackThread> srcThread;
-    sp<AudioFlinger> af = mClient->audioFlinger();
+    const auto& af = mClient->afClientCallback();
     status_t status = af->moveAuxEffectToIo(EffectId, dstThread, &srcThread);
 
     if (EffectId != 0 && status == NO_ERROR) {
@@ -1869,7 +1870,7 @@
     const sp<IAfThreadBase> thread = mThread.promote();
     if (thread != 0) {
         auto* const t = thread->asIAfPlaybackThread().get();
-        Mutex::Autolock _l(t->mutex());
+        audio_utils::lock_guard _l(t->mutex());
         t->broadcast_l();
     }
 }
@@ -1881,7 +1882,7 @@
         const sp<IAfThreadBase> thread = mThread.promote();
         if (thread != nullptr) {
             auto* const t = thread->asIAfPlaybackThread().get();
-            Mutex::Autolock _l(t->mutex());
+            audio_utils::lock_guard _l(t->mutex());
             status = t->getOutput_l()->stream->getDualMonoMode(mode);
             ALOGD_IF((status == NO_ERROR) && (mDualMonoMode != *mode),
                     "%s: mode %d inconsistent", __func__, mDualMonoMode);
@@ -1897,7 +1898,7 @@
         const sp<IAfThreadBase> thread = mThread.promote();
         if (thread != nullptr) {
             auto* const t = thread->asIAfPlaybackThread().get();
-            Mutex::Autolock lock(t->mutex());
+            audio_utils::lock_guard lock(t->mutex());
             status = t->getOutput_l()->stream->setDualMonoMode(mode);
             if (status == NO_ERROR) {
                 mDualMonoMode = mode;
@@ -1914,7 +1915,7 @@
         sp<IAfThreadBase> thread = mThread.promote();
         if (thread != nullptr) {
             auto* const t = thread->asIAfPlaybackThread().get();
-            Mutex::Autolock lock(t->mutex());
+            audio_utils::lock_guard lock(t->mutex());
             status = t->getOutput_l()->stream->getAudioDescriptionMixLevel(leveldB);
             ALOGD_IF((status == NO_ERROR) && (mAudioDescriptionMixLevel != *leveldB),
                     "%s: level %.3f inconsistent", __func__, mAudioDescriptionMixLevel);
@@ -1930,7 +1931,7 @@
         const sp<IAfThreadBase> thread = mThread.promote();
         if (thread != nullptr) {
             auto* const t = thread->asIAfPlaybackThread().get();
-            Mutex::Autolock lock(t->mutex());
+            audio_utils::lock_guard lock(t->mutex());
             status = t->getOutput_l()->stream->setAudioDescriptionMixLevel(leveldB);
             if (status == NO_ERROR) {
                 mAudioDescriptionMixLevel = leveldB;
@@ -1948,7 +1949,7 @@
         const sp<IAfThreadBase> thread = mThread.promote();
         if (thread != nullptr) {
             auto* const t = thread->asIAfPlaybackThread().get();
-            Mutex::Autolock lock(t->mutex());
+            audio_utils::lock_guard lock(t->mutex());
             status = t->getOutput_l()->stream->getPlaybackRateParameters(playbackRate);
             ALOGD_IF((status == NO_ERROR) &&
                     !isAudioPlaybackRateEqual(mPlaybackRateParameters, *playbackRate),
@@ -1966,7 +1967,7 @@
         const sp<IAfThreadBase> thread = mThread.promote();
         if (thread != nullptr) {
             auto* const t = thread->asIAfPlaybackThread().get();
-            Mutex::Autolock lock(t->mutex());
+            audio_utils::lock_guard lock(t->mutex());
             status = t->getOutput_l()->stream->setPlaybackRateParameters(playbackRate);
             if (status == NO_ERROR) {
                 mPlaybackRateParameters = playbackRate;
@@ -2089,7 +2090,7 @@
     const sp<IAfThreadBase> thread = mTrack->mThread.promote();
     if (thread != 0) {
         // Lock for updating mHapticPlaybackEnabled.
-        Mutex::Autolock _l(thread->mutex());
+        audio_utils::lock_guard _l(thread->mutex());
         auto* const playbackThread = thread->asIAfPlaybackThread().get();
         if ((mTrack->channelMask() & AUDIO_CHANNEL_HAPTIC_ALL) != AUDIO_CHANNEL_NONE
                 && playbackThread->hapticChannelCount() > 0) {
@@ -2352,13 +2353,13 @@
 
 void OutputTrack::copyMetadataTo(MetadataInserter& backInserter) const
 {
-    std::lock_guard<std::mutex> lock(mTrackMetadatasMutex);
+    audio_utils::lock_guard lock(trackMetadataMutex());
     backInserter = std::copy(mTrackMetadatas.begin(), mTrackMetadatas.end(), backInserter);
 }
 
 void OutputTrack::setMetadatas(const SourceMetadatas& metadatas) {
     {
-        std::lock_guard<std::mutex> lock(mTrackMetadatasMutex);
+        audio_utils::lock_guard lock(trackMetadataMutex());
         mTrackMetadatas = metadatas;
     }
     // No need to adjust metadata track volumes as OutputTrack volumes are always 0dBFS.
@@ -2614,7 +2615,6 @@
     : BnAudioRecord(),
     mRecordTrack(recordTrack)
 {
-    // TODO(b/288339104) binder thread priority change not needed.
     setMinSchedulerPolicy(SCHED_NORMAL, ANDROID_PRIORITY_AUDIO);
 }
 
@@ -2669,7 +2669,7 @@
 #define LOG_TAG "AF::RecordTrack"
 
 
-/* static */ // TODO(b/288339104)
+/* static */
 sp<IAfRecordTrack> IAfRecordTrack::create(IAfRecordThread* thread,
         const sp<Client>& client,
         const audio_attributes_t& attr,
@@ -2846,7 +2846,7 @@
         track_state priorState = mState;
         const sp<IAfThreadBase> thread = mThread.promote();
         if (thread != 0) {
-            Mutex::Autolock _l(thread->mutex());
+            audio_utils::lock_guard _l(thread->mutex());
             auto* const recordThread = thread->asIAfRecordThread().get();
             priorState = mState;
             if (!mSharedAudioPackageName.empty()) {
@@ -3270,7 +3270,7 @@
     *thread = mThread.promote();
     if (!*thread) return nullptr;
     auto* const recordThread = (*thread)->asIAfRecordThread().get();
-    Mutex::Autolock _l(recordThread->mutex());
+    audio_utils::lock_guard _l(recordThread->mutex());
     return recordThread->getInput() ? recordThread->getInput()->stream : nullptr;
 }
 
@@ -3307,7 +3307,7 @@
     }
 
     {
-        std::lock_guard<std::mutex> lock(mReadLock);
+        audio_utils::lock_guard lock(readMutex());
         mReadBytes += bytesRead;
         mReadError = NO_ERROR;
     }
@@ -3334,7 +3334,7 @@
 stream_error:
     stream->standby();
     {
-        std::lock_guard<std::mutex> lock(mReadLock);
+        audio_utils::lock_guard lock(readMutex());
         mReadError = result;
     }
     mReadCV.notify_one();
@@ -3363,7 +3363,7 @@
 {
     bytes = std::min(bytes, mFrameCount * mFrameSize);
     {
-        std::unique_lock<std::mutex> lock(mReadLock);
+        audio_utils::unique_lock lock(readMutex());
         mReadCV.wait(lock, [&]{ return mReadError != NO_ERROR || mReadBytes != 0; });
         if (mReadError != NO_ERROR) {
             mLastReadFrames = 0;
diff --git a/services/audioflinger/afutils/Android.bp b/services/audioflinger/afutils/Android.bp
index 1580b8f..5e29ce9 100644
--- a/services/audioflinger/afutils/Android.bp
+++ b/services/audioflinger/afutils/Android.bp
@@ -39,18 +39,24 @@
         "AudioWatchdog.cpp",
         "BufLog.cpp",
         "NBAIO_Tee.cpp",
+        "Permission.cpp",
         "PropertyUtils.cpp",
         "TypedLogger.cpp",
+        "Vibrator.cpp",
     ],
 
     shared_libs: [
+        "framework-permission-aidl-cpp",
+        "libaudioclient_aidl_conversion",
         "libaudioutils",
         "libbase",
+        "libbinder",
         "libcutils", // property_get_int32
         "liblog",
         "libnbaio",
         "libnblog",
         "libutils",
+        "libvibrator",
     ],
 
     static_libs: [
diff --git a/services/audioflinger/afutils/DumpTryLock.h b/services/audioflinger/afutils/DumpTryLock.h
new file mode 100644
index 0000000..e4ad112
--- /dev/null
+++ b/services/audioflinger/afutils/DumpTryLock.h
@@ -0,0 +1,48 @@
+/*
+ *
+ * Copyright 2023, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <audio_utils/mutex.h>
+#include <utils/Mutex.h>
+#include <utils/Timers.h>
+
+namespace android::afutils {
+
+inline bool dumpTryLock(Mutex& mutex)
+{
+    static constexpr int kDumpLockTimeoutNs = 1'000'000'000;
+    const status_t err = mutex.timedLock(kDumpLockTimeoutNs);
+    return err == NO_ERROR;
+}
+
+// Note: the std::timed_mutex try_lock_for and try_lock_until methods are inefficient.
+// It is better to use std::mutex and call this method.
+//
+inline bool dumpTryLock(audio_utils::mutex& mutex) TRY_ACQUIRE(true, mutex)
+{
+    static constexpr int64_t kDumpLockTimeoutNs = 1'000'000'000;
+
+    const int64_t timeoutNs = kDumpLockTimeoutNs + systemTime(SYSTEM_TIME_REALTIME);
+    const struct timespec ts = {
+        .tv_sec = static_cast<time_t>(timeoutNs / 1000000000),
+        .tv_nsec = static_cast<long>(timeoutNs % 1000000000),
+    };
+    return pthread_mutex_timedlock(mutex.native_handle(), &ts) == 0;
+}
+
+}  // android::afutils
diff --git a/services/audioflinger/afutils/Permission.cpp b/services/audioflinger/afutils/Permission.cpp
new file mode 100644
index 0000000..35448e3
--- /dev/null
+++ b/services/audioflinger/afutils/Permission.cpp
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "Permission"
+//#define LOG_NDEBUG 0
+
+#include "Permission.h"
+
+#include <binder/PermissionController.h>
+#include <media/AidlConversionCppNdk.h>
+#include <utils/Log.h>
+
+namespace android::afutils {
+
+// TODO b/182392769: use attribution source util
+content::AttributionSourceState checkAttributionSourcePackage(
+        const content::AttributionSourceState& attributionSource) {
+    Vector<String16> packages;
+    PermissionController{}.getPackagesForUid(attributionSource.uid, packages);
+
+    content::AttributionSourceState checkedAttributionSource = attributionSource;
+    if (!attributionSource.packageName.has_value()
+            || attributionSource.packageName.value().size() == 0) {
+        if (!packages.isEmpty()) {
+            checkedAttributionSource.packageName =
+                std::move(legacy2aidl_String16_string(packages[0]).value());
+        }
+    } else {
+        const String16 opPackageLegacy = VALUE_OR_FATAL(
+                aidl2legacy_string_view_String16(attributionSource.packageName.value_or("")));
+        if (std::find_if(packages.begin(), packages.end(),
+                [&opPackageLegacy](const auto& package) {
+                return opPackageLegacy == package; }) == packages.end()) {
+            ALOGW("The package name(%s) provided does not correspond to the uid %d",
+                    attributionSource.packageName.value_or("").c_str(), attributionSource.uid);
+        }
+    }
+    return checkedAttributionSource;
+}
+
+}  // namespace android::afutils
diff --git a/services/audioflinger/afutils/Permission.h b/services/audioflinger/afutils/Permission.h
new file mode 100644
index 0000000..97c7ff9
--- /dev/null
+++ b/services/audioflinger/afutils/Permission.h
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <android/content/AttributionSourceState.h>
+
+namespace android::afutils {
+
+content::AttributionSourceState checkAttributionSourcePackage(
+        const content::AttributionSourceState& attributionSource);
+
+}  // namespace android::afutils
diff --git a/services/audioflinger/afutils/Vibrator.cpp b/services/audioflinger/afutils/Vibrator.cpp
new file mode 100644
index 0000000..25fcc6a
--- /dev/null
+++ b/services/audioflinger/afutils/Vibrator.cpp
@@ -0,0 +1,71 @@
+/*
+ *
+ * Copyright 2023, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "AudioFlinger::Vibrator"
+//#define LOG_NDEBUG 0
+
+#include "Vibrator.h"
+
+#include <android/os/IExternalVibratorService.h>
+#include <binder/IServiceManager.h>
+#include <utils/Log.h>
+
+#include <mutex>
+
+namespace android::afutils {
+
+static sp<os::IExternalVibratorService> getExternalVibratorService() {
+    static std::mutex m;
+    static sp<os::IExternalVibratorService> sExternalVibratorService;
+
+    std::lock_guard l(m);
+    if (sExternalVibratorService == nullptr) {
+        const sp<IBinder> binder = defaultServiceManager()->getService(
+                String16("external_vibrator_service"));
+        if (binder != nullptr) {
+            sExternalVibratorService = interface_cast<os::IExternalVibratorService>(binder);
+        }
+    }
+    return sExternalVibratorService;
+}
+
+os::HapticScale onExternalVibrationStart(const sp<os::ExternalVibration>& externalVibration) {
+    const sp<os::IExternalVibratorService> evs = getExternalVibratorService();
+    if (evs != nullptr) {
+        int32_t ret;
+        binder::Status status = evs->onExternalVibrationStart(*externalVibration, &ret);
+        if (status.isOk()) {
+            ALOGD("%s, start external vibration with intensity as %d", __func__, ret);
+            return os::ExternalVibration::externalVibrationScaleToHapticScale(ret);
+        }
+    }
+    ALOGD("%s, start external vibration with intensity as MUTE due to %s",
+            __func__,
+            evs == nullptr ? "external vibration service not found"
+                           : "error when querying intensity");
+    return os::HapticScale::MUTE;
+}
+
+void onExternalVibrationStop(const sp<os::ExternalVibration>& externalVibration) {
+    const sp<os::IExternalVibratorService> evs = getExternalVibratorService();
+    if (evs != nullptr) {
+        ALOGD("%s, stop external vibration", __func__);
+        evs->onExternalVibrationStop(*externalVibration);
+    }
+}
+
+}  // namespace android::afutils
diff --git a/services/audioflinger/afutils/Vibrator.h b/services/audioflinger/afutils/Vibrator.h
new file mode 100644
index 0000000..4354872
--- /dev/null
+++ b/services/audioflinger/afutils/Vibrator.h
@@ -0,0 +1,29 @@
+/*
+ *
+ * Copyright 2023, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <vibrator/ExternalVibration.h>
+#include <vibrator/ExternalVibrationUtils.h>
+
+namespace android::afutils {
+
+os::HapticScale onExternalVibrationStart(const sp<os::ExternalVibration>& externalVibration);
+
+void onExternalVibrationStop(const sp<os::ExternalVibration>& externalVibration);
+
+} // namespace android::afutils
diff --git a/services/audioflinger/datapath/AudioStreamIn.h b/services/audioflinger/datapath/AudioStreamIn.h
index 7b3a090..604a4e4 100644
--- a/services/audioflinger/datapath/AudioStreamIn.h
+++ b/services/audioflinger/datapath/AudioStreamIn.h
@@ -16,6 +16,7 @@
 
 #pragma once
 
+#include "AudioHwDevice.h"
 #include <media/audiohal/DeviceHalInterface.h>
 #include <media/audiohal/StreamHalInterface.h>
 
diff --git a/services/audioflinger/datapath/ThreadMetrics.h b/services/audioflinger/datapath/ThreadMetrics.h
index 5493b3c..c643a57 100644
--- a/services/audioflinger/datapath/ThreadMetrics.h
+++ b/services/audioflinger/datapath/ThreadMetrics.h
@@ -17,6 +17,8 @@
 #ifndef ANDROID_AUDIO_THREADMETRICS_H
 #define ANDROID_AUDIO_THREADMETRICS_H
 
+#include <media/MediaMetricsItem.h>
+
 #include <mutex>
 
 namespace android {
diff --git a/services/audioflinger/datapath/TrackMetrics.h b/services/audioflinger/datapath/TrackMetrics.h
index f3425df..2b44acb 100644
--- a/services/audioflinger/datapath/TrackMetrics.h
+++ b/services/audioflinger/datapath/TrackMetrics.h
@@ -20,6 +20,8 @@
 #include <binder/IActivityManager.h>
 #include <binder/IPCThreadState.h>
 #include <binder/IServiceManager.h>
+#include <media/MediaMetricsItem.h>
+
 #include <mutex>
 
 namespace android {
diff --git a/services/audiopolicy/service/AudioPolicyService.cpp b/services/audiopolicy/service/AudioPolicyService.cpp
index d7aa5c9..0620553 100644
--- a/services/audiopolicy/service/AudioPolicyService.cpp
+++ b/services/audiopolicy/service/AudioPolicyService.cpp
@@ -25,6 +25,7 @@
 #include <sys/time.h>
 #include <dlfcn.h>
 
+#include <android/content/pm/IPackageManagerNative.h>
 #include <audio_utils/clock.h>
 #include <binder/IServiceManager.h>
 #include <utils/Log.h>
@@ -215,6 +216,26 @@
 {
     delete interface;
 }
+
+namespace {
+int getTargetSdkForPackageName(std::string_view packageName) {
+    const auto binder = defaultServiceManager()->checkService(String16{"package_native"});
+    int targetSdk = -1;
+    if (binder != nullptr) {
+        const auto pm = interface_cast<content::pm::IPackageManagerNative>(binder);
+        if (pm != nullptr) {
+            const auto status = pm->getTargetSdkVersionForPackage(
+                    String16{packageName.data(), packageName.size()}, &targetSdk);
+            return status.isOk() ? targetSdk : -1;
+        }
+    }
+    return targetSdk;
+}
+
+bool doesPackageTargetAtLeastU(std::string_view packageName) {
+    return getTargetSdkForPackageName(packageName) >= __ANDROID_API_U__;
+}
+} // anonymous
 // ----------------------------------------------------------------------------
 
 AudioPolicyService::AudioPolicyService()
@@ -1926,10 +1947,14 @@
     checkOp();
     mOpCallback = new RecordAudioOpCallback(this);
     ALOGV("start watching op %d for %s", mAppOp, mAttributionSource.toString().c_str());
+    int flags = doesPackageTargetAtLeastU(
+            mAttributionSource.packageName.value_or("")) ?
+            AppOpsManager::WATCH_FOREGROUND_CHANGES : 0;
     // TODO: We need to always watch AppOpsManager::OP_RECORD_AUDIO too
     // since it controls the mic permission for legacy apps.
     mAppOpsManager.startWatchingMode(mAppOp, VALUE_OR_FATAL(aidl2legacy_string_view_String16(
         mAttributionSource.packageName.value_or(""))),
+        flags,
         mOpCallback);
 }
 
diff --git a/services/mediaresourcemanager/test/Android.bp b/services/mediaresourcemanager/test/Android.bp
index de24e1e..f903c62 100644
--- a/services/mediaresourcemanager/test/Android.bp
+++ b/services/mediaresourcemanager/test/Android.bp
@@ -20,7 +20,6 @@
         "libmedia",
         "libmediautils",
         "libutils",
-        "libmediautils",
         "libstats_media_metrics",
         "libstatspull",
         "libstatssocket",