diff --git a/android/app/src/com/android/bluetooth/le_audio/LeAudioService.java b/android/app/src/com/android/bluetooth/le_audio/LeAudioService.java
index 1e577b3734fb8562f678bd395392f76ce2620ee1..36aa3b94aa93b5160563761ecd65ba0b90c980db 100644
--- a/android/app/src/com/android/bluetooth/le_audio/LeAudioService.java
+++ b/android/app/src/com/android/bluetooth/le_audio/LeAudioService.java
@@ -87,7 +87,6 @@ import com.android.bluetooth.mcp.McpService;
 import com.android.bluetooth.tbs.TbsGatt;
 import com.android.bluetooth.tbs.TbsService;
 import com.android.bluetooth.vc.VolumeControlService;
-import com.android.internal.annotations.GuardedBy;
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.modules.utils.SynchronousResultReceiver;
 
@@ -98,7 +97,9 @@ import java.util.List;
 import java.util.Map;
 import java.util.Objects;
 import java.util.Optional;
+import java.util.concurrent.locks.Lock;
 import java.util.concurrent.locks.ReentrantLock;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
 import java.util.stream.Collectors;
 
 /**
@@ -145,6 +146,9 @@ public class LeAudioService extends ProfileService {
     private BluetoothDevice mExposedActiveDevice;
     private LeAudioCodecConfig mLeAudioCodecConfig;
     private final ReentrantLock mGroupLock = new ReentrantLock();
+    private final ReentrantReadWriteLock mGroupReadWriteLock = new ReentrantReadWriteLock();
+    private final Lock mGroupReadLock = mGroupReadWriteLock.readLock();
+    private final Lock mGroupWriteLock = mGroupReadWriteLock.writeLock();
     private FeatureFlags mFeatureFlags;
     ServiceFactory mServiceFactory = new ServiceFactory();
 
@@ -270,7 +274,6 @@ public class LeAudioService extends ProfileService {
     List<BluetoothLeAudioCodecConfig> mInputLocalCodecCapabilities = new ArrayList<>();
     List<BluetoothLeAudioCodecConfig> mOutputLocalCodecCapabilities = new ArrayList<>();
 
-    @GuardedBy("mGroupLock")
     private final Map<Integer, LeAudioGroupDescriptor> mGroupDescriptors = new LinkedHashMap<>();
     private final Map<BluetoothDevice, LeAudioDeviceDescriptor> mDeviceDescriptors =
             new LinkedHashMap<>();
@@ -340,12 +343,12 @@ public class LeAudioService extends ProfileService {
 
         mBroadcastDescriptors.clear();
 
-        mGroupLock.lock();
+        groupMutexLock(/* isReadOnly */ false);
         try {
             mDeviceDescriptors.clear();
             mGroupDescriptors.clear();
         } finally {
-            mGroupLock.unlock();
+            groupMutexUnlock(/* isReadOnly */ false);
         }
 
         // Setup broadcast callbacks
