152ccb49fbe65c8e84a5d4fde1d8028b62a713204jackqdyulei/* 252ccb49fbe65c8e84a5d4fde1d8028b62a713204jackqdyulei * Copyright (C) 2017 The Android Open Source Project 352ccb49fbe65c8e84a5d4fde1d8028b62a713204jackqdyulei * 452ccb49fbe65c8e84a5d4fde1d8028b62a713204jackqdyulei * Licensed under the Apache License, Version 2.0 (the "License"); 552ccb49fbe65c8e84a5d4fde1d8028b62a713204jackqdyulei * you may not use this file except in compliance with the License. 652ccb49fbe65c8e84a5d4fde1d8028b62a713204jackqdyulei * You may obtain a copy of the License at 752ccb49fbe65c8e84a5d4fde1d8028b62a713204jackqdyulei * 852ccb49fbe65c8e84a5d4fde1d8028b62a713204jackqdyulei * http://www.apache.org/licenses/LICENSE-2.0 952ccb49fbe65c8e84a5d4fde1d8028b62a713204jackqdyulei * 1052ccb49fbe65c8e84a5d4fde1d8028b62a713204jackqdyulei * Unless required by applicable law or agreed to in writing, software 1152ccb49fbe65c8e84a5d4fde1d8028b62a713204jackqdyulei * distributed under the License is distributed on an "AS IS" BASIS, 1252ccb49fbe65c8e84a5d4fde1d8028b62a713204jackqdyulei * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1352ccb49fbe65c8e84a5d4fde1d8028b62a713204jackqdyulei * See the License for the specific language governing permissions and 1452ccb49fbe65c8e84a5d4fde1d8028b62a713204jackqdyulei * limitations under the License. 1552ccb49fbe65c8e84a5d4fde1d8028b62a713204jackqdyulei */ 1652ccb49fbe65c8e84a5d4fde1d8028b62a713204jackqdyulei 1752ccb49fbe65c8e84a5d4fde1d8028b62a713204jackqdyuleipackage com.android.settings.bluetooth; 1852ccb49fbe65c8e84a5d4fde1d8028b62a713204jackqdyulei 1952ccb49fbe65c8e84a5d4fde1d8028b62a713204jackqdyuleiimport static com.google.common.truth.Truth.assertThat; 2052ccb49fbe65c8e84a5d4fde1d8028b62a713204jackqdyulei 2152ccb49fbe65c8e84a5d4fde1d8028b62a713204jackqdyuleiimport static org.mockito.Matchers.any; 2252ccb49fbe65c8e84a5d4fde1d8028b62a713204jackqdyuleiimport static org.mockito.Matchers.anyBoolean; 2352ccb49fbe65c8e84a5d4fde1d8028b62a713204jackqdyuleiimport static org.mockito.Matchers.anyInt; 2452ccb49fbe65c8e84a5d4fde1d8028b62a713204jackqdyuleiimport static org.mockito.Mockito.doNothing; 2552ccb49fbe65c8e84a5d4fde1d8028b62a713204jackqdyuleiimport static org.mockito.Mockito.doReturn; 26c11af01481dd7fb4515e681128340724f2008dc0Jack Heimport static org.mockito.Mockito.never; 2752ccb49fbe65c8e84a5d4fde1d8028b62a713204jackqdyuleiimport static org.mockito.Mockito.spy; 28c11af01481dd7fb4515e681128340724f2008dc0Jack Heimport static org.mockito.Mockito.times; 2952ccb49fbe65c8e84a5d4fde1d8028b62a713204jackqdyuleiimport static org.mockito.Mockito.verify; 3052ccb49fbe65c8e84a5d4fde1d8028b62a713204jackqdyulei 3152ccb49fbe65c8e84a5d4fde1d8028b62a713204jackqdyuleiimport android.bluetooth.BluetoothAdapter; 3252ccb49fbe65c8e84a5d4fde1d8028b62a713204jackqdyuleiimport android.content.Context; 3352ccb49fbe65c8e84a5d4fde1d8028b62a713204jackqdyuleiimport android.content.res.Resources; 3452ccb49fbe65c8e84a5d4fde1d8028b62a713204jackqdyuleiimport android.os.UserManager; 3552ccb49fbe65c8e84a5d4fde1d8028b62a713204jackqdyuleiimport android.support.v7.preference.PreferenceGroup; 3652ccb49fbe65c8e84a5d4fde1d8028b62a713204jackqdyulei 3752ccb49fbe65c8e84a5d4fde1d8028b62a713204jackqdyuleiimport com.android.settings.R; 389f1e911759dc6fedaac9fa65afb79f6a93022bf4Andrew Sappersteinimport com.android.settings.testutils.SettingsRobolectricTestRunner; 3952ccb49fbe65c8e84a5d4fde1d8028b62a713204jackqdyuleiimport com.android.settings.TestConfig; 4052ccb49fbe65c8e84a5d4fde1d8028b62a713204jackqdyuleiimport com.android.settingslib.bluetooth.BluetoothDeviceFilter; 4152ccb49fbe65c8e84a5d4fde1d8028b62a713204jackqdyuleiimport com.android.settingslib.bluetooth.LocalBluetoothAdapter; 4252ccb49fbe65c8e84a5d4fde1d8028b62a713204jackqdyuleiimport com.android.settingslib.bluetooth.LocalBluetoothManager; 4352ccb49fbe65c8e84a5d4fde1d8028b62a713204jackqdyuleiimport com.android.settingslib.widget.FooterPreference; 4452ccb49fbe65c8e84a5d4fde1d8028b62a713204jackqdyulei 4552ccb49fbe65c8e84a5d4fde1d8028b62a713204jackqdyuleiimport org.junit.Before; 4652ccb49fbe65c8e84a5d4fde1d8028b62a713204jackqdyuleiimport org.junit.Test; 4752ccb49fbe65c8e84a5d4fde1d8028b62a713204jackqdyuleiimport org.junit.runner.RunWith; 4852ccb49fbe65c8e84a5d4fde1d8028b62a713204jackqdyuleiimport org.mockito.Answers; 4952ccb49fbe65c8e84a5d4fde1d8028b62a713204jackqdyuleiimport org.mockito.Mock; 5052ccb49fbe65c8e84a5d4fde1d8028b62a713204jackqdyuleiimport org.mockito.MockitoAnnotations; 5152ccb49fbe65c8e84a5d4fde1d8028b62a713204jackqdyuleiimport org.robolectric.RuntimeEnvironment; 5252ccb49fbe65c8e84a5d4fde1d8028b62a713204jackqdyuleiimport org.robolectric.annotation.Config; 5352ccb49fbe65c8e84a5d4fde1d8028b62a713204jackqdyulei 5452ccb49fbe65c8e84a5d4fde1d8028b62a713204jackqdyulei@RunWith(SettingsRobolectricTestRunner.class) 5552ccb49fbe65c8e84a5d4fde1d8028b62a713204jackqdyulei@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION) 5652ccb49fbe65c8e84a5d4fde1d8028b62a713204jackqdyuleipublic class BluetoothPairingDetailTest { 5752ccb49fbe65c8e84a5d4fde1d8028b62a713204jackqdyulei 5852ccb49fbe65c8e84a5d4fde1d8028b62a713204jackqdyulei @Mock 5952ccb49fbe65c8e84a5d4fde1d8028b62a713204jackqdyulei private UserManager mUserManager; 6052ccb49fbe65c8e84a5d4fde1d8028b62a713204jackqdyulei @Mock 6152ccb49fbe65c8e84a5d4fde1d8028b62a713204jackqdyulei private Resources mResource; 6252ccb49fbe65c8e84a5d4fde1d8028b62a713204jackqdyulei @Mock 6352ccb49fbe65c8e84a5d4fde1d8028b62a713204jackqdyulei private LocalBluetoothAdapter mLocalAdapter; 6452ccb49fbe65c8e84a5d4fde1d8028b62a713204jackqdyulei @Mock(answer = Answers.RETURNS_DEEP_STUBS) 6552ccb49fbe65c8e84a5d4fde1d8028b62a713204jackqdyulei private LocalBluetoothManager mLocalManager; 6652ccb49fbe65c8e84a5d4fde1d8028b62a713204jackqdyulei @Mock 6752ccb49fbe65c8e84a5d4fde1d8028b62a713204jackqdyulei private PreferenceGroup mPreferenceGroup; 6852ccb49fbe65c8e84a5d4fde1d8028b62a713204jackqdyulei private BluetoothPairingDetail mFragment; 6952ccb49fbe65c8e84a5d4fde1d8028b62a713204jackqdyulei private Context mContext; 7052ccb49fbe65c8e84a5d4fde1d8028b62a713204jackqdyulei private BluetoothProgressCategory mAvailableDevicesCategory; 7152ccb49fbe65c8e84a5d4fde1d8028b62a713204jackqdyulei private FooterPreference mFooterPreference; 7252ccb49fbe65c8e84a5d4fde1d8028b62a713204jackqdyulei 7352ccb49fbe65c8e84a5d4fde1d8028b62a713204jackqdyulei @Before 7452ccb49fbe65c8e84a5d4fde1d8028b62a713204jackqdyulei public void setUp() { 7552ccb49fbe65c8e84a5d4fde1d8028b62a713204jackqdyulei MockitoAnnotations.initMocks(this); 7652ccb49fbe65c8e84a5d4fde1d8028b62a713204jackqdyulei 7752ccb49fbe65c8e84a5d4fde1d8028b62a713204jackqdyulei mContext = RuntimeEnvironment.application; 7852ccb49fbe65c8e84a5d4fde1d8028b62a713204jackqdyulei mFragment = spy(new BluetoothPairingDetail()); 7952ccb49fbe65c8e84a5d4fde1d8028b62a713204jackqdyulei doReturn(mContext).when(mFragment).getContext(); 8052ccb49fbe65c8e84a5d4fde1d8028b62a713204jackqdyulei doReturn(mResource).when(mFragment).getResources(); 8152ccb49fbe65c8e84a5d4fde1d8028b62a713204jackqdyulei 8252ccb49fbe65c8e84a5d4fde1d8028b62a713204jackqdyulei mAvailableDevicesCategory = spy(new BluetoothProgressCategory(mContext)); 8352ccb49fbe65c8e84a5d4fde1d8028b62a713204jackqdyulei mFooterPreference = new FooterPreference(mContext); 8452ccb49fbe65c8e84a5d4fde1d8028b62a713204jackqdyulei 8552ccb49fbe65c8e84a5d4fde1d8028b62a713204jackqdyulei mFragment.mLocalAdapter = mLocalAdapter; 8652ccb49fbe65c8e84a5d4fde1d8028b62a713204jackqdyulei mFragment.mLocalManager = mLocalManager; 8752ccb49fbe65c8e84a5d4fde1d8028b62a713204jackqdyulei mFragment.mDeviceListGroup = mPreferenceGroup; 88c86440538fb156718228299bd44698e24995632eAntony Sargent mFragment.mAlwaysDiscoverable = new AlwaysDiscoverable(mContext, mLocalAdapter); 8952ccb49fbe65c8e84a5d4fde1d8028b62a713204jackqdyulei } 9052ccb49fbe65c8e84a5d4fde1d8028b62a713204jackqdyulei 9152ccb49fbe65c8e84a5d4fde1d8028b62a713204jackqdyulei @Test 9252ccb49fbe65c8e84a5d4fde1d8028b62a713204jackqdyulei public void testInitPreferencesFromPreferenceScreen_findPreferences() { 9352ccb49fbe65c8e84a5d4fde1d8028b62a713204jackqdyulei doReturn(mAvailableDevicesCategory).when(mFragment).findPreference( 9452ccb49fbe65c8e84a5d4fde1d8028b62a713204jackqdyulei BluetoothPairingDetail.KEY_AVAIL_DEVICES); 9552ccb49fbe65c8e84a5d4fde1d8028b62a713204jackqdyulei doReturn(mFooterPreference).when(mFragment).findPreference( 9652ccb49fbe65c8e84a5d4fde1d8028b62a713204jackqdyulei BluetoothPairingDetail.KEY_FOOTER_PREF); 9752ccb49fbe65c8e84a5d4fde1d8028b62a713204jackqdyulei 9852ccb49fbe65c8e84a5d4fde1d8028b62a713204jackqdyulei mFragment.initPreferencesFromPreferenceScreen(); 9952ccb49fbe65c8e84a5d4fde1d8028b62a713204jackqdyulei 10052ccb49fbe65c8e84a5d4fde1d8028b62a713204jackqdyulei assertThat(mFragment.mAvailableDevicesCategory).isEqualTo(mAvailableDevicesCategory); 10152ccb49fbe65c8e84a5d4fde1d8028b62a713204jackqdyulei assertThat(mFragment.mFooterPreference).isEqualTo(mFooterPreference); 10252ccb49fbe65c8e84a5d4fde1d8028b62a713204jackqdyulei } 10352ccb49fbe65c8e84a5d4fde1d8028b62a713204jackqdyulei 10452ccb49fbe65c8e84a5d4fde1d8028b62a713204jackqdyulei @Test 10552ccb49fbe65c8e84a5d4fde1d8028b62a713204jackqdyulei public void testStartScanning_startScanAndRemoveDevices() { 10652ccb49fbe65c8e84a5d4fde1d8028b62a713204jackqdyulei mFragment.mAvailableDevicesCategory = mAvailableDevicesCategory; 10752ccb49fbe65c8e84a5d4fde1d8028b62a713204jackqdyulei mFragment.mDeviceListGroup = mAvailableDevicesCategory; 10852ccb49fbe65c8e84a5d4fde1d8028b62a713204jackqdyulei 109c11af01481dd7fb4515e681128340724f2008dc0Jack He mFragment.enableScanning(); 11052ccb49fbe65c8e84a5d4fde1d8028b62a713204jackqdyulei 11152ccb49fbe65c8e84a5d4fde1d8028b62a713204jackqdyulei verify(mLocalAdapter).startScanning(true); 11252ccb49fbe65c8e84a5d4fde1d8028b62a713204jackqdyulei verify(mAvailableDevicesCategory).removeAll(); 11352ccb49fbe65c8e84a5d4fde1d8028b62a713204jackqdyulei } 11452ccb49fbe65c8e84a5d4fde1d8028b62a713204jackqdyulei 11552ccb49fbe65c8e84a5d4fde1d8028b62a713204jackqdyulei @Test 11652ccb49fbe65c8e84a5d4fde1d8028b62a713204jackqdyulei public void testUpdateContent_stateOn_addDevices() { 11752ccb49fbe65c8e84a5d4fde1d8028b62a713204jackqdyulei mFragment.mAvailableDevicesCategory = mAvailableDevicesCategory; 11852ccb49fbe65c8e84a5d4fde1d8028b62a713204jackqdyulei mFragment.mFooterPreference = mFooterPreference; 11952ccb49fbe65c8e84a5d4fde1d8028b62a713204jackqdyulei doNothing().when(mFragment).addDeviceCategory(any(), anyInt(), any(), anyBoolean()); 12052ccb49fbe65c8e84a5d4fde1d8028b62a713204jackqdyulei 12152ccb49fbe65c8e84a5d4fde1d8028b62a713204jackqdyulei mFragment.updateContent(BluetoothAdapter.STATE_ON); 12252ccb49fbe65c8e84a5d4fde1d8028b62a713204jackqdyulei 12352ccb49fbe65c8e84a5d4fde1d8028b62a713204jackqdyulei verify(mFragment).addDeviceCategory(mAvailableDevicesCategory, 12452ccb49fbe65c8e84a5d4fde1d8028b62a713204jackqdyulei R.string.bluetooth_preference_found_devices, 12552ccb49fbe65c8e84a5d4fde1d8028b62a713204jackqdyulei BluetoothDeviceFilter.UNBONDED_DEVICE_FILTER, false); 12652ccb49fbe65c8e84a5d4fde1d8028b62a713204jackqdyulei verify(mLocalAdapter).setScanMode(BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE); 12752ccb49fbe65c8e84a5d4fde1d8028b62a713204jackqdyulei } 12852ccb49fbe65c8e84a5d4fde1d8028b62a713204jackqdyulei 12952ccb49fbe65c8e84a5d4fde1d8028b62a713204jackqdyulei @Test 13052ccb49fbe65c8e84a5d4fde1d8028b62a713204jackqdyulei public void testUpdateContent_stateOff_finish() { 13152ccb49fbe65c8e84a5d4fde1d8028b62a713204jackqdyulei mFragment.updateContent(BluetoothAdapter.STATE_OFF); 13252ccb49fbe65c8e84a5d4fde1d8028b62a713204jackqdyulei 13352ccb49fbe65c8e84a5d4fde1d8028b62a713204jackqdyulei verify(mFragment).finish(); 13452ccb49fbe65c8e84a5d4fde1d8028b62a713204jackqdyulei } 13552ccb49fbe65c8e84a5d4fde1d8028b62a713204jackqdyulei 136c11af01481dd7fb4515e681128340724f2008dc0Jack He @Test 137c11af01481dd7fb4515e681128340724f2008dc0Jack He public void testOnScanningStateChanged_restartScanAfterInitialScanning() { 138c11af01481dd7fb4515e681128340724f2008dc0Jack He mFragment.mAvailableDevicesCategory = mAvailableDevicesCategory; 139c11af01481dd7fb4515e681128340724f2008dc0Jack He mFragment.mFooterPreference = mFooterPreference; 140c11af01481dd7fb4515e681128340724f2008dc0Jack He mFragment.mDeviceListGroup = mAvailableDevicesCategory; 141c11af01481dd7fb4515e681128340724f2008dc0Jack He doNothing().when(mFragment).addDeviceCategory(any(), anyInt(), any(), anyBoolean()); 142c11af01481dd7fb4515e681128340724f2008dc0Jack He 143c11af01481dd7fb4515e681128340724f2008dc0Jack He // Initial Bluetooth ON will trigger scan enable, list clear and scan start 144c11af01481dd7fb4515e681128340724f2008dc0Jack He mFragment.updateContent(BluetoothAdapter.STATE_ON); 145c11af01481dd7fb4515e681128340724f2008dc0Jack He verify(mFragment).enableScanning(); 146c11af01481dd7fb4515e681128340724f2008dc0Jack He assertThat(mAvailableDevicesCategory.getPreferenceCount()).isEqualTo(0); 147c11af01481dd7fb4515e681128340724f2008dc0Jack He verify(mLocalAdapter).startScanning(true); 148c11af01481dd7fb4515e681128340724f2008dc0Jack He 149c11af01481dd7fb4515e681128340724f2008dc0Jack He // Subsequent scan started event will not trigger start/stop nor list clear 150c11af01481dd7fb4515e681128340724f2008dc0Jack He mFragment.onScanningStateChanged(true); 151c11af01481dd7fb4515e681128340724f2008dc0Jack He verify(mLocalAdapter, times(1)).startScanning(anyBoolean()); 152c11af01481dd7fb4515e681128340724f2008dc0Jack He verify(mAvailableDevicesCategory, times(1)).setProgress(true); 153c11af01481dd7fb4515e681128340724f2008dc0Jack He 154c11af01481dd7fb4515e681128340724f2008dc0Jack He // Subsequent scan finished event will trigger scan start without list clean 155c11af01481dd7fb4515e681128340724f2008dc0Jack He mFragment.onScanningStateChanged(false); 156c11af01481dd7fb4515e681128340724f2008dc0Jack He verify(mLocalAdapter, times(2)).startScanning(true); 157c11af01481dd7fb4515e681128340724f2008dc0Jack He verify(mAvailableDevicesCategory, times(2)).setProgress(true); 158c11af01481dd7fb4515e681128340724f2008dc0Jack He 159c11af01481dd7fb4515e681128340724f2008dc0Jack He // Subsequent scan started event will not trigger any change 160c11af01481dd7fb4515e681128340724f2008dc0Jack He mFragment.onScanningStateChanged(true); 161c11af01481dd7fb4515e681128340724f2008dc0Jack He verify(mLocalAdapter, times(2)).startScanning(anyBoolean()); 162c11af01481dd7fb4515e681128340724f2008dc0Jack He verify(mAvailableDevicesCategory, times(3)).setProgress(true); 163c11af01481dd7fb4515e681128340724f2008dc0Jack He verify(mLocalAdapter, never()).stopScanning(); 164c11af01481dd7fb4515e681128340724f2008dc0Jack He 165c11af01481dd7fb4515e681128340724f2008dc0Jack He // Disable scanning will trigger scan stop 166c11af01481dd7fb4515e681128340724f2008dc0Jack He mFragment.disableScanning(); 167c11af01481dd7fb4515e681128340724f2008dc0Jack He verify(mLocalAdapter, times(1)).stopScanning(); 168c11af01481dd7fb4515e681128340724f2008dc0Jack He 169c11af01481dd7fb4515e681128340724f2008dc0Jack He // Subsequent scan start event will not trigger any change besides progress circle 170c11af01481dd7fb4515e681128340724f2008dc0Jack He mFragment.onScanningStateChanged(true); 171c11af01481dd7fb4515e681128340724f2008dc0Jack He verify(mAvailableDevicesCategory, times(4)).setProgress(true); 172c11af01481dd7fb4515e681128340724f2008dc0Jack He 173c11af01481dd7fb4515e681128340724f2008dc0Jack He // However, subsequent scan finished event won't trigger new scan start and will stop 174c11af01481dd7fb4515e681128340724f2008dc0Jack He // progress circle from spinning 175c11af01481dd7fb4515e681128340724f2008dc0Jack He mFragment.onScanningStateChanged(false); 176c11af01481dd7fb4515e681128340724f2008dc0Jack He verify(mAvailableDevicesCategory, times(1)).setProgress(false); 177c11af01481dd7fb4515e681128340724f2008dc0Jack He verify(mLocalAdapter, times(2)).startScanning(anyBoolean()); 178c11af01481dd7fb4515e681128340724f2008dc0Jack He verify(mLocalAdapter, times(1)).stopScanning(); 179c11af01481dd7fb4515e681128340724f2008dc0Jack He 180c11af01481dd7fb4515e681128340724f2008dc0Jack He // Verify that clean up only happen once at initialization 181c11af01481dd7fb4515e681128340724f2008dc0Jack He verify(mAvailableDevicesCategory, times(1)).removeAll(); 182c11af01481dd7fb4515e681128340724f2008dc0Jack He } 183c11af01481dd7fb4515e681128340724f2008dc0Jack He 184c11af01481dd7fb4515e681128340724f2008dc0Jack He 185c11af01481dd7fb4515e681128340724f2008dc0Jack He 18652ccb49fbe65c8e84a5d4fde1d8028b62a713204jackqdyulei} 187