Loading src/com/android/settings/bluetooth/BluetoothDeviceUpdater.java +5 −2 Original line number Diff line number Diff line Loading @@ -277,7 +277,10 @@ public abstract class BluetoothDeviceUpdater implements BluetoothCallback, } } private void removePreference(BluetoothDevice device) { /** * Remove the {@link Preference} that represents the {@code device} */ protected void removePreference(BluetoothDevice device) { if (mPreferenceMap.containsKey(device)) { if (mPreferenceMap.get(device) instanceof BluetoothDevicePreference preference) { BluetoothDevice prefDevice = preference.getBluetoothDevice().getDevice(); Loading Loading @@ -362,7 +365,7 @@ public abstract class BluetoothDeviceUpdater implements BluetoothCallback, return mLocalManager.getCachedDeviceManager().getCachedDevicesCopy().contains(cachedDevice); } private boolean isDeviceOfMapInCachedDevicesList(BluetoothDevice inputBluetoothDevice) { protected boolean isDeviceOfMapInCachedDevicesList(BluetoothDevice inputBluetoothDevice) { Collection<CachedBluetoothDevice> cachedDevices = mLocalManager.getCachedDeviceManager().getCachedDevicesCopy(); if (cachedDevices == null || cachedDevices.isEmpty()) { Loading src/com/android/settings/connecteddevice/audiosharing/AudioSharingDeviceVolumeControlUpdater.java +34 −9 Original line number Diff line number Diff line Loading @@ -31,7 +31,6 @@ import com.android.settings.connecteddevice.DevicePreferenceCallback; import com.android.settingslib.bluetooth.BluetoothUtils; import com.android.settingslib.bluetooth.CachedBluetoothDevice; import com.android.settingslib.bluetooth.LocalBluetoothManager; import com.android.settingslib.bluetooth.VolumeControlProfile; public class AudioSharingDeviceVolumeControlUpdater extends BluetoothDeviceUpdater implements Preference.OnPreferenceClickListener { Loading @@ -42,7 +41,6 @@ public class AudioSharingDeviceVolumeControlUpdater extends BluetoothDeviceUpdat static final String PREF_KEY_PREFIX = "audio_sharing_volume_control_"; @Nullable private final LocalBluetoothManager mBtManager; @Nullable private final VolumeControlProfile mVolumeControl; public AudioSharingDeviceVolumeControlUpdater( Context context, Loading @@ -50,10 +48,6 @@ public class AudioSharingDeviceVolumeControlUpdater extends BluetoothDeviceUpdat int metricsCategory) { super(context, devicePreferenceCallback, metricsCategory); mBtManager = Utils.getLocalBluetoothManager(context); mVolumeControl = mBtManager == null ? null : mBtManager.getProfileManager().getVolumeControlProfile(); } @Override Loading Loading @@ -99,6 +93,40 @@ public class AudioSharingDeviceVolumeControlUpdater extends BluetoothDeviceUpdat } } @Override public void refreshPreference() { mPreferenceMap.forEach((key, preference) -> { if (isDeviceOfMapInCachedDevicesList(key)) { ((AudioSharingDeviceVolumePreference) preference).onPreferenceAttributesChanged(); } else { // Remove staled preference. Log.d(TAG, "removePreference key: " + key.getAnonymizedAddress()); removePreference(key); } }); } @Override protected void removePreference(BluetoothDevice device) { if (mPreferenceMap.containsKey(device)) { if (mPreferenceMap.get(device) instanceof AudioSharingDeviceVolumePreference pref) { BluetoothDevice prefDevice = pref.getCachedDevice().getDevice(); // For CSIP device, when it {@link CachedBluetoothDevice}#switchMemberDeviceContent, // it will change its mDevice and lead to the hashcode change for this preference. // This will cause unintended remove preference, see b/394765052 if (device.equals(prefDevice) || !mPreferenceMap.containsKey(prefDevice)) { mDevicePreferenceCallback.onDeviceRemoved(pref); } else { Log.w(TAG, "Inconsistent key and preference when removePreference"); } mPreferenceMap.remove(device); } else { mDevicePreferenceCallback.onDeviceRemoved(mPreferenceMap.get(device)); mPreferenceMap.remove(device); } } } @Override protected String getPreferenceKeyPrefix() { return PREF_KEY_PREFIX; Loading @@ -121,7 +149,4 @@ public class AudioSharingDeviceVolumeControlUpdater extends BluetoothDeviceUpdat @Override protected void launchDeviceDetails(Preference preference) {} @Override public void refreshPreference() {} } src/com/android/settings/connecteddevice/audiosharing/AudioSharingDeviceVolumeGroupController.java +1 −0 Original line number Diff line number Diff line Loading @@ -368,6 +368,7 @@ public class AudioSharingDeviceVolumeGroupController extends AudioSharingBasePre mAssistant.registerServiceCallBack(mExecutor, mBroadcastAssistantCallback); mVolumeControl.registerCallback(mExecutor, mVolumeControlCallback); mBluetoothDeviceUpdater.registerCallback(); mBluetoothDeviceUpdater.refreshPreference(); mContentResolver.registerContentObserver( Settings.Secure.getUriFor(BluetoothUtils.getPrimaryGroupIdUriForBroadcast()), false, Loading src/com/android/settings/connecteddevice/audiosharing/AudioSharingDeviceVolumePreference.java +33 −0 Original line number Diff line number Diff line Loading @@ -104,6 +104,39 @@ public class AudioSharingDeviceVolumePreference extends SeekBarPreference { handleProgressChange(seekBar.getProgress()); } @Override public boolean equals(@Nullable Object o) { if ((o == null) || !(o instanceof AudioSharingDeviceVolumePreference)) { return false; } return mCachedDevice.equals( ((AudioSharingDeviceVolumePreference) o).mCachedDevice); } @Override public int hashCode() { return mCachedDevice.hashCode(); } @Override @NonNull public String toString() { StringBuilder builder = new StringBuilder("Preference{"); builder.append("preference=").append(super.toString()); if (mCachedDevice.getDevice() != null) { builder.append(", device=").append(mCachedDevice.getDevice().getAnonymizedAddress()); } builder.append("}"); return builder.toString(); } void onPreferenceAttributesChanged() { var unused = ThreadUtils.postOnBackgroundThread(() -> { String name = mCachedDevice.getName(); AudioSharingUtils.postOnMainThread(mContext, () -> setTitle(name)); }); } private void handleProgressChange(int progress) { var unused = ThreadUtils.postOnBackgroundThread( Loading tests/robotests/src/com/android/settings/bluetooth/AvailableMediaBluetoothDeviceUpdaterTest.java +3 −2 Original line number Diff line number Diff line Loading @@ -518,6 +518,7 @@ public class AvailableMediaBluetoothDeviceUpdaterTest { mContext, mDevicePreferenceCallback, /* metricsCategory= */ 0)); mBluetoothDeviceUpdater.setPrefContext(mContext); doNothing().when(mBluetoothDeviceUpdater).addPreference(any()); doNothing().when(mBluetoothDeviceUpdater).removePreference(any()); doNothing().when(mBluetoothDeviceUpdater).removePreference( any(CachedBluetoothDevice.class)); } } Loading
src/com/android/settings/bluetooth/BluetoothDeviceUpdater.java +5 −2 Original line number Diff line number Diff line Loading @@ -277,7 +277,10 @@ public abstract class BluetoothDeviceUpdater implements BluetoothCallback, } } private void removePreference(BluetoothDevice device) { /** * Remove the {@link Preference} that represents the {@code device} */ protected void removePreference(BluetoothDevice device) { if (mPreferenceMap.containsKey(device)) { if (mPreferenceMap.get(device) instanceof BluetoothDevicePreference preference) { BluetoothDevice prefDevice = preference.getBluetoothDevice().getDevice(); Loading Loading @@ -362,7 +365,7 @@ public abstract class BluetoothDeviceUpdater implements BluetoothCallback, return mLocalManager.getCachedDeviceManager().getCachedDevicesCopy().contains(cachedDevice); } private boolean isDeviceOfMapInCachedDevicesList(BluetoothDevice inputBluetoothDevice) { protected boolean isDeviceOfMapInCachedDevicesList(BluetoothDevice inputBluetoothDevice) { Collection<CachedBluetoothDevice> cachedDevices = mLocalManager.getCachedDeviceManager().getCachedDevicesCopy(); if (cachedDevices == null || cachedDevices.isEmpty()) { Loading
src/com/android/settings/connecteddevice/audiosharing/AudioSharingDeviceVolumeControlUpdater.java +34 −9 Original line number Diff line number Diff line Loading @@ -31,7 +31,6 @@ import com.android.settings.connecteddevice.DevicePreferenceCallback; import com.android.settingslib.bluetooth.BluetoothUtils; import com.android.settingslib.bluetooth.CachedBluetoothDevice; import com.android.settingslib.bluetooth.LocalBluetoothManager; import com.android.settingslib.bluetooth.VolumeControlProfile; public class AudioSharingDeviceVolumeControlUpdater extends BluetoothDeviceUpdater implements Preference.OnPreferenceClickListener { Loading @@ -42,7 +41,6 @@ public class AudioSharingDeviceVolumeControlUpdater extends BluetoothDeviceUpdat static final String PREF_KEY_PREFIX = "audio_sharing_volume_control_"; @Nullable private final LocalBluetoothManager mBtManager; @Nullable private final VolumeControlProfile mVolumeControl; public AudioSharingDeviceVolumeControlUpdater( Context context, Loading @@ -50,10 +48,6 @@ public class AudioSharingDeviceVolumeControlUpdater extends BluetoothDeviceUpdat int metricsCategory) { super(context, devicePreferenceCallback, metricsCategory); mBtManager = Utils.getLocalBluetoothManager(context); mVolumeControl = mBtManager == null ? null : mBtManager.getProfileManager().getVolumeControlProfile(); } @Override Loading Loading @@ -99,6 +93,40 @@ public class AudioSharingDeviceVolumeControlUpdater extends BluetoothDeviceUpdat } } @Override public void refreshPreference() { mPreferenceMap.forEach((key, preference) -> { if (isDeviceOfMapInCachedDevicesList(key)) { ((AudioSharingDeviceVolumePreference) preference).onPreferenceAttributesChanged(); } else { // Remove staled preference. Log.d(TAG, "removePreference key: " + key.getAnonymizedAddress()); removePreference(key); } }); } @Override protected void removePreference(BluetoothDevice device) { if (mPreferenceMap.containsKey(device)) { if (mPreferenceMap.get(device) instanceof AudioSharingDeviceVolumePreference pref) { BluetoothDevice prefDevice = pref.getCachedDevice().getDevice(); // For CSIP device, when it {@link CachedBluetoothDevice}#switchMemberDeviceContent, // it will change its mDevice and lead to the hashcode change for this preference. // This will cause unintended remove preference, see b/394765052 if (device.equals(prefDevice) || !mPreferenceMap.containsKey(prefDevice)) { mDevicePreferenceCallback.onDeviceRemoved(pref); } else { Log.w(TAG, "Inconsistent key and preference when removePreference"); } mPreferenceMap.remove(device); } else { mDevicePreferenceCallback.onDeviceRemoved(mPreferenceMap.get(device)); mPreferenceMap.remove(device); } } } @Override protected String getPreferenceKeyPrefix() { return PREF_KEY_PREFIX; Loading @@ -121,7 +149,4 @@ public class AudioSharingDeviceVolumeControlUpdater extends BluetoothDeviceUpdat @Override protected void launchDeviceDetails(Preference preference) {} @Override public void refreshPreference() {} }
src/com/android/settings/connecteddevice/audiosharing/AudioSharingDeviceVolumeGroupController.java +1 −0 Original line number Diff line number Diff line Loading @@ -368,6 +368,7 @@ public class AudioSharingDeviceVolumeGroupController extends AudioSharingBasePre mAssistant.registerServiceCallBack(mExecutor, mBroadcastAssistantCallback); mVolumeControl.registerCallback(mExecutor, mVolumeControlCallback); mBluetoothDeviceUpdater.registerCallback(); mBluetoothDeviceUpdater.refreshPreference(); mContentResolver.registerContentObserver( Settings.Secure.getUriFor(BluetoothUtils.getPrimaryGroupIdUriForBroadcast()), false, Loading
src/com/android/settings/connecteddevice/audiosharing/AudioSharingDeviceVolumePreference.java +33 −0 Original line number Diff line number Diff line Loading @@ -104,6 +104,39 @@ public class AudioSharingDeviceVolumePreference extends SeekBarPreference { handleProgressChange(seekBar.getProgress()); } @Override public boolean equals(@Nullable Object o) { if ((o == null) || !(o instanceof AudioSharingDeviceVolumePreference)) { return false; } return mCachedDevice.equals( ((AudioSharingDeviceVolumePreference) o).mCachedDevice); } @Override public int hashCode() { return mCachedDevice.hashCode(); } @Override @NonNull public String toString() { StringBuilder builder = new StringBuilder("Preference{"); builder.append("preference=").append(super.toString()); if (mCachedDevice.getDevice() != null) { builder.append(", device=").append(mCachedDevice.getDevice().getAnonymizedAddress()); } builder.append("}"); return builder.toString(); } void onPreferenceAttributesChanged() { var unused = ThreadUtils.postOnBackgroundThread(() -> { String name = mCachedDevice.getName(); AudioSharingUtils.postOnMainThread(mContext, () -> setTitle(name)); }); } private void handleProgressChange(int progress) { var unused = ThreadUtils.postOnBackgroundThread( Loading
tests/robotests/src/com/android/settings/bluetooth/AvailableMediaBluetoothDeviceUpdaterTest.java +3 −2 Original line number Diff line number Diff line Loading @@ -518,6 +518,7 @@ public class AvailableMediaBluetoothDeviceUpdaterTest { mContext, mDevicePreferenceCallback, /* metricsCategory= */ 0)); mBluetoothDeviceUpdater.setPrefContext(mContext); doNothing().when(mBluetoothDeviceUpdater).addPreference(any()); doNothing().when(mBluetoothDeviceUpdater).removePreference(any()); doNothing().when(mBluetoothDeviceUpdater).removePreference( any(CachedBluetoothDevice.class)); } }