• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2017 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.settings.bluetooth;
18 
19 import static com.google.common.truth.Truth.assertThat;
20 
21 import static org.mockito.ArgumentMatchers.any;
22 import static org.mockito.ArgumentMatchers.anyBoolean;
23 import static org.mockito.ArgumentMatchers.anyInt;
24 import static org.mockito.Mockito.doNothing;
25 import static org.mockito.Mockito.doReturn;
26 import static org.mockito.Mockito.never;
27 import static org.mockito.Mockito.spy;
28 import static org.mockito.Mockito.times;
29 import static org.mockito.Mockito.verify;
30 
31 import android.bluetooth.BluetoothAdapter;
32 import android.bluetooth.BluetoothDevice;
33 import android.content.Context;
34 import android.content.res.Resources;
35 
36 import androidx.preference.PreferenceGroup;
37 
38 import com.android.settings.R;
39 import com.android.settings.testutils.shadow.ShadowBluetoothAdapter;
40 import com.android.settingslib.bluetooth.BluetoothDeviceFilter;
41 import com.android.settingslib.bluetooth.CachedBluetoothDevice;
42 import com.android.settingslib.bluetooth.LocalBluetoothManager;
43 import com.android.settingslib.widget.FooterPreference;
44 
45 import org.junit.Before;
46 import org.junit.Test;
47 import org.junit.runner.RunWith;
48 import org.mockito.Answers;
49 import org.mockito.Mock;
50 import org.mockito.MockitoAnnotations;
51 import org.robolectric.RobolectricTestRunner;
52 import org.robolectric.RuntimeEnvironment;
53 import org.robolectric.annotation.Config;
54 import org.robolectric.shadow.api.Shadow;
55 
56 @RunWith(RobolectricTestRunner.class)
57 @Config(shadows = {ShadowBluetoothAdapter.class})
58 public class BluetoothPairingDetailTest {
59     private static final String TEST_DEVICE_ADDRESS = "00:A1:A1:A1:A1:A1";
60 
61     @Mock
62     private Resources mResource;
63     @Mock(answer = Answers.RETURNS_DEEP_STUBS)
64     private LocalBluetoothManager mLocalManager;
65     @Mock
66     private PreferenceGroup mPreferenceGroup;
67     @Mock
68     private CachedBluetoothDevice mCachedBluetoothDevice;
69     private BluetoothPairingDetail mFragment;
70     private Context mContext;
71     private BluetoothProgressCategory mAvailableDevicesCategory;
72     private FooterPreference mFooterPreference;
73     private BluetoothAdapter mBluetoothAdapter;
74     private ShadowBluetoothAdapter mShadowBluetoothAdapter;
75     private BluetoothDevice mBluetoothDevice;
76 
77     @Before
setUp()78     public void setUp() {
79         MockitoAnnotations.initMocks(this);
80 
81         mContext = RuntimeEnvironment.application;
82         mFragment = spy(new BluetoothPairingDetail());
83         doReturn(mContext).when(mFragment).getContext();
84         doReturn(mResource).when(mFragment).getResources();
85 
86         mAvailableDevicesCategory = spy(new BluetoothProgressCategory(mContext));
87         mFooterPreference = new FooterPreference(mContext);
88         mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
89         mShadowBluetoothAdapter = Shadow.extract(BluetoothAdapter.getDefaultAdapter());
90         mBluetoothDevice = mBluetoothAdapter.getRemoteDevice(TEST_DEVICE_ADDRESS);
91 
92         mFragment.mBluetoothAdapter = mBluetoothAdapter;
93         mFragment.mLocalManager = mLocalManager;
94         mFragment.mDeviceListGroup = mPreferenceGroup;
95         mFragment.mAlwaysDiscoverable = new AlwaysDiscoverable(mContext);
96     }
97 
98     @Test
initPreferencesFromPreferenceScreen_findPreferences()99     public void initPreferencesFromPreferenceScreen_findPreferences() {
100         doReturn(mAvailableDevicesCategory).when(mFragment)
101             .findPreference(BluetoothPairingDetail.KEY_AVAIL_DEVICES);
102         doReturn(mFooterPreference).when(mFragment)
103             .findPreference(BluetoothPairingDetail.KEY_FOOTER_PREF);
104 
105         mFragment.initPreferencesFromPreferenceScreen();
106 
107         assertThat(mFragment.mAvailableDevicesCategory).isEqualTo(mAvailableDevicesCategory);
108         assertThat(mFragment.mFooterPreference).isEqualTo(mFooterPreference);
109     }
110 
111     @Test
startScanning_startScanAndRemoveDevices()112     public void startScanning_startScanAndRemoveDevices() {
113         mFragment.mAvailableDevicesCategory = mAvailableDevicesCategory;
114         mFragment.mDeviceListGroup = mAvailableDevicesCategory;
115 
116         mFragment.enableScanning();
117 
118         verify(mFragment).startScanning();
119         verify(mAvailableDevicesCategory).removeAll();
120     }
121 
122     @Test
updateContent_stateOn_addDevices()123     public void updateContent_stateOn_addDevices() {
124         mFragment.mAvailableDevicesCategory = mAvailableDevicesCategory;
125         mFragment.mFooterPreference = mFooterPreference;
126         doNothing().when(mFragment).addDeviceCategory(any(), anyInt(), any(), anyBoolean());
127 
128         mFragment.updateContent(BluetoothAdapter.STATE_ON);
129 
130         verify(mFragment).addDeviceCategory(mAvailableDevicesCategory,
131                 R.string.bluetooth_preference_found_media_devices,
132                 BluetoothDeviceFilter.ALL_FILTER, false);
133         assertThat(mBluetoothAdapter.getScanMode())
134                 .isEqualTo(BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE);
135     }
136 
137     @Test
updateContent_stateOff_finish()138     public void updateContent_stateOff_finish() {
139         mFragment.updateContent(BluetoothAdapter.STATE_OFF);
140 
141         verify(mFragment).finish();
142     }
143 
144     @Test
updateBluetooth_bluetoothOff_turnOnBluetooth()145     public void updateBluetooth_bluetoothOff_turnOnBluetooth() {
146         mShadowBluetoothAdapter.setEnabled(false);
147 
148         mFragment.updateBluetooth();
149 
150         assertThat(mBluetoothAdapter.isEnabled()).isTrue();
151     }
152 
153     @Test
updateBluetooth_bluetoothOn_updateState()154     public void updateBluetooth_bluetoothOn_updateState() {
155         mShadowBluetoothAdapter.setEnabled(true);
156         doNothing().when(mFragment).updateContent(anyInt());
157 
158         mFragment.updateBluetooth();
159 
160         verify(mFragment).updateContent(anyInt());
161     }
162 
163     @Test
onScanningStateChanged_restartScanAfterInitialScanning()164     public void onScanningStateChanged_restartScanAfterInitialScanning() {
165         mFragment.mAvailableDevicesCategory = mAvailableDevicesCategory;
166         mFragment.mFooterPreference = mFooterPreference;
167         mFragment.mDeviceListGroup = mAvailableDevicesCategory;
168         doNothing().when(mFragment).addDeviceCategory(any(), anyInt(), any(), anyBoolean());
169 
170         // Initial Bluetooth ON will trigger scan enable, list clear and scan start
171         mFragment.updateContent(BluetoothAdapter.STATE_ON);
172         verify(mFragment).enableScanning();
173         assertThat(mAvailableDevicesCategory.getPreferenceCount()).isEqualTo(0);
174         verify(mFragment).startScanning();
175 
176         // Subsequent scan started event will not trigger start/stop nor list clear
177         mFragment.onScanningStateChanged(true);
178         verify(mFragment, times(1)).startScanning();
179         verify(mAvailableDevicesCategory, times(1)).setProgress(true);
180 
181         // Subsequent scan finished event will trigger scan start without list clean
182         mFragment.onScanningStateChanged(false);
183         verify(mFragment, times(2)).startScanning();
184         verify(mAvailableDevicesCategory, times(2)).setProgress(true);
185 
186         // Subsequent scan started event will not trigger any change
187         mFragment.onScanningStateChanged(true);
188         verify(mFragment, times(2)).startScanning();
189         verify(mAvailableDevicesCategory, times(3)).setProgress(true);
190         verify(mFragment, never()).stopScanning();
191 
192         // Disable scanning will trigger scan stop
193         mFragment.disableScanning();
194         verify(mFragment, times(1)).stopScanning();
195 
196         // Subsequent scan start event will not trigger any change besides progress circle
197         mFragment.onScanningStateChanged(true);
198         verify(mAvailableDevicesCategory, times(4)).setProgress(true);
199 
200         // However, subsequent scan finished event won't trigger new scan start and will stop
201         // progress circle from spinning
202         mFragment.onScanningStateChanged(false);
203         verify(mAvailableDevicesCategory, times(1)).setProgress(false);
204         verify(mFragment, times(2)).startScanning();
205         verify(mFragment, times(1)).stopScanning();
206 
207         // Verify that clean up only happen once at initialization
208         verify(mAvailableDevicesCategory, times(1)).removeAll();
209     }
210 
211     @Test
onBluetoothStateChanged_whenTurnedOnBTShowToast()212     public void onBluetoothStateChanged_whenTurnedOnBTShowToast() {
213         doNothing().when(mFragment).updateContent(anyInt());
214 
215         mFragment.onBluetoothStateChanged(BluetoothAdapter.STATE_ON);
216 
217         verify(mFragment).showBluetoothTurnedOnToast();
218     }
219 
220     @Test
onConnectionStateChanged_connected_finish()221     public void onConnectionStateChanged_connected_finish() {
222         mFragment.mSelectedDevice = mBluetoothDevice;
223         doReturn(mBluetoothDevice).when(mCachedBluetoothDevice).getDevice();
224 
225         mFragment.onConnectionStateChanged(mCachedBluetoothDevice,
226                 BluetoothAdapter.STATE_CONNECTED);
227 
228         verify(mFragment).finish();
229     }
230 }