Fix dup preference key on Connected devices page

Use different key (prefix + CacheBluetooothDevice hash) for
each BluetoothDevicePreference to avoid Java crash due to "Two different
ViewHolders have the same change ID".

Test: atest
Fix: 325831741
Flag: EXEMPT safe fix only change preference key string
Change-Id: Ic993f3cab206b794045c2f46e6b4b376bfa3adea
This commit is contained in:
Yiyi Shen
2024-07-01 14:28:50 +08:00
parent 1d838f62ea
commit 07a346fcf5
11 changed files with 36 additions and 30 deletions

View File

@@ -27,7 +27,7 @@ import com.android.settingslib.bluetooth.CachedBluetoothDevice;
*/ */
public class AvailableHearingDeviceUpdater extends AvailableMediaBluetoothDeviceUpdater { public class AvailableHearingDeviceUpdater extends AvailableMediaBluetoothDeviceUpdater {
private static final String PREF_KEY = "connected_hearing_device"; private static final String PREF_KEY_PREFIX = "connected_hearing_device_";
public AvailableHearingDeviceUpdater(Context context, public AvailableHearingDeviceUpdater(Context context,
DevicePreferenceCallback devicePreferenceCallback, int metricsCategory) { DevicePreferenceCallback devicePreferenceCallback, int metricsCategory) {
@@ -42,7 +42,7 @@ public class AvailableHearingDeviceUpdater extends AvailableMediaBluetoothDevice
} }
@Override @Override
protected String getPreferenceKey() { protected String getPreferenceKeyPrefix() {
return PREF_KEY; return PREF_KEY_PREFIX;
} }
} }

View File

@@ -29,7 +29,7 @@ import com.android.settingslib.bluetooth.CachedBluetoothDevice;
*/ */
public class SavedHearingDeviceUpdater extends SavedBluetoothDeviceUpdater { public class SavedHearingDeviceUpdater extends SavedBluetoothDeviceUpdater {
private static final String PREF_KEY = "saved_hearing_device"; private static final String PREF_KEY_PREFIX = "saved_hearing_device_";
public SavedHearingDeviceUpdater(Context context, public SavedHearingDeviceUpdater(Context context,
DevicePreferenceCallback devicePreferenceCallback, int metricsCategory) { DevicePreferenceCallback devicePreferenceCallback, int metricsCategory) {
@@ -47,7 +47,7 @@ public class SavedHearingDeviceUpdater extends SavedBluetoothDeviceUpdater {
} }
@Override @Override
protected String getPreferenceKey() { protected String getPreferenceKeyPrefix() {
return PREF_KEY; return PREF_KEY_PREFIX;
} }
} }

View File

@@ -35,7 +35,7 @@ public class AvailableMediaBluetoothDeviceUpdater extends BluetoothDeviceUpdater
private static final String TAG = "AvailableMediaBluetoothDeviceUpdater"; private static final String TAG = "AvailableMediaBluetoothDeviceUpdater";
private static final boolean DBG = Log.isLoggable(BluetoothDeviceUpdater.TAG, Log.DEBUG); private static final boolean DBG = Log.isLoggable(BluetoothDeviceUpdater.TAG, Log.DEBUG);
private static final String PREF_KEY = "available_media_bt"; private static final String PREF_KEY_PREFIX = "available_media_bt_";
private final AudioManager mAudioManager; private final AudioManager mAudioManager;
private final LocalBluetoothManager mLocalBtManager; private final LocalBluetoothManager mLocalBtManager;
@@ -141,8 +141,8 @@ public class AvailableMediaBluetoothDeviceUpdater extends BluetoothDeviceUpdater
} }
@Override @Override
protected String getPreferenceKey() { protected String getPreferenceKeyPrefix() {
return PREF_KEY; return PREF_KEY_PREFIX;
} }
@Override @Override

View File

