• 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 package com.android.settings.bluetooth;
17 
18 import static org.mockito.ArgumentMatchers.any;
19 import static org.mockito.Mockito.doNothing;
20 import static org.mockito.Mockito.doReturn;
21 import static org.mockito.Mockito.doThrow;
22 import static org.mockito.Mockito.mock;
23 import static org.mockito.Mockito.never;
24 import static org.mockito.Mockito.spy;
25 import static org.mockito.Mockito.verify;
26 import static org.mockito.Mockito.when;
27 
28 import android.bluetooth.BluetoothAdapter;
29 import android.bluetooth.BluetoothDevice;
30 import android.bluetooth.BluetoothProfile;
31 import android.content.Context;
32 import android.content.pm.ApplicationInfo;
33 import android.content.pm.PackageManager;
34 import android.graphics.drawable.Drawable;
35 import android.util.Pair;
36 
37 import com.android.settings.connecteddevice.DevicePreferenceCallback;
38 import com.android.settings.dashboard.DashboardFragment;
39 import com.android.settings.testutils.shadow.ShadowBluetoothAdapter;
40 import com.android.settingslib.bluetooth.CachedBluetoothDevice;
41 import com.android.settingslib.bluetooth.CachedBluetoothDeviceManager;
42 import com.android.settingslib.bluetooth.LocalBluetoothManager;
43 
44 import org.junit.Before;
45 import org.junit.Test;
46 import org.junit.runner.RunWith;
47 import org.mockito.Mock;
48 import org.mockito.MockitoAnnotations;
49 import org.robolectric.RobolectricTestRunner;
50 import org.robolectric.RuntimeEnvironment;
51 import org.robolectric.annotation.Config;
52 
53 import java.util.ArrayList;
54 import java.util.Collection;
55 import java.util.List;
56 
57 @RunWith(RobolectricTestRunner.class)
58 @Config(shadows = {ShadowBluetoothAdapter.class})
59 public class SavedBluetoothDeviceUpdaterTest {
60 
61     private static final String MAC_ADDRESS = "04:52:C7:0B:D8:3C";
62     private static final String TEST_EXCLUSIVE_MANAGER = "com.test.manager";
63 
64     @Mock
65     private DashboardFragment mDashboardFragment;
66     @Mock
67     private DevicePreferenceCallback mDevicePreferenceCallback;
68     @Mock
69     private CachedBluetoothDevice mCachedBluetoothDevice;
70     @Mock
71     private BluetoothDevice mBluetoothDevice;
72     @Mock
73     private BluetoothAdapter mBluetoothAdapter;
74     @Mock
75     private CachedBluetoothDeviceManager mDeviceManager;
76     @Mock
77     private LocalBluetoothManager mBluetoothManager;
78     @Mock
79     private Drawable mDrawable;
80     @Mock
81     private PackageManager mPackageManager;
82 
83     private Context mContext;
84     private SavedBluetoothDeviceUpdater mBluetoothDeviceUpdater;
85     private BluetoothDevicePreference mPreference;
86     private List<CachedBluetoothDevice> mCachedDevices = new ArrayList<>();
87 
88     @Before
setUp()89     public void setUp() {
90         MockitoAnnotations.initMocks(this);
91 
92         Pair<Drawable, String> pairs = new Pair<>(mDrawable, "fake_device");
93         mContext = spy(RuntimeEnvironment.application);
94         doReturn(mContext).when(mDashboardFragment).getContext();
95         when(mCachedBluetoothDevice.getDevice()).thenReturn(mBluetoothDevice);
96         when(mCachedBluetoothDevice.getAddress()).thenReturn(MAC_ADDRESS);
97         when(mBluetoothDevice.getBondState()).thenReturn(BluetoothDevice.BOND_BONDED);
98         when(mCachedBluetoothDevice.getDrawableWithDescription()).thenReturn(pairs);
99         when(mContext.getPackageManager()).thenReturn(mPackageManager);
100 
101         mBluetoothDeviceUpdater = spy(new SavedBluetoothDeviceUpdater(mContext,
102                 mDevicePreferenceCallback, false, /* metricsCategory= */ 0));
103         mBluetoothDeviceUpdater.setPrefContext(mContext);
104         mBluetoothDeviceUpdater.mBluetoothAdapter = mBluetoothAdapter;
105         mBluetoothDeviceUpdater.mLocalManager = mBluetoothManager;
106         mPreference = new BluetoothDevicePreference(mContext, mCachedBluetoothDevice,
107                 false, BluetoothDevicePreference.SortType.TYPE_DEFAULT);
108         doNothing().when(mBluetoothDeviceUpdater).addPreference(any());
109         doNothing().when(mBluetoothDeviceUpdater).removePreference(
110                 any(CachedBluetoothDevice.class));
111         mCachedDevices.add(mCachedBluetoothDevice);
112         when(mBluetoothManager.getCachedDeviceManager()).thenReturn(mDeviceManager);
113         when(mDeviceManager.getCachedDevicesCopy()).thenReturn(mCachedDevices);
114     }
115 
116     @Test
onProfileConnectionStateChanged_deviceConnected_removePreference()117     public void onProfileConnectionStateChanged_deviceConnected_removePreference() {
118         when(mBluetoothDevice.isConnected()).thenReturn(true);
119 
120         mBluetoothDeviceUpdater.onProfileConnectionStateChanged(mCachedBluetoothDevice,
121                 BluetoothProfile.STATE_CONNECTED, BluetoothProfile.A2DP);
122 
123         verify(mBluetoothDeviceUpdater).removePreference(mCachedBluetoothDevice);
124     }
125 
126     @Test
onProfileConnectionStateChanged_deviceDisconnected_addPreference()127     public void onProfileConnectionStateChanged_deviceDisconnected_addPreference() {
128         when(mBluetoothDevice.isConnected()).thenReturn(false);
129 
130         mBluetoothDeviceUpdater.onProfileConnectionStateChanged(mCachedBluetoothDevice,
131                 BluetoothProfile.STATE_DISCONNECTED, BluetoothProfile.A2DP);
132 
133         verify(mBluetoothDeviceUpdater).addPreference(mCachedBluetoothDevice,
134                 BluetoothDevicePreference.SortType.TYPE_NO_SORT);
135     }
136 
137     @Test
138     public void
onProfileConnectionStateChanged_leDeviceDisconnected_inDeviceList_invokesAddPreference()139             onProfileConnectionStateChanged_leDeviceDisconnected_inDeviceList_invokesAddPreference()
140     {
141         when(mBluetoothDevice.isConnected()).thenReturn(false);
142 
143         mBluetoothDeviceUpdater.onProfileConnectionStateChanged(mCachedBluetoothDevice,
144                 BluetoothProfile.STATE_DISCONNECTED, BluetoothProfile.LE_AUDIO);
145 
146         verify(mBluetoothDeviceUpdater).addPreference(mCachedBluetoothDevice,
147                 BluetoothDevicePreference.SortType.TYPE_NO_SORT);
148     }
149 
150     @Test
151     public void
onProfileConnectionStateChanged_deviceDisconnected_notInDeviceList_invokesRemovePreference()152     onProfileConnectionStateChanged_deviceDisconnected_notInDeviceList_invokesRemovePreference() {
153         when(mBluetoothDevice.isConnected()).thenReturn(false);
154         mCachedDevices.clear();
155 
156         mBluetoothDeviceUpdater.onProfileConnectionStateChanged(mCachedBluetoothDevice,
157                 BluetoothProfile.STATE_DISCONNECTED, BluetoothProfile.LE_AUDIO);
158 
159         verify(mBluetoothDeviceUpdater).removePreference(mCachedBluetoothDevice);
160     }
161 
162     @Test
onClick_Preference_setConnect()163     public void onClick_Preference_setConnect() {
164         mBluetoothDeviceUpdater.onPreferenceClick(mPreference);
165 
166         verify(mCachedBluetoothDevice).connect();
167     }
168 
169     @Test
onClick_Preference_connected_setActive()170     public void onClick_Preference_connected_setActive() {
171         when(mCachedBluetoothDevice.isConnected()).thenReturn(true);
172 
173         mBluetoothDeviceUpdater.onPreferenceClick(mPreference);
174 
175         verify(mCachedBluetoothDevice).setActive();
176     }
177 
178     @Test
forceUpdate_findCachedBluetoothDeviceIsMatched_addPreference()179     public void forceUpdate_findCachedBluetoothDeviceIsMatched_addPreference() {
180         final List<BluetoothDevice> bluetoothDevices = new ArrayList<>();
181         bluetoothDevices.add(mBluetoothDevice);
182 
183         when(mBluetoothAdapter.isEnabled()).thenReturn(true);
184         when(mBluetoothAdapter.getMostRecentlyConnectedDevices()).thenReturn(bluetoothDevices);
185         when(mBluetoothManager.getCachedDeviceManager()).thenReturn(mDeviceManager);
186         when(mDeviceManager.findDevice(mBluetoothDevice)).thenReturn(mCachedBluetoothDevice);
187         when(mBluetoothDevice.getBondState()).thenReturn(BluetoothDevice.BOND_BONDED);
188         when(mBluetoothDevice.isConnected()).thenReturn(false);
189 
190         mBluetoothDeviceUpdater.forceUpdate();
191 
192         verify(mBluetoothDeviceUpdater).addPreference(mCachedBluetoothDevice,
193                 BluetoothDevicePreference.SortType.TYPE_NO_SORT);
194     }
195 
196     @Test
forceUpdate_findCachedBluetoothDeviceNotMatched_removePreference()197     public void forceUpdate_findCachedBluetoothDeviceNotMatched_removePreference() {
198         final List<BluetoothDevice> bluetoothDevices = new ArrayList<>();
199         bluetoothDevices.add(mBluetoothDevice);
200 
201         when(mBluetoothAdapter.isEnabled()).thenReturn(true);
202         when(mBluetoothAdapter.getMostRecentlyConnectedDevices()).thenReturn(bluetoothDevices);
203         when(mBluetoothManager.getCachedDeviceManager()).thenReturn(mDeviceManager);
204         when(mDeviceManager.findDevice(mBluetoothDevice)).thenReturn(mCachedBluetoothDevice);
205         when(mBluetoothDevice.getBondState()).thenReturn(BluetoothDevice.BOND_BONDED);
206         when(mBluetoothDevice.isConnected()).thenReturn(true);
207 
208         mBluetoothDeviceUpdater.forceUpdate();
209 
210         verify(mBluetoothDeviceUpdater).removePreference(mCachedBluetoothDevice);
211     }
212 
213     @Test
forceUpdate_notFindCachedBluetoothDevice_doNothing()214     public void forceUpdate_notFindCachedBluetoothDevice_doNothing() {
215         final List<BluetoothDevice> bluetoothDevices = new ArrayList<>();
216         bluetoothDevices.add(mBluetoothDevice);
217 
218         when(mBluetoothAdapter.isEnabled()).thenReturn(true);
219         when(mBluetoothAdapter.getMostRecentlyConnectedDevices()).thenReturn(bluetoothDevices);
220         when(mBluetoothManager.getCachedDeviceManager()).thenReturn(mDeviceManager);
221         when(mDeviceManager.findDevice(mBluetoothDevice)).thenReturn(null);
222 
223         mBluetoothDeviceUpdater.forceUpdate();
224 
225         verify(mBluetoothDeviceUpdater, never()).removePreference(mCachedBluetoothDevice);
226         verify(mBluetoothDeviceUpdater, never()).addPreference(mCachedBluetoothDevice,
227                 BluetoothDevicePreference.SortType.TYPE_NO_SORT);
228     }
229 
230     @Test
forceUpdate_bluetoothAdapterNotEnable_removeAllDevicesFromPreference()231     public void forceUpdate_bluetoothAdapterNotEnable_removeAllDevicesFromPreference() {
232         final Collection<CachedBluetoothDevice> cachedDevices = new ArrayList<>();
233         cachedDevices.add(mCachedBluetoothDevice);
234 
235         when(mBluetoothManager.getCachedDeviceManager()).thenReturn(mDeviceManager);
236         when(mDeviceManager.getCachedDevicesCopy()).thenReturn(cachedDevices);
237         when(mBluetoothAdapter.isEnabled()).thenReturn(false);
238 
239         mBluetoothDeviceUpdater.forceUpdate();
240 
241         verify(mBluetoothDeviceUpdater).removeAllDevicesFromPreference();
242     }
243 
244     @Test
forceUpdate_deviceNotContain_removePreference()245     public void forceUpdate_deviceNotContain_removePreference() {
246         final List<BluetoothDevice> bluetoothDevices = new ArrayList<>();
247         bluetoothDevices.add(mBluetoothDevice);
248         final BluetoothDevice device2 = mock(BluetoothDevice.class);
249         final CachedBluetoothDevice cachedDevice2 = mock(CachedBluetoothDevice.class);
250 
251         mBluetoothDeviceUpdater.mPreferenceMap.put(device2, mPreference);
252 
253         when(cachedDevice2.getDevice()).thenReturn(device2);
254         when(cachedDevice2.getAddress()).thenReturn("04:52:C7:0B:D8:3S");
255         when(mDeviceManager.findDevice(device2)).thenReturn(cachedDevice2);
256         when(mBluetoothAdapter.isEnabled()).thenReturn(true);
257         when(mBluetoothAdapter.getMostRecentlyConnectedDevices()).thenReturn(bluetoothDevices);
258         when(mBluetoothManager.getCachedDeviceManager()).thenReturn(mDeviceManager);
259         when(mDeviceManager.findDevice(mBluetoothDevice)).thenReturn(mCachedBluetoothDevice);
260         when(mBluetoothDevice.getBondState()).thenReturn(BluetoothDevice.BOND_BONDED);
261         when(mBluetoothDevice.isConnected()).thenReturn(false);
262 
263         mBluetoothDeviceUpdater.forceUpdate();
264 
265         verify(mBluetoothDeviceUpdater).removePreference(cachedDevice2);
266         verify(mBluetoothDeviceUpdater).addPreference(mCachedBluetoothDevice,
267                 BluetoothDevicePreference.SortType.TYPE_NO_SORT);
268     }
269 
270     @Test
forceUpdate_deviceIsSubDevice_doesNothing()271     public void forceUpdate_deviceIsSubDevice_doesNothing() {
272         final List<BluetoothDevice> bluetoothDevices = new ArrayList<>();
273         bluetoothDevices.add(mBluetoothDevice);
274 
275         when(mBluetoothAdapter.isEnabled()).thenReturn(true);
276         when(mBluetoothAdapter.getMostRecentlyConnectedDevices()).thenReturn(bluetoothDevices);
277         when(mBluetoothManager.getCachedDeviceManager()).thenReturn(mDeviceManager);
278         when(mDeviceManager.findDevice(mBluetoothDevice)).thenReturn(mCachedBluetoothDevice);
279         when(mDeviceManager.isSubDevice(mBluetoothDevice)).thenReturn(true);
280 
281         mBluetoothDeviceUpdater.forceUpdate();
282 
283         verify(mBluetoothDeviceUpdater, never()).removePreference(mCachedBluetoothDevice);
284         verify(mBluetoothDeviceUpdater, never()).addPreference(mCachedBluetoothDevice,
285                 BluetoothDevicePreference.SortType.TYPE_NO_SORT);
286     }
287 
288     @Test
update_notExclusivelyManagedDevice_addDevice()289     public void update_notExclusivelyManagedDevice_addDevice() {
290         final Collection<CachedBluetoothDevice> cachedDevices = new ArrayList<>();
291         cachedDevices.add(mCachedBluetoothDevice);
292 
293         when(mBluetoothAdapter.isEnabled()).thenReturn(true);
294         when(mBluetoothManager.getCachedDeviceManager()).thenReturn(mDeviceManager);
295         when(mDeviceManager.getCachedDevicesCopy()).thenReturn(cachedDevices);
296         when(mBluetoothDevice.getBondState()).thenReturn(BluetoothDevice.BOND_BONDED);
297         when(mBluetoothDevice.isConnected()).thenReturn(false);
298         when(mBluetoothDevice.getMetadata(BluetoothDevice.METADATA_EXCLUSIVE_MANAGER)).thenReturn(
299                 null);
300 
301         mBluetoothDeviceUpdater.update(mCachedBluetoothDevice);
302 
303         verify(mBluetoothDeviceUpdater).addPreference(mCachedBluetoothDevice,
304                 BluetoothDevicePreference.SortType.TYPE_NO_SORT);
305     }
306 
307     @Test
update_existingExclusivelyManagedDevice_packageEnabled_removePreference()308     public void update_existingExclusivelyManagedDevice_packageEnabled_removePreference()
309             throws Exception {
310         final Collection<CachedBluetoothDevice> cachedDevices = new ArrayList<>();
311         when(mBluetoothAdapter.isEnabled()).thenReturn(true);
312         when(mBluetoothManager.getCachedDeviceManager()).thenReturn(mDeviceManager);
313         when(mDeviceManager.getCachedDevicesCopy()).thenReturn(cachedDevices);
314         when(mBluetoothDevice.getBondState()).thenReturn(BluetoothDevice.BOND_BONDED);
315         when(mBluetoothDevice.isConnected()).thenReturn(false);
316         when(mBluetoothDevice.getMetadata(BluetoothDevice.METADATA_EXCLUSIVE_MANAGER)).thenReturn(
317                 TEST_EXCLUSIVE_MANAGER.getBytes());
318         doReturn(new ApplicationInfo()).when(mPackageManager).getApplicationInfo(
319                 TEST_EXCLUSIVE_MANAGER, 0);
320         mBluetoothDeviceUpdater.mPreferenceMap.put(mBluetoothDevice, mPreference);
321 
322         mBluetoothDeviceUpdater.update(mCachedBluetoothDevice);
323 
324         verify(mBluetoothDeviceUpdater).removePreference(mCachedBluetoothDevice);
325         verify(mBluetoothDeviceUpdater, never()).addPreference(mCachedBluetoothDevice,
326                 BluetoothDevicePreference.SortType.TYPE_NO_SORT);
327     }
328 
329     @Test
update_newExclusivelyManagedDevice_packageEnabled_doNotAddPreference()330     public void update_newExclusivelyManagedDevice_packageEnabled_doNotAddPreference()
331             throws Exception {
332         final Collection<CachedBluetoothDevice> cachedDevices = new ArrayList<>();
333         cachedDevices.add(mCachedBluetoothDevice);
334         when(mBluetoothAdapter.isEnabled()).thenReturn(true);
335         when(mBluetoothManager.getCachedDeviceManager()).thenReturn(mDeviceManager);
336         when(mDeviceManager.getCachedDevicesCopy()).thenReturn(cachedDevices);
337         when(mBluetoothDevice.getBondState()).thenReturn(BluetoothDevice.BOND_BONDED);
338         when(mBluetoothDevice.isConnected()).thenReturn(false);
339         when(mBluetoothDevice.getMetadata(BluetoothDevice.METADATA_EXCLUSIVE_MANAGER)).thenReturn(
340                 TEST_EXCLUSIVE_MANAGER.getBytes());
341         doReturn(new ApplicationInfo()).when(mPackageManager).getApplicationInfo(
342                 TEST_EXCLUSIVE_MANAGER, 0);
343 
344         mBluetoothDeviceUpdater.update(mCachedBluetoothDevice);
345 
346         verify(mBluetoothDeviceUpdater).removePreference(mCachedBluetoothDevice);
347         verify(mBluetoothDeviceUpdater, never()).addPreference(mCachedBluetoothDevice,
348                 BluetoothDevicePreference.SortType.TYPE_NO_SORT);
349     }
350 
351     @Test
update_exclusivelyManagedDevice_packageNotInstalled_addDevice()352     public void update_exclusivelyManagedDevice_packageNotInstalled_addDevice()
353             throws Exception {
354         final Collection<CachedBluetoothDevice> cachedDevices = new ArrayList<>();
355         cachedDevices.add(mCachedBluetoothDevice);
356         when(mBluetoothAdapter.isEnabled()).thenReturn(true);
357         when(mBluetoothManager.getCachedDeviceManager()).thenReturn(mDeviceManager);
358         when(mDeviceManager.getCachedDevicesCopy()).thenReturn(cachedDevices);
359         when(mBluetoothDevice.getBondState()).thenReturn(BluetoothDevice.BOND_BONDED);
360         when(mBluetoothDevice.isConnected()).thenReturn(false);
361         when(mBluetoothDevice.getMetadata(BluetoothDevice.METADATA_EXCLUSIVE_MANAGER)).thenReturn(
362                 TEST_EXCLUSIVE_MANAGER.getBytes());
363         doThrow(new PackageManager.NameNotFoundException()).when(mPackageManager)
364                 .getApplicationInfo(TEST_EXCLUSIVE_MANAGER, 0);
365 
366         mBluetoothDeviceUpdater.update(mCachedBluetoothDevice);
367 
368         verify(mBluetoothDeviceUpdater).addPreference(mCachedBluetoothDevice,
369                 BluetoothDevicePreference.SortType.TYPE_NO_SORT);
370     }
371 
372     @Test
update_exclusivelyManagedDevice_packageNotEnabled_addDevice()373     public void update_exclusivelyManagedDevice_packageNotEnabled_addDevice()
374             throws Exception {
375         final Collection<CachedBluetoothDevice> cachedDevices = new ArrayList<>();
376         cachedDevices.add(mCachedBluetoothDevice);
377         ApplicationInfo appInfo = new ApplicationInfo();
378         appInfo.enabled = false;
379         when(mBluetoothAdapter.isEnabled()).thenReturn(true);
380         when(mBluetoothManager.getCachedDeviceManager()).thenReturn(mDeviceManager);
381         when(mDeviceManager.getCachedDevicesCopy()).thenReturn(cachedDevices);
382         when(mBluetoothDevice.getBondState()).thenReturn(BluetoothDevice.BOND_BONDED);
383         when(mBluetoothDevice.isConnected()).thenReturn(false);
384         when(mBluetoothDevice.getMetadata(BluetoothDevice.METADATA_EXCLUSIVE_MANAGER)).thenReturn(
385                 TEST_EXCLUSIVE_MANAGER.getBytes());
386         doReturn(appInfo).when(mPackageManager).getApplicationInfo(TEST_EXCLUSIVE_MANAGER, 0);
387 
388         mBluetoothDeviceUpdater.update(mCachedBluetoothDevice);
389 
390         verify(mBluetoothDeviceUpdater).addPreference(mCachedBluetoothDevice,
391                 BluetoothDevicePreference.SortType.TYPE_NO_SORT);
392     }
393 }
394