diff --git a/res/layout/preference_ambient_volume.xml b/res/layout/preference_ambient_volume.xml
new file mode 100644
index 0000000..a8595c6
--- /dev/null
+++ b/res/layout/preference_ambient_volume.xml
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2024 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.
+-->
+
+<LinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:gravity="center_vertical"
+    android:minHeight="?android:attr/listPreferredItemHeightSmall"
+    android:paddingStart="?android:attr/listPreferredItemPaddingStart"
+    android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
+    android:clickable="false"
+    android:orientation="horizontal">
+
+    <include
+        layout="@layout/settingslib_icon_frame"
+        android:layout_width="48dp"
+        android:layout_height="48dp"/>
+
+    <TextView
+        android:id="@android:id/title"
+        android:layout_width="0dp"
+        android:layout_height="wrap_content"
+        android:layout_weight="1"
+        android:singleLine="true"
+        android:textAppearance="?android:attr/textAppearanceListItem"
+        android:textColor="?android:attr/textColorPrimary"
+        android:ellipsize="marquee"
+        android:fadingEdge="horizontal"/>
+    <ImageView
+        android:id="@+id/expand_icon"
+        android:layout_width="48dp"
+        android:layout_height="48dp"
+        android:padding="10dp"
+        android:contentDescription="@null"
+        android:tint="@androidprv:color/materialColorOnPrimaryContainer"
+        android:src="@drawable/ic_keyboard_arrow_down"/>
+
+</LinearLayout>
\ No newline at end of file
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 89f6d8f..5a408d2 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -164,6 +164,22 @@
     <string name="bluetooth_hearing_aids_presets_empty_list_message">There are no presets programmed by your audiologist</string>
     <!-- Message when selecting hearing aids presets failed. [CHAR LIMIT=NONE] -->
     <string name="bluetooth_hearing_aids_presets_error">Couldn\u2019t update preset</string>
+    <!-- Connected devices settings. Title for ambient volume control which controls the remote device's microphone input volume. [CHAR LIMIT=60] -->
+    <string name="bluetooth_ambient_volume_control">Surroundings</string>
+    <!-- Connected devices settings. Content description for the icon to expand the unified ambient volume control to left and right separated controls. [CHAR LIMIT=NONE] -->
+    <string name="bluetooth_ambient_volume_control_expand">Expand to left and right separated controls</string>
+    <!-- Connected devices settings. Content description for the icon to collapse the left and right separated ambient volume controls to unified control. [CHAR LIMIT=NONE] -->
+    <string name="bluetooth_ambient_volume_control_collapse">Collapse to unified control</string>
+    <!-- Connected devices settings. The text to show the control is for left side device. [CHAR LIMIT=30] -->
+    <string name="bluetooth_ambient_volume_control_left">Left</string>
+    <!-- Connected devices settings. The text to show the control is for right side device. [CHAR LIMIT=30] -->
+    <string name="bluetooth_ambient_volume_control_right">Right</string>
+    <!-- Connected devices settings. Content description for a button, that mute ambient volume [CHAR_LIMIT=NONE] -->
+    <string name="bluetooth_ambient_volume_mute">Mute surroundings</string>
+    <!-- Connected devices settings. Content description for a button, that unmute ambient volume [CHAR LIMIT=NONE] -->
+    <string name="bluetooth_ambient_volume_unmute">Unmute surroundings</string>
+    <!-- Message when changing ambient state failed. [CHAR LIMIT=NONE] -->
+    <string name="bluetooth_ambient_volume_error">Couldn\u2019t update surroundings</string>
     <!-- Connected devices settings. Title of the preference to show the entrance of the audio output page. It can change different types of audio are played on phone or other bluetooth devices. [CHAR LIMIT=35] -->
     <string name="bluetooth_audio_routing_title">Audio output</string>
     <!-- Title for bluetooth audio routing page footer. [CHAR LIMIT=30] -->