@@ -213,9 +213,9 @@ public abstract class BluetoothDeviceUpdater implements BluetoothCallback,
public abstract boolean isFilterMatched(CachedBluetoothDevice cachedBluetoothDevice); public abstract boolean isFilterMatched(CachedBluetoothDevice cachedBluetoothDevice);
/** /**
* Return a preference key for logging * Return a preference key prefix for logging
*/ */
protected abstract String getPreferenceKey(); protected abstract String getPreferenceKeyPrefix();
/** /**
* Update whether to show {@link CachedBluetoothDevice} in the list. * Update whether to show {@link CachedBluetoothDevice} in the list.
@@ -248,7 +248,7 @@ public abstract class BluetoothDeviceUpdater implements BluetoothCallback,
new BluetoothDevicePreference(mPrefContext, cachedDevice, new BluetoothDevicePreference(mPrefContext, cachedDevice,
true /* showDeviceWithoutNames */, true /* showDeviceWithoutNames */,
type); type);
btPreference.setKey(getPreferenceKey()); btPreference.setKey(getPreferenceKeyPrefix() + cachedDevice.hashCode());
btPreference.setOnGearClickListener(mDeviceProfilesListener); btPreference.setOnGearClickListener(mDeviceProfilesListener);
if (this instanceof Preference.OnPreferenceClickListener) { if (this instanceof Preference.OnPreferenceClickListener) {
btPreference.setOnPreferenceClickListener( btPreference.setOnPreferenceClickListener(

View File

@@ -36,7 +36,7 @@ public class ConnectedBluetoothDeviceUpdater extends BluetoothDeviceUpdater {
private static final String TAG = "ConnBluetoothDeviceUpdater"; private static final String TAG = "ConnBluetoothDeviceUpdater";
private static final boolean DBG = Log.isLoggable(BluetoothDeviceUpdater.TAG, Log.DEBUG); private static final boolean DBG = Log.isLoggable(BluetoothDeviceUpdater.TAG, Log.DEBUG);
private static final String PREF_KEY = "connected_bt"; private static final String PREF_KEY_PREFIX = "connected_bt_";
private final AudioManager mAudioManager; private final AudioManager mAudioManager;
@@ -126,8 +126,8 @@ public class ConnectedBluetoothDeviceUpdater extends BluetoothDeviceUpdater {
} }
@Override @Override
protected String getPreferenceKey() { protected String getPreferenceKeyPrefix() {
return PREF_KEY; return PREF_KEY_PREFIX;
} }
@Override @Override

View File

@@ -41,7 +41,7 @@ public class SavedBluetoothDeviceUpdater extends BluetoothDeviceUpdater
private static final String TAG = "SavedBluetoothDeviceUpdater"; private static final String TAG = "SavedBluetoothDeviceUpdater";
private static final String PREF_KEY = "saved_bt"; private static final String PREF_KEY_PREFIX = "saved_bt_";
private final boolean mShowConnectedDevice; private final boolean mShowConnectedDevice;
@@ -134,8 +134,8 @@ public class SavedBluetoothDeviceUpdater extends BluetoothDeviceUpdater
} }
@Override @Override
protected String getPreferenceKey() { protected String getPreferenceKeyPrefix() {
return PREF_KEY; return PREF_KEY_PREFIX;
} }
@Override @Override

View File

@@ -21,6 +21,7 @@ import android.content.Context;
import android.util.Log; import android.util.Log;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.annotation.VisibleForTesting;
import androidx.preference.Preference; import androidx.preference.Preference;
import com.android.settings.bluetooth.BluetoothDeviceUpdater; import com.android.settings.bluetooth.BluetoothDeviceUpdater;
@@ -35,7 +36,8 @@ public class AudioSharingBluetoothDeviceUpdater extends BluetoothDeviceUpdater
private static final String TAG = "AudioSharingBluetoothDeviceUpdater"; private static final String TAG = "AudioSharingBluetoothDeviceUpdater";
private static final String PREF_KEY = "audio_sharing_bt"; @VisibleForTesting
static final String PREF_KEY_PREFIX = "audio_sharing_bt_";
@Nullable private LocalBluetoothManager mLocalBtManager; @Nullable private LocalBluetoothManager mLocalBtManager;
@@ -76,8 +78,8 @@ public class AudioSharingBluetoothDeviceUpdater extends BluetoothDeviceUpdater
} }
@Override @Override
protected String getPreferenceKey() { protected String getPreferenceKeyPrefix() {
return PREF_KEY; return PREF_KEY_PREFIX;
} }
@Override @Override

View File

@@ -25,6 +25,7 @@ import android.util.Log;
import android.widget.SeekBar; import android.widget.SeekBar;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.annotation.VisibleForTesting;
import androidx.preference.Preference; import androidx.preference.Preference;
import com.android.settings.bluetooth.BluetoothDevicePreference; import com.android.settings.bluetooth.BluetoothDevicePreference;
@@ -41,7 +42,8 @@ public class AudioSharingDeviceVolumeControlUpdater extends BluetoothDeviceUpdat
private static final String TAG = "AudioSharingDeviceVolumeControlUpdater"; private static final String TAG = "AudioSharingDeviceVolumeControlUpdater";
private static final String PREF_KEY = "audio_sharing_volume_control"; @VisibleForTesting
static final String PREF_KEY_PREFIX = "audio_sharing_volume_control_";
@Nullable private final LocalBluetoothManager mBtManager; @Nullable private final LocalBluetoothManager mBtManager;
@Nullable private final VolumeControlProfile mVolumeControl; @Nullable private final VolumeControlProfile mVolumeControl;
@@ -119,7 +121,7 @@ public class AudioSharingDeviceVolumeControlUpdater extends BluetoothDeviceUpdat
new AudioSharingDeviceVolumePreference(mPrefContext, cachedDevice); new AudioSharingDeviceVolumePreference(mPrefContext, cachedDevice);
vPreference.initialize(); vPreference.initialize();
vPreference.setOnSeekBarChangeListener(listener); vPreference.setOnSeekBarChangeListener(listener);
vPreference.setKey(getPreferenceKey()); vPreference.setKey(getPreferenceKeyPrefix() + cachedDevice.hashCode());
vPreference.setIcon(com.android.settingslib.R.drawable.ic_bt_untethered_earbuds); vPreference.setIcon(com.android.settingslib.R.drawable.ic_bt_untethered_earbuds);
vPreference.setTitle(cachedDevice.getName()); vPreference.setTitle(cachedDevice.getName());
mPreferenceMap.put(device, vPreference); mPreferenceMap.put(device, vPreference);
@@ -128,8 +130,8 @@ public class AudioSharingDeviceVolumeControlUpdater extends BluetoothDeviceUpdat
} }
@Override @Override
protected String getPreferenceKey() { protected String getPreferenceKeyPrefix() {
return PREF_KEY; return PREF_KEY_PREFIX;
} }
@Override @Override

