1 /*
2  * Copyright (C) 2021 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.car.settings.qc;
18 
19 import static android.os.UserManager.DISALLOW_BLUETOOTH;
20 
21 import static com.android.car.qc.QCItem.QC_ACTION_TOGGLE_STATE;
22 import static com.android.car.settings.qc.PairedBluetoothDevices.BLUETOOTH_BUTTON;
23 import static com.android.car.settings.qc.PairedBluetoothDevices.EXTRA_BUTTON_TYPE;
24 import static com.android.car.settings.qc.PairedBluetoothDevices.EXTRA_DEVICE_KEY;
25 import static com.android.car.settings.qc.PairedBluetoothDevices.MEDIA_BUTTON;
26 import static com.android.car.settings.qc.PairedBluetoothDevices.PHONE_BUTTON;
27 
28 import static com.google.common.truth.Truth.assertThat;
29 
30 import static org.mockito.ArgumentMatchers.any;
31 import static org.mockito.ArgumentMatchers.anyBoolean;
32 import static org.mockito.ArgumentMatchers.eq;
33 import static org.mockito.Mockito.mock;
34 import static org.mockito.Mockito.verify;
35 import static org.mockito.Mockito.when;
36 
37 import android.bluetooth.BluetoothAdapter;
38 import android.bluetooth.BluetoothClass;
39 import android.bluetooth.BluetoothDevice;
40 import android.bluetooth.BluetoothProfile;
41 import android.content.Intent;
42 import android.os.UserManager;
43 
44 import androidx.test.ext.junit.runners.AndroidJUnit4;
45 
46 import com.android.car.qc.QCActionItem;
47 import com.android.car.qc.QCItem;
48 import com.android.car.qc.QCList;
49 import com.android.car.qc.QCRow;
50 import com.android.car.settings.R;
51 import com.android.dx.mockito.inline.extended.ExtendedMockito;
52 import com.android.settingslib.bluetooth.CachedBluetoothDevice;
53 import com.android.settingslib.bluetooth.CachedBluetoothDeviceManager;
54 import com.android.settingslib.bluetooth.LocalBluetoothAdapter;
55 import com.android.settingslib.bluetooth.LocalBluetoothManager;
56 import com.android.settingslib.bluetooth.LocalBluetoothProfile;
57 
58 import org.junit.After;
59 import org.junit.Before;
60 import org.junit.Test;
61 import org.junit.runner.RunWith;
62 import org.mockito.Mock;
63 import org.mockito.MockitoAnnotations;
64 import org.mockito.MockitoSession;
65 import org.mockito.quality.Strictness;
66 
67 import java.util.ArrayList;
68 import java.util.Arrays;
69 import java.util.HashSet;
70 import java.util.Set;
71 
72 @RunWith(AndroidJUnit4.class)
73 public class PairedBluetoothDevicesTest extends BaseSettingsQCItemTestCase {
74     private static final String DEFAULT_NAME = "DEFAULT_NAME";
75     private static final String DEFAULT_SUMMARY = "DEFAULT_SUMMARY";
76     private static final String DEFAULT_ADDRESS = "F6:8F:AC:E8:32:50";
77 
78     private PairedBluetoothDevices mPairedBluetoothDevices;
79     private MockitoSession mSession;
80     private ArrayList<CachedBluetoothDevice> mCachedDevices = new ArrayList<>();
81     private Set<BluetoothDevice> mBondedDevices = new HashSet<>();
82 
83     @Mock
84     private BluetoothAdapter mBluetoothAdapter;
85     @Mock
86     private LocalBluetoothAdapter mLocalBluetoothAdapter;
87     @Mock
88     private LocalBluetoothManager mBluetoothManager;
89 
90     @Before
setUp()91     public void setUp() {
92         MockitoAnnotations.initMocks(this);
93         mSession = ExtendedMockito.mockitoSession()
94                 .strictness(Strictness.LENIENT)
95                 .mockStatic(BluetoothAdapter.class)
96                 .mockStatic(LocalBluetoothManager.class)
97                 .startMocking();
98         when(BluetoothAdapter.getDefaultAdapter()).thenReturn(mBluetoothAdapter);
99         when(mBluetoothAdapter.isEnabled()).thenReturn(true);
100         when(LocalBluetoothManager.getInstance(any(), any())).thenReturn(mBluetoothManager);
101         when(mBluetoothManager.getBluetoothAdapter()).thenReturn(mLocalBluetoothAdapter);
102         when(mLocalBluetoothAdapter.getBondedDevices()).thenReturn(mBondedDevices);
103 
104         CachedBluetoothDeviceManager deviceManager = mock(CachedBluetoothDeviceManager.class);
105         when(mBluetoothManager.getCachedDeviceManager()).thenReturn(deviceManager);
106         when(deviceManager.getCachedDevicesCopy()).thenReturn(mCachedDevices);
107 
108         mPairedBluetoothDevices = new PairedBluetoothDevices(mContext);
109     }
110 
111     @After
tearDown()112     public void tearDown() {
113         if (mSession != null) {
114             mSession.finishMocking();
115         }
116     }
117 
118     @Test
getQCItem_bluetoothDisallowed_returnsNull()119     public void getQCItem_bluetoothDisallowed_returnsNull() {
120         setUserRestriction(DISALLOW_BLUETOOTH, true);
121         QCItem item = mPairedBluetoothDevices.getQCItem();
122         assertThat(item).isNull();
123     }
124 
125     @Test
getQCItem_bluetoothDisabled_returnsBluetoothDisabledMessage()126     public void getQCItem_bluetoothDisabled_returnsBluetoothDisabledMessage() {
127         when(mBluetoothAdapter.isEnabled()).thenReturn(false);
128         QCItem item = mPairedBluetoothDevices.getQCItem();
129         assertThat(item).isNotNull();
130         QCList list = (QCList) item;
131         assertThat(list.getRows().size()).isEqualTo(1);
132         QCRow row = list.getRows().get(0);
133         assertThat(row.getTitle()).isEqualTo(
134                 mContext.getString(R.string.qc_bluetooth_off_devices_info));
135         assertThat(row.getStartIcon()).isNotNull();
136     }
137 
138     @Test
getQCItem_noDevices_returnsPairMessage()139     public void getQCItem_noDevices_returnsPairMessage() {
140         QCList list = (QCList) mPairedBluetoothDevices.getQCItem();
141         assertThat(list.getRows().size()).isEqualTo(1);
142         QCRow row = list.getRows().get(0);
143         assertThat(row.getTitle()).isEqualTo(
144                 mContext.getString(R.string.qc_bluetooth_on_no_devices_info));
145         assertThat(row.getStartIcon()).isNotNull();
146     }
147 
148     @Test
getQCItem_hasDevices_hasRows()149     public void getQCItem_hasDevices_hasRows() {
150         addBluetoothDevice("Device1", /* connected= */ true, /* busy= */ false,
151                 /* phoneEnabled= */ true, /* mediaEnabled= */ true,
152                 /* hasHumanReadableName= */ true);
153         addBluetoothDevice("Device2",  /* connected= */ true, /* busy= */ false,
154                 /* phoneEnabled= */ true, /* mediaEnabled= */ true,
155                 /* hasHumanReadableName= */ true);
156         QCList list = (QCList) mPairedBluetoothDevices.getQCItem();
157         assertThat(list.getRows().size()).isEqualTo(2);
158     }
159 
160     @Test
getQCItem_hasDevices_onlyDisplaysHumanReadableNames()161     public void getQCItem_hasDevices_onlyDisplaysHumanReadableNames() {
162         addBluetoothDevice("Device1", /* connected= */ true, /* busy= */ false,
163                 /* phoneEnabled= */ true, /* mediaEnabled= */ true,
164                 /* hasHumanReadableName= */ true);
165         addBluetoothDevice("Device2",  /* connected= */ true, /* busy= */ false,
166                 /* phoneEnabled= */ true, /* mediaEnabled= */ true,
167                 /* hasHumanReadableName= */ false);
168         QCList list = (QCList) mPairedBluetoothDevices.getQCItem();
169         assertThat(list.getRows().size()).isEqualTo(1);
170     }
171 
172     @Test
getQCItem_limitsDeviceCount()173     public void getQCItem_limitsDeviceCount() {
174         addBluetoothDevice("Device1", /* connected= */ true, /* busy= */ false,
175                 /* phoneEnabled= */ true, /* mediaEnabled= */ true,
176                 /* hasHumanReadableName= */ true);
177         addBluetoothDevice("Device2",  /* connected= */ false, /* busy= */ false,
178                 /* phoneEnabled= */ false, /* mediaEnabled= */ false,
179                 /* hasHumanReadableName= */ true);
180         addBluetoothDevice("Device3",  /* connected= */ false, /* busy= */ false,
181                 /* phoneEnabled= */ false, /* mediaEnabled= */ false,
182                 /* hasHumanReadableName= */ true);
183         addBluetoothDevice("Device4",  /* connected= */ false, /* busy= */ false,
184                 /* phoneEnabled= */ false, /* mediaEnabled= */ false,
185                 /* hasHumanReadableName= */ true);
186         QCList list = (QCList) mPairedBluetoothDevices.getQCItem();
187         assertThat(list.getRows().size()).isEqualTo(3);
188     }
189 
190     @Test
getQCItem_setsTitle()191     public void getQCItem_setsTitle() {
192         addBluetoothDevice(DEFAULT_NAME, /* connected= */ true, /* busy= */ false,
193                 /* phoneEnabled= */ true, /* mediaEnabled= */ true,
194                 /* hasHumanReadableName= */ true);
195         QCList list = (QCList) mPairedBluetoothDevices.getQCItem();
196         QCRow row = list.getRows().get(0);
197         assertThat(row.getTitle()).isEqualTo(DEFAULT_NAME);
198     }
199 
200     @Test
getQCItem_bluetoothDisabled_togglesUpdated()201     public void getQCItem_bluetoothDisabled_togglesUpdated() {
202         addBluetoothDevice(DEFAULT_NAME, /* connected= */ false, /* busy= */ false,
203                 /* phoneEnabled= */ true, /* mediaEnabled= */ true,
204                 /* hasHumanReadableName= */ true);
205         QCList list = (QCList) mPairedBluetoothDevices.getQCItem();
206         QCRow row = list.getRows().get(0);
207         QCActionItem btToggle = row.getEndItems().get(0);
208         QCActionItem phoneToggle = row.getEndItems().get(1);
209         QCActionItem mediaToggle = row.getEndItems().get(2);
210         assertThat(btToggle.isChecked()).isFalse();
211         assertThat(btToggle.isEnabled()).isTrue();
212         assertThat(phoneToggle.isAvailable()).isFalse();
213         assertThat(mediaToggle.isAvailable()).isFalse();
214     }
215 
216     @Test
getQCItem_bluetoothEnabled_togglesUpdated()217     public void getQCItem_bluetoothEnabled_togglesUpdated() {
218         addBluetoothDevice(DEFAULT_NAME, /* connected= */ true, /* busy= */ false,
219                 /* phoneEnabled= */ true, /* mediaEnabled= */ true,
220                 /* hasHumanReadableName= */ true);
221         QCList list = (QCList) mPairedBluetoothDevices.getQCItem();
222         QCRow row = list.getRows().get(0);
223         QCActionItem btToggle = row.getEndItems().get(0);
224         QCActionItem phoneToggle = row.getEndItems().get(1);
225         QCActionItem mediaToggle = row.getEndItems().get(2);
226         assertThat(btToggle.isChecked()).isTrue();
227         assertThat(btToggle.isEnabled()).isTrue();
228         assertThat(phoneToggle.isChecked()).isTrue();
229         assertThat(phoneToggle.isEnabled()).isTrue();
230         assertThat(phoneToggle.isAvailable()).isTrue();
231         assertThat(mediaToggle.isChecked()).isTrue();
232         assertThat(mediaToggle.isEnabled()).isTrue();
233         assertThat(mediaToggle.isAvailable()).isTrue();
234     }
235 
236     @Test
getQCItem_isBusy_togglesDisabled()237     public void getQCItem_isBusy_togglesDisabled() {
238         addBluetoothDevice(DEFAULT_NAME, /* connected= */ true, /* busy= */ true,
239                 /* phoneEnabled= */ true, /* mediaEnabled= */ true,
240                 /* hasHumanReadableName= */ true);
241         QCList list = (QCList) mPairedBluetoothDevices.getQCItem();
242         QCRow row = list.getRows().get(0);
243         QCActionItem btToggle = row.getEndItems().get(0);
244         QCActionItem phoneToggle = row.getEndItems().get(1);
245         QCActionItem mediaToggle = row.getEndItems().get(2);
246         assertThat(btToggle.isEnabled()).isFalse();
247         assertThat(phoneToggle.isEnabled()).isFalse();
248         assertThat(mediaToggle.isEnabled()).isFalse();
249     }
250 
251     @Test
getQCItem_hasBaseUmRestriction_togglesDisabled()252     public void getQCItem_hasBaseUmRestriction_togglesDisabled() {
253         addBluetoothDevice(DEFAULT_NAME, /* connected= */ true, /* busy= */ false,
254                 /* phoneEnabled= */ true, /* mediaEnabled= */ true,
255                 /* hasHumanReadableName= */ true);
256         setBaseUserRestriction(UserManager.DISALLOW_CONFIG_BLUETOOTH, /* restricted= */ true);
257         QCList list = (QCList) mPairedBluetoothDevices.getQCItem();
258         QCRow row = list.getRows().get(0);
259         QCActionItem btToggle = row.getEndItems().get(0);
260         QCActionItem phoneToggle = row.getEndItems().get(1);
261         QCActionItem mediaToggle = row.getEndItems().get(2);
262         assertThat(btToggle.isEnabled()).isTrue();
263         assertThat(phoneToggle.isEnabled()).isFalse();
264         assertThat(phoneToggle.isClickableWhileDisabled()).isFalse();
265         assertThat(mediaToggle.isEnabled()).isFalse();
266         assertThat(mediaToggle.isClickableWhileDisabled()).isFalse();
267     }
268 
269     @Test
getQCItem_hasUmRestriction_togglesClickableWhileDisabled()270     public void getQCItem_hasUmRestriction_togglesClickableWhileDisabled() {
271         addBluetoothDevice(DEFAULT_NAME, /* connected= */ true, /* busy= */ false,
272                 /* phoneEnabled= */ true, /* mediaEnabled= */ true,
273                 /* hasHumanReadableName= */ true);
274         setUserRestriction(UserManager.DISALLOW_CONFIG_BLUETOOTH, /* restricted= */ true);
275         QCList list = (QCList) mPairedBluetoothDevices.getQCItem();
276         QCRow row = list.getRows().get(0);
277         QCActionItem btToggle = row.getEndItems().get(0);
278         QCActionItem phoneToggle = row.getEndItems().get(1);
279         QCActionItem mediaToggle = row.getEndItems().get(2);
280         assertThat(btToggle.isEnabled()).isTrue();
281         assertThat(phoneToggle.isEnabled()).isFalse();
282         assertThat(phoneToggle.isClickableWhileDisabled()).isTrue();
283         assertThat(mediaToggle.isEnabled()).isFalse();
284         assertThat(mediaToggle.isClickableWhileDisabled()).isTrue();
285     }
286 
287     @Test
onNotifyChange_toggleBluetooth()288     public void onNotifyChange_toggleBluetooth() {
289         addBluetoothDevice(DEFAULT_NAME, /* connected= */ false, /* busy= */ true,
290                 /* phoneEnabled= */ true, /* mediaEnabled= */ true,
291                 /* hasHumanReadableName= */ true);
292         Intent intent = new Intent();
293         intent.putExtra(EXTRA_DEVICE_KEY, DEFAULT_ADDRESS);
294         intent.putExtra(EXTRA_BUTTON_TYPE, BLUETOOTH_BUTTON);
295         intent.putExtra(QC_ACTION_TOGGLE_STATE, true);
296         mPairedBluetoothDevices.onNotifyChange(intent);
297         CachedBluetoothDevice device = mCachedDevices.get(0);
298         verify(device).connect();
299     }
300 
301     @Test
onNotifyChange_togglePhone()302     public void onNotifyChange_togglePhone() {
303         addBluetoothDevice(DEFAULT_NAME, /* connected= */ false, /* busy= */ true,
304                 /* phoneEnabled= */ false, /* mediaEnabled= */ true,
305                 /* hasHumanReadableName= */ true);
306         Intent intent = new Intent();
307         intent.putExtra(EXTRA_DEVICE_KEY, DEFAULT_ADDRESS);
308         intent.putExtra(EXTRA_BUTTON_TYPE, PHONE_BUTTON);
309         intent.putExtra(QC_ACTION_TOGGLE_STATE, true);
310         mPairedBluetoothDevices.onNotifyChange(intent);
311         CachedBluetoothDevice device = mCachedDevices.get(0);
312         LocalBluetoothProfile profile = getProfile(device, BluetoothProfile.HEADSET_CLIENT);
313         verify(profile).setEnabled(any(), eq(true));
314     }
315 
316     @Test
onNotifyChange_toggleMedia()317     public void onNotifyChange_toggleMedia() {
318         addBluetoothDevice(DEFAULT_NAME, /* connected= */ false, /* busy= */ true,
319                 /* phoneEnabled= */ true, /* mediaEnabled= */ false,
320                 /* hasHumanReadableName= */ true);
321         Intent intent = new Intent();
322         intent.putExtra(EXTRA_DEVICE_KEY, DEFAULT_ADDRESS);
323         intent.putExtra(EXTRA_BUTTON_TYPE, MEDIA_BUTTON);
324         intent.putExtra(QC_ACTION_TOGGLE_STATE, true);
325         mPairedBluetoothDevices.onNotifyChange(intent);
326         CachedBluetoothDevice device = mCachedDevices.get(0);
327         LocalBluetoothProfile profile = getProfile(device, BluetoothProfile.A2DP_SINK);
328         verify(profile).setEnabled(any(), eq(true));
329     }
330 
331     @Test
getQCItem_createsItem_bluetoothDisabled_zoneWrite()332     public void getQCItem_createsItem_bluetoothDisabled_zoneWrite() {
333         when(mBluetoothAdapter.isEnabled()).thenReturn(false);
334         mPairedBluetoothDevices.setAvailabilityStatusForZone("write");
335         QCItem item = mPairedBluetoothDevices.getQCItem();
336         assertThat(item).isNotNull();
337     }
338 
339     @Test
getQCItem_createsItem_bluetoothDisabled_zoneRead()340     public void getQCItem_createsItem_bluetoothDisabled_zoneRead() {
341         when(mBluetoothAdapter.isEnabled()).thenReturn(false);
342         mPairedBluetoothDevices.setAvailabilityStatusForZone("read");
343         QCItem item = mPairedBluetoothDevices.getQCItem();
344         assertThat(item).isNotNull();
345     }
346 
347     @Test
getQCItem_createsItem_bluetoothDisabled_zoneHidden()348     public void getQCItem_createsItem_bluetoothDisabled_zoneHidden() {
349         when(mBluetoothAdapter.isEnabled()).thenReturn(false);
350         mPairedBluetoothDevices.setAvailabilityStatusForZone("hidden");
351         QCItem item = mPairedBluetoothDevices.getQCItem();
352         assertThat(item).isNull();
353     }
354 
355     @Test
getQCItem_createsItem_noDevices_zoneWrite()356     public void getQCItem_createsItem_noDevices_zoneWrite() {
357         mPairedBluetoothDevices.setAvailabilityStatusForZone("write");
358         QCList list = (QCList) mPairedBluetoothDevices.getQCItem();
359         assertThat(list.getRows().size()).isEqualTo(1);
360         QCRow row = list.getRows().get(0);
361         assertThat(row.getStartIcon()).isNotNull();
362     }
363 
364     @Test
getQCItem_createsItem_noDevices_zoneRead()365     public void getQCItem_createsItem_noDevices_zoneRead() {
366         mPairedBluetoothDevices.setAvailabilityStatusForZone("read");
367         QCList list = (QCList) mPairedBluetoothDevices.getQCItem();
368         assertThat(list.getRows().size()).isEqualTo(1);
369         QCRow row = list.getRows().get(0);
370         assertThat(row.getStartIcon()).isNotNull();
371     }
372 
373     @Test
getQCItem_createsItem_noDevices_zoneHidden()374     public void getQCItem_createsItem_noDevices_zoneHidden() {
375         mPairedBluetoothDevices.setAvailabilityStatusForZone("hidden");
376         QCList list = (QCList) mPairedBluetoothDevices.getQCItem();
377         assertThat(list).isNull();
378     }
379 
380     @Test
getQCItem_createsToggles_bluetoothEnabled_zoneWrite()381     public void getQCItem_createsToggles_bluetoothEnabled_zoneWrite() {
382         mPairedBluetoothDevices.setAvailabilityStatusForZone("write");
383         addBluetoothDevice(DEFAULT_NAME, /* connected= */ true, /* busy= */ false,
384                 /* phoneEnabled= */ true, /* mediaEnabled= */ true,
385                 /* hasHumanReadableName= */ true);
386         QCList list = (QCList) mPairedBluetoothDevices.getQCItem();
387         QCRow row = list.getRows().get(0);
388         QCActionItem btToggle = row.getEndItems().get(0);
389         QCActionItem phoneToggle = row.getEndItems().get(1);
390         QCActionItem mediaToggle = row.getEndItems().get(2);
391         assertThat(btToggle.isEnabled()).isTrue();
392         assertThat(phoneToggle.isEnabled()).isTrue();
393         assertThat(mediaToggle.isEnabled()).isTrue();
394     }
395 
396     @Test
getQCItem_createsToggles_bluetoothEnabled_zoneRead()397     public void getQCItem_createsToggles_bluetoothEnabled_zoneRead() {
398         mPairedBluetoothDevices.setAvailabilityStatusForZone("read");
399         addBluetoothDevice(DEFAULT_NAME, /* connected= */ true, /* busy= */ false,
400                 /* phoneEnabled= */ true, /* mediaEnabled= */ true,
401                 /* hasHumanReadableName= */ true);
402         QCList list = (QCList) mPairedBluetoothDevices.getQCItem();
403         QCRow row = list.getRows().get(0);
404         QCActionItem btToggle = row.getEndItems().get(0);
405         QCActionItem phoneToggle = row.getEndItems().get(1);
406         QCActionItem mediaToggle = row.getEndItems().get(2);
407         assertThat(btToggle.isEnabled()).isFalse();
408         assertThat(phoneToggle.isEnabled()).isFalse();
409         assertThat(mediaToggle.isEnabled()).isFalse();
410         assertThat(btToggle.isClickableWhileDisabled()).isTrue();
411         assertThat(phoneToggle.isClickableWhileDisabled()).isTrue();
412         assertThat(mediaToggle.isClickableWhileDisabled()).isTrue();
413     }
414 
415     @Test
getQCItem_createsToggles_bluetoothEnabled_zoneHidden()416     public void getQCItem_createsToggles_bluetoothEnabled_zoneHidden() {
417         mPairedBluetoothDevices.setAvailabilityStatusForZone("hidden");
418         addBluetoothDevice(DEFAULT_NAME, /* connected= */ true, /* busy= */ false,
419                 /* phoneEnabled= */ true, /* mediaEnabled= */ true,
420                 /* hasHumanReadableName= */ true);
421         QCList list = (QCList) mPairedBluetoothDevices.getQCItem();
422         assertThat(list).isNull();
423     }
424 
addBluetoothDevice(String name, boolean connected, boolean busy, boolean phoneEnabled, boolean mediaEnabled, boolean hasHumanReadableName)425     private void addBluetoothDevice(String name, boolean connected, boolean busy,
426             boolean phoneEnabled, boolean mediaEnabled, boolean hasHumanReadableName) {
427         CachedBluetoothDevice cachedDevice = mock(CachedBluetoothDevice.class);
428         BluetoothDevice device = mock(BluetoothDevice.class);
429         when(cachedDevice.getDevice()).thenReturn(device);
430         when(device.getBondState()).thenReturn(BluetoothDevice.BOND_BONDED);
431         when(cachedDevice.getName()).thenReturn(name);
432         when(cachedDevice.getAddress()).thenReturn(DEFAULT_ADDRESS);
433         when(cachedDevice.isConnected()).thenReturn(connected);
434         when(cachedDevice.isBusy()).thenReturn(busy);
435         when(cachedDevice.getCarConnectionSummary(anyBoolean())).thenReturn(DEFAULT_SUMMARY);
436         when(cachedDevice.hasHumanReadableName()).thenReturn(hasHumanReadableName);
437         BluetoothClass btClass = mock(BluetoothClass.class);
438         when(cachedDevice.getBtClass()).thenReturn(btClass);
439         when(btClass.getMajorDeviceClass()).thenReturn(BluetoothClass.Device.Major.PHONE);
440         LocalBluetoothProfile phoneProfile = mock(LocalBluetoothProfile.class);
441         LocalBluetoothProfile mediaProfile = mock(LocalBluetoothProfile.class);
442         when(phoneProfile.getProfileId()).thenReturn(BluetoothProfile.HEADSET_CLIENT);
443         when(mediaProfile.getProfileId()).thenReturn(BluetoothProfile.A2DP_SINK);
444         when(phoneProfile.isEnabled(any())).thenReturn(phoneEnabled);
445         when(mediaProfile.isEnabled(any())).thenReturn(mediaEnabled);
446         when(cachedDevice.getProfiles()).thenReturn(Arrays.asList(phoneProfile, mediaProfile));
447         mCachedDevices.add(cachedDevice);
448         mBondedDevices.add(device);
449     }
450 
getProfile(CachedBluetoothDevice device, int profileId)451     private LocalBluetoothProfile getProfile(CachedBluetoothDevice device, int profileId) {
452         for (LocalBluetoothProfile profile : device.getProfiles()) {
453             if (profile.getProfileId() == profileId) {
454                 return profile;
455             }
456         }
457         return null;
458     }
459 }
460