Merge "[BT] Correct the filter when addCachedDevices" into udc-qpr-dev
This commit is contained in:
@@ -101,10 +101,8 @@ public class BluetoothPairingDetail extends BluetoothDevicePairingDetailBase imp
|
|||||||
if (bluetoothState == BluetoothAdapter.STATE_ON) {
|
if (bluetoothState == BluetoothAdapter.STATE_ON) {
|
||||||
if (mInitialScanStarted) {
|
if (mInitialScanStarted) {
|
||||||
// Don't show bonded devices when screen turned back on
|
// Don't show bonded devices when screen turned back on
|
||||||
setFilter(BluetoothDeviceFilter.UNBONDED_DEVICE_FILTER);
|
addCachedDevices(BluetoothDeviceFilter.UNBONDED_DEVICE_FILTER);
|
||||||
addCachedDevices();
|
|
||||||
}
|
}
|
||||||
setFilter(BluetoothDeviceFilter.ALL_FILTER);
|
|
||||||
updateFooterPreference(mFooterPreference);
|
updateFooterPreference(mFooterPreference);
|
||||||
mAlwaysDiscoverable.start();
|
mAlwaysDiscoverable.start();
|
||||||
}
|
}
|
||||||
|
@@ -28,7 +28,6 @@ import android.text.BidiFormatter
|
|||||||
import android.util.Log
|
import android.util.Log
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import androidx.annotation.VisibleForTesting
|
import androidx.annotation.VisibleForTesting
|
||||||
import androidx.lifecycle.LifecycleCoroutineScope
|
|
||||||
import androidx.lifecycle.lifecycleScope
|
import androidx.lifecycle.lifecycleScope
|
||||||
import androidx.preference.Preference
|
import androidx.preference.Preference
|
||||||
import androidx.preference.PreferenceCategory
|
import androidx.preference.PreferenceCategory
|
||||||
@@ -41,6 +40,7 @@ import com.android.settingslib.bluetooth.CachedBluetoothDevice
|
|||||||
import com.android.settingslib.bluetooth.CachedBluetoothDeviceManager
|
import com.android.settingslib.bluetooth.CachedBluetoothDeviceManager
|
||||||
import com.android.settingslib.bluetooth.LocalBluetoothManager
|
import com.android.settingslib.bluetooth.LocalBluetoothManager
|
||||||
import java.util.concurrent.ConcurrentHashMap
|
import java.util.concurrent.ConcurrentHashMap
|
||||||
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
@@ -85,11 +85,10 @@ abstract class DeviceListPreferenceFragment(restrictedKey: String?) :
|
|||||||
@JvmField
|
@JvmField
|
||||||
val mSelectedList: MutableList<BluetoothDevice> = ArrayList()
|
val mSelectedList: MutableList<BluetoothDevice> = ArrayList()
|
||||||
|
|
||||||
private var showDevicesWithoutNames = false
|
@VisibleForTesting
|
||||||
|
var lifecycleScope: CoroutineScope? = null
|
||||||
|
|
||||||
protected fun setFilter(filter: BluetoothDeviceFilter.Filter?) {
|
private var showDevicesWithoutNames = false
|
||||||
this.filter = filter
|
|
||||||
}
|
|
||||||
|
|
||||||
protected fun setFilter(filterType: Int) {
|
protected fun setFilter(filterType: Int) {
|
||||||
filter = BluetoothDeviceFilter.getFilter(filterType)
|
filter = BluetoothDeviceFilter.getFilter(filterType)
|
||||||
@@ -125,8 +124,6 @@ abstract class DeviceListPreferenceFragment(restrictedKey: String?) :
|
|||||||
/** find and update preference that already existed in preference screen */
|
/** find and update preference that already existed in preference screen */
|
||||||
protected abstract fun initPreferencesFromPreferenceScreen()
|
protected abstract fun initPreferencesFromPreferenceScreen()
|
||||||
|
|
||||||
private var lifecycleScope: LifecycleCoroutineScope? = null
|
|
||||||
|
|
||||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
super.onViewCreated(view, savedInstanceState)
|
super.onViewCreated(view, savedInstanceState)
|
||||||
lifecycleScope = viewLifecycleOwner.lifecycleScope
|
lifecycleScope = viewLifecycleOwner.lifecycleScope
|
||||||
@@ -154,13 +151,15 @@ abstract class DeviceListPreferenceFragment(restrictedKey: String?) :
|
|||||||
mDeviceListGroup!!.removeAll()
|
mDeviceListGroup!!.removeAll()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun addCachedDevices() {
|
@JvmOverloads
|
||||||
|
fun addCachedDevices(filterForCachedDevices: BluetoothDeviceFilter.Filter? = null) {
|
||||||
lifecycleScope?.launch {
|
lifecycleScope?.launch {
|
||||||
withContext(Dispatchers.Default) {
|
withContext(Dispatchers.Default) {
|
||||||
val cachedDevices = mCachedDeviceManager!!.cachedDevicesCopy
|
mCachedDeviceManager!!.cachedDevicesCopy
|
||||||
for (cachedDevice in cachedDevices) {
|
.filter {
|
||||||
onDeviceAdded(cachedDevice)
|
filterForCachedDevices == null || filterForCachedDevices.matches(it.device)
|
||||||
}
|
}
|
||||||
|
.forEach(::onDeviceAdded)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,237 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2017 The Android Open Source Project
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.android.settings.bluetooth;
|
|
||||||
|
|
||||||
import static com.google.common.truth.Truth.assertThat;
|
|
||||||
|
|
||||||
import static org.mockito.ArgumentMatchers.any;
|
|
||||||
import static org.mockito.ArgumentMatchers.eq;
|
|
||||||
import static org.mockito.Mockito.doReturn;
|
|
||||||
import static org.mockito.Mockito.spy;
|
|
||||||
import static org.mockito.Mockito.times;
|
|
||||||
import static org.mockito.Mockito.verify;
|
|
||||||
|
|
||||||
import android.bluetooth.BluetoothAdapter;
|
|
||||||
import android.bluetooth.BluetoothUuid;
|
|
||||||
import android.bluetooth.le.BluetoothLeScanner;
|
|
||||||
import android.bluetooth.le.ScanCallback;
|
|
||||||
import android.bluetooth.le.ScanFilter;
|
|
||||||
import android.bluetooth.le.ScanSettings;
|
|
||||||
import android.content.Context;
|
|
||||||
import android.content.res.Resources;
|
|
||||||
|
|
||||||
import androidx.preference.Preference;
|
|
||||||
|
|
||||||
import com.android.settings.R;
|
|
||||||
import com.android.settings.testutils.shadow.ShadowBluetoothAdapter;
|
|
||||||
import com.android.settingslib.bluetooth.CachedBluetoothDevice;
|
|
||||||
import com.android.settingslib.core.AbstractPreferenceController;
|
|
||||||
|
|
||||||
import org.junit.Before;
|
|
||||||
import org.junit.Test;
|
|
||||||
import org.junit.runner.RunWith;
|
|
||||||
import org.mockito.Mock;
|
|
||||||
import org.mockito.MockitoAnnotations;
|
|
||||||
import org.robolectric.RobolectricTestRunner;
|
|
||||||
import org.robolectric.RuntimeEnvironment;
|
|
||||||
import org.robolectric.annotation.Config;
|
|
||||||
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
@RunWith(RobolectricTestRunner.class)
|
|
||||||
@Config(shadows = {ShadowBluetoothAdapter.class})
|
|
||||||
public class DeviceListPreferenceFragmentTest {
|
|
||||||
|
|
||||||
private static final String FOOTAGE_MAC_STRING = "Bluetooth mac: xxxx";
|
|
||||||
|
|
||||||
@Mock
|
|
||||||
private Resources mResource;
|
|
||||||
@Mock
|
|
||||||
private Context mContext;
|
|
||||||
@Mock
|
|
||||||
private BluetoothLeScanner mBluetoothLeScanner;
|
|
||||||
|
|
||||||
private TestFragment mFragment;
|
|
||||||
private Preference mMyDevicePreference;
|
|
||||||
|
|
||||||
|
|
||||||
private BluetoothAdapter mBluetoothAdapter;
|
|
||||||
@Before
|
|
||||||
public void setUp() {
|
|
||||||
MockitoAnnotations.initMocks(this);
|
|
||||||
|
|
||||||
mFragment = spy(new TestFragment());
|
|
||||||
doReturn(mContext).when(mFragment).getContext();
|
|
||||||
doReturn(mResource).when(mFragment).getResources();
|
|
||||||
mBluetoothAdapter = spy(BluetoothAdapter.getDefaultAdapter());
|
|
||||||
mFragment.mBluetoothAdapter = mBluetoothAdapter;
|
|
||||||
|
|
||||||
mMyDevicePreference = new Preference(RuntimeEnvironment.application);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void setUpdateMyDevicePreference_setTitleCorrectly() {
|
|
||||||
doReturn(FOOTAGE_MAC_STRING).when(mFragment)
|
|
||||||
.getString(eq(R.string.bluetooth_footer_mac_message), any());
|
|
||||||
|
|
||||||
mFragment.updateFooterPreference(mMyDevicePreference);
|
|
||||||
|
|
||||||
assertThat(mMyDevicePreference.getTitle()).isEqualTo(FOOTAGE_MAC_STRING);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testEnableDisableScanning_testStateAfterEanbleDisable() {
|
|
||||||
mFragment.enableScanning();
|
|
||||||
verify(mFragment).startScanning();
|
|
||||||
assertThat(mFragment.mScanEnabled).isTrue();
|
|
||||||
|
|
||||||
mFragment.disableScanning();
|
|
||||||
verify(mFragment).stopScanning();
|
|
||||||
assertThat(mFragment.mScanEnabled).isFalse();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testScanningStateChanged_testScanStarted() {
|
|
||||||
mFragment.enableScanning();
|
|
||||||
assertThat(mFragment.mScanEnabled).isTrue();
|
|
||||||
verify(mFragment).startScanning();
|
|
||||||
|
|
||||||
mFragment.onScanningStateChanged(true);
|
|
||||||
verify(mFragment, times(1)).startScanning();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testScanningStateChanged_testScanFinished() {
|
|
||||||
// Could happen when last scanning not done while current scan gets enabled
|
|
||||||
mFragment.enableScanning();
|
|
||||||
verify(mFragment).startScanning();
|
|
||||||
assertThat(mFragment.mScanEnabled).isTrue();
|
|
||||||
|
|
||||||
mFragment.onScanningStateChanged(false);
|
|
||||||
verify(mFragment, times(2)).startScanning();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testScanningStateChanged_testScanStateMultiple() {
|
|
||||||
// Could happen when last scanning not done while current scan gets enabled
|
|
||||||
mFragment.enableScanning();
|
|
||||||
assertThat(mFragment.mScanEnabled).isTrue();
|
|
||||||
verify(mFragment).startScanning();
|
|
||||||
|
|
||||||
mFragment.onScanningStateChanged(true);
|
|
||||||
verify(mFragment, times(1)).startScanning();
|
|
||||||
|
|
||||||
mFragment.onScanningStateChanged(false);
|
|
||||||
verify(mFragment, times(2)).startScanning();
|
|
||||||
|
|
||||||
mFragment.onScanningStateChanged(true);
|
|
||||||
verify(mFragment, times(2)).startScanning();
|
|
||||||
|
|
||||||
mFragment.disableScanning();
|
|
||||||
verify(mFragment).stopScanning();
|
|
||||||
|
|
||||||
mFragment.onScanningStateChanged(false);
|
|
||||||
verify(mFragment, times(2)).startScanning();
|
|
||||||
|
|
||||||
mFragment.onScanningStateChanged(true);
|
|
||||||
verify(mFragment, times(2)).startScanning();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testScanningStateChanged_testScanFinishedAfterDisable() {
|
|
||||||
mFragment.enableScanning();
|
|
||||||
verify(mFragment).startScanning();
|
|
||||||
assertThat(mFragment.mScanEnabled).isTrue();
|
|
||||||
|
|
||||||
mFragment.disableScanning();
|
|
||||||
verify(mFragment).stopScanning();
|
|
||||||
assertThat(mFragment.mScanEnabled).isFalse();
|
|
||||||
|
|
||||||
mFragment.onScanningStateChanged(false);
|
|
||||||
verify(mFragment, times(1)).startScanning();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testScanningStateChanged_testScanStartedAfterDisable() {
|
|
||||||
mFragment.enableScanning();
|
|
||||||
verify(mFragment).startScanning();
|
|
||||||
assertThat(mFragment.mScanEnabled).isTrue();
|
|
||||||
|
|
||||||
mFragment.disableScanning();
|
|
||||||
verify(mFragment).stopScanning();
|
|
||||||
assertThat(mFragment.mScanEnabled).isFalse();
|
|
||||||
|
|
||||||
mFragment.onScanningStateChanged(true);
|
|
||||||
verify(mFragment, times(1)).startScanning();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void startScanning_setLeScanFilter_shouldStartLeScan() {
|
|
||||||
final ScanFilter leScanFilter = new ScanFilter.Builder()
|
|
||||||
.setServiceData(BluetoothUuid.HEARING_AID, new byte[]{0}, new byte[]{0})
|
|
||||||
.build();
|
|
||||||
doReturn(mBluetoothLeScanner).when(mBluetoothAdapter).getBluetoothLeScanner();
|
|
||||||
|
|
||||||
mFragment.setFilter(Collections.singletonList(leScanFilter));
|
|
||||||
mFragment.startScanning();
|
|
||||||
|
|
||||||
verify(mBluetoothLeScanner).startScan(eq(Collections.singletonList(leScanFilter)),
|
|
||||||
any(ScanSettings.class), any(ScanCallback.class));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Fragment to test since {@code DeviceListPreferenceFragment} is abstract
|
|
||||||
*/
|
|
||||||
public static class TestFragment extends DeviceListPreferenceFragment {
|
|
||||||
|
|
||||||
public TestFragment() {
|
|
||||||
super("");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getMetricsCategory() {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onDeviceBondStateChanged(CachedBluetoothDevice cachedDevice, int bondState) {}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void initPreferencesFromPreferenceScreen() {}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getDeviceListKey() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected String getLogTag() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected int getPreferenceScreenResId() {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected List<AbstractPreferenceController> createPreferenceControllers(Context context) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@@ -0,0 +1,260 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2023 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.android.settings.bluetooth
|
||||||
|
|
||||||
|
import android.bluetooth.BluetoothAdapter
|
||||||
|
import android.bluetooth.BluetoothDevice
|
||||||
|
import android.bluetooth.BluetoothUuid
|
||||||
|
import android.bluetooth.le.BluetoothLeScanner
|
||||||
|
import android.bluetooth.le.ScanCallback
|
||||||
|
import android.bluetooth.le.ScanFilter
|
||||||
|
import android.content.Context
|
||||||
|
import android.content.res.Resources
|
||||||
|
import androidx.preference.Preference
|
||||||
|
import com.android.settings.R
|
||||||
|
import com.android.settings.testutils.shadow.ShadowBluetoothAdapter
|
||||||
|
import com.android.settingslib.bluetooth.BluetoothDeviceFilter
|
||||||
|
import com.android.settingslib.bluetooth.CachedBluetoothDevice
|
||||||
|
import com.android.settingslib.bluetooth.CachedBluetoothDeviceManager
|
||||||
|
import com.google.common.truth.Truth.assertThat
|
||||||
|
import kotlinx.coroutines.delay
|
||||||
|
import kotlinx.coroutines.runBlocking
|
||||||
|
import org.junit.Before
|
||||||
|
import org.junit.Rule
|
||||||
|
import org.junit.Test
|
||||||
|
import org.junit.runner.RunWith
|
||||||
|
import org.mockito.ArgumentMatchers.any
|
||||||
|
import org.mockito.ArgumentMatchers.eq
|
||||||
|
import org.mockito.Mock
|
||||||
|
import org.mockito.Mockito.doNothing
|
||||||
|
import org.mockito.Mockito.doReturn
|
||||||
|
import org.mockito.Mockito.mock
|
||||||
|
import org.mockito.Mockito.never
|
||||||
|
import org.mockito.Mockito.spy
|
||||||
|
import org.mockito.Mockito.times
|
||||||
|
import org.mockito.Mockito.verify
|
||||||
|
import org.mockito.Spy
|
||||||
|
import org.mockito.junit.MockitoJUnit
|
||||||
|
import org.mockito.junit.MockitoRule
|
||||||
|
import org.robolectric.RobolectricTestRunner
|
||||||
|
import org.robolectric.RuntimeEnvironment
|
||||||
|
import org.robolectric.annotation.Config
|
||||||
|
import org.mockito.Mockito.`when` as whenever
|
||||||
|
|
||||||
|
@RunWith(RobolectricTestRunner::class)
|
||||||
|
@Config(shadows = [ShadowBluetoothAdapter::class])
|
||||||
|
class DeviceListPreferenceFragmentTest {
|
||||||
|
@get:Rule
|
||||||
|
val mockito: MockitoRule = MockitoJUnit.rule()
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private lateinit var resource: Resources
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private lateinit var context: Context
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private lateinit var bluetoothLeScanner: BluetoothLeScanner
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private lateinit var cachedDeviceManager: CachedBluetoothDeviceManager
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private lateinit var cachedDevice: CachedBluetoothDevice
|
||||||
|
|
||||||
|
@Spy
|
||||||
|
private var fragment = TestFragment()
|
||||||
|
|
||||||
|
private lateinit var myDevicePreference: Preference
|
||||||
|
private lateinit var bluetoothAdapter: BluetoothAdapter
|
||||||
|
|
||||||
|
@Before
|
||||||
|
fun setUp() {
|
||||||
|
doReturn(context).`when`(fragment).context
|
||||||
|
doReturn(resource).`when`(fragment).resources
|
||||||
|
doNothing().`when`(fragment).onDeviceAdded(cachedDevice)
|
||||||
|
bluetoothAdapter = spy(BluetoothAdapter.getDefaultAdapter())
|
||||||
|
fragment.mBluetoothAdapter = bluetoothAdapter
|
||||||
|
fragment.mCachedDeviceManager = cachedDeviceManager
|
||||||
|
|
||||||
|
myDevicePreference = Preference(RuntimeEnvironment.application)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun setUpdateMyDevicePreference_setTitleCorrectly() {
|
||||||
|
doReturn(FOOTAGE_MAC_STRING).`when`(fragment)
|
||||||
|
.getString(eq(R.string.bluetooth_footer_mac_message), any())
|
||||||
|
|
||||||
|
fragment.updateFooterPreference(myDevicePreference)
|
||||||
|
|
||||||
|
assertThat(myDevicePreference.title).isEqualTo(FOOTAGE_MAC_STRING)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testEnableDisableScanning_testStateAfterEnableDisable() {
|
||||||
|
fragment.enableScanning()
|
||||||
|
verify(fragment).startScanning()
|
||||||
|
assertThat(fragment.mScanEnabled).isTrue()
|
||||||
|
|
||||||
|
fragment.disableScanning()
|
||||||
|
verify(fragment).stopScanning()
|
||||||
|
assertThat(fragment.mScanEnabled).isFalse()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testScanningStateChanged_testScanStarted() {
|
||||||
|
fragment.enableScanning()
|
||||||
|
assertThat(fragment.mScanEnabled).isTrue()
|
||||||
|
verify(fragment).startScanning()
|
||||||
|
|
||||||
|
fragment.onScanningStateChanged(true)
|
||||||
|
verify(fragment, times(1)).startScanning()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testScanningStateChanged_testScanFinished() {
|
||||||
|
// Could happen when last scanning not done while current scan gets enabled
|
||||||
|
fragment.enableScanning()
|
||||||
|
verify(fragment).startScanning()
|
||||||
|
assertThat(fragment.mScanEnabled).isTrue()
|
||||||
|
|
||||||
|
fragment.onScanningStateChanged(false)
|
||||||
|
verify(fragment, times(2)).startScanning()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testScanningStateChanged_testScanStateMultiple() {
|
||||||
|
// Could happen when last scanning not done while current scan gets enabled
|
||||||
|
fragment.enableScanning()
|
||||||
|
assertThat(fragment.mScanEnabled).isTrue()
|
||||||
|
verify(fragment).startScanning()
|
||||||
|
|
||||||
|
fragment.onScanningStateChanged(true)
|
||||||
|
verify(fragment, times(1)).startScanning()
|
||||||
|
|
||||||
|
fragment.onScanningStateChanged(false)
|
||||||
|
verify(fragment, times(2)).startScanning()
|
||||||
|
|
||||||
|
fragment.onScanningStateChanged(true)
|
||||||
|
verify(fragment, times(2)).startScanning()
|
||||||
|
|
||||||
|
fragment.disableScanning()
|
||||||
|
verify(fragment).stopScanning()
|
||||||
|
|
||||||
|
fragment.onScanningStateChanged(false)
|
||||||
|
verify(fragment, times(2)).startScanning()
|
||||||
|
|
||||||
|
fragment.onScanningStateChanged(true)
|
||||||
|
verify(fragment, times(2)).startScanning()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testScanningStateChanged_testScanFinishedAfterDisable() {
|
||||||
|
fragment.enableScanning()
|
||||||
|
verify(fragment).startScanning()
|
||||||
|
assertThat(fragment.mScanEnabled).isTrue()
|
||||||
|
|
||||||
|
fragment.disableScanning()
|
||||||
|
verify(fragment).stopScanning()
|
||||||
|
assertThat(fragment.mScanEnabled).isFalse()
|
||||||
|
|
||||||
|
fragment.onScanningStateChanged(false)
|
||||||
|
verify(fragment, times(1)).startScanning()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testScanningStateChanged_testScanStartedAfterDisable() {
|
||||||
|
fragment.enableScanning()
|
||||||
|
verify(fragment).startScanning()
|
||||||
|
assertThat(fragment.mScanEnabled).isTrue()
|
||||||
|
|
||||||
|
fragment.disableScanning()
|
||||||
|
verify(fragment).stopScanning()
|
||||||
|
assertThat(fragment.mScanEnabled).isFalse()
|
||||||
|
|
||||||
|
fragment.onScanningStateChanged(true)
|
||||||
|
verify(fragment, times(1)).startScanning()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun startScanning_setLeScanFilter_shouldStartLeScan() {
|
||||||
|
val leScanFilter = ScanFilter.Builder()
|
||||||
|
.setServiceData(BluetoothUuid.HEARING_AID, byteArrayOf(0), byteArrayOf(0))
|
||||||
|
.build()
|
||||||
|
doReturn(bluetoothLeScanner).`when`(bluetoothAdapter).bluetoothLeScanner
|
||||||
|
|
||||||
|
fragment.setFilter(listOf(leScanFilter))
|
||||||
|
fragment.startScanning()
|
||||||
|
|
||||||
|
verify(bluetoothLeScanner).startScan(eq(listOf(leScanFilter)), any(), any<ScanCallback>())
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun addCachedDevices_whenFilterIsNull_onDeviceAddedIsCalled() = runBlocking {
|
||||||
|
val mockCachedDevice = mock(CachedBluetoothDevice::class.java)
|
||||||
|
whenever(cachedDeviceManager.cachedDevicesCopy).thenReturn(listOf(mockCachedDevice))
|
||||||
|
fragment.lifecycleScope = this
|
||||||
|
|
||||||
|
fragment.addCachedDevices(filterForCachedDevices = null)
|
||||||
|
delay(100)
|
||||||
|
|
||||||
|
verify(fragment).onDeviceAdded(mockCachedDevice)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun addCachedDevices_whenFilterMatched_onDeviceAddedIsCalled() = runBlocking {
|
||||||
|
val mockBluetoothDevice = mock(BluetoothDevice::class.java)
|
||||||
|
whenever(mockBluetoothDevice.bondState).thenReturn(BluetoothDevice.BOND_NONE)
|
||||||
|
whenever(cachedDevice.device).thenReturn(mockBluetoothDevice)
|
||||||
|
whenever(cachedDeviceManager.cachedDevicesCopy).thenReturn(listOf(cachedDevice))
|
||||||
|
fragment.lifecycleScope = this
|
||||||
|
|
||||||
|
fragment.addCachedDevices(BluetoothDeviceFilter.UNBONDED_DEVICE_FILTER)
|
||||||
|
delay(100)
|
||||||
|
|
||||||
|
verify(fragment).onDeviceAdded(cachedDevice)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun addCachedDevices_whenFilterNoMatch_onDeviceAddedNotCalled() = runBlocking {
|
||||||
|
val mockBluetoothDevice = mock(BluetoothDevice::class.java)
|
||||||
|
whenever(mockBluetoothDevice.bondState).thenReturn(BluetoothDevice.BOND_BONDED)
|
||||||
|
whenever(cachedDevice.device).thenReturn(mockBluetoothDevice)
|
||||||
|
whenever(cachedDeviceManager.cachedDevicesCopy).thenReturn(listOf(cachedDevice))
|
||||||
|
fragment.lifecycleScope = this
|
||||||
|
|
||||||
|
fragment.addCachedDevices(BluetoothDeviceFilter.UNBONDED_DEVICE_FILTER)
|
||||||
|
delay(100)
|
||||||
|
|
||||||
|
verify(fragment, never()).onDeviceAdded(cachedDevice)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fragment to test since `DeviceListPreferenceFragment` is abstract
|
||||||
|
*/
|
||||||
|
open class TestFragment : DeviceListPreferenceFragment(null) {
|
||||||
|
override fun getMetricsCategory() = 0
|
||||||
|
override fun initPreferencesFromPreferenceScreen() {}
|
||||||
|
override val deviceListKey = "device_list"
|
||||||
|
override fun getLogTag() = null
|
||||||
|
override fun getPreferenceScreenResId() = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
private companion object {
|
||||||
|
const val FOOTAGE_MAC_STRING = "Bluetooth mac: xxxx"
|
||||||
|
}
|
||||||
|
}
|
Reference in New Issue
Block a user