View File

@@ -275,7 +275,7 @@ public class BluetoothDeviceUpdaterTest {
} }
@Override @Override
protected String getPreferenceKey() { protected String getPreferenceKeyPrefix() {
return "test_bt"; return "test_bt";
} }
} }

View File

@@ -16,6 +16,8 @@
package com.android.settings.connecteddevice.audiosharing; package com.android.settings.connecteddevice.audiosharing;
import static com.android.settings.connecteddevice.audiosharing.AudioSharingBluetoothDeviceUpdater.PREF_KEY_PREFIX;
import static com.google.common.truth.Truth.assertThat; import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.any;
@@ -85,7 +87,6 @@ import java.util.List;
public class AudioSharingBluetoothDeviceUpdaterTest { public class AudioSharingBluetoothDeviceUpdaterTest {
private static final String MAC_ADDRESS = "04:52:C7:0B:D8:3C"; private static final String MAC_ADDRESS = "04:52:C7:0B:D8:3C";
private static final String TEST_DEVICE_NAME = "test"; private static final String TEST_DEVICE_NAME = "test";
private static final String PREF_KEY = "audio_sharing_bt";
private static final String TAG = "AudioSharingBluetoothDeviceUpdater"; private static final String TAG = "AudioSharingBluetoothDeviceUpdater";
@Rule public final MockitoRule mMockitoRule = MockitoJUnit.rule(); @Rule public final MockitoRule mMockitoRule = MockitoJUnit.rule();
@@ -263,7 +264,7 @@ public class AudioSharingBluetoothDeviceUpdaterTest {
@Test @Test
public void getPreferenceKey_returnsCorrectKey() { public void getPreferenceKey_returnsCorrectKey() {
assertThat(mDeviceUpdater.getPreferenceKey()).isEqualTo(PREF_KEY); assertThat(mDeviceUpdater.getPreferenceKeyPrefix()).isEqualTo(PREF_KEY_PREFIX);
} }
@Test @Test

View File

@@ -16,6 +16,8 @@
package com.android.settings.connecteddevice.audiosharing; package com.android.settings.connecteddevice.audiosharing;
import static com.android.settings.connecteddevice.audiosharing.AudioSharingDeviceVolumeControlUpdater.PREF_KEY_PREFIX;
import static com.google.common.truth.Truth.assertThat; import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.any;
@@ -79,7 +81,6 @@ import java.util.List;
public class AudioSharingDeviceVolumeControlUpdaterTest { public class AudioSharingDeviceVolumeControlUpdaterTest {
private static final String TEST_DEVICE_NAME = "test"; private static final String TEST_DEVICE_NAME = "test";
private static final String TAG = "AudioSharingDeviceVolumeControlUpdater"; private static final String TAG = "AudioSharingDeviceVolumeControlUpdater";
private static final String PREF_KEY = "audio_sharing_volume_control";
private static final String TEST_SETTINGS_KEY = private static final String TEST_SETTINGS_KEY =
"bluetooth_le_broadcast_fallback_active_group_id"; "bluetooth_le_broadcast_fallback_active_group_id";
private static final int TEST_DEVICE_GROUP_ID = 1; private static final int TEST_DEVICE_GROUP_ID = 1;
@@ -326,7 +327,7 @@ public class AudioSharingDeviceVolumeControlUpdaterTest {
@Test @Test
public void getPreferenceKey_returnsCorrectKey() { public void getPreferenceKey_returnsCorrectKey() {
assertThat(mDeviceUpdater.getPreferenceKey()).isEqualTo(PREF_KEY); assertThat(mDeviceUpdater.getPreferenceKeyPrefix()).isEqualTo(PREF_KEY_PREFIX);
} }
@Test @Test