diff --git a/src/com/android/settings/bluetooth/AmbientVolumePreference.java b/src/com/android/settings/bluetooth/AmbientVolumePreference.java
new file mode 100644
index 0000000..e916c04
--- /dev/null
+++ b/src/com/android/settings/bluetooth/AmbientVolumePreference.java
@@ -0,0 +1,307 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.bluetooth;
+
+import static android.view.View.GONE;
+import static android.view.View.IMPORTANT_FOR_ACCESSIBILITY_NO;
+import static android.view.View.IMPORTANT_FOR_ACCESSIBILITY_YES;
+import static android.view.View.VISIBLE;
+
+import static com.android.settingslib.bluetooth.HearingAidInfo.DeviceSide.SIDE_LEFT;
+import static com.android.settingslib.bluetooth.HearingAidInfo.DeviceSide.SIDE_RIGHT;
+
+import android.content.Context;
+import android.util.ArrayMap;
+import android.view.View;
+import android.widget.ImageView;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.preference.PreferenceGroup;
+import androidx.preference.PreferenceViewHolder;
+
+import com.android.settings.R;
+import com.android.settings.widget.SeekBarPreference;
+
+import com.google.common.primitives.Ints;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * A preference group of ambient volume controls.
+ *
+ * <p> It consists of a header with an expand icon and volume sliders for unified control and
+ * separated control for devices in the same set. Toggle the expand icon will make the UI switch
+ * between unified and separated control.
+ */
+public class AmbientVolumePreference extends PreferenceGroup {
+
+    /** Interface definition for a callback to be invoked when the icon is clicked. */
+    public interface OnIconClickListener {
+        /** Called when the expand icon is clicked. */
+        void onExpandIconClick();
+
+        /** Called when the ambient volume icon is clicked. */
+        void onAmbientVolumeIconClick();
+    };
+
+    static final float ROTATION_COLLAPSED = 0f;
+    static final float ROTATION_EXPANDED = 180f;
+    static final int AMBIENT_VOLUME_LEVEL_MIN = 0;
+    static final int AMBIENT_VOLUME_LEVEL_MAX = 24;
+    static final int AMBIENT_VOLUME_LEVEL_DEFAULT = 24;
+    static final int SIDE_UNIFIED = 999;
+    static final List<Integer> VALID_SIDES = List.of(SIDE_UNIFIED, SIDE_LEFT, SIDE_RIGHT);
+
+    @Nullable
+    private OnIconClickListener mListener;
+    @Nullable
+    private View mExpandIcon;
+    @Nullable
+    private ImageView mVolumeIcon;
+    private boolean mExpandable = true;
+    private boolean mExpanded = false;
+    private boolean mMutable = false;
+    private boolean mMuted = false;
+    private Map<Integer, SeekBarPreference> mSideToSliderMap = new ArrayMap<>();
+
+    /**
+     * Ambient volume level for hearing device ambient control icon
+     * <p>
+     * This icon visually represents the current ambient gain setting.
+     * It displays separate levels for the left and right sides, each with 5 levels ranging from 0
+     * to 4.
+     * <p>
+     * To represent the combined left/right levels with a single value, the following calculation
+     * is used:
+     *      finalLevel = (leftLevel * 5) + rightLevel
+     * For example:
+     * <ul>
+     *    <li>If left level is 2 and right level is 3, the final level will be 13 (2 * 5 + 3)</li>
+     *    <li>If both left and right levels are 0, the final level will be 0</li>
+     *    <li>If both left and right levels are 4, the final level will be 24</li>
+     * </ul>
+     */
+    private int mVolumeLevel = AMBIENT_VOLUME_LEVEL_DEFAULT;
+
+    public AmbientVolumePreference(@NonNull Context context) {
+        super(context, null);
+        setLayoutResource(R.layout.preference_ambient_volume);
+        setIcon(com.android.settingslib.R.drawable.ic_ambient_volume);
+        setTitle(R.string.bluetooth_ambient_volume_control);
+        setSelectable(false);
+    }
+
+    @Override
+    public void onBindViewHolder(@NonNull PreferenceViewHolder holder) {
+        super.onBindViewHolder(holder);
+        holder.setDividerAllowedAbove(false);
+        holder.setDividerAllowedBelow(false);
+
+        mVolumeIcon = holder.itemView.requireViewById(com.android.internal.R.id.icon);
+        mVolumeIcon.getDrawable().mutate().setTint(getContext().getColor(
+                com.android.internal.R.color.materialColorOnPrimaryContainer));
+        final View iconView = holder.itemView.requireViewById(R.id.icon_frame);
+        iconView.setOnClickListener(v -> {
+            if (!mMutable) {
+                return;
+            }
+            setMuted(!mMuted);
+            if (mListener != null) {
+                mListener.onAmbientVolumeIconClick();
+            }
+        });
+        updateVolumeIcon();
+
+        mExpandIcon = holder.itemView.requireViewById(R.id.expand_icon);
+        mExpandIcon.setOnClickListener(v -> {
+            setExpanded(!mExpanded);
+            if (mListener != null) {
+                mListener.onExpandIconClick();
+            }
+        });
+        updateExpandIcon();
+    }
+
+    void setExpandable(boolean expandable) {
+        mExpandable = expandable;
+        if (!mExpandable) {
+            setExpanded(false);
+        }
+        updateExpandIcon();
+    }
+
+    boolean isExpandable() {
+        return mExpandable;
+    }
+
+    void setExpanded(boolean expanded) {
+        if (!mExpandable && expanded) {
+            return;
+        }
+        mExpanded = expanded;
+        updateExpandIcon();
+        updateLayout();
+    }
+
+    boolean isExpanded() {
+        return mExpanded;
+    }
+
+    void setMutable(boolean mutable) {
+        mMutable = mutable;
+        if (!mMutable) {
+            mVolumeLevel = AMBIENT_VOLUME_LEVEL_DEFAULT;
+            setMuted(false);
+        }
+        updateVolumeIcon();
+    }
+
+    boolean isMutable() {
+        return mMutable;
+    }
+
+    void setMuted(boolean muted) {
+        if (!mMutable && muted) {
+            return;
+        }
+        mMuted = muted;
+        if (mMutable && mMuted) {
+            for (SeekBarPreference slider : mSideToSliderMap.values()) {
+                slider.setProgress(slider.getMin());
+            }
+        }
+        updateVolumeIcon();
+    }
+
+    boolean isMuted() {
+        return mMuted;
+    }
+
+    void setOnIconClickListener(@Nullable OnIconClickListener listener) {
+        mListener = listener;
+    }
+
+    void setSliders(Map<Integer, SeekBarPreference> sideToSliderMap) {
+        mSideToSliderMap = sideToSliderMap;
+        for (SeekBarPreference preference : sideToSliderMap.values()) {
+            if (findPreference(preference.getKey()) == null) {
+                addPreference(preference);
+            }
+        }
+        updateLayout();
+    }
+
+    void setSliderEnabled(int side, boolean enabled) {
+        SeekBarPreference slider = mSideToSliderMap.get(side);
+        if (slider != null && slider.isEnabled() != enabled) {
+            slider.setEnabled(enabled);
+            updateLayout();
+        }
+    }
+
+    void setSliderValue(int side, int value) {
+        SeekBarPreference slider = mSideToSliderMap.get(side);
+        if (slider != null && slider.getProgress() != value) {
+            slider.setProgress(value);
+            updateVolumeLevel();
+        }
+    }
+
+    void setSliderRange(int side, int min, int max) {
+        SeekBarPreference slider = mSideToSliderMap.get(side);
+        if (slider != null) {
+            slider.setMin(min);
+            slider.setMax(max);
+        }
+    }
+
+    void updateLayout() {
+        mSideToSliderMap.forEach((side, slider) -> {
+            if (side == SIDE_UNIFIED) {
+                slider.setVisible(!mExpanded);
+            } else {
+                slider.setVisible(mExpanded);
+            }
+            if (!slider.isEnabled()) {
+                slider.setProgress(slider.getMin());
+            }
+        });
+        updateVolumeLevel();
+    }
+
+    private void updateVolumeLevel() {
+        int leftLevel, rightLevel;
+        if (mExpanded) {
+            leftLevel = getVolumeLevel(SIDE_LEFT);
+            rightLevel = getVolumeLevel(SIDE_RIGHT);
+        } else {
+            final int unifiedLevel = getVolumeLevel(SIDE_UNIFIED);
+            leftLevel = unifiedLevel;
+            rightLevel = unifiedLevel;
+        }
+        mVolumeLevel = Ints.constrainToRange(leftLevel * 5 + rightLevel,
+                AMBIENT_VOLUME_LEVEL_MIN, AMBIENT_VOLUME_LEVEL_MAX);
+        updateVolumeIcon();
+    }
+
+    private int getVolumeLevel(int side) {
+        SeekBarPreference slider = mSideToSliderMap.get(side);
+        if (slider == null || !slider.isEnabled()) {
+            return 0;
+        }
+        final double min = slider.getMin();
+        final double max = slider.getMax();
+        final double levelGap = (max - min) / 4.0;
+        final int value = slider.getProgress();
+        return (int) Math.ceil((value - min) / levelGap);
+    }
+
+    private void updateExpandIcon() {
+        if (mExpandIcon == null) {
+            return;
+        }
+        mExpandIcon.setVisibility(mExpandable ? VISIBLE : GONE);
+        mExpandIcon.setRotation(mExpanded ? ROTATION_EXPANDED : ROTATION_COLLAPSED);
+        if (mExpandable) {
+            final int stringRes = mExpanded
+                    ? R.string.bluetooth_ambient_volume_control_collapse
+                    : R.string.bluetooth_ambient_volume_control_expand;
+            mExpandIcon.setContentDescription(getContext().getString(stringRes));
+        } else {
+            mExpandIcon.setContentDescription(null);
+        }
+    }
+
+    private void updateVolumeIcon() {
+        if (mVolumeIcon == null) {
+            return;
+        }
+        mVolumeIcon.setImageLevel(mMuted ? 0 : mVolumeLevel);
+        if (mMutable) {
+            final int stringRes = mMuted
+                    ? R.string.bluetooth_ambient_volume_unmute
+                    : R.string.bluetooth_ambient_volume_mute;
+            mVolumeIcon.setContentDescription(getContext().getString(stringRes));
+            mVolumeIcon.setImportantForAccessibility(IMPORTANT_FOR_ACCESSIBILITY_YES);
+        }  else {
+            mVolumeIcon.setContentDescription(null);
+            mVolumeIcon.setImportantForAccessibility(IMPORTANT_FOR_ACCESSIBILITY_NO);
+        }
+    }
+}
diff --git a/src/com/android/settings/bluetooth/BluetoothDetailsAmbientVolumePreferenceController.java b/src/com/android/settings/bluetooth/BluetoothDetailsAmbientVolumePreferenceController.java
new file mode 100644
index 0000000..f237ffe
--- /dev/null
+++ b/src/com/android/settings/bluetooth/BluetoothDetailsAmbientVolumePreferenceController.java
@@ -0,0 +1,614 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.bluetooth;
+
+import static android.bluetooth.AudioInputControl.MUTE_NOT_MUTED;
+import static android.bluetooth.AudioInputControl.MUTE_MUTED;
+import static android.bluetooth.BluetoothDevice.BOND_BONDED;
+
+import static com.android.settings.bluetooth.AmbientVolumePreference.SIDE_UNIFIED;
+import static com.android.settings.bluetooth.AmbientVolumePreference.VALID_SIDES;
+import static com.android.settings.bluetooth.BluetoothDetailsHearingDeviceController.KEY_HEARING_DEVICE_GROUP;
+import static com.android.settings.bluetooth.BluetoothDetailsHearingDeviceController.ORDER_AMBIENT_VOLUME;
+import static com.android.settingslib.bluetooth.HearingAidInfo.DeviceSide.SIDE_INVALID;
+import static com.android.settingslib.bluetooth.HearingAidInfo.DeviceSide.SIDE_LEFT;
+import static com.android.settingslib.bluetooth.HearingAidInfo.DeviceSide.SIDE_RIGHT;
+import static com.android.settingslib.bluetooth.HearingDeviceLocalDataManager.Data.INVALID_VOLUME;
+
+import android.bluetooth.BluetoothDevice;
+import android.bluetooth.BluetoothProfile;
+import android.content.Context;
+import android.util.ArraySet;
+import android.util.Log;
+import android.widget.Toast;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.annotation.VisibleForTesting;
+import androidx.preference.Preference;
+import androidx.preference.PreferenceCategory;
+import androidx.preference.PreferenceFragmentCompat;
+import androidx.preference.PreferenceScreen;
+
+import com.android.settings.R;
+import com.android.settings.widget.SeekBarPreference;
+import com.android.settingslib.bluetooth.AmbientVolumeController;
+import com.android.settingslib.bluetooth.BluetoothCallback;
+import com.android.settingslib.bluetooth.CachedBluetoothDevice;
+import com.android.settingslib.bluetooth.HearingDeviceLocalDataManager;
+import com.android.settingslib.bluetooth.HearingDeviceLocalDataManager.Data;
+import com.android.settingslib.bluetooth.LocalBluetoothManager;
+import com.android.settingslib.bluetooth.VolumeControlProfile;
+import com.android.settingslib.core.lifecycle.Lifecycle;
+import com.android.settingslib.core.lifecycle.events.OnStart;
+import com.android.settingslib.core.lifecycle.events.OnStop;
+import com.android.settingslib.utils.ThreadUtils;
+
+import com.google.common.collect.BiMap;
+import com.google.common.collect.HashBiMap;
+
+import java.util.Map;
+import java.util.Set;
+
+/** A {@link BluetoothDetailsController} that manages ambient volume control preferences. */
+public class BluetoothDetailsAmbientVolumePreferenceController extends
+        BluetoothDetailsController implements Preference.OnPreferenceChangeListener,
+        HearingDeviceLocalDataManager.OnDeviceLocalDataChangeListener, OnStart, OnStop,
+        AmbientVolumeController.AmbientVolumeControlCallback, BluetoothCallback {
+
+    private static final boolean DEBUG = true;
+    private static final String TAG = "AmbientPrefController";
+
+    static final String KEY_AMBIENT_VOLUME = "ambient_volume";
+    static final String KEY_AMBIENT_VOLUME_SLIDER = "ambient_volume_slider";
+    private static final int ORDER_AMBIENT_VOLUME_CONTROL_UNIFIED = 0;
+    private static final int ORDER_AMBIENT_VOLUME_CONTROL_SEPARATED = 1;
+
+    private final LocalBluetoothManager mBluetoothManager;
+    private final Set<CachedBluetoothDevice> mCachedDevices = new ArraySet<>();
+    private final BiMap<Integer, BluetoothDevice> mSideToDeviceMap = HashBiMap.create();
+    private final BiMap<Integer, SeekBarPreference> mSideToSliderMap = HashBiMap.create();
+    private final HearingDeviceLocalDataManager mLocalDataManager;
+    private final AmbientVolumeController mVolumeController;
+
+    @Nullable
+    private PreferenceCategory mDeviceControls;
+    @Nullable
+    private AmbientVolumePreference mPreference;
+    @Nullable
+    private Toast mToast;
+
+    public BluetoothDetailsAmbientVolumePreferenceController(@NonNull Context context,
+            @NonNull LocalBluetoothManager manager,
+            @NonNull PreferenceFragmentCompat fragment,
+            @NonNull CachedBluetoothDevice device,
+            @NonNull Lifecycle lifecycle) {
+        super(context, fragment, device, lifecycle);
+        mBluetoothManager = manager;
+        mLocalDataManager = new HearingDeviceLocalDataManager(context);
+        mLocalDataManager.setOnDeviceLocalDataChangeListener(this,
+                ThreadUtils.getBackgroundExecutor());
+        mVolumeController = new AmbientVolumeController(manager.getProfileManager(), this);
+    }
+
+    @VisibleForTesting
+    BluetoothDetailsAmbientVolumePreferenceController(@NonNull Context context,
+            @NonNull LocalBluetoothManager manager,
+            @NonNull PreferenceFragmentCompat fragment,
+            @NonNull CachedBluetoothDevice device,
+            @NonNull Lifecycle lifecycle,
+            @NonNull HearingDeviceLocalDataManager localSettings,
+            @NonNull AmbientVolumeController volumeController) {
+        super(context, fragment, device, lifecycle);
+        mBluetoothManager = manager;
+        mLocalDataManager = localSettings;
+        mVolumeController = volumeController;
+    }
+
+    @Override
+    protected void init(PreferenceScreen screen) {
+        mDeviceControls = screen.findPreference(KEY_HEARING_DEVICE_GROUP);
+        if (mDeviceControls == null) {
+            return;
+        }
+        loadDevices();
+    }
+
+    @Override
+    public void onStart() {
+        ThreadUtils.postOnBackgroundThread(() -> {
+            mBluetoothManager.getEventManager().registerCallback(this);
+            mLocalDataManager.start();
+            mCachedDevices.forEach(device -> {
+                device.registerCallback(ThreadUtils.getBackgroundExecutor(), this);
+                mVolumeController.registerCallback(ThreadUtils.getBackgroundExecutor(),
+                        device.getDevice());
+            });
+        });
+    }
+
+    @Override
+    public void onResume() {
+        refresh();
+    }
+
+    @Override
+    public void onPause() {
+    }
+
+    @Override
+    public void onStop() {
+        ThreadUtils.postOnBackgroundThread(() -> {
+            mBluetoothManager.getEventManager().unregisterCallback(this);
+            mLocalDataManager.stop();
+            mCachedDevices.forEach(device -> {
+                device.unregisterCallback(this);
+                mVolumeController.unregisterCallback(device.getDevice());
+            });
+        });
+    }
+
+    @Override
+    protected void refresh() {
+        if (!isAvailable()) {
+            return;
+        }
+        boolean shouldShowAmbientControl = isAmbientControlAvailable();
+        if (shouldShowAmbientControl) {
+            if (mPreference != null) {
+                mPreference.setVisible(true);
+            }
+            loadRemoteDataToUi();
+        } else {
+            if (mPreference != null) {
+                mPreference.setVisible(false);
+            }
+        }
+    }
+
+    @Override
+    public boolean isAvailable() {
+        return mCachedDevice.getProfiles().stream().anyMatch(
+                profile -> profile instanceof VolumeControlProfile);
+    }
+
+    @Nullable
+    @Override
+    public String getPreferenceKey() {
+        return KEY_AMBIENT_VOLUME;
+    }
+
+    @Override
+    public boolean onPreferenceChange(@NonNull Preference preference, @Nullable Object newValue) {
+        if (preference instanceof SeekBarPreference && newValue instanceof final Integer value) {
+            final int side = mSideToSliderMap.inverse().getOrDefault(preference, SIDE_INVALID);
+            if (DEBUG) {
+                Log.d(TAG, "onPreferenceChange: side=" + side + ", value=" + value);
+            }
+            setVolumeIfValid(side, value);
+
+            Runnable setAmbientRunnable = () -> {
+                if (side == SIDE_UNIFIED) {
+                    mSideToDeviceMap.forEach((s, d) -> mVolumeController.setAmbient(d, value));
+                } else {
+                    final BluetoothDevice device = mSideToDeviceMap.get(side);
+                    mVolumeController.setAmbient(device, value);
+                }
+            };
+
+            if (isControlMuted()) {
+                // User drag on the volume slider when muted. Unmute the devices first.
+                if (mPreference != null) {
+                    mPreference.setMuted(false);
+                }
+                for (BluetoothDevice device : mSideToDeviceMap.values()) {
+                    mVolumeController.setMuted(device, false);
+                }
+                // Restore the value before muted
+                loadLocalDataToUi();
+                // Delay set ambient on remote device since the immediately sequential command
+                // might get failed sometimes
+                mContext.getMainThreadHandler().postDelayed(setAmbientRunnable, 1000L);
+            } else {
+                setAmbientRunnable.run();
+            }
+            return true;
+        }
+        return false;
+    }
+
+    @Override
+    public void onProfileConnectionStateChanged(@NonNull CachedBluetoothDevice cachedDevice,
+            int state, int bluetoothProfile) {
+        if (bluetoothProfile == BluetoothProfile.VOLUME_CONTROL
+                && state == BluetoothProfile.STATE_CONNECTED
+                && mCachedDevices.contains(cachedDevice)) {
+            // After VCP connected, AICS may not ready yet and still return invalid value, delay
+            // a while to wait AICS ready as a workaround
+            mContext.getMainThreadHandler().postDelayed(this::refresh, 1000L);
+        }
+    }
+
+    @Override
+    public void onDeviceAttributesChanged() {
+        mCachedDevices.forEach(device -> {
+            device.unregisterCallback(this);
+            mVolumeController.unregisterCallback(device.getDevice());
+        });
+        mContext.getMainExecutor().execute(() -> {
+            loadDevices();
+            if (!mCachedDevices.isEmpty()) {
+                refresh();
+            }
+            ThreadUtils.postOnBackgroundThread(() ->
+                    mCachedDevices.forEach(device -> {
+                        device.registerCallback(ThreadUtils.getBackgroundExecutor(), this);
+                        mVolumeController.registerCallback(ThreadUtils.getBackgroundExecutor(),
+                                device.getDevice());
+                    })
+            );
+        });
+    }
+
+    @Override
+    public void onDeviceLocalDataChange(@NonNull String address, @Nullable Data data) {
+        if (data == null) {
+            // The local data is removed because the device is unpaired, do nothing
+            return;
+        }
+        for (BluetoothDevice device : mSideToDeviceMap.values()) {
+            if (device.getAnonymizedAddress().equals(address)) {
+                mContext.getMainExecutor().execute(() -> loadLocalDataToUi(device));
+                return;
+            }
+        }
+    }
+
+    @Override
+    public void onVolumeControlServiceConnected() {
+        mCachedDevices.forEach(
+                device -> mVolumeController.registerCallback(ThreadUtils.getBackgroundExecutor(),
+                        device.getDevice()));
+    }
+
+    @Override
+    public void onAmbientChanged(@NonNull BluetoothDevice device, int gainSettings) {
+        if (DEBUG) {
+            Log.d(TAG, "onAmbientChanged, value:" + gainSettings + ", device:" + device);
+        }
+        Data data = mLocalDataManager.get(device);
+        boolean isInitiatedFromUi = (isControlExpanded() && data.ambient() == gainSettings)
+                || (!isControlExpanded() && data.groupAmbient() == gainSettings);
+        if (isInitiatedFromUi) {
+            // The change is initiated from UI, no need to update UI
+            return;
+        }
+
+        // We have to check if we need to expand the controls by getting all remote
+        // device's ambient value, delay for a while to wait all remote devices update
+        // to the latest value to avoid unnecessary expand action.
+        mContext.getMainThreadHandler().postDelayed(this::refresh, 1200L);
+    }
+
+    @Override
+    public void onMuteChanged(@NonNull BluetoothDevice device, int mute) {
+        if (DEBUG) {
+            Log.d(TAG, "onMuteChanged, mute:" + mute + ", device:" + device);
+        }
+        boolean isInitiatedFromUi = (isControlMuted() && mute == MUTE_MUTED)
+                || (!isControlMuted() && mute == MUTE_NOT_MUTED);
+        if (isInitiatedFromUi) {
+            // The change is initiated from UI, no need to update UI
+            return;
+        }
+
+        // We have to check if we need to mute the devices by getting all remote
+        // device's mute state, delay for a while to wait all remote devices update
+        // to the latest value.
+        mContext.getMainThreadHandler().postDelayed(this::refresh, 1200L);
+    }
+
+    @Override
+    public void onCommandFailed(@NonNull BluetoothDevice device) {
+        Log.w(TAG, "onCommandFailed, device:" + device);
+        mContext.getMainExecutor().execute(() -> {
+            showErrorToast();
+            refresh();
+        });
+    }
+
+    private void loadDevices() {
+        mSideToDeviceMap.clear();
+        mCachedDevices.clear();
+        if (VALID_SIDES.contains(mCachedDevice.getDeviceSide())
+                && mCachedDevice.getBondState() == BOND_BONDED) {
+            mSideToDeviceMap.put(mCachedDevice.getDeviceSide(), mCachedDevice.getDevice());
+            mCachedDevices.add(mCachedDevice);
+        }
+        for (CachedBluetoothDevice memberDevice : mCachedDevice.getMemberDevice()) {
+            if (VALID_SIDES.contains(memberDevice.getDeviceSide())
+                    && memberDevice.getBondState() == BOND_BONDED) {
+                mSideToDeviceMap.put(memberDevice.getDeviceSide(), memberDevice.getDevice());
+                mCachedDevices.add(memberDevice);
+            }
+        }
+        createAmbientVolumePreference();
+        createSliderPreferences();
+        if (mPreference != null) {
+            mPreference.setExpandable(mSideToDeviceMap.size() > 1);
+            mPreference.setSliders((mSideToSliderMap));
+        }
+    }
+
+    private void createAmbientVolumePreference() {
+        if (mPreference != null || mDeviceControls == null) {
+            return;
+        }
+
+        mPreference = new AmbientVolumePreference(mDeviceControls.getContext());
+        mPreference.setKey(KEY_AMBIENT_VOLUME);
+        mPreference.setOrder(ORDER_AMBIENT_VOLUME);
+        mPreference.setOnIconClickListener(
+                new AmbientVolumePreference.OnIconClickListener() {
+                    @Override
+                    public void onExpandIconClick() {
+                        mSideToDeviceMap.forEach((s, d) -> {
+                            if (!isControlMuted()) {
+                                // Apply previous collapsed/expanded volume to remote device
+                                Data data = mLocalDataManager.get(d);
+                                int volume = isControlExpanded()
+                                        ? data.ambient() : data.groupAmbient();
+                                mVolumeController.setAmbient(d, volume);
+                            }
+                            // Update new value to local data
+                            mLocalDataManager.updateAmbientControlExpanded(d, isControlExpanded());
+                        });
+                    }
+
+                    @Override
+                    public void onAmbientVolumeIconClick() {
+                        if (!isControlMuted()) {
+                            loadLocalDataToUi();
+                        }
+                        for (BluetoothDevice device : mSideToDeviceMap.values()) {
+                            mVolumeController.setMuted(device, isControlMuted());
+                        }
+                    }
+                });
+        if (mDeviceControls.findPreference(mPreference.getKey()) == null) {
+            mDeviceControls.addPreference(mPreference);
+        }
+    }
+
+    private void createSliderPreferences() {
+        mSideToDeviceMap.forEach((s, d) ->
+                createSliderPreference(s, ORDER_AMBIENT_VOLUME_CONTROL_SEPARATED + s));
+        createSliderPreference(SIDE_UNIFIED, ORDER_AMBIENT_VOLUME_CONTROL_UNIFIED);
+    }
+
+    private void createSliderPreference(int side, int order) {
+        if (mSideToSliderMap.containsKey(side) || mDeviceControls == null) {
+            return;
+        }
+        SeekBarPreference preference = new SeekBarPreference(mDeviceControls.getContext());
+        preference.setKey(KEY_AMBIENT_VOLUME_SLIDER + "_" + side);
+        preference.setOrder(order);
+        preference.setOnPreferenceChangeListener(this);
+        if (side == SIDE_LEFT) {
+            preference.setTitle(mContext.getString(R.string.bluetooth_ambient_volume_control_left));
+        } else if (side == SIDE_RIGHT) {
+            preference.setTitle(
+                    mContext.getString(R.string.bluetooth_ambient_volume_control_right));
+        }
+        mSideToSliderMap.put(side, preference);
+    }
+
+    /** Refreshes the control UI visibility and enabled state. */
+    private void refreshControlUi() {
+        if (mPreference != null) {
+            boolean isAnySliderEnabled = false;
+            for (Map.Entry<Integer, BluetoothDevice> entry : mSideToDeviceMap.entrySet()) {
+                final int side = entry.getKey();
+                final BluetoothDevice device = entry.getValue();
+                final boolean enabled = isDeviceConnectedToVcp(device)
+                        && mVolumeController.isAmbientControlAvailable(device);
+                isAnySliderEnabled |= enabled;
+                mPreference.setSliderEnabled(side, enabled);
+            }
+            mPreference.setSliderEnabled(SIDE_UNIFIED, isAnySliderEnabled);
+            mPreference.updateLayout();
+        }
+    }
+
+    /** Sets the volume to the corresponding control slider. */
+    private void setVolumeIfValid(int side, int volume) {
+        if (volume == INVALID_VOLUME) {
+            return;
+        }
+        if (mPreference != null) {
+            mPreference.setSliderValue(side, volume);
+        }
+        // Update new value to local data
+        if (side == SIDE_UNIFIED) {
+            mSideToDeviceMap.forEach((s, d) -> mLocalDataManager.updateGroupAmbient(d, volume));
+        } else {
+            mLocalDataManager.updateAmbient(mSideToDeviceMap.get(side), volume);
+        }
+    }
+
+    private void loadLocalDataToUi() {
+        mSideToDeviceMap.forEach((s, d) -> loadLocalDataToUi(d));
+    }
+
+    private void loadLocalDataToUi(BluetoothDevice device) {
+        final Data data = mLocalDataManager.get(device);
+        if (DEBUG) {
+            Log.d(TAG, "loadLocalDataToUi, data=" + data + ", device=" + device);
+        }
+        final int side = mSideToDeviceMap.inverse().getOrDefault(device, SIDE_INVALID);
+        if (isDeviceConnectedToVcp(device) && !isControlMuted()) {
+            setVolumeIfValid(side, data.ambient());
+            setVolumeIfValid(SIDE_UNIFIED, data.groupAmbient());
+        }
+        setControlExpanded(data.ambientControlExpanded());
+        refreshControlUi();
+    }
+
+    private void loadRemoteDataToUi() {
+        BluetoothDevice leftDevice = mSideToDeviceMap.get(SIDE_LEFT);
+        AmbientVolumeController.RemoteAmbientState leftState =
+                mVolumeController.refreshAmbientState(leftDevice);
+        BluetoothDevice rightDevice = mSideToDeviceMap.get(SIDE_RIGHT);
+        AmbientVolumeController.RemoteAmbientState rightState =
+                mVolumeController.refreshAmbientState(rightDevice);
+        if (DEBUG) {
+            Log.d(TAG, "loadRemoteDataToUi, left=" + leftState + ", right=" + rightState);
+        }
+
+        if (mPreference != null) {
+            mSideToDeviceMap.forEach((side, device) -> {
+                int ambientMax = mVolumeController.getAmbientMax(device);
+                int ambientMin = mVolumeController.getAmbientMin(device);
+                if (ambientMin != ambientMax) {
+                    mPreference.setSliderRange(side, ambientMin, ambientMax);
+                    mPreference.setSliderRange(SIDE_UNIFIED, ambientMin, ambientMax);
+                }
+            });
+        }
+
+        // Update ambient volume
+        final int leftAmbient = leftState != null ? leftState.gainSetting() : INVALID_VOLUME;
+        final int rightAmbient = rightState != null ? rightState.gainSetting() : INVALID_VOLUME;
+        if (isControlExpanded()) {
+            setVolumeIfValid(SIDE_LEFT, leftAmbient);
+            setVolumeIfValid(SIDE_RIGHT, rightAmbient);
+        } else {
+            if (leftAmbient != rightAmbient && leftAmbient != INVALID_VOLUME
+                    && rightAmbient != INVALID_VOLUME) {
+                setVolumeIfValid(SIDE_LEFT, leftAmbient);
+                setVolumeIfValid(SIDE_RIGHT, rightAmbient);
+                setControlExpanded(true);
+            } else {
+                int unifiedAmbient = leftAmbient != INVALID_VOLUME ? leftAmbient : rightAmbient;
+                setVolumeIfValid(SIDE_UNIFIED, unifiedAmbient);
+            }
+        }
+        // Initialize local data between side and group value
+        initLocalDataIfNeeded();
+
+        // Update mute state
+        boolean mutable = true;
+        boolean muted = true;
+        if (isDeviceConnectedToVcp(leftDevice) && leftState != null) {
+            mutable &= leftState.isMutable();
+            muted &= leftState.isMuted();
+        }
+        if (isDeviceConnectedToVcp(rightDevice) && rightState != null) {
+            mutable &= rightState.isMutable();
+            muted &= rightState.isMuted();
+        }
+        if (mPreference != null) {
+            mPreference.setMutable(mutable);
+            mPreference.setMuted(muted);
+        }
+
+        // Ensure remote device mute state is synced
+        syncMuteStateIfNeeded(leftDevice, leftState, muted);
+        syncMuteStateIfNeeded(rightDevice, rightState, muted);
+
+        refreshControlUi();
+    }
+
+    /** Check if any device in the group has valid ambient control points */
+    private boolean isAmbientControlAvailable() {
+        for (BluetoothDevice device : mSideToDeviceMap.values()) {
+            // Found ambient local data for this device, show the ambient control
+            if (mLocalDataManager.get(device).hasAmbientData()) {
+                return true;
+            }
+            // Found remote ambient control points on this device, show the ambient control
+            if (mVolumeController.isAmbientControlAvailable(device)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    private boolean isControlExpanded() {
+        return mPreference != null && mPreference.isExpanded();
+    }
+
+    private void setControlExpanded(boolean expanded) {
+        if (mPreference != null && mPreference.isExpanded() != expanded) {
+            mPreference.setExpanded(expanded);
+        }
+        mSideToDeviceMap.forEach((s, d) -> {
+            // Update new value to local data
+            mLocalDataManager.updateAmbientControlExpanded(d, expanded);
+        });
+    }
+
+    private boolean isControlMuted() {
+        return mPreference != null && mPreference.isMuted();
+    }
+
+    private void initLocalDataIfNeeded() {
+        int smallerVolumeAmongGroup = Integer.MAX_VALUE;
+        for (BluetoothDevice device : mSideToDeviceMap.values()) {
+            Data data = mLocalDataManager.get(device);
+            if (data.ambient() != INVALID_VOLUME) {
+                smallerVolumeAmongGroup = Math.min(data.ambient(), smallerVolumeAmongGroup);
+            } else if (data.groupAmbient() != INVALID_VOLUME) {
+                // Initialize side ambient from group ambient value
+                mLocalDataManager.updateAmbient(device, data.groupAmbient());
+            }
+        }
+        if (smallerVolumeAmongGroup != Integer.MAX_VALUE) {
+            for (BluetoothDevice device : mSideToDeviceMap.values()) {
+                Data data = mLocalDataManager.get(device);
+                if (data.groupAmbient() == INVALID_VOLUME) {
+                    // Initialize group ambient from smaller side ambient value
+                    mLocalDataManager.updateGroupAmbient(device, smallerVolumeAmongGroup);
+                }
+            }
+        }
+    }
+
+    private void syncMuteStateIfNeeded(@Nullable BluetoothDevice device,
+            @Nullable AmbientVolumeController.RemoteAmbientState state, boolean muted) {
+        if (isDeviceConnectedToVcp(device) && state != null && state.isMutable()) {
+            if (state.isMuted() != muted) {
+                mVolumeController.setMuted(device, muted);
+            }
+        }
+    }
+
+    private boolean isDeviceConnectedToVcp(@Nullable BluetoothDevice device) {
+        return device != null && device.isConnected()
+                && mBluetoothManager.getProfileManager().getVolumeControlProfile()
+                .getConnectionStatus(device) == BluetoothProfile.STATE_CONNECTED;
+    }
+
+    private void showErrorToast() {
+        if (mToast != null) {
+            mToast.cancel();
+        }
+        mToast = Toast.makeText(mContext, R.string.bluetooth_ambient_volume_error,
+                Toast.LENGTH_SHORT);
+        mToast.show();
+    }
+}
diff --git a/src/com/android/settings/bluetooth/BluetoothDetailsHearingDeviceController.java b/src/com/android/settings/bluetooth/BluetoothDetailsHearingDeviceController.java
index 3703b71..8af0879 100644
--- a/src/com/android/settings/bluetooth/BluetoothDetailsHearingDeviceController.java
+++ b/src/com/android/settings/bluetooth/BluetoothDetailsHearingDeviceController.java
@@ -42,6 +42,7 @@
 
     public static final int ORDER_HEARING_DEVICE_SETTINGS = 1;
     public static final int ORDER_HEARING_AIDS_PRESETS = 2;
+    public static final int ORDER_AMBIENT_VOLUME = 4;
     static final String KEY_HEARING_DEVICE_GROUP = "hearing_device_group";
 
     private final List<BluetoothDetailsController> mControllers = new ArrayList<>();
@@ -107,6 +108,10 @@
             mControllers.add(new BluetoothDetailsHearingAidsPresetsController(mContext, mFragment,
                     mManager, mCachedDevice, mLifecycle));
         }
+        if (com.android.settingslib.flags.Flags.hearingDevicesAmbientVolumeControl()) {
+            mControllers.add(new BluetoothDetailsAmbientVolumePreferenceController(mContext,
+                    mManager, mFragment, mCachedDevice, mLifecycle));
+        }
     }
 
     @NonNull
diff --git a/tests/robotests/src/com/android/settings/bluetooth/AmbientVolumePreferenceTest.java b/tests/robotests/src/com/android/settings/bluetooth/AmbientVolumePreferenceTest.java
new file mode 100644
index 0000000..ec406c4
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/bluetooth/AmbientVolumePreferenceTest.java
@@ -0,0 +1,238 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.bluetooth;
+
+import static com.android.settings.bluetooth.AmbientVolumePreference.ROTATION_COLLAPSED;
+import static com.android.settings.bluetooth.AmbientVolumePreference.ROTATION_EXPANDED;
+import static com.android.settings.bluetooth.AmbientVolumePreference.SIDE_UNIFIED;
+import static com.android.settings.bluetooth.BluetoothDetailsAmbientVolumePreferenceController.KEY_AMBIENT_VOLUME;
+import static com.android.settings.bluetooth.BluetoothDetailsAmbientVolumePreferenceController.KEY_AMBIENT_VOLUME_SLIDER;
+import static com.android.settingslib.bluetooth.HearingAidInfo.DeviceSide.SIDE_LEFT;
+import static com.android.settingslib.bluetooth.HearingAidInfo.DeviceSide.SIDE_RIGHT;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+import android.util.ArrayMap;
+import android.view.View;
+import android.widget.ImageView;
+
+import androidx.preference.PreferenceManager;
+import androidx.preference.PreferenceScreen;
+import androidx.preference.PreferenceViewHolder;
+import androidx.test.core.app.ApplicationProvider;
+
+import com.android.settings.R;
+import com.android.settings.widget.SeekBarPreference;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.Spy;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
+import org.robolectric.RobolectricTestRunner;
+
+import java.util.Map;
+
+/** Tests for {@link AmbientVolumePreference}. */
+@RunWith(RobolectricTestRunner.class)
+public class AmbientVolumePreferenceTest {
+
+    private static final int TEST_LEFT_VOLUME_LEVEL = 1;
+    private static final int TEST_RIGHT_VOLUME_LEVEL = 2;
+    private static final int TEST_UNIFIED_VOLUME_LEVEL = 3;
+    private static final String KEY_UNIFIED_SLIDER = KEY_AMBIENT_VOLUME_SLIDER + "_" + SIDE_UNIFIED;
+    private static final String KEY_LEFT_SLIDER = KEY_AMBIENT_VOLUME_SLIDER + "_" + SIDE_LEFT;
+    private static final String KEY_RIGHT_SLIDER = KEY_AMBIENT_VOLUME_SLIDER + "_" + SIDE_RIGHT;
+
+    @Rule
+    public final MockitoRule mMockitoRule = MockitoJUnit.rule();
+    @Spy
+    private Context mContext = ApplicationProvider.getApplicationContext();
+    @Mock
+    private AmbientVolumePreference.OnIconClickListener mListener;
+    @Mock
+    private View mItemView;
+
+    private AmbientVolumePreference mPreference;
+    private ImageView mExpandIcon;
+    private ImageView mVolumeIcon;
+    private final Map<Integer, SeekBarPreference> mSideToSlidersMap = new ArrayMap<>();
+
+    @Before
+    public void setUp() {
+        PreferenceManager preferenceManager = new PreferenceManager(mContext);
+        PreferenceScreen preferenceScreen = preferenceManager.createPreferenceScreen(mContext);
+        mPreference = new AmbientVolumePreference(mContext);
+        mPreference.setKey(KEY_AMBIENT_VOLUME);
+        mPreference.setOnIconClickListener(mListener);
+        mPreference.setExpandable(true);
+        mPreference.setMutable(true);
+        preferenceScreen.addPreference(mPreference);
+
+        prepareSliders();
+        mPreference.setSliders(mSideToSlidersMap);
+
+        mExpandIcon = new ImageView(mContext);
+        mVolumeIcon = new ImageView(mContext);
+        mVolumeIcon.setImageResource(com.android.settingslib.R.drawable.ic_ambient_volume);
+        mVolumeIcon.setImageLevel(0);
+        when(mItemView.requireViewById(R.id.expand_icon)).thenReturn(mExpandIcon);
+        when(mItemView.requireViewById(com.android.internal.R.id.icon)).thenReturn(mVolumeIcon);
+        when(mItemView.requireViewById(R.id.icon_frame)).thenReturn(mVolumeIcon);
+
+        PreferenceViewHolder preferenceViewHolder = PreferenceViewHolder.createInstanceForTests(
+                mItemView);
+        mPreference.onBindViewHolder(preferenceViewHolder);
+    }
+
+    @Test
+    public void setExpandable_expandable_expandIconVisible() {
+        mPreference.setExpandable(true);
+
+        assertThat(mExpandIcon.getVisibility()).isEqualTo(View.VISIBLE);
+    }
+
+    @Test
+    public void setExpandable_notExpandable_expandIconGone() {
+        mPreference.setExpandable(false);
+
+        assertThat(mExpandIcon.getVisibility()).isEqualTo(View.GONE);
+    }
+
+    @Test
+    public void setExpanded_expanded_assertControlUiCorrect() {
+        mPreference.setExpanded(true);
+
+        assertControlUiCorrect();
+    }
+
+    @Test
+    public void setExpanded_notExpanded_assertControlUiCorrect() {
+        mPreference.setExpanded(false);
+
+        assertControlUiCorrect();
+    }
+
+    @Test
+    public void setMutable_mutable_clickOnMuteIconChangeMuteState() {
+        mPreference.setMutable(true);
+        mPreference.setMuted(false);
+
+        mVolumeIcon.callOnClick();
+
+        assertThat(mPreference.isMuted()).isTrue();
+    }
+
+    @Test
+    public void setMutable_notMutable_clickOnMuteIconWontChangeMuteState() {
+        mPreference.setMutable(false);
+        mPreference.setMuted(false);
+
+        mVolumeIcon.callOnClick();
+
+        assertThat(mPreference.isMuted()).isFalse();
+    }
+
+    @Test
+    public void updateLayout_mute_volumeIconIsCorrect() {
+        mPreference.setMuted(true);
+        mPreference.updateLayout();
+
+        assertThat(mVolumeIcon.getDrawable().getLevel()).isEqualTo(0);
+    }
+
+    @Test
+    public void updateLayout_unmuteAndExpanded_volumeIconIsCorrect() {
+        mPreference.setMuted(false);
+        mPreference.setExpanded(true);
+        mPreference.updateLayout();
+
+        int expectedLevel = calculateVolumeLevel(TEST_LEFT_VOLUME_LEVEL, TEST_RIGHT_VOLUME_LEVEL);
+        assertThat(mVolumeIcon.getDrawable().getLevel()).isEqualTo(expectedLevel);
+    }
+
+    @Test
+    public void updateLayout_unmuteAndNotExpanded_volumeIconIsCorrect() {
+        mPreference.setMuted(false);
+        mPreference.setExpanded(false);
+        mPreference.updateLayout();
+
+        int expectedLevel = calculateVolumeLevel(TEST_UNIFIED_VOLUME_LEVEL,
+                TEST_UNIFIED_VOLUME_LEVEL);
+        assertThat(mVolumeIcon.getDrawable().getLevel()).isEqualTo(expectedLevel);
+    }
+
+    @Test
+    public void setSliderEnabled_expandedAndLeftIsDisabled_volumeIconIcCorrect() {
+        mPreference.setExpanded(true);
+        mPreference.setSliderEnabled(SIDE_LEFT, false);
+
+        int expectedLevel = calculateVolumeLevel(0, TEST_RIGHT_VOLUME_LEVEL);
+        assertThat(mVolumeIcon.getDrawable().getLevel()).isEqualTo(expectedLevel);
+    }
+
+    @Test
+    public void setSliderValue_expandedAndLeftValueChanged_volumeIconIcCorrect() {
+        mPreference.setExpanded(true);
+        mPreference.setSliderValue(SIDE_LEFT, 4);
+
+        int expectedLevel = calculateVolumeLevel(4, TEST_RIGHT_VOLUME_LEVEL);
+        assertThat(mVolumeIcon.getDrawable().getLevel()).isEqualTo(expectedLevel);
+    }
+
+    private int calculateVolumeLevel(int left, int right) {
+        return left * 5 + right;
+    }
+
+    private void assertControlUiCorrect() {
+        final boolean expanded = mPreference.isExpanded();
+        assertThat(mSideToSlidersMap.get(SIDE_UNIFIED).isVisible()).isEqualTo(!expanded);
+        assertThat(mSideToSlidersMap.get(SIDE_LEFT).isVisible()).isEqualTo(expanded);
+        assertThat(mSideToSlidersMap.get(SIDE_RIGHT).isVisible()).isEqualTo(expanded);
+        final float rotation = expanded ? ROTATION_EXPANDED : ROTATION_COLLAPSED;
+        assertThat(mExpandIcon.getRotation()).isEqualTo(rotation);
+    }
+
+    private void prepareSliders() {
+        prepareSlider(SIDE_UNIFIED);
+        prepareSlider(SIDE_LEFT);
+        prepareSlider(SIDE_RIGHT);
+    }
+
+    private void prepareSlider(int side) {
+        SeekBarPreference slider = new SeekBarPreference(mContext);
+        slider.setMin(0);
+        slider.setMax(4);
+        if (side == SIDE_LEFT) {
+            slider.setKey(KEY_LEFT_SLIDER);
+            slider.setProgress(TEST_LEFT_VOLUME_LEVEL);
+        } else if (side == SIDE_RIGHT) {
+            slider.setKey(KEY_RIGHT_SLIDER);
+            slider.setProgress(TEST_RIGHT_VOLUME_LEVEL);
+        } else {
+            slider.setKey(KEY_UNIFIED_SLIDER);
+            slider.setProgress(TEST_UNIFIED_VOLUME_LEVEL);
+        }
+        mSideToSlidersMap.put(side, slider);
+    }
+}
diff --git a/tests/robotests/src/com/android/settings/bluetooth/BluetoothDetailsAmbientVolumePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/bluetooth/BluetoothDetailsAmbientVolumePreferenceControllerTest.java
new file mode 100644
index 0000000..975d3b4
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/bluetooth/BluetoothDetailsAmbientVolumePreferenceControllerTest.java
@@ -0,0 +1,434 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.bluetooth;
+
+import static android.bluetooth.AudioInputControl.MUTE_DISABLED;
+import static android.bluetooth.AudioInputControl.MUTE_NOT_MUTED;
+import static android.bluetooth.AudioInputControl.MUTE_MUTED;
+import static android.bluetooth.BluetoothDevice.BOND_BONDED;
+
+import static com.android.settings.bluetooth.BluetoothDetailsAmbientVolumePreferenceController.KEY_AMBIENT_VOLUME;
+import static com.android.settings.bluetooth.BluetoothDetailsAmbientVolumePreferenceController.KEY_AMBIENT_VOLUME_SLIDER;
+import static com.android.settings.bluetooth.BluetoothDetailsHearingDeviceController.KEY_HEARING_DEVICE_GROUP;
+import static com.android.settingslib.bluetooth.HearingAidInfo.DeviceSide.SIDE_LEFT;
+import static com.android.settingslib.bluetooth.HearingAidInfo.DeviceSide.SIDE_RIGHT;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyBoolean;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.anyLong;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.atLeastOnce;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+import static org.robolectric.Shadows.shadowOf;
+
+import android.bluetooth.BluetoothDevice;
+import android.bluetooth.BluetoothProfile;
+import android.content.ContentResolver;
+import android.os.Handler;
+import android.os.Looper;
+import android.provider.Settings;
+
+import androidx.preference.PreferenceCategory;
+
+import com.android.settings.testutils.shadow.ShadowThreadUtils;
+import com.android.settings.widget.SeekBarPreference;
+import com.android.settingslib.bluetooth.AmbientVolumeController;
+import com.android.settingslib.bluetooth.BluetoothEventManager;
+import com.android.settingslib.bluetooth.CachedBluetoothDevice;
+import com.android.settingslib.bluetooth.HearingDeviceLocalDataManager;
+import com.android.settingslib.bluetooth.LocalBluetoothManager;
+import com.android.settingslib.bluetooth.LocalBluetoothProfileManager;
+import com.android.settingslib.bluetooth.VolumeControlProfile;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.annotation.Config;
+import org.robolectric.annotation.Implementation;
+import org.robolectric.annotation.Implements;
+import org.robolectric.shadows.ShadowSettings;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.Executor;
+
+/** Tests for {@link BluetoothDetailsAmbientVolumePreferenceController}. */
+@RunWith(RobolectricTestRunner.class)
+@Config(shadows = {
+        BluetoothDetailsAmbientVolumePreferenceControllerTest.ShadowGlobal.class,
+        ShadowThreadUtils.class
+})
+public class BluetoothDetailsAmbientVolumePreferenceControllerTest extends
+        BluetoothDetailsControllerTestBase {
+
+    @Rule
+    public final MockitoRule mMockitoRule = MockitoJUnit.rule();
+
+    private static final String LEFT_CONTROL_KEY = KEY_AMBIENT_VOLUME_SLIDER + "_" + SIDE_LEFT;
+    private static final String RIGHT_CONTROL_KEY = KEY_AMBIENT_VOLUME_SLIDER + "_" + SIDE_RIGHT;
+    private static final String TEST_ADDRESS = "00:00:00:00:11";
+    private static final String TEST_MEMBER_ADDRESS = "00:00:00:00:22";
+
+    @Mock
+    private CachedBluetoothDevice mCachedMemberDevice;
+    @Mock
+    private BluetoothDevice mDevice;
+    @Mock
+    private BluetoothDevice mMemberDevice;
+    @Mock
+    private HearingDeviceLocalDataManager mLocalDataManager;
+    @Mock
+    private LocalBluetoothManager mBluetoothManager;
+    @Mock
+    private BluetoothEventManager mEventManager;
+    @Mock
+    private LocalBluetoothProfileManager mProfileManager;
+    @Mock
+    private VolumeControlProfile mVolumeControlProfile;
+    @Mock
+    private AmbientVolumeController mVolumeController;
+    @Mock
+    private Handler mTestHandler;
+
+    private BluetoothDetailsAmbientVolumePreferenceController mController;
+
+    @Before
+    public void setUp() {
+        super.setUp();
+
+        mContext = spy(mContext);
+        PreferenceCategory deviceControls = new PreferenceCategory(mContext);
+        deviceControls.setKey(KEY_HEARING_DEVICE_GROUP);
+        mScreen.addPreference(deviceControls);
+        mController = spy(
+                new BluetoothDetailsAmbientVolumePreferenceController(mContext, mBluetoothManager,
+                        mFragment, mCachedDevice, mLifecycle, mLocalDataManager,
+                        mVolumeController));
+
+        when(mBluetoothManager.getEventManager()).thenReturn(mEventManager);
+        when(mBluetoothManager.getProfileManager()).thenReturn(mProfileManager);
+        when(mProfileManager.getVolumeControlProfile()).thenReturn(mVolumeControlProfile);
+        when(mVolumeControlProfile.getConnectionStatus(mDevice)).thenReturn(
+                BluetoothProfile.STATE_CONNECTED);
+        when(mVolumeControlProfile.getConnectionStatus(mMemberDevice)).thenReturn(
+                BluetoothProfile.STATE_CONNECTED);
+        when(mCachedDevice.getProfiles()).thenReturn(List.of(mVolumeControlProfile));
+        when(mLocalDataManager.get(any(BluetoothDevice.class))).thenReturn(
+                new HearingDeviceLocalDataManager.Data.Builder().build());
+
+        when(mContext.getMainThreadHandler()).thenReturn(mTestHandler);
+        when(mTestHandler.postDelayed(any(Runnable.class), anyLong())).thenAnswer(
+                invocationOnMock -> {
+                    invocationOnMock.getArgument(0, Runnable.class).run();
+                    return null;
+                });
+    }
+
+    @Test
+    public void init_deviceWithoutMember_controlNotExpandable() {
+        prepareDevice(/* hasMember= */ false);
+
+        mController.init(mScreen);
+
+        AmbientVolumePreference preference = mScreen.findPreference(KEY_AMBIENT_VOLUME);
+        assertThat(preference).isNotNull();
+        assertThat(preference.isExpandable()).isFalse();
+    }
+
+    @Test
+    public void init_deviceWithMember_controlExpandable() {
+        prepareDevice(/* hasMember= */ true);
+
+        mController.init(mScreen);
+
+        AmbientVolumePreference preference = mScreen.findPreference(KEY_AMBIENT_VOLUME);
+        assertThat(preference).isNotNull();
+        assertThat(preference.isExpandable()).isTrue();
+    }
+
+    @Test
+    public void onDeviceLocalDataChange_noMemberAndExpanded_uiCorrectAndDataUpdated() {
+        prepareDevice(/* hasMember= */ false);
+        mController.init(mScreen);
+        HearingDeviceLocalDataManager.Data data = new HearingDeviceLocalDataManager.Data.Builder()
+                .ambient(0).groupAmbient(0).ambientControlExpanded(true).build();
+        when(mLocalDataManager.get(mDevice)).thenReturn(data);
+
+        mController.onDeviceLocalDataChange(TEST_ADDRESS, data);
+        shadowOf(Looper.getMainLooper()).idle();
+
+        AmbientVolumePreference preference = mScreen.findPreference(KEY_AMBIENT_VOLUME);
+        assertThat(preference).isNotNull();
+        assertThat(preference.isExpanded()).isFalse();
+        verifyDeviceDataUpdated(mDevice);
+    }
+
+    @Test
+    public void onDeviceLocalDataChange_noMemberAndCollapsed_uiCorrectAndDataUpdated() {
+        prepareDevice(/* hasMember= */ false);
+        mController.init(mScreen);
+        HearingDeviceLocalDataManager.Data data = new HearingDeviceLocalDataManager.Data.Builder()
+                .ambient(0).groupAmbient(0).ambientControlExpanded(false).build();
+        when(mLocalDataManager.get(mDevice)).thenReturn(data);
+
+        mController.onDeviceLocalDataChange(TEST_ADDRESS, data);
+        shadowOf(Looper.getMainLooper()).idle();
+
+        AmbientVolumePreference preference = mScreen.findPreference(KEY_AMBIENT_VOLUME);
+        assertThat(preference).isNotNull();
+        assertThat(preference.isExpanded()).isFalse();
+        verifyDeviceDataUpdated(mDevice);
+    }
+
+    @Test
+    public void onDeviceLocalDataChange_hasMemberAndExpanded_uiCorrectAndDataUpdated() {
+        prepareDevice(/* hasMember= */ true);
+        mController.init(mScreen);
+        HearingDeviceLocalDataManager.Data data = new HearingDeviceLocalDataManager.Data.Builder()
+                .ambient(0).groupAmbient(0).ambientControlExpanded(true).build();
+        when(mLocalDataManager.get(mDevice)).thenReturn(data);
+
+        mController.onDeviceLocalDataChange(TEST_ADDRESS, data);
+        shadowOf(Looper.getMainLooper()).idle();
+
+        AmbientVolumePreference preference = mScreen.findPreference(KEY_AMBIENT_VOLUME);
+        assertThat(preference).isNotNull();
+        assertThat(preference.isExpanded()).isTrue();
+        verifyDeviceDataUpdated(mDevice);
+    }
+
+    @Test
+    public void onDeviceLocalDataChange_hasMemberAndCollapsed_uiCorrectAndDataUpdated() {
+        prepareDevice(/* hasMember= */ true);
+        mController.init(mScreen);
+        HearingDeviceLocalDataManager.Data data = new HearingDeviceLocalDataManager.Data.Builder()
+                .ambient(0).groupAmbient(0).ambientControlExpanded(false).build();
+        when(mLocalDataManager.get(mDevice)).thenReturn(data);
+
+        mController.onDeviceLocalDataChange(TEST_ADDRESS, data);
+        shadowOf(Looper.getMainLooper()).idle();
+
+        AmbientVolumePreference preference = mScreen.findPreference(KEY_AMBIENT_VOLUME);
+        assertThat(preference).isNotNull();
+        assertThat(preference.isExpanded()).isFalse();
+        verifyDeviceDataUpdated(mDevice);
+    }
+
+    @Test
+    public void onStart_localDataManagerStartAndCallbackRegistered() {
+        prepareDevice(/* hasMember= */ true);
+        mController.init(mScreen);
+
+        mController.onStart();
+
+        verify(mLocalDataManager, atLeastOnce()).start();
+        verify(mVolumeController).registerCallback(any(Executor.class), eq(mDevice));
+        verify(mVolumeController).registerCallback(any(Executor.class), eq(mMemberDevice));
+        verify(mCachedDevice).registerCallback(any(Executor.class),
+                any(CachedBluetoothDevice.Callback.class));
+        verify(mCachedMemberDevice).registerCallback(any(Executor.class),
+                any(CachedBluetoothDevice.Callback.class));
+    }
+
+    @Test
+    public void onStop_localDataManagerStopAndCallbackUnregistered() {
+        prepareDevice(/* hasMember= */ true);
+        mController.init(mScreen);
+
+        mController.onStop();
+
+        verify(mLocalDataManager).stop();
+        verify(mVolumeController).unregisterCallback(mDevice);
+        verify(mVolumeController).unregisterCallback(mMemberDevice);
+        verify(mCachedDevice).unregisterCallback(any(CachedBluetoothDevice.Callback.class));
+        verify(mCachedMemberDevice).unregisterCallback(any(CachedBluetoothDevice.Callback.class));
+    }
+
+    @Test
+    public void onDeviceAttributesChanged_newDevice_newPreference() {
+        prepareDevice(/* hasMember= */ false);
+        mController.init(mScreen);
+
+        // check the right control is null before onDeviceAttributesChanged()
+        SeekBarPreference leftControl = mScreen.findPreference(LEFT_CONTROL_KEY);
+        SeekBarPreference rightControl = mScreen.findPreference(RIGHT_CONTROL_KEY);
+        assertThat(leftControl).isNotNull();
+        assertThat(rightControl).isNull();
+
+        prepareDevice(/* hasMember= */ true);
+        mController.onDeviceAttributesChanged();
+        shadowOf(Looper.getMainLooper()).idle();
+
+        // check the right control is created after onDeviceAttributesChanged()
+        SeekBarPreference updatedLeftControl = mScreen.findPreference(LEFT_CONTROL_KEY);
+        SeekBarPreference updatedRightControl = mScreen.findPreference(RIGHT_CONTROL_KEY);
+        assertThat(updatedLeftControl).isEqualTo(leftControl);
+        assertThat(updatedRightControl).isNotNull();
+    }
+
+    @Test
+    public void onAmbientChanged_refreshWhenNotInitiateFromUi() {
+        prepareDevice(/* hasMember= */ false);
+        mController.init(mScreen);
+        final int testAmbient = 10;
+        HearingDeviceLocalDataManager.Data data = new HearingDeviceLocalDataManager.Data.Builder()
+                .ambient(testAmbient)
+                .groupAmbient(testAmbient)
+                .ambientControlExpanded(false)
+                .build();
+        when(mLocalDataManager.get(mDevice)).thenReturn(data);
+        getPreference().setExpanded(true);
+
+        mController.onAmbientChanged(mDevice, testAmbient);
+        verify(mController, never()).refresh();
+
+        final int updatedTestAmbient = 20;
+        mController.onAmbientChanged(mDevice, updatedTestAmbient);
+        verify(mController).refresh();
+    }
+
+    @Test
+    public void onMuteChanged_refreshWhenNotInitiateFromUi() {
+        prepareDevice(/* hasMember= */ false);
+        mController.init(mScreen);
+        final int testMute = MUTE_NOT_MUTED;
+        AmbientVolumeController.RemoteAmbientState state =
+                new AmbientVolumeController.RemoteAmbientState(testMute, 0);
+        when(mVolumeController.refreshAmbientState(mDevice)).thenReturn(state);
+        getPreference().setMuted(false);
+
+        mController.onMuteChanged(mDevice, testMute);
+        verify(mController, never()).refresh();
+
+        final int updatedTestMute = MUTE_MUTED;
+        mController.onMuteChanged(mDevice, updatedTestMute);
+        verify(mController).refresh();
+    }
+
+    @Test
+    public void refresh_leftAndRightDifferentGainSetting_expandControl() {
+        prepareDevice(/* hasMember= */ true);
+        mController.init(mScreen);
+        prepareRemoteData(mDevice, 10, MUTE_NOT_MUTED);
+        prepareRemoteData(mMemberDevice, 20, MUTE_NOT_MUTED);
+        getPreference().setExpanded(false);
+
+        mController.refresh();
+
+        assertThat(getPreference().isExpanded()).isTrue();
+    }
+
+    @Test
+    public void refresh_oneSideNotMutable_controlNotMutableAndNotMuted() {
+        prepareDevice(/* hasMember= */ true);
+        mController.init(mScreen);
+        prepareRemoteData(mDevice, 10, MUTE_DISABLED);
+        prepareRemoteData(mMemberDevice, 20, MUTE_NOT_MUTED);
+        getPreference().setMutable(true);
+        getPreference().setMuted(true);
+
+        mController.refresh();
+
+        assertThat(getPreference().isMutable()).isFalse();
+        assertThat(getPreference().isMuted()).isFalse();
+    }
+
+    @Test
+    public void refresh_oneSideNotMuted_controlNotMutedAndSyncToRemote() {
+        prepareDevice(/* hasMember= */ true);
+        mController.init(mScreen);
+        prepareRemoteData(mDevice, 10, MUTE_MUTED);
+        prepareRemoteData(mMemberDevice, 20, MUTE_NOT_MUTED);
+        getPreference().setMutable(true);
+        getPreference().setMuted(true);
+
+        mController.refresh();
+
+        assertThat(getPreference().isMutable()).isTrue();
+        assertThat(getPreference().isMuted()).isFalse();
+        verify(mVolumeController).setMuted(mDevice, false);
+    }
+
+    private void prepareDevice(boolean hasMember) {
+        when(mCachedDevice.getDeviceSide()).thenReturn(SIDE_LEFT);
+        when(mCachedDevice.getDevice()).thenReturn(mDevice);
+        when(mCachedDevice.getBondState()).thenReturn(BOND_BONDED);
+        when(mDevice.getAddress()).thenReturn(TEST_ADDRESS);
+        when(mDevice.getAnonymizedAddress()).thenReturn(TEST_ADDRESS);
+        when(mDevice.isConnected()).thenReturn(true);
+        if (hasMember) {
+            when(mCachedDevice.getMemberDevice()).thenReturn(Set.of(mCachedMemberDevice));
+            when(mCachedMemberDevice.getDeviceSide()).thenReturn(SIDE_RIGHT);
+            when(mCachedMemberDevice.getDevice()).thenReturn(mMemberDevice);
+            when(mCachedMemberDevice.getBondState()).thenReturn(BOND_BONDED);
+            when(mMemberDevice.getAddress()).thenReturn(TEST_MEMBER_ADDRESS);
+            when(mMemberDevice.getAnonymizedAddress()).thenReturn(TEST_MEMBER_ADDRESS);
+            when(mMemberDevice.isConnected()).thenReturn(true);
+        }
+    }
+
+    private void prepareRemoteData(BluetoothDevice device, int gainSetting, int mute) {
+        when(mVolumeController.isAmbientControlAvailable(device)).thenReturn(true);
+        when(mVolumeController.refreshAmbientState(device)).thenReturn(
+                new AmbientVolumeController.RemoteAmbientState(gainSetting, mute));
+    }
+
+    private void verifyDeviceDataUpdated(BluetoothDevice device) {
+        verify(mLocalDataManager, atLeastOnce()).updateAmbient(eq(device), anyInt());
+        verify(mLocalDataManager, atLeastOnce()).updateGroupAmbient(eq(device), anyInt());
+        verify(mLocalDataManager, atLeastOnce()).updateAmbientControlExpanded(eq(device),
+                anyBoolean());
+    }
+
+    private AmbientVolumePreference getPreference() {
+        return mScreen.findPreference(KEY_AMBIENT_VOLUME);
+    }
+
+    @Implements(value = Settings.Global.class)
+    public static class ShadowGlobal extends ShadowSettings.ShadowGlobal {
+        private static final Map<ContentResolver, Map<String, String>> sDataMap = new HashMap<>();
+
+        @Implementation
+        protected static boolean putStringForUser(
+                ContentResolver cr, String name, String value, int userHandle) {
+            get(cr).put(name, value);
+            return true;
+        }
+
+        @Implementation
+        protected static String getStringForUser(ContentResolver cr, String name, int userHandle) {
+            return get(cr).get(name);
+        }
+
+        private static Map<String, String> get(ContentResolver cr) {
+            return sDataMap.computeIfAbsent(cr, k -> new HashMap<>());
+        }
+    }
+}
diff --git a/tests/robotests/src/com/android/settings/bluetooth/BluetoothDetailsHearingDeviceControllerTest.java b/tests/robotests/src/com/android/settings/bluetooth/BluetoothDetailsHearingDeviceControllerTest.java
index 2a50f89..4e3c742 100644
--- a/tests/robotests/src/com/android/settings/bluetooth/BluetoothDetailsHearingDeviceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/bluetooth/BluetoothDetailsHearingDeviceControllerTest.java
@@ -53,12 +53,12 @@
     @Mock
     private LocalBluetoothProfileManager mProfileManager;
     @Mock
-    private BluetoothDetailsHearingDeviceController mHearingDeviceController;
-    @Mock
     private BluetoothDetailsHearingAidsPresetsController mPresetsController;
     @Mock
     private BluetoothDetailsHearingDeviceSettingsController mHearingDeviceSettingsController;
 
+    private BluetoothDetailsHearingDeviceController mHearingDeviceController;
+
     @Override
     public void setUp() {
         super.setUp();
@@ -126,4 +126,24 @@
         assertThat(mHearingDeviceController.getSubControllers().stream().anyMatch(
                 c -> c instanceof BluetoothDetailsHearingAidsPresetsController)).isFalse();
     }
+
+    @Test
+    @RequiresFlagsEnabled(
+            com.android.settingslib.flags.Flags.FLAG_HEARING_DEVICES_AMBIENT_VOLUME_CONTROL)
+    public void initSubControllers_flagEnabled_ambientVolumeControllerExist() {
+        mHearingDeviceController.initSubControllers(false);
+
+        assertThat(mHearingDeviceController.getSubControllers().stream().anyMatch(
+                c -> c instanceof BluetoothDetailsAmbientVolumePreferenceController)).isTrue();
+    }
+
+    @Test
+    @RequiresFlagsDisabled(
+            com.android.settingslib.flags.Flags.FLAG_HEARING_DEVICES_AMBIENT_VOLUME_CONTROL)
+    public void initSubControllers_flagDisabled_ambientVolumeControllerNotExist() {
+        mHearingDeviceController.initSubControllers(false);
+
+        assertThat(mHearingDeviceController.getSubControllers().stream().anyMatch(
+                c -> c instanceof BluetoothDetailsAmbientVolumePreferenceController)).isFalse();
+    }
 }
