Fix bluetooth settings force close
This CL include following change: - Add null check of cacedBluetoothDevice, cachedBluetooth could be null if the input BluetoothDevice can't found in CachedBluetoothDeviceManager. - Move addPreference() and removePreference() to update() method, because update() will be called to update UI when recevice Bluetooth device change event. - Add test case to test CachedBluetoothDevice null check. Bug: 149068434 Test: make -j42 RunSettingsRoboTests Change-Id: I90016bf1175925821b0d9b634c62cf796289a734
This commit is contained in:
@@ -20,6 +20,7 @@ import android.bluetooth.BluetoothDevice;
|
|||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
|
import androidx.annotation.VisibleForTesting;
|
||||||
import androidx.preference.Preference;
|
import androidx.preference.Preference;
|
||||||
|
|
||||||
import com.android.settings.connecteddevice.DevicePreferenceCallback;
|
import com.android.settings.connecteddevice.DevicePreferenceCallback;
|
||||||
@@ -38,24 +39,25 @@ public class SavedBluetoothDeviceUpdater extends BluetoothDeviceUpdater
|
|||||||
|
|
||||||
private static final String PREF_KEY = "saved_bt";
|
private static final String PREF_KEY = "saved_bt";
|
||||||
|
|
||||||
|
@VisibleForTesting
|
||||||
|
BluetoothAdapter mBluetoothAdapter;
|
||||||
|
|
||||||
public SavedBluetoothDeviceUpdater(Context context, DashboardFragment fragment,
|
public SavedBluetoothDeviceUpdater(Context context, DashboardFragment fragment,
|
||||||
DevicePreferenceCallback devicePreferenceCallback) {
|
DevicePreferenceCallback devicePreferenceCallback) {
|
||||||
super(context, fragment, devicePreferenceCallback);
|
super(context, fragment, devicePreferenceCallback);
|
||||||
|
|
||||||
|
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void forceUpdate() {
|
public void forceUpdate() {
|
||||||
if (BluetoothAdapter.getDefaultAdapter().isEnabled()) {
|
if (mBluetoothAdapter.isEnabled()) {
|
||||||
final CachedBluetoothDeviceManager cachedManager =
|
final CachedBluetoothDeviceManager cachedManager =
|
||||||
mLocalManager.getCachedDeviceManager();
|
mLocalManager.getCachedDeviceManager();
|
||||||
for (BluetoothDevice device
|
for (BluetoothDevice device : mBluetoothAdapter.getMostRecentlyConnectedDevices()) {
|
||||||
: BluetoothAdapter.getDefaultAdapter().getMostRecentlyConnectedDevices()) {
|
|
||||||
final CachedBluetoothDevice cachedDevice = cachedManager.findDevice(device);
|
final CachedBluetoothDevice cachedDevice = cachedManager.findDevice(device);
|
||||||
if (isFilterMatched(cachedDevice)) {
|
if (cachedDevice != null) {
|
||||||
// Add the preference if it is new one
|
update(cachedDevice);
|
||||||
addPreference(cachedDevice, BluetoothDevicePreference.SortType.TYPE_NO_SORT);
|
|
||||||
} else {
|
|
||||||
removePreference(cachedDevice);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -63,6 +65,16 @@ public class SavedBluetoothDeviceUpdater extends BluetoothDeviceUpdater
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void update(CachedBluetoothDevice cachedDevice) {
|
||||||
|
if (isFilterMatched(cachedDevice)) {
|
||||||
|
// Add the preference if it is new one
|
||||||
|
addPreference(cachedDevice, BluetoothDevicePreference.SortType.TYPE_NO_SORT);
|
||||||
|
} else {
|
||||||
|
removePreference(cachedDevice);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isFilterMatched(CachedBluetoothDevice cachedDevice) {
|
public boolean isFilterMatched(CachedBluetoothDevice cachedDevice) {
|
||||||
final BluetoothDevice device = cachedDevice.getDevice();
|
final BluetoothDevice device = cachedDevice.getDevice();
|
||||||
|
@@ -18,10 +18,12 @@ package com.android.settings.bluetooth;
|
|||||||
import static org.mockito.ArgumentMatchers.any;
|
import static org.mockito.ArgumentMatchers.any;
|
||||||
import static org.mockito.Mockito.doNothing;
|
import static org.mockito.Mockito.doNothing;
|
||||||
import static org.mockito.Mockito.doReturn;
|
import static org.mockito.Mockito.doReturn;
|
||||||
|
import static org.mockito.Mockito.never;
|
||||||
import static org.mockito.Mockito.spy;
|
import static org.mockito.Mockito.spy;
|
||||||
import static org.mockito.Mockito.verify;
|
import static org.mockito.Mockito.verify;
|
||||||
import static org.mockito.Mockito.when;
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
|
import android.bluetooth.BluetoothAdapter;
|
||||||
import android.bluetooth.BluetoothDevice;
|
import android.bluetooth.BluetoothDevice;
|
||||||
import android.bluetooth.BluetoothProfile;
|
import android.bluetooth.BluetoothProfile;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
@@ -30,6 +32,8 @@ import com.android.settings.connecteddevice.DevicePreferenceCallback;
|
|||||||
import com.android.settings.dashboard.DashboardFragment;
|
import com.android.settings.dashboard.DashboardFragment;
|
||||||
import com.android.settings.testutils.shadow.ShadowBluetoothAdapter;
|
import com.android.settings.testutils.shadow.ShadowBluetoothAdapter;
|
||||||
import com.android.settingslib.bluetooth.CachedBluetoothDevice;
|
import com.android.settingslib.bluetooth.CachedBluetoothDevice;
|
||||||
|
import com.android.settingslib.bluetooth.CachedBluetoothDeviceManager;
|
||||||
|
import com.android.settingslib.bluetooth.LocalBluetoothManager;
|
||||||
|
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
@@ -40,6 +44,10 @@ import org.robolectric.RobolectricTestRunner;
|
|||||||
import org.robolectric.RuntimeEnvironment;
|
import org.robolectric.RuntimeEnvironment;
|
||||||
import org.robolectric.annotation.Config;
|
import org.robolectric.annotation.Config;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
@RunWith(RobolectricTestRunner.class)
|
@RunWith(RobolectricTestRunner.class)
|
||||||
@Config(shadows = {ShadowBluetoothAdapter.class})
|
@Config(shadows = {ShadowBluetoothAdapter.class})
|
||||||
public class SavedBluetoothDeviceUpdaterTest {
|
public class SavedBluetoothDeviceUpdaterTest {
|
||||||
@@ -54,6 +62,12 @@ public class SavedBluetoothDeviceUpdaterTest {
|
|||||||
private CachedBluetoothDevice mCachedBluetoothDevice;
|
private CachedBluetoothDevice mCachedBluetoothDevice;
|
||||||
@Mock
|
@Mock
|
||||||
private BluetoothDevice mBluetoothDevice;
|
private BluetoothDevice mBluetoothDevice;
|
||||||
|
@Mock
|
||||||
|
private BluetoothAdapter mBluetoothAdapter;
|
||||||
|
@Mock
|
||||||
|
private CachedBluetoothDeviceManager mDeviceManager;
|
||||||
|
@Mock
|
||||||
|
private LocalBluetoothManager mBluetoothManager;
|
||||||
|
|
||||||
private Context mContext;
|
private Context mContext;
|
||||||
private SavedBluetoothDeviceUpdater mBluetoothDeviceUpdater;
|
private SavedBluetoothDeviceUpdater mBluetoothDeviceUpdater;
|
||||||
@@ -72,6 +86,8 @@ public class SavedBluetoothDeviceUpdaterTest {
|
|||||||
mBluetoothDeviceUpdater = spy(new SavedBluetoothDeviceUpdater(mContext, mDashboardFragment,
|
mBluetoothDeviceUpdater = spy(new SavedBluetoothDeviceUpdater(mContext, mDashboardFragment,
|
||||||
mDevicePreferenceCallback));
|
mDevicePreferenceCallback));
|
||||||
mBluetoothDeviceUpdater.setPrefContext(mContext);
|
mBluetoothDeviceUpdater.setPrefContext(mContext);
|
||||||
|
mBluetoothDeviceUpdater.mBluetoothAdapter = mBluetoothAdapter;
|
||||||
|
mBluetoothDeviceUpdater.mLocalManager = mBluetoothManager;
|
||||||
mPreference = new BluetoothDevicePreference(mContext, mCachedBluetoothDevice,
|
mPreference = new BluetoothDevicePreference(mContext, mCachedBluetoothDevice,
|
||||||
false, BluetoothDevicePreference.SortType.TYPE_DEFAULT);
|
false, BluetoothDevicePreference.SortType.TYPE_DEFAULT);
|
||||||
doNothing().when(mBluetoothDeviceUpdater).addPreference(any());
|
doNothing().when(mBluetoothDeviceUpdater).addPreference(any());
|
||||||
@@ -85,7 +101,8 @@ public class SavedBluetoothDeviceUpdaterTest {
|
|||||||
|
|
||||||
mBluetoothDeviceUpdater.update(mCachedBluetoothDevice);
|
mBluetoothDeviceUpdater.update(mCachedBluetoothDevice);
|
||||||
|
|
||||||
verify(mBluetoothDeviceUpdater).addPreference(mCachedBluetoothDevice);
|
verify(mBluetoothDeviceUpdater).addPreference(mCachedBluetoothDevice,
|
||||||
|
BluetoothDevicePreference.SortType.TYPE_NO_SORT);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -115,7 +132,8 @@ public class SavedBluetoothDeviceUpdaterTest {
|
|||||||
mBluetoothDeviceUpdater.onProfileConnectionStateChanged(mCachedBluetoothDevice,
|
mBluetoothDeviceUpdater.onProfileConnectionStateChanged(mCachedBluetoothDevice,
|
||||||
BluetoothProfile.STATE_DISCONNECTED, BluetoothProfile.A2DP);
|
BluetoothProfile.STATE_DISCONNECTED, BluetoothProfile.A2DP);
|
||||||
|
|
||||||
verify(mBluetoothDeviceUpdater).addPreference(mCachedBluetoothDevice);
|
verify(mBluetoothDeviceUpdater).addPreference(mCachedBluetoothDevice,
|
||||||
|
BluetoothDevicePreference.SortType.TYPE_NO_SORT);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -124,4 +142,70 @@ public class SavedBluetoothDeviceUpdaterTest {
|
|||||||
|
|
||||||
verify(mCachedBluetoothDevice).connect();
|
verify(mCachedBluetoothDevice).connect();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void forceUpdate_findCachedBluetoothDeviceIsMatched_addPreference() {
|
||||||
|
final List<BluetoothDevice> bluetoothDevices = new ArrayList<>();
|
||||||
|
bluetoothDevices.add(mBluetoothDevice);
|
||||||
|
|
||||||
|
when(mBluetoothAdapter.isEnabled()).thenReturn(true);
|
||||||
|
when(mBluetoothAdapter.getMostRecentlyConnectedDevices()).thenReturn(bluetoothDevices);
|
||||||
|
when(mBluetoothManager.getCachedDeviceManager()).thenReturn(mDeviceManager);
|
||||||
|
when(mDeviceManager.findDevice(mBluetoothDevice)).thenReturn(mCachedBluetoothDevice);
|
||||||
|
when(mBluetoothDevice.getBondState()).thenReturn(BluetoothDevice.BOND_BONDED);
|
||||||
|
when(mBluetoothDevice.isConnected()).thenReturn(false);
|
||||||
|
|
||||||
|
mBluetoothDeviceUpdater.forceUpdate();
|
||||||
|
|
||||||
|
verify(mBluetoothDeviceUpdater).addPreference(mCachedBluetoothDevice,
|
||||||
|
BluetoothDevicePreference.SortType.TYPE_NO_SORT);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void forceUpdate_findCachedBluetoothDeviceNotMatched_removePreference() {
|
||||||
|
final List<BluetoothDevice> bluetoothDevices = new ArrayList<>();
|
||||||
|
bluetoothDevices.add(mBluetoothDevice);
|
||||||
|
|
||||||
|
when(mBluetoothAdapter.isEnabled()).thenReturn(true);
|
||||||
|
when(mBluetoothAdapter.getMostRecentlyConnectedDevices()).thenReturn(bluetoothDevices);
|
||||||
|
when(mBluetoothManager.getCachedDeviceManager()).thenReturn(mDeviceManager);
|
||||||
|
when(mDeviceManager.findDevice(mBluetoothDevice)).thenReturn(mCachedBluetoothDevice);
|
||||||
|
when(mBluetoothDevice.getBondState()).thenReturn(BluetoothDevice.BOND_BONDED);
|
||||||
|
when(mBluetoothDevice.isConnected()).thenReturn(true);
|
||||||
|
|
||||||
|
mBluetoothDeviceUpdater.forceUpdate();
|
||||||
|
|
||||||
|
verify(mBluetoothDeviceUpdater).removePreference(mCachedBluetoothDevice);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void forceUpdate_notFindCachedBluetoothDevice_doNothing() {
|
||||||
|
final List<BluetoothDevice> bluetoothDevices = new ArrayList<>();
|
||||||
|
bluetoothDevices.add(mBluetoothDevice);
|
||||||
|
|
||||||
|
when(mBluetoothAdapter.isEnabled()).thenReturn(true);
|
||||||
|
when(mBluetoothAdapter.getMostRecentlyConnectedDevices()).thenReturn(bluetoothDevices);
|
||||||
|
when(mBluetoothManager.getCachedDeviceManager()).thenReturn(mDeviceManager);
|
||||||
|
when(mDeviceManager.findDevice(mBluetoothDevice)).thenReturn(null);
|
||||||
|
|
||||||
|
mBluetoothDeviceUpdater.forceUpdate();
|
||||||
|
|
||||||
|
verify(mBluetoothDeviceUpdater, never()).removePreference(mCachedBluetoothDevice);
|
||||||
|
verify(mBluetoothDeviceUpdater, never()).addPreference(mCachedBluetoothDevice,
|
||||||
|
BluetoothDevicePreference.SortType.TYPE_NO_SORT);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void forceUpdate_bluetoothAdapterNotEnable_removeAllDevicesFromPreference() {
|
||||||
|
final Collection<CachedBluetoothDevice> cachedDevices = new ArrayList<>();
|
||||||
|
cachedDevices.add(mCachedBluetoothDevice);
|
||||||
|
|
||||||
|
when(mBluetoothManager.getCachedDeviceManager()).thenReturn(mDeviceManager);
|
||||||
|
when(mDeviceManager.getCachedDevicesCopy()).thenReturn(cachedDevices);
|
||||||
|
when(mBluetoothAdapter.isEnabled()).thenReturn(false);
|
||||||
|
|
||||||
|
mBluetoothDeviceUpdater.forceUpdate();
|
||||||
|
|
||||||
|
verify(mBluetoothDeviceUpdater).removeAllDevicesFromPreference();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user