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 com.google.common.truth.Truth.assertThat;
19 
20 import static org.mockito.ArgumentMatchers.any;
21 import static org.mockito.Mockito.doNothing;
22 import static org.mockito.Mockito.doReturn;
23 import static org.mockito.Mockito.spy;
24 import static org.mockito.Mockito.verify;
25 import static org.mockito.Mockito.when;
26 
27 import android.bluetooth.BluetoothAdapter;
28 import android.bluetooth.BluetoothDevice;
29 import android.bluetooth.BluetoothProfile;
30 import android.content.Context;
31 import android.graphics.drawable.Drawable;
32 import android.media.AudioManager;
33 import android.util.Pair;
34 
35 import com.android.settings.connecteddevice.DevicePreferenceCallback;
36 import com.android.settings.dashboard.DashboardFragment;
37 import com.android.settings.testutils.shadow.ShadowAudioManager;
38 import com.android.settings.testutils.shadow.ShadowBluetoothAdapter;
39 import com.android.settings.testutils.shadow.ShadowCachedBluetoothDeviceManager;
40 import com.android.settingslib.bluetooth.CachedBluetoothDevice;
41 
42 import org.junit.Before;
43 import org.junit.Test;
44 import org.junit.runner.RunWith;
45 import org.mockito.Mock;
46 import org.mockito.MockitoAnnotations;
47 import org.robolectric.RobolectricTestRunner;
48 import org.robolectric.RuntimeEnvironment;
49 import org.robolectric.annotation.Config;
50 import org.robolectric.shadow.api.Shadow;
51 
52 import java.util.ArrayList;
53 import java.util.Collection;
54 
55 @RunWith(RobolectricTestRunner.class)
56 @Config(shadows = {ShadowAudioManager.class, ShadowBluetoothAdapter.class,
57         ShadowCachedBluetoothDeviceManager.class})
58 public class ConnectedBluetoothDeviceUpdaterTest {
59 
60     private static final String MAC_ADDRESS = "04:52:C7:0B:D8:3C";
61 
62     @Mock
63     private DashboardFragment mDashboardFragment;
64     @Mock
65     private DevicePreferenceCallback mDevicePreferenceCallback;
66     @Mock
67     private CachedBluetoothDevice mCachedBluetoothDevice;
68     @Mock
69     private BluetoothDevice mBluetoothDevice;
70     @Mock
71     private Drawable mDrawable;
72 
73     private Context mContext;
74     private ConnectedBluetoothDeviceUpdater mBluetoothDeviceUpdater;
75     private Collection<CachedBluetoothDevice> mCachedDevices;
76     private AudioManager mAudioManager;
77     private ShadowBluetoothAdapter mShadowBluetoothAdapter;
78     private ShadowCachedBluetoothDeviceManager mShadowCachedBluetoothDeviceManager;
79 
80     @Before
setUp()81     public void setUp() {
82         MockitoAnnotations.initMocks(this);
83 
84         Pair<Drawable, String> pairs = new Pair<>(mDrawable, "fake_device");
85         mContext = RuntimeEnvironment.application;
86         mAudioManager = mContext.getSystemService(AudioManager.class);
87         mShadowBluetoothAdapter = Shadow.extract(BluetoothAdapter.getDefaultAdapter());
88         mShadowBluetoothAdapter.setEnabled(true);
89         mShadowCachedBluetoothDeviceManager = Shadow.extract(
90                 Utils.getLocalBtManager(mContext).getCachedDeviceManager());
91         doReturn(mContext).when(mDashboardFragment).getContext();
92         mCachedDevices = new ArrayList<>();
93 
94         when(mCachedBluetoothDevice.getDevice()).thenReturn(mBluetoothDevice);
95         when(mCachedBluetoothDevice.getAddress()).thenReturn(MAC_ADDRESS);
96         when(mCachedBluetoothDevice.getDrawableWithDescription()).thenReturn(pairs);
97         mShadowCachedBluetoothDeviceManager.setCachedDevicesCopy(mCachedDevices);
98         mBluetoothDeviceUpdater = spy(new ConnectedBluetoothDeviceUpdater(mContext,
99                 mDashboardFragment, mDevicePreferenceCallback));
100         mBluetoothDeviceUpdater.setPrefContext(mContext);
101         doNothing().when(mBluetoothDeviceUpdater).addPreference(any());
102         doNothing().when(mBluetoothDeviceUpdater).removePreference(any());
103     }
104 
105     @Test
onAudioModeChanged_hfpDeviceConnected_notInCall_addPreference()106     public void onAudioModeChanged_hfpDeviceConnected_notInCall_addPreference() {
107         mAudioManager.setMode(AudioManager.MODE_NORMAL);
108         when(mBluetoothDeviceUpdater.
109                 isDeviceConnected(any(CachedBluetoothDevice.class))).thenReturn(true);
110         when(mCachedBluetoothDevice.isConnectedHfpDevice()).thenReturn(true);
111         mCachedDevices.add(mCachedBluetoothDevice);
112 
113         mBluetoothDeviceUpdater.onAudioModeChanged();
114 
115         verify(mBluetoothDeviceUpdater).addPreference(mCachedBluetoothDevice);
116     }
117 
118     @Test
onAudioModeChanged_hfpDeviceConnected_inCall_removePreference()119     public void onAudioModeChanged_hfpDeviceConnected_inCall_removePreference() {
120         mAudioManager.setMode(AudioManager.MODE_IN_CALL);
121         when(mBluetoothDeviceUpdater.
122                 isDeviceConnected(any(CachedBluetoothDevice.class))).thenReturn(true);
123         when(mCachedBluetoothDevice.isConnectedHfpDevice()).thenReturn(true);
124         mCachedDevices.add(mCachedBluetoothDevice);
125 
126         mBluetoothDeviceUpdater.onAudioModeChanged();
127 
128         verify(mBluetoothDeviceUpdater).removePreference(mCachedBluetoothDevice);
129     }
130 
131     @Test
onAudioModeChanged_a2dpDeviceConnected_notInCall_removePreference()132     public void onAudioModeChanged_a2dpDeviceConnected_notInCall_removePreference() {
133         mAudioManager.setMode(AudioManager.MODE_NORMAL);
134         when(mBluetoothDeviceUpdater.
135                 isDeviceConnected(any(CachedBluetoothDevice.class))).thenReturn(true);
136         when(mCachedBluetoothDevice.isConnectedA2dpDevice()).thenReturn(true);
137         mCachedDevices.add(mCachedBluetoothDevice);
138 
139         mBluetoothDeviceUpdater.onAudioModeChanged();
140 
141         verify(mBluetoothDeviceUpdater).removePreference(mCachedBluetoothDevice);
142     }
143 
144     @Test
onAudioModeChanged_a2dpDeviceConnected_inCall_addPreference()145     public void onAudioModeChanged_a2dpDeviceConnected_inCall_addPreference() {
146         mAudioManager.setMode(AudioManager.MODE_IN_CALL);
147         when(mBluetoothDeviceUpdater.
148                 isDeviceConnected(any(CachedBluetoothDevice.class))).thenReturn(true);
149         when(mCachedBluetoothDevice.isConnectedA2dpDevice()).thenReturn(true);
150         mCachedDevices.add(mCachedBluetoothDevice);
151 
152         mBluetoothDeviceUpdater.onAudioModeChanged();
153 
154         verify(mBluetoothDeviceUpdater).addPreference(mCachedBluetoothDevice);
155     }
156 
157     @Test
onProfileConnectionStateChanged_a2dpDeviceConnected_inCall_addPreference()158     public void onProfileConnectionStateChanged_a2dpDeviceConnected_inCall_addPreference() {
159         mAudioManager.setMode(AudioManager.MODE_IN_CALL);
160         when(mBluetoothDeviceUpdater.
161                 isDeviceConnected(any(CachedBluetoothDevice.class))).thenReturn(true);
162         when(mCachedBluetoothDevice.isConnectedA2dpDevice()).thenReturn(true);
163 
164         mBluetoothDeviceUpdater.onProfileConnectionStateChanged(mCachedBluetoothDevice,
165                 BluetoothProfile.STATE_CONNECTED, BluetoothProfile.A2DP);
166 
167         verify(mBluetoothDeviceUpdater).addPreference(mCachedBluetoothDevice);
168     }
169 
170     @Test
onProfileConnectionStateChanged_a2dpDeviceConnected_notInCall_removePreference()171     public void onProfileConnectionStateChanged_a2dpDeviceConnected_notInCall_removePreference() {
172         mAudioManager.setMode(AudioManager.MODE_NORMAL);
173         when(mBluetoothDeviceUpdater.
174                 isDeviceConnected(any(CachedBluetoothDevice.class))).thenReturn(true);
175         when(mCachedBluetoothDevice.isConnectedA2dpDevice()).thenReturn(true);
176 
177         mBluetoothDeviceUpdater.onProfileConnectionStateChanged(mCachedBluetoothDevice,
178                 BluetoothProfile.STATE_CONNECTED, BluetoothProfile.A2DP);
179 
180         verify(mBluetoothDeviceUpdater).removePreference(mCachedBluetoothDevice);
181     }
182 
183     @Test
onProfileConnectionStateChanged_hfpDeviceConnected_inCall_removePreference()184     public void onProfileConnectionStateChanged_hfpDeviceConnected_inCall_removePreference() {
185         mAudioManager.setMode(AudioManager.MODE_IN_CALL);
186         when(mBluetoothDeviceUpdater.
187                 isDeviceConnected(any(CachedBluetoothDevice.class))).thenReturn(true);
188         when(mCachedBluetoothDevice.isConnectedHfpDevice()).thenReturn(true);
189 
190         mBluetoothDeviceUpdater.onProfileConnectionStateChanged(mCachedBluetoothDevice,
191                 BluetoothProfile.STATE_CONNECTED, BluetoothProfile.A2DP);
192 
193         verify(mBluetoothDeviceUpdater).removePreference(mCachedBluetoothDevice);
194     }
195 
196     @Test
onProfileConnectionStateChanged_hfpDeviceConnected_notInCall_addPreference()197     public void onProfileConnectionStateChanged_hfpDeviceConnected_notInCall_addPreference() {
198         mAudioManager.setMode(AudioManager.MODE_NORMAL);
199         when(mBluetoothDeviceUpdater.
200                 isDeviceConnected(any(CachedBluetoothDevice.class))).thenReturn(true);
201         when(mCachedBluetoothDevice.isConnectedHfpDevice()).thenReturn(true);
202 
203         mBluetoothDeviceUpdater.onProfileConnectionStateChanged(mCachedBluetoothDevice,
204                 BluetoothProfile.STATE_CONNECTED, BluetoothProfile.A2DP);
205 
206         verify(mBluetoothDeviceUpdater).addPreference(mCachedBluetoothDevice);
207     }
208 
209     @Test
onProfileConnectionStateChanged_hearingAidDeviceConnected_inCall_removePreference()210     public void onProfileConnectionStateChanged_hearingAidDeviceConnected_inCall_removePreference()
211     {
212         mAudioManager.setMode(AudioManager.MODE_IN_CALL);
213         when(mBluetoothDeviceUpdater.
214                 isDeviceConnected(any(CachedBluetoothDevice.class))).thenReturn(true);
215         when(mCachedBluetoothDevice.isConnectedHearingAidDevice()).thenReturn(true);
216 
217         mBluetoothDeviceUpdater.onProfileConnectionStateChanged(mCachedBluetoothDevice,
218                 BluetoothProfile.STATE_CONNECTED, BluetoothProfile.HEARING_AID);
219 
220         verify(mBluetoothDeviceUpdater).removePreference(mCachedBluetoothDevice);
221     }
222 
223     @Test
onProfileConnectionStateChanged_hearingAidDeviceConnected_notInCall_removePreference()224     public void onProfileConnectionStateChanged_hearingAidDeviceConnected_notInCall_removePreference
225             () {
226         mAudioManager.setMode(AudioManager.MODE_NORMAL);
227         when(mBluetoothDeviceUpdater.
228                 isDeviceConnected(any(CachedBluetoothDevice.class))).thenReturn(true);
229         when(mCachedBluetoothDevice.isConnectedHearingAidDevice()).thenReturn(true);
230 
231         mBluetoothDeviceUpdater.onProfileConnectionStateChanged(mCachedBluetoothDevice,
232                 BluetoothProfile.STATE_CONNECTED, BluetoothProfile.HEARING_AID);
233 
234         verify(mBluetoothDeviceUpdater).removePreference(mCachedBluetoothDevice);
235     }
236 
237     @Test
onProfileConnectionStateChanged_deviceDisconnected_removePreference()238     public void onProfileConnectionStateChanged_deviceDisconnected_removePreference() {
239         mBluetoothDeviceUpdater.onProfileConnectionStateChanged(mCachedBluetoothDevice,
240                 BluetoothProfile.STATE_DISCONNECTED, BluetoothProfile.A2DP);
241 
242         verify(mBluetoothDeviceUpdater).removePreference(mCachedBluetoothDevice);
243     }
244 
245     @Test
addPreference_addPreference_shouldHideSecondTarget()246     public void addPreference_addPreference_shouldHideSecondTarget() {
247         BluetoothDevicePreference btPreference =
248                 new BluetoothDevicePreference(mContext, mCachedBluetoothDevice,
249                         true, BluetoothDevicePreference.SortType.TYPE_DEFAULT);
250         mBluetoothDeviceUpdater.mPreferenceMap.put(mBluetoothDevice, btPreference);
251 
252         mBluetoothDeviceUpdater.addPreference(mCachedBluetoothDevice);
253 
254         assertThat(btPreference.shouldHideSecondTarget()).isTrue();
255     }
256 }
257