@@ -434,33 +437,46 @@ public class LeAudioService extends ProfileService {
 
         // Don't wait for async call with INACTIVE group status, clean active
         // device for active group.
-        mGroupLock.lock();
+        groupMutexLock(/* isReadOnly */ true);
         try {
-            for (Map.Entry<Integer, LeAudioGroupDescriptor> entry : mGroupDescriptors.entrySet()) {
-                LeAudioGroupDescriptor descriptor = entry.getValue();
-                Integer group_id = entry.getKey();
-                if (descriptor.mIsActive) {
-                    descriptor.mIsActive = false;
-                    updateActiveDevices(group_id, descriptor.mDirection, AUDIO_DIRECTION_NONE,
-                            descriptor.mIsActive, false, false);
-                    break;
+            try {
+                for (Map.Entry<Integer, LeAudioGroupDescriptor> entry :
+                        mGroupDescriptors.entrySet()) {
+                    LeAudioGroupDescriptor descriptor = entry.getValue();
+                    Integer group_id = entry.getKey();
+                    if (descriptor.mIsActive) {
+                        descriptor.mIsActive = false;
+                        updateActiveDevices(
+                                group_id,
+                                descriptor.mDirection,
+                                AUDIO_DIRECTION_NONE,
+                                descriptor.mIsActive,
+                                false,
+                                false);
+                        break;
+                    }
                 }
-            }
 
-            // Destroy state machines and stop handler thread
-            for (LeAudioDeviceDescriptor descriptor : mDeviceDescriptors.values()) {
-                LeAudioStateMachine sm = descriptor.mStateMachine;
-                if (sm == null) {
-                    continue;
+                // Destroy state machines and stop handler thread
+                for (LeAudioDeviceDescriptor descriptor : mDeviceDescriptors.values()) {
+                    LeAudioStateMachine sm = descriptor.mStateMachine;
+                    if (sm == null) {
+                        continue;
+                    }
+                    sm.quit();
+                    sm.cleanup();
+                }
+            } finally {
+                if (mFeatureFlags.leaudioApiSynchronizedBlockFix()) {
+                    // Upgrade to write lock
+                    groupMutexUnlock(/* isReadOnly */ true);
+                    groupMutexLock(/* isReadOnly */ false);
                 }
-                sm.quit();
-                sm.cleanup();
             }
-
             mDeviceDescriptors.clear();
             mGroupDescriptors.clear();
         } finally {
-            mGroupLock.unlock();
+            groupMutexUnlock(/* isReadOnly */ false);
         }
 
         // Cleanup native interfaces
@@ -614,7 +630,9 @@ public class LeAudioService extends ProfileService {
             return false;
         }
 
-        mGroupLock.lock();
+        LeAudioStateMachine sm = null;
+
+        groupMutexLock(/* isReadOnly */ false);
         try {
             boolean isInbandRingtoneEnabled = false;
             int groupId = getGroupId(device);
@@ -626,16 +644,59 @@ public class LeAudioService extends ProfileService {
                 return false;
             }
 
-            LeAudioStateMachine sm = getOrCreateStateMachine(device);
+            sm = getOrCreateStateMachine(device);
             if (sm == null) {
                 Log.e(TAG, "Ignored connect request for " + device + " : no state machine");
                 return false;
             }
+
+            if (!mFeatureFlags.leaudioApiSynchronizedBlockFix()) {
+                sm.sendMessage(LeAudioStateMachine.CONNECT);
+            }
+
+        } finally {
+            groupMutexUnlock(/* isReadOnly */ false);
+        }
+
+        if (mFeatureFlags.leaudioApiSynchronizedBlockFix()) {
             sm.sendMessage(LeAudioStateMachine.CONNECT);
+        }
+
+        return true;
+    }
+
+    /**
+     * Disconnects LE Audio for the remote bluetooth device
+     *
+     * @param device is the device with which we would like to disconnect LE Audio
+     * @return true if profile disconnected, false if device not connected over LE Audio
+     */
+    boolean disconnectV2(BluetoothDevice device) {
+        if (DBG) {
+            Log.d(TAG, "disconnectV2(): " + device);
+        }
+
+        LeAudioStateMachine sm = null;
+
+        groupMutexLock(/* isReadOnly */ true);
+        try {
+            LeAudioDeviceDescriptor descriptor = getDeviceDescriptor(device);
+            if (descriptor == null) {
+                Log.e(TAG, "disconnect: No valid descriptor for device: " + device);
+                return false;
+            }
+            sm = descriptor.mStateMachine;
         } finally {
-            mGroupLock.unlock();
+            groupMutexUnlock(/* isReadOnly */ true);
+        }
+
+        if (sm == null) {
+            Log.e(TAG, "Ignored disconnect request for " + device + " : no state machine");
+            return false;
         }
 
+        sm.sendMessage(LeAudioStateMachine.DISCONNECT);
+
         return true;
     }
 
@@ -646,11 +707,15 @@ public class LeAudioService extends ProfileService {
      * @return true if profile disconnected, false if device not connected over LE Audio
      */
     public boolean disconnect(BluetoothDevice device) {
+        if (mFeatureFlags.leaudioApiSynchronizedBlockFix()) {
+            return disconnectV2(device);
+        }
+
         if (DBG) {
             Log.d(TAG, "disconnect(): " + device);
         }
 
-        mGroupLock.lock();
+        groupMutexLock(/* isReadOnly */ true);
         try {
             LeAudioDeviceDescriptor descriptor = getDeviceDescriptor(device);
             if (descriptor == null) {
@@ -667,14 +732,14 @@ public class LeAudioService extends ProfileService {
 
             sm.sendMessage(LeAudioStateMachine.DISCONNECT);
         } finally {
-            mGroupLock.unlock();
+            groupMutexUnlock(/* isReadOnly */ true);
         }
 
         return true;
     }
 
     public List<BluetoothDevice> getConnectedDevices() {
-        mGroupLock.lock();
+        groupMutexLock(/* isReadOnly */ true);
         try {
             List<BluetoothDevice> devices = new ArrayList<>();
             for (LeAudioDeviceDescriptor descriptor : mDeviceDescriptors.values()) {
@@ -685,7 +750,7 @@ public class LeAudioService extends ProfileService {
             }
             return devices;
         } finally {
-            mGroupLock.unlock();
+            groupMutexUnlock(/* isReadOnly */ true);
         }
     }
 
@@ -706,7 +771,7 @@ public class LeAudioService extends ProfileService {
         if (bondedDevices == null) {
             return devices;
         }
-        mGroupLock.lock();
+        groupMutexLock(/* isReadOnly */ true);
         try {
             for (BluetoothDevice device : bondedDevices) {
                 final ParcelUuid[] featureUuids = device.getUuids();
@@ -734,7 +799,7 @@ public class LeAudioService extends ProfileService {
             }
             return devices;
         } finally {
-            mGroupLock.unlock();
+            groupMutexUnlock(/* isReadOnly */ true);
         }
     }
 
@@ -746,7 +811,7 @@ public class LeAudioService extends ProfileService {
     @VisibleForTesting
     List<BluetoothDevice> getDevices() {
         List<BluetoothDevice> devices = new ArrayList<>();
-        mGroupLock.lock();
+        groupMutexLock(/* isReadOnly */ true);
         try {
             for (LeAudioDeviceDescriptor descriptor : mDeviceDescriptors.values()) {
                 if (descriptor.mStateMachine != null) {
@@ -755,7 +820,7 @@ public class LeAudioService extends ProfileService {
             }
             return devices;
         } finally {
-            mGroupLock.unlock();
+            groupMutexUnlock(/* isReadOnly */ true);
         }
     }
 
@@ -769,7 +834,7 @@ public class LeAudioService extends ProfileService {
      * {@link BluetoothProfile#STATE_DISCONNECTING} if this profile is being disconnected
      */
     public int getConnectionState(BluetoothDevice device) {
-        mGroupLock.lock();
+        groupMutexLock(/* isReadOnly */ true);
         try {
             LeAudioDeviceDescriptor descriptor = getDeviceDescriptor(device);
             if (descriptor == null) {
@@ -782,7 +847,7 @@ public class LeAudioService extends ProfileService {
             }
             return sm.getConnectionState();
         } finally {
-            mGroupLock.unlock();
+            groupMutexUnlock(/* isReadOnly */ true);
         }
     }
 
@@ -820,11 +885,11 @@ public class LeAudioService extends ProfileService {
      * @return true given group exists, otherwise false
      */
     public boolean isValidDeviceGroup(int groupId) {
-        mGroupLock.lock();
+        groupMutexLock(/* isReadOnly */ true);
         try {
             return groupId != LE_AUDIO_GROUP_ID_INVALID && mGroupDescriptors.containsKey(groupId);
         } finally {
-            mGroupLock.unlock();
+            groupMutexUnlock(/* isReadOnly */ true);
         }
     }
 
@@ -840,7 +905,7 @@ public class LeAudioService extends ProfileService {
             return result;
         }
 
-        mGroupLock.lock();
+        groupMutexLock(/* isReadOnly */ true);
         try {
             for (Map.Entry<BluetoothDevice, LeAudioDeviceDescriptor> entry
                     : mDeviceDescriptors.entrySet()) {
@@ -849,7 +914,7 @@ public class LeAudioService extends ProfileService {
                 }
             }
         } finally {
-            mGroupLock.unlock();
+            groupMutexUnlock(/* isReadOnly */ true);
         }
         return result;
     }
@@ -867,7 +932,7 @@ public class LeAudioService extends ProfileService {
             return result;
         }
 
-        mGroupLock.lock();
+        groupMutexLock(/* isReadOnly */ true);
         try {
             for (Map.Entry<BluetoothDevice, LeAudioDeviceDescriptor> entry
                     : mDeviceDescriptors.entrySet()) {
@@ -876,7 +941,7 @@ public class LeAudioService extends ProfileService {
                 }
             }
         } finally {
-            mGroupLock.unlock();
+            groupMutexUnlock(/* isReadOnly */ true);
         }
         return result;
     }
@@ -885,7 +950,7 @@ public class LeAudioService extends ProfileService {
      * Get the active device group id
      */
     public Integer getActiveGroupId() {
-        mGroupLock.lock();
+        groupMutexLock(/* isReadOnly */ true);
         try {
             for (Map.Entry<Integer, LeAudioGroupDescriptor> entry : mGroupDescriptors.entrySet()) {
                 LeAudioGroupDescriptor descriptor = entry.getValue();
@@ -894,7 +959,7 @@ public class LeAudioService extends ProfileService {
                 }
             }
         } finally {
-            mGroupLock.unlock();
+            groupMutexUnlock(/* isReadOnly */ true);
         }
         return LE_AUDIO_GROUP_ID_INVALID;
     }
@@ -1214,7 +1279,7 @@ public class LeAudioService extends ProfileService {
     }
 
     private boolean areAllGroupsInNotActiveState() {
-        mGroupLock.lock();
+        groupMutexLock(/* isReadOnly */ true);
         try {
             for (Map.Entry<Integer, LeAudioGroupDescriptor> entry : mGroupDescriptors.entrySet()) {
                 LeAudioGroupDescriptor descriptor = entry.getValue();
@@ -1223,7 +1288,7 @@ public class LeAudioService extends ProfileService {
                 }
             }
         } finally {
-            mGroupLock.unlock();
+            groupMutexUnlock(/* isReadOnly */ true);
         }
         return true;
     }
@@ -1232,7 +1297,7 @@ public class LeAudioService extends ProfileService {
         if (groupId == LE_AUDIO_GROUP_ID_INVALID) {
             return null;
         }
-        mGroupLock.lock();
+        groupMutexLock(/* isReadOnly */ true);
         try {
             LeAudioGroupDescriptor groupDescriptor = getGroupDescriptor(groupId);
             if (groupDescriptor == null) {
@@ -1259,7 +1324,7 @@ public class LeAudioService extends ProfileService {
                 return groupDescriptor.mCurrentLeadDevice;
             }
         } finally {
-            mGroupLock.unlock();
+            groupMutexUnlock(/* isReadOnly */ true);
         }
         return null;
     }
@@ -1490,7 +1555,7 @@ public class LeAudioService extends ProfileService {
     }
 
     boolean allLeAudioDevicesConnected() {
-        mGroupLock.lock();
+        groupMutexLock(/* isReadOnly */ true);
         try {
             for (Map.Entry<BluetoothDevice, LeAudioDeviceDescriptor> deviceEntry :
                     mDeviceDescriptors.entrySet()) {
@@ -1507,7 +1572,7 @@ public class LeAudioService extends ProfileService {
                 }
             }
         } finally {
-            mGroupLock.unlock();
+            groupMutexUnlock(/* isReadOnly */ true);
         }
         return true;
     }
@@ -1767,7 +1832,7 @@ public class LeAudioService extends ProfileService {
     }
 
     private void clearInactiveDueToContextTypeFlags() {
-        mGroupLock.lock();
+        groupMutexLock(/* isReadOnly */ true);
         try {
             for (Map.Entry<Integer, LeAudioGroupDescriptor> groupEntry :
                     mGroupDescriptors.entrySet()) {
@@ -1780,7 +1845,7 @@ public class LeAudioService extends ProfileService {
                 }
             }
         } finally {
-            mGroupLock.unlock();
+            groupMutexUnlock(/* isReadOnly */ true);
         }
     }
 
@@ -1997,7 +2062,7 @@ public class LeAudioService extends ProfileService {
                 Log.d(TAG, "connect(): " + storedDevice);
             }
 
-            mGroupLock.lock();
+            groupMutexLock(/* isReadOnly */ true);
             try {
                 LeAudioStateMachine sm = getOrCreateStateMachine(storedDevice);
                 if (sm == null) {
@@ -2007,7 +2072,7 @@ public class LeAudioService extends ProfileService {
                 }
                 sm.sendMessage(LeAudioStateMachine.CONNECT);
             } finally {
-                mGroupLock.unlock();
+                groupMutexUnlock(/* isReadOnly */ true);
             }
         }
     }
@@ -2027,7 +2092,7 @@ public class LeAudioService extends ProfileService {
     }
 
     private void clearLostDevicesWhileStreaming(LeAudioGroupDescriptor descriptor) {
-        mGroupLock.lock();
+        groupMutexLock(/* isReadOnly */ true);
         try {
             if (DBG) {
                 Log.d(TAG, "Clearing lost dev: " + descriptor.mLostLeadDeviceWhileStreaming);
@@ -2052,7 +2117,7 @@ public class LeAudioService extends ProfileService {
             }
             descriptor.mLostLeadDeviceWhileStreaming = null;
         } finally {
-            mGroupLock.unlock();
+            groupMutexUnlock(/* isReadOnly */ true);
         }
     }
 
@@ -2129,7 +2194,7 @@ public class LeAudioService extends ProfileService {
     }
 
     private void handleGroupTransitToActive(int groupId) {
-        mGroupLock.lock();
+        groupMutexLock(/* isReadOnly */ true);
         try {
             LeAudioGroupDescriptor descriptor = getGroupDescriptor(groupId);
             if (descriptor == null || descriptor.mIsActive) {
@@ -2146,12 +2211,12 @@ public class LeAudioService extends ProfileService {
                 updateInbandRingtoneForTheGroup(groupId);
             }
         } finally {
-            mGroupLock.unlock();
+            groupMutexUnlock(/* isReadOnly */ true);
         }
     }
 
     private void handleGroupTransitToInactive(int groupId) {
-        mGroupLock.lock();
+        groupMutexLock(/* isReadOnly */ true);
         try {
             LeAudioGroupDescriptor descriptor = getGroupDescriptor(groupId);
             if (descriptor == null || !descriptor.mIsActive) {
@@ -2187,7 +2252,7 @@ public class LeAudioService extends ProfileService {
             notifyGroupStatusChanged(groupId, LeAudioStackEvent.GROUP_STATUS_INACTIVE);
             updateInbandRingtoneForTheGroup(groupId);
         } finally {
-            mGroupLock.unlock();
+            groupMutexUnlock(/* isReadOnly */ true);
         }
     }
 
@@ -2296,7 +2361,7 @@ public class LeAudioService extends ProfileService {
             return;
         }
 
-        mGroupLock.lock();
+        groupMutexLock(/* isReadOnly */ true);
         try {
             LeAudioGroupDescriptor groupDescriptor = getGroupDescriptor(groupId);
             if (groupDescriptor == null) {
@@ -2356,7 +2421,7 @@ public class LeAudioService extends ProfileService {
                 }
             }
         } finally {
-            mGroupLock.unlock();
+            groupMutexUnlock(/* isReadOnly */ true);
         }
     }
 
@@ -2479,7 +2544,7 @@ public class LeAudioService extends ProfileService {
 
         if (stackEvent.type == LeAudioStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED) {
             // Some events require device state machine
-            mGroupLock.lock();
+            groupMutexLock(/* isReadOnly */ true);
             try {
                 LeAudioDeviceDescriptor deviceDescriptor = getDeviceDescriptor(device);
                 if (deviceDescriptor == null) {
@@ -2558,7 +2623,7 @@ public class LeAudioService extends ProfileService {
                 sm.sendMessage(LeAudioStateMachine.STACK_EVENT, stackEvent);
                 return;
             } finally {
-                mGroupLock.unlock();
+                groupMutexUnlock(/* isReadOnly */ true);
             }
         } else if (stackEvent.type == LeAudioStackEvent.EVENT_TYPE_GROUP_NODE_STATUS_CHANGED) {
             int groupId = stackEvent.valueInt1;
@@ -2628,7 +2693,7 @@ public class LeAudioService extends ProfileService {
             int src_audio_location = stackEvent.valueInt4;
             int available_contexts = stackEvent.valueInt5;
 
-            mGroupLock.lock();
+            groupMutexLock(/* isReadOnly */ true);
             try {
                 LeAudioGroupDescriptor descriptor = getGroupDescriptor(groupId);
                 if (descriptor != null) {
@@ -2657,7 +2722,7 @@ public class LeAudioService extends ProfileService {
                     Log.e(TAG, "messageFromNative: no descriptors for group: " + groupId);
                 }
             } finally {
-                mGroupLock.unlock();
+                groupMutexUnlock(/* isReadOnly */ true);
             }
         } else if (stackEvent.type == LeAudioStackEvent.EVENT_TYPE_SINK_AUDIO_LOCATION_AVAILABLE) {
             Objects.requireNonNull(stackEvent.device,
@@ -2955,65 +3020,85 @@ public class LeAudioService extends ProfileService {
             return;
         }
 
-        mGroupLock.lock();
+        groupMutexLock(/* isReadOnly */ true);
         try {
-            LeAudioDeviceDescriptor descriptor = getDeviceDescriptor(device);
-            if (descriptor == null) {
-                Log.e(TAG, "bondStateChanged: No valid descriptor for device: " + device);
-                return;
-            }
+            try {
+                LeAudioDeviceDescriptor descriptor = getDeviceDescriptor(device);
+                if (descriptor == null) {
+                    Log.e(TAG, "bondStateChanged: No valid descriptor for device: " + device);
+                    return;
+                }
 
-            if (descriptor.mGroupId != LE_AUDIO_GROUP_ID_INVALID) {
-                /* In case device is still in the group, let's remove it */
-                mLeAudioNativeInterface.groupRemoveNode(descriptor.mGroupId, device);
-            }
+                if (descriptor.mGroupId != LE_AUDIO_GROUP_ID_INVALID) {
+                    /* In case device is still in the group, let's remove it */
+                    mLeAudioNativeInterface.groupRemoveNode(descriptor.mGroupId, device);
+                }
 
-            descriptor.mGroupId = LE_AUDIO_GROUP_ID_INVALID;
-            descriptor.mSinkAudioLocation = BluetoothLeAudio.AUDIO_LOCATION_INVALID;
-            descriptor.mDirection = AUDIO_DIRECTION_NONE;
+                descriptor.mGroupId = LE_AUDIO_GROUP_ID_INVALID;
+                descriptor.mSinkAudioLocation = BluetoothLeAudio.AUDIO_LOCATION_INVALID;
+                descriptor.mDirection = AUDIO_DIRECTION_NONE;
 
-            LeAudioStateMachine sm = descriptor.mStateMachine;
-            if (sm == null) {
-                return;
-            }
-            if (sm.getConnectionState() != BluetoothProfile.STATE_DISCONNECTED) {
-                Log.w(TAG, "Device is not disconnected yet.");
-                disconnect(device);
-                return;
+                LeAudioStateMachine sm = descriptor.mStateMachine;
+                if (sm == null) {
+                    return;
+                }
+                if (sm.getConnectionState() != BluetoothProfile.STATE_DISCONNECTED) {
+                    Log.w(TAG, "Device is not disconnected yet.");
+                    disconnect(device);
+                    return;
+                }
+            } finally {
+                // Reduce size of critical section when this feature is enabled
+                if (mFeatureFlags.leaudioApiSynchronizedBlockFix()) {
+                    groupMutexUnlock(/* isReadOnly */ true);
+                }
             }
             removeStateMachine(device);
             removeAuthorizationInfoForRelatedProfiles(device);
         } finally {
-            mGroupLock.unlock();
+            if (!mFeatureFlags.leaudioApiSynchronizedBlockFix()) {
+                groupMutexUnlock(/* isReadOnly */ true);
+            }
         }
     }
 
     private void removeStateMachine(BluetoothDevice device) {
-        mGroupLock.lock();
+        groupMutexLock(/* isReadOnly */ true);
         try {
-            LeAudioDeviceDescriptor descriptor = getDeviceDescriptor(device);
-            if (descriptor == null) {
-                Log.e(TAG, "removeStateMachine: No valid descriptor for device: " + device);
-                return;
-            }
+            try {
+                LeAudioDeviceDescriptor descriptor = getDeviceDescriptor(device);
+                if (descriptor == null) {
+                    Log.e(TAG, "removeStateMachine: No valid descriptor for device: " + device);
+                    return;
+                }
 
-            LeAudioStateMachine sm = descriptor.mStateMachine;
-            if (sm == null) {
-                Log.w(TAG, "removeStateMachine: device " + device
-                        + " does not have a state machine");
-                return;
+                LeAudioStateMachine sm = descriptor.mStateMachine;
+                if (sm == null) {
+                    Log.w(
+                            TAG,
+                            "removeStateMachine: device "
+                                    + device
+                                    + " does not have a state machine");
+                    return;
+                }
+                Log.i(TAG, "removeStateMachine: removing state machine for device: " + device);
+                sm.quit();
+                sm.cleanup();
+                descriptor.mStateMachine = null;
+            } finally {
+                if (mFeatureFlags.leaudioApiSynchronizedBlockFix()) {
+                    // Upgrade to write lock
+                    groupMutexUnlock(/* isReadOnly */ true);
+                    groupMutexLock(/* isReadOnly */ false);
+                }
             }
-            Log.i(TAG, "removeStateMachine: removing state machine for device: " + device);
-            sm.quit();
-            sm.cleanup();
-            descriptor.mStateMachine = null;
-
             mDeviceDescriptors.remove(device);
             if (!isScannerNeeded()) {
                 stopAudioServersBackgroundScan();
             }
         } finally {
-            mGroupLock.unlock();
+            /* Note, when flag is disabled, isReadyOnly param have no impact */
+            groupMutexUnlock(/* isReadOnly */ false);
         }
     }
 
@@ -3059,11 +3144,104 @@ public class LeAudioService extends ProfileService {
         }
     }
 
+    /** Process a change for disconnection of a device. */
+    synchronized void deviceDisconnectedV2(BluetoothDevice device, boolean hasFallbackDevice) {
+        if (DBG) {
+            Log.d(TAG, "deviceDisconnectedV2 " + device);
+        }
+
+        int groupId = LE_AUDIO_GROUP_ID_INVALID;
+        groupMutexLock(/* isReadOnly */ true);
+        try {
+            LeAudioDeviceDescriptor deviceDescriptor = getDeviceDescriptor(device);
+            if (deviceDescriptor == null) {
+                Log.e(TAG, "deviceDisconnected: No valid descriptor for device: " + device);
+                return;
+            }
+            groupId = deviceDescriptor.mGroupId;
+        } finally {
+            groupMutexUnlock(/* isReadOnly */ true);
+        }
+
+        int bondState = mAdapterService.getBondState(device);
+        if (bondState == BluetoothDevice.BOND_NONE) {
+            if (DBG) {
+                Log.d(TAG, device + " is unbond. Remove state machine");
+            }
+
+            removeStateMachine(device);
+            removeAuthorizationInfoForRelatedProfiles(device);
+        }
+
+        if (!isScannerNeeded()) {
+            stopAudioServersBackgroundScan();
+        }
+
+        groupMutexLock(/* isReadOnly */ true);
+        try {
+            LeAudioGroupDescriptor descriptor = getGroupDescriptor(groupId);
+            if (descriptor == null) {
+                Log.e(TAG, "deviceDisconnected: no descriptors for group: " + groupId);
+                return;
+            }
+
+            List<BluetoothDevice> connectedDevices = getConnectedPeerDevices(groupId);
+            /* Let's check if the last connected device is really connected */
+            if (connectedDevices.size() == 1
+                    && Objects.equals(
+                            connectedDevices.get(0), descriptor.mLostLeadDeviceWhileStreaming)) {
+                clearLostDevicesWhileStreaming(descriptor);
+                return;
+            }
+
+            if (getConnectedPeerDevices(groupId).isEmpty()) {
+                descriptor.mIsConnected = false;
+                if (descriptor.mIsActive) {
+                    /* Notify Native layer */
+                    removeActiveDevice(hasFallbackDevice);
+                    descriptor.mIsActive = false;
+                    /* Update audio framework */
+                    updateActiveDevices(
+                            groupId,
+                            descriptor.mDirection,
+                            descriptor.mDirection,
+                            descriptor.mIsActive,
+                            hasFallbackDevice,
+                            false);
+                    return;
+                }
+            }
+
+            if (descriptor.mIsActive
+                    || Objects.equals(mActiveAudioOutDevice, device)
+                    || Objects.equals(mActiveAudioInDevice, device)) {
+                updateActiveDevices(
+                        groupId,
+                        descriptor.mDirection,
+                        descriptor.mDirection,
+                        descriptor.mIsActive,
+                        hasFallbackDevice,
+                        false);
+            }
+        } finally {
+            groupMutexUnlock(/* isReadOnly */ true);
+        }
+    }
+
     /**
      * Process a change for disconnection of a device.
      */
     public synchronized void deviceDisconnected(BluetoothDevice device, boolean hasFallbackDevice) {
-        mGroupLock.lock();
+        if (mFeatureFlags.leaudioApiSynchronizedBlockFix()) {
+            deviceDisconnectedV2(device, hasFallbackDevice);
+            return;
+        }
+
+        if (DBG) {
+            Log.d(TAG, "deviceDisconnected " + device);
+        }
+
+        groupMutexLock(/* isReadOnly */ true);
         try {
             LeAudioDeviceDescriptor deviceDescriptor = getDeviceDescriptor(device);
             if (deviceDescriptor == null) {
@@ -3127,7 +3305,7 @@ public class LeAudioService extends ProfileService {
                         false);
             }
         } finally {
-            mGroupLock.unlock();
+            groupMutexUnlock(/* isReadOnly */ true);
         }
     }
 
@@ -3377,7 +3555,7 @@ public class LeAudioService extends ProfileService {
             return LE_AUDIO_GROUP_ID_INVALID;
         }
 
-        mGroupLock.lock();
+        groupMutexLock(/* isReadOnly */ true);
         try {
             LeAudioDeviceDescriptor descriptor = getDeviceDescriptor(device);
             if (descriptor == null) {
@@ -3387,7 +3565,7 @@ public class LeAudioService extends ProfileService {
 
             return descriptor.mGroupId;
         } finally {
-            mGroupLock.unlock();
+            groupMutexUnlock(/* isReadOnly */ true);
         }
     }
 
@@ -3493,49 +3671,51 @@ public class LeAudioService extends ProfileService {
 
         mBluetoothEnabled = true;
 
-        mGroupLock.lock();
+        groupMutexLock(/* isReadOnly */ true);
         try {
-            if (mDeviceDescriptors.isEmpty()) {
-                return;
+            try {
+                if (mDeviceDescriptors.isEmpty()) {
+                    return;
+                }
+            } finally {
+                if (!mFeatureFlags.leaudioApiSynchronizedBlockFix()) {
+                    // Keep previous behavior where a lock is released and acquired immediately
+                    groupMutexUnlock(/* isReadOnly */ true);
+                    groupMutexLock(/* isReadOnly */ true);
+                }
             }
-        } finally {
-            mGroupLock.unlock();
-        }
-
-        mGroupLock.lock();
-        try {
             for (BluetoothDevice device : mDeviceDescriptors.keySet()) {
                 if (getConnectionPolicy(device) != BluetoothProfile.CONNECTION_POLICY_FORBIDDEN) {
                     setAuthorizationForRelatedProfiles(device, true);
                 }
             }
         } finally {
-            mGroupLock.unlock();
+            groupMutexUnlock(/* isReadOnly */ true);
         }
 
         startAudioServersBackgroundScan(/* retry = */ false);
     }
 
     private LeAudioGroupDescriptor getGroupDescriptor(int groupId) {
-        mGroupLock.lock();
+        groupMutexLock(/* isReadOnly */ true);
         try {
             return mGroupDescriptors.get(groupId);
         } finally {
-            mGroupLock.unlock();
+            groupMutexUnlock(/* isReadOnly */ true);
         }
     }
 
     private LeAudioDeviceDescriptor getDeviceDescriptor(BluetoothDevice device) {
-        mGroupLock.lock();
+        groupMutexLock(/* isReadOnly */ true);
         try {
             return mDeviceDescriptors.get(device);
         } finally {
-            mGroupLock.unlock();
+            groupMutexUnlock(/* isReadOnly */ true);
         }
     }
 
     private void handleGroupNodeAdded(BluetoothDevice device, int groupId) {
-        mGroupLock.lock();
+        groupMutexLock(/* isReadOnly */ false);
         try {
             if (DBG) {
                 Log.d(TAG, "Device " + device + " added to group " + groupId);
@@ -3571,7 +3751,7 @@ public class LeAudioService extends ProfileService {
 
             notifyGroupNodeAdded(device, groupId);
         } finally {
-            mGroupLock.unlock();
+            groupMutexUnlock(/* isReadOnly */ false);
         }
 
         if (mBluetoothEnabled) {
@@ -3604,7 +3784,8 @@ public class LeAudioService extends ProfileService {
             Log.d(TAG, "Removing device " + device + " grom group " + groupId);
         }
 
-        mGroupLock.lock();
+        boolean isGroupEmpty = true;
+        groupMutexLock(/* isReadOnly */ true);
         try {
             LeAudioGroupDescriptor groupDescriptor = getGroupDescriptor(groupId);
             if (groupDescriptor == null) {
@@ -3625,8 +3806,6 @@ public class LeAudioService extends ProfileService {
             }
             deviceDescriptor.mGroupId = LE_AUDIO_GROUP_ID_INVALID;
 
-            boolean isGroupEmpty = true;
-
             for (LeAudioDeviceDescriptor descriptor : mDeviceDescriptors.values()) {
                 if (descriptor.mGroupId == groupId) {
                     isGroupEmpty = false;
@@ -3642,7 +3821,9 @@ public class LeAudioService extends ProfileService {
                         || Objects.equals(device, mActiveAudioInDevice)) {
                     handleGroupTransitToInactive(groupId);
                 }
-                mGroupDescriptors.remove(groupId);
+                if (!mFeatureFlags.leaudioApiSynchronizedBlockFix()) {
+                    mGroupDescriptors.remove(groupId);
+                }
 
                 if (mUnicastGroupIdDeactivatedForBroadcastTransition == groupId) {
                     updateFallbackUnicastGroupIdForBroadcast(LE_AUDIO_GROUP_ID_INVALID);
@@ -3650,7 +3831,16 @@ public class LeAudioService extends ProfileService {
             }
             notifyGroupNodeRemoved(device, groupId);
         } finally {
-            mGroupLock.unlock();
+            groupMutexUnlock(/* isReadOnly */ true);
+        }
+
+        if (isGroupEmpty && mFeatureFlags.leaudioApiSynchronizedBlockFix()) {
+            groupMutexLock(/* isReadOnly */ false);
+            try {
+                mGroupDescriptors.remove(groupId);
+            } finally {
+                groupMutexUnlock(/* isReadOnly */ false);
+            }
         }
 
         setAuthorizationForRelatedProfiles(device, false);
@@ -4717,7 +4907,7 @@ public class LeAudioService extends ProfileService {
                                 + mLeAudioInbandRingtoneSupportedByPlatform);
 
         int numberOfUngroupedDevs = 0;
-        mGroupLock.lock();
+        groupMutexLock(/* isReadOnly */ true);
         try {
             for (Map.Entry<Integer, LeAudioGroupDescriptor> groupEntry
                                                 : mGroupDescriptors.entrySet()) {
@@ -4763,7 +4953,7 @@ public class LeAudioService extends ProfileService {
                 }
             }
         } finally {
-            mGroupLock.unlock();
+            groupMutexUnlock(/* isReadOnly */ true);
         }
 
         if (numberOfUngroupedDevs > 0) {
@@ -4785,4 +4975,28 @@ public class LeAudioService extends ProfileService {
             }
         }
     }
+
+    private void groupMutexLock(boolean isReadOnly) {
+        if (mFeatureFlags.leaudioApiSynchronizedBlockFix()) {
+            if (isReadOnly) {
+                mGroupReadLock.lock();
+            } else {
+                mGroupWriteLock.lock();
+            }
+        } else {
+            mGroupLock.lock();
+        }
+    }
+
+    private void groupMutexUnlock(boolean isReadOnly) {
+        if (mFeatureFlags.leaudioApiSynchronizedBlockFix()) {
+            if (isReadOnly) {
+                mGroupReadLock.unlock();
+            } else {
+                mGroupWriteLock.unlock();
+            }
+        } else {
+            mGroupLock.unlock();
+        }
+    }
 }
diff --git a/android/app/tests/unit/src/com/android/bluetooth/le_audio/LeAudioBinderTest.java b/android/app/tests/unit/src/com/android/bluetooth/le_audio/LeAudioBinderTest.java
index 4c6d90933920e02cd7879ddf1a9d9773f9893efc..ad136454979af149473cf3f465b6f79acc30408f 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/le_audio/LeAudioBinderTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/le_audio/LeAudioBinderTest.java
@@ -84,6 +84,8 @@ public class LeAudioBinderTest {
         doReturn(mAudioRoutingManager).when(mAdapterService).getActiveDeviceManager();
 
         mFakeFlagsImpl = new FakeFeatureFlagsImpl();
+        mFakeFlagsImpl.setFlag(Flags.FLAG_LEAUDIO_API_SYNCHRONIZED_BLOCK_FIX, false);
+
         mLeAudioService =
                 spy(
                         new LeAudioService(
diff --git a/android/app/tests/unit/src/com/android/bluetooth/le_audio/LeAudioBroadcastServiceTest.java b/android/app/tests/unit/src/com/android/bluetooth/le_audio/LeAudioBroadcastServiceTest.java
index 33894b8500817769dd58d39da8bb30ba68135f2f..81d19db69a8fbfb15b99892490cfd16cb242f133 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/le_audio/LeAudioBroadcastServiceTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/le_audio/LeAudioBroadcastServiceTest.java
@@ -192,6 +192,7 @@ public class LeAudioBroadcastServiceTest {
         mFakeFlagsImpl.setFlag(Flags.FLAG_LEAUDIO_UNICAST_INACTIVATE_DEVICE_BASED_ON_CONTEXT, false);
         mFakeFlagsImpl.setFlag(Flags.FLAG_AUDIO_ROUTING_CENTRALIZATION, false);
         mFakeFlagsImpl.setFlag(Flags.FLAG_LEAUDIO_BROADCAST_AUDIO_HANDOVER_POLICIES, false);
+        mFakeFlagsImpl.setFlag(Flags.FLAG_LEAUDIO_API_SYNCHRONIZED_BLOCK_FIX, false);
         mService.setFeatureFlags(mFakeFlagsImpl);
 
         mService.mAudioManager = mAudioManager;
diff --git a/android/app/tests/unit/src/com/android/bluetooth/le_audio/LeAudioServiceTest.java b/android/app/tests/unit/src/com/android/bluetooth/le_audio/LeAudioServiceTest.java
index 46c35d35160e65b99a4779fd41dc746cd2aff173..022abb3c2c236c6774738e146737c81325a7042e 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/le_audio/LeAudioServiceTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/le_audio/LeAudioServiceTest.java
@@ -200,6 +200,7 @@ public class LeAudioServiceTest {
         mFakeFlagsImpl.setFlag(Flags.FLAG_AUDIO_ROUTING_CENTRALIZATION, false);
         mFakeFlagsImpl.setFlag(Flags.FLAG_LEAUDIO_BROADCAST_AUDIO_HANDOVER_POLICIES, false);
         mFakeFlagsImpl.setFlag(Flags.FLAG_LEAUDIO_MCS_TBS_AUTHORIZATION_REBOND_FIX, false);
+        mFakeFlagsImpl.setFlag(Flags.FLAG_LEAUDIO_API_SYNCHRONIZED_BLOCK_FIX, false);
         mService.setFeatureFlags(mFakeFlagsImpl);
 
         mService.mAudioManager = mAudioManager;
@@ -939,6 +940,12 @@ public class LeAudioServiceTest {
         verify(mMcpService, times(1)).removeDeviceAuthorizationInfo(mLeftDevice);
     }
 
+    @Test
+    public void testAuthorizationInfoRemovedFromTbsMcsOnUnbondEventsWithSynchBlockFixFlag() {
+        mFakeFlagsImpl.setFlag(Flags.FLAG_LEAUDIO_API_SYNCHRONIZED_BLOCK_FIX, true);
+
+        testAuthorizationInfoRemovedFromTbsMcsOnUnbondEvents();
+    }
     /**
      * Test that a CONNECTION_STATE_DISCONNECTED Le Audio stack event will remove the state
      * machine only if the device is unbond.