diff --git a/src/com/android/settings/bluetooth/BluetoothPairingDetail.java b/src/com/android/settings/bluetooth/BluetoothPairingDetail.java index 45da8f31256..2e0e9b5c2ff 100644 --- a/src/com/android/settings/bluetooth/BluetoothPairingDetail.java +++ b/src/com/android/settings/bluetooth/BluetoothPairingDetail.java @@ -29,9 +29,9 @@ import android.widget.Toast; import androidx.annotation.VisibleForTesting; import com.android.settings.R; -import com.android.settingslib.search.Indexable; import com.android.settingslib.bluetooth.BluetoothDeviceFilter; import com.android.settingslib.bluetooth.CachedBluetoothDevice; +import com.android.settingslib.search.Indexable; import com.android.settingslib.widget.FooterPreference; /** @@ -191,12 +191,19 @@ public class BluetoothPairingDetail extends DeviceListPreferenceFragment impleme } @Override - public void onConnectionStateChanged(CachedBluetoothDevice cachedDevice, int state) { - if (mSelectedDevice != null) { - BluetoothDevice device = cachedDevice.getDevice(); - if (device != null && mSelectedDevice.equals(device) - && state == BluetoothAdapter.STATE_CONNECTED) { + public void onProfileConnectionStateChanged(CachedBluetoothDevice cachedDevice, int state, + int bluetoothProfile) { + // This callback is used to handle the case that bonded device is connected in pairing list. + // 1. If user selected multiple bonded devices in pairing list, after connected + // finish this page. + // 2. If the bonded devices auto connected in paring list, after connected it will be + // removed from paring list. + if (cachedDevice != null && cachedDevice.isConnected()) { + final BluetoothDevice device = cachedDevice.getDevice(); + if (device != null && mSelectedList.contains(device)) { finish(); + } else if (mDevicePreferenceMap.containsKey(cachedDevice)) { + onDeviceDeleted(cachedDevice); } } } diff --git a/src/com/android/settings/bluetooth/DeviceListPreferenceFragment.java b/src/com/android/settings/bluetooth/DeviceListPreferenceFragment.java index 8a286e411ca..1ad322aab97 100644 --- a/src/com/android/settings/bluetooth/DeviceListPreferenceFragment.java +++ b/src/com/android/settings/bluetooth/DeviceListPreferenceFragment.java @@ -35,9 +35,10 @@ import com.android.settingslib.bluetooth.BluetoothDeviceFilter; import com.android.settingslib.bluetooth.CachedBluetoothDevice; import com.android.settingslib.bluetooth.LocalBluetoothManager; +import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; -import java.util.WeakHashMap; +import java.util.List; /** * Parent class for settings fragments that contain a list of Bluetooth @@ -72,6 +73,7 @@ public abstract class DeviceListPreferenceFragment extends final HashMap mDevicePreferenceMap = new HashMap<>(); + final List mSelectedList = new ArrayList<>(); boolean mShowDevicesWithoutNames; @@ -154,6 +156,7 @@ public abstract class DeviceListPreferenceFragment extends BluetoothDevicePreference btPreference = (BluetoothDevicePreference) preference; CachedBluetoothDevice device = btPreference.getCachedDevice(); mSelectedDevice = device.getDevice(); + mSelectedList.add(mSelectedDevice); onDevicePreferenceClick(btPreference); return true; } diff --git a/tests/robotests/src/com/android/settings/bluetooth/BluetoothPairingDetailTest.java b/tests/robotests/src/com/android/settings/bluetooth/BluetoothPairingDetailTest.java index ac89b5b0027..34bb069f6e8 100644 --- a/tests/robotests/src/com/android/settings/bluetooth/BluetoothPairingDetailTest.java +++ b/tests/robotests/src/com/android/settings/bluetooth/BluetoothPairingDetailTest.java @@ -23,13 +23,16 @@ import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothDevice; +import android.bluetooth.BluetoothProfile; import android.content.Context; import android.content.res.Resources; @@ -57,6 +60,7 @@ import org.robolectric.shadow.api.Shadow; @Config(shadows = {ShadowBluetoothAdapter.class}) public class BluetoothPairingDetailTest { private static final String TEST_DEVICE_ADDRESS = "00:A1:A1:A1:A1:A1"; + private static final String TEST_DEVICE_ADDRESS_B = "00:B1:B1:B1:B1:B1"; @Mock private Resources mResource; @@ -82,6 +86,7 @@ public class BluetoothPairingDetailTest { mFragment = spy(new BluetoothPairingDetail()); doReturn(mContext).when(mFragment).getContext(); doReturn(mResource).when(mFragment).getResources(); + when(mCachedBluetoothDevice.getAddress()).thenReturn(TEST_DEVICE_ADDRESS); mAvailableDevicesCategory = spy(new BluetoothProgressCategory(mContext)); mFooterPreference = new FooterPreference(mContext); @@ -218,13 +223,85 @@ public class BluetoothPairingDetailTest { } @Test - public void onConnectionStateChanged_connected_finish() { - mFragment.mSelectedDevice = mBluetoothDevice; - doReturn(mBluetoothDevice).when(mCachedBluetoothDevice).getDevice(); + public void onProfileConnectionStateChanged_deviceInSelectedListAndConnected_finish() { + final BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(TEST_DEVICE_ADDRESS_B); + mFragment.mSelectedList.add(mBluetoothDevice); + mFragment.mSelectedList.add(device); - mFragment.onConnectionStateChanged(mCachedBluetoothDevice, - BluetoothAdapter.STATE_CONNECTED); + when(mCachedBluetoothDevice.isConnected()).thenReturn(true); + when(mCachedBluetoothDevice.getDevice()).thenReturn(device); + + mFragment.onProfileConnectionStateChanged(mCachedBluetoothDevice, + BluetoothProfile.A2DP, BluetoothAdapter.STATE_CONNECTED); verify(mFragment).finish(); } + + @Test + public void onProfileConnectionStateChanged_deviceNotInSelectedList_doNothing() { + final BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(TEST_DEVICE_ADDRESS_B); + mFragment.mSelectedList.add(device); + + when(mCachedBluetoothDevice.isConnected()).thenReturn(true); + when(mCachedBluetoothDevice.getDevice()).thenReturn(mBluetoothDevice); + + mFragment.onProfileConnectionStateChanged(mCachedBluetoothDevice, + BluetoothProfile.A2DP, BluetoothAdapter.STATE_CONNECTED); + + // not crash + } + + @Test + public void onProfileConnectionStateChanged_deviceDisconnected_doNothing() { + final BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(TEST_DEVICE_ADDRESS_B); + mFragment.mSelectedList.add(mBluetoothDevice); + mFragment.mSelectedList.add(device); + + when(mCachedBluetoothDevice.isConnected()).thenReturn(false); + when(mCachedBluetoothDevice.getDevice()).thenReturn(device); + + mFragment.onProfileConnectionStateChanged(mCachedBluetoothDevice, + BluetoothProfile.A2DP, BluetoothAdapter.STATE_DISCONNECTED); + + // not crash + } + + @Test + public void onProfileConnectionStateChanged_deviceInPreferenceMapAndConnected_removed() { + final BluetoothDevicePreference preference = + new BluetoothDevicePreference(mContext, mCachedBluetoothDevice, + true, BluetoothDevicePreference.SortType.TYPE_FIFO); + final BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(TEST_DEVICE_ADDRESS); + mFragment.mDevicePreferenceMap.put(mCachedBluetoothDevice, preference); + + when(mCachedBluetoothDevice.isConnected()).thenReturn(true); + when(mCachedBluetoothDevice.getDevice()).thenReturn(device); + + mFragment.onProfileConnectionStateChanged(mCachedBluetoothDevice, + BluetoothProfile.A2DP, BluetoothAdapter.STATE_CONNECTED); + + assertThat(mFragment.mDevicePreferenceMap.size()).isEqualTo(0); + } + + @Test + public void onProfileConnectionStateChanged_deviceNotInPreferenceMap_doNothing() { + final CachedBluetoothDevice cachedDevice = mock(CachedBluetoothDevice.class); + final BluetoothDevicePreference preference = + new BluetoothDevicePreference(mContext, mCachedBluetoothDevice, + true, BluetoothDevicePreference.SortType.TYPE_FIFO); + final BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(TEST_DEVICE_ADDRESS); + final BluetoothDevice device2 = mBluetoothAdapter.getRemoteDevice(TEST_DEVICE_ADDRESS_B); + mFragment.mDevicePreferenceMap.put(mCachedBluetoothDevice, preference); + + when(mCachedBluetoothDevice.isConnected()).thenReturn(true); + when(mCachedBluetoothDevice.getDevice()).thenReturn(device); + when(cachedDevice.isConnected()).thenReturn(true); + when(cachedDevice.getDevice()).thenReturn(device2); + when(cachedDevice.getAddress()).thenReturn(TEST_DEVICE_ADDRESS_B); + + mFragment.onProfileConnectionStateChanged(cachedDevice, BluetoothProfile.A2DP, + BluetoothAdapter.STATE_CONNECTED); + + // not crash + } } \ No newline at end of file