Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 1b3f570a authored by hughchen's avatar hughchen
Browse files

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
parent 978b19ec
Loading
Loading
Loading
Loading
+20 −8
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@ import android.bluetooth.BluetoothDevice;
import android.content.Context;
import android.util.Log;

import androidx.annotation.VisibleForTesting;
import androidx.preference.Preference;

import com.android.settings.connecteddevice.DevicePreferenceCallback;
@@ -38,19 +39,34 @@ public class SavedBluetoothDeviceUpdater extends BluetoothDeviceUpdater

    private static final String PREF_KEY = "saved_bt";

    @VisibleForTesting
    BluetoothAdapter mBluetoothAdapter;

    public SavedBluetoothDeviceUpdater(Context context, DashboardFragment fragment,
            DevicePreferenceCallback devicePreferenceCallback) {
        super(context, fragment, devicePreferenceCallback);

        mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
    }

    @Override
    public void forceUpdate() {
        if (BluetoothAdapter.getDefaultAdapter().isEnabled()) {
        if (mBluetoothAdapter.isEnabled()) {
            final CachedBluetoothDeviceManager cachedManager =
                    mLocalManager.getCachedDeviceManager();
            for (BluetoothDevice device
                    : BluetoothAdapter.getDefaultAdapter().getMostRecentlyConnectedDevices()) {
            for (BluetoothDevice device : mBluetoothAdapter.getMostRecentlyConnectedDevices()) {
                final CachedBluetoothDevice cachedDevice = cachedManager.findDevice(device);
                if (cachedDevice != null) {
                    update(cachedDevice);
                }
            }
        } else {
            removeAllDevicesFromPreference();
        }
    }

    @Override
    public void update(CachedBluetoothDevice cachedDevice) {
        if (isFilterMatched(cachedDevice)) {
            // Add the preference if it is new one
            addPreference(cachedDevice, BluetoothDevicePreference.SortType.TYPE_NO_SORT);
@@ -58,10 +74,6 @@ public class SavedBluetoothDeviceUpdater extends BluetoothDeviceUpdater
            removePreference(cachedDevice);
        }
    }
        } else {
            removeAllDevicesFromPreference();
        }
    }

    @Override
    public boolean isFilterMatched(CachedBluetoothDevice cachedDevice) {
+86 −2
Original line number Diff line number Diff line
@@ -18,10 +18,12 @@ package com.android.settings.bluetooth;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.spy;
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;
@@ -30,6 +32,8 @@ import com.android.settings.connecteddevice.DevicePreferenceCallback;
import com.android.settings.dashboard.DashboardFragment;
import com.android.settings.testutils.shadow.ShadowBluetoothAdapter;
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.Test;
@@ -40,6 +44,10 @@ import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

@RunWith(RobolectricTestRunner.class)
@Config(shadows = {ShadowBluetoothAdapter.class})
public class SavedBluetoothDeviceUpdaterTest {
@@ -54,6 +62,12 @@ public class SavedBluetoothDeviceUpdaterTest {
    private CachedBluetoothDevice mCachedBluetoothDevice;
    @Mock
    private BluetoothDevice mBluetoothDevice;
    @Mock
    private BluetoothAdapter mBluetoothAdapter;
    @Mock
    private CachedBluetoothDeviceManager mDeviceManager;
    @Mock
    private LocalBluetoothManager mBluetoothManager;

    private Context mContext;
    private SavedBluetoothDeviceUpdater mBluetoothDeviceUpdater;
@@ -72,6 +86,8 @@ public class SavedBluetoothDeviceUpdaterTest {
        mBluetoothDeviceUpdater = spy(new SavedBluetoothDeviceUpdater(mContext, mDashboardFragment,
                mDevicePreferenceCallback));
        mBluetoothDeviceUpdater.setPrefContext(mContext);
        mBluetoothDeviceUpdater.mBluetoothAdapter = mBluetoothAdapter;
        mBluetoothDeviceUpdater.mLocalManager = mBluetoothManager;
        mPreference = new BluetoothDevicePreference(mContext, mCachedBluetoothDevice,
                false, BluetoothDevicePreference.SortType.TYPE_DEFAULT);
        doNothing().when(mBluetoothDeviceUpdater).addPreference(any());
@@ -85,7 +101,8 @@ public class SavedBluetoothDeviceUpdaterTest {

        mBluetoothDeviceUpdater.update(mCachedBluetoothDevice);

        verify(mBluetoothDeviceUpdater).addPreference(mCachedBluetoothDevice);
        verify(mBluetoothDeviceUpdater).addPreference(mCachedBluetoothDevice,
                BluetoothDevicePreference.SortType.TYPE_NO_SORT);
    }

    @Test
@@ -115,7 +132,8 @@ public class SavedBluetoothDeviceUpdaterTest {
        mBluetoothDeviceUpdater.onProfileConnectionStateChanged(mCachedBluetoothDevice,
                BluetoothProfile.STATE_DISCONNECTED, BluetoothProfile.A2DP);

        verify(mBluetoothDeviceUpdater).addPreference(mCachedBluetoothDevice);
        verify(mBluetoothDeviceUpdater).addPreference(mCachedBluetoothDevice,
                BluetoothDevicePreference.SortType.TYPE_NO_SORT);
    }

    @Test
@@ -124,4 +142,70 @@ public class SavedBluetoothDeviceUpdaterTest {

        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();
    }
}