mSideToSliderMap = new ArrayMap<>();
+ /**
+ * Ambient volume level for hearing device ambient control icon
+ *
+ * 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.
+ *
+ * To represent the combined left/right levels with a single value, the following calculation
+ * is used:
+ * finalLevel = (leftLevel * 5) + rightLevel
+ * For example:
+ *
+ * - If left level is 2 and right level is 3, the final level will be 13 (2 * 5 + 3)
+ * - If both left and right levels are 0, the final level will be 0
+ * - If both left and right levels are 4, the final level will be 24
+ *
+ */
+ private int mVolumeLevel = AMBIENT_VOLUME_LEVEL_DEFAULT;
+
public AmbientVolumePreference(@NonNull Context context) {
super(context, null);
setLayoutResource(R.layout.preference_ambient_volume);
@@ -79,6 +113,21 @@ public class AmbientVolumePreference extends PreferenceGroup {
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);
@@ -114,6 +163,36 @@ public class AmbientVolumePreference extends PreferenceGroup {
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;
}
@@ -140,6 +219,7 @@ public class AmbientVolumePreference extends PreferenceGroup {
SeekBarPreference slider = mSideToSliderMap.get(side);
if (slider != null && slider.getProgress() != value) {
slider.setProgress(value);
+ updateVolumeLevel();
}
}
@@ -162,6 +242,34 @@ public class AmbientVolumePreference extends PreferenceGroup {
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() {
@@ -179,4 +287,21 @@ public class AmbientVolumePreference extends PreferenceGroup {
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
index 887c220c99f..f237ffe50c3 100644
--- a/src/com/android/settings/bluetooth/BluetoothDetailsAmbientVolumePreferenceController.java
+++ b/src/com/android/settings/bluetooth/BluetoothDetailsAmbientVolumePreferenceController.java
@@ -16,6 +16,8 @@
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;
@@ -180,9 +182,8 @@ public class BluetoothDetailsAmbientVolumePreferenceController extends
@Override
public boolean isAvailable() {
- boolean isDeviceSupportVcp = mCachedDevice.getProfiles().stream().anyMatch(
+ return mCachedDevice.getProfiles().stream().anyMatch(
profile -> profile instanceof VolumeControlProfile);
- return isDeviceSupportVcp;
}
@Nullable
@@ -200,11 +201,30 @@ public class BluetoothDetailsAmbientVolumePreferenceController extends
}
setVolumeIfValid(side, value);
- if (side == SIDE_UNIFIED) {
- mSideToDeviceMap.forEach((s, d) -> mVolumeController.setAmbient(d, 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 {
- final BluetoothDevice device = mSideToDeviceMap.get(side);
- mVolumeController.setAmbient(device, value);
+ setAmbientRunnable.run();
}
return true;
}
@@ -284,6 +304,24 @@ public class BluetoothDetailsAmbientVolumePreferenceController extends
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);
@@ -324,17 +362,33 @@ public class BluetoothDetailsAmbientVolumePreferenceController extends
mPreference = new AmbientVolumePreference(mDeviceControls.getContext());
mPreference.setKey(KEY_AMBIENT_VOLUME);
mPreference.setOrder(ORDER_AMBIENT_VOLUME);
- mPreference.setOnIconClickListener(() -> {
- mSideToDeviceMap.forEach((s, d) -> {
- // 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());
- });
- });
+ 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);
}
@@ -406,7 +460,7 @@ public class BluetoothDetailsAmbientVolumePreferenceController extends
Log.d(TAG, "loadLocalDataToUi, data=" + data + ", device=" + device);
}
final int side = mSideToDeviceMap.inverse().getOrDefault(device, SIDE_INVALID);
- if (isDeviceConnectedToVcp(device)) {
+ if (isDeviceConnectedToVcp(device) && !isControlMuted()) {
setVolumeIfValid(side, data.ambient());
setVolumeIfValid(SIDE_UNIFIED, data.groupAmbient());
}
@@ -456,6 +510,26 @@ public class BluetoothDetailsAmbientVolumePreferenceController extends
// 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();
}
@@ -488,6 +562,10 @@ public class BluetoothDetailsAmbientVolumePreferenceController extends
});
}
+ private boolean isControlMuted() {
+ return mPreference != null && mPreference.isMuted();
+ }
+
private void initLocalDataIfNeeded() {
int smallerVolumeAmongGroup = Integer.MAX_VALUE;
for (BluetoothDevice device : mSideToDeviceMap.values()) {
@@ -510,6 +588,15 @@ public class BluetoothDetailsAmbientVolumePreferenceController extends
}
}
+ 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()
diff --git a/tests/robotests/src/com/android/settings/bluetooth/AmbientVolumePreferenceTest.java b/tests/robotests/src/com/android/settings/bluetooth/AmbientVolumePreferenceTest.java
index 75f3c9a1180..ec406c45503 100644
--- a/tests/robotests/src/com/android/settings/bluetooth/AmbientVolumePreferenceTest.java
+++ b/tests/robotests/src/com/android/settings/bluetooth/AmbientVolumePreferenceTest.java
@@ -57,6 +57,9 @@ import java.util.Map;
@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;
@@ -72,6 +75,7 @@ public class AmbientVolumePreferenceTest {
private AmbientVolumePreference mPreference;
private ImageView mExpandIcon;
+ private ImageView mVolumeIcon;
private final Map mSideToSlidersMap = new ArrayMap<>();
@Before
@@ -82,13 +86,19 @@ public class AmbientVolumePreferenceTest {
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);
@@ -123,6 +133,77 @@ public class AmbientVolumePreferenceTest {
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);
@@ -140,12 +221,17 @@ public class AmbientVolumePreferenceTest {
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
index b7aaab4527a..975d3b491aa 100644
--- a/tests/robotests/src/com/android/settings/bluetooth/BluetoothDetailsAmbientVolumePreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/bluetooth/BluetoothDetailsAmbientVolumePreferenceControllerTest.java
@@ -16,6 +16,9 @@
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;
@@ -71,6 +74,7 @@ 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;
@@ -135,6 +139,9 @@ public class BluetoothDetailsAmbientVolumePreferenceControllerTest extends
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(
@@ -307,6 +314,68 @@ public class BluetoothDetailsAmbientVolumePreferenceControllerTest extends
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);
@@ -325,6 +394,12 @@ public class BluetoothDetailsAmbientVolumePreferenceControllerTest extends
}
}
+ 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());