blob: d342bc878477145fa58b93ed14a84d0ea2fc8c9d [file] [log] [blame]
Hansong Zhang490d0202018-04-10 16:06:19 -07001/*
2 * Copyright (C) 2018 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
17package com.android.settingslib.bluetooth;
18
19import static com.google.common.truth.Truth.assertThat;
20
ryanywlin44de3a02018-05-02 15:15:37 +080021import static org.mockito.ArgumentMatchers.any;
22import static org.mockito.ArgumentMatchers.anyInt;
23import static org.mockito.Mockito.never;
24import static org.mockito.Mockito.spy;
25import static org.mockito.Mockito.verify;
Hansong Zhang490d0202018-04-10 16:06:19 -070026import static org.mockito.Mockito.when;
27
ryanywlin44de3a02018-05-02 15:15:37 +080028import android.bluetooth.BluetoothA2dp;
Hansong Zhang490d0202018-04-10 16:06:19 -070029import android.bluetooth.BluetoothAdapter;
30import android.bluetooth.BluetoothDevice;
ryanywlin44de3a02018-05-02 15:15:37 +080031import android.bluetooth.BluetoothHeadset;
32import android.bluetooth.BluetoothHearingAid;
33import android.bluetooth.BluetoothPan;
34import android.bluetooth.BluetoothProfile;
Hansong Zhang490d0202018-04-10 16:06:19 -070035import android.bluetooth.BluetoothUuid;
36import android.content.Context;
ryanywlin44de3a02018-05-02 15:15:37 +080037import android.content.Intent;
Hansong Zhang490d0202018-04-10 16:06:19 -070038import android.os.ParcelUuid;
39
40import java.util.ArrayList;
41import java.util.List;
42
43import org.junit.Before;
44import org.junit.Test;
45import org.junit.runner.RunWith;
46import org.mockito.Mock;
47import org.mockito.MockitoAnnotations;
48import org.robolectric.RobolectricTestRunner;
49import org.robolectric.RuntimeEnvironment;
50import org.robolectric.annotation.Config;
51
52@RunWith(RobolectricTestRunner.class)
53@Config(resourceDir = "../../res")
54public class LocalBluetoothProfileManagerTest {
ryanywlin44de3a02018-05-02 15:15:37 +080055 @Mock
56 private CachedBluetoothDeviceManager mDeviceManager;
57 @Mock
58 private BluetoothEventManager mEventManager;
59 @Mock
60 private LocalBluetoothAdapter mAdapter;
61 @Mock
62 private BluetoothDevice mDevice;
63 @Mock
64 private CachedBluetoothDevice mCachedBluetoothDevice;
65
Hansong Zhang490d0202018-04-10 16:06:19 -070066 private Context mContext;
67 private LocalBluetoothProfileManager mProfileManager;
ryanywlin44de3a02018-05-02 15:15:37 +080068 private Intent mIntent;
Hansong Zhang490d0202018-04-10 16:06:19 -070069
70 @Before
71 public void setUp() {
72 MockitoAnnotations.initMocks(this);
ryanywlin44de3a02018-05-02 15:15:37 +080073 mContext = spy(RuntimeEnvironment.application);
74 mEventManager = spy(new BluetoothEventManager(mAdapter,
75 mDeviceManager, mContext));
Hansong Zhang490d0202018-04-10 16:06:19 -070076 when(mAdapter.getBluetoothState()).thenReturn(BluetoothAdapter.STATE_ON);
ryanywlin44de3a02018-05-02 15:15:37 +080077 when(mDeviceManager.findDevice(mDevice)).thenReturn(mCachedBluetoothDevice);
Hansong Zhang490d0202018-04-10 16:06:19 -070078 }
79
80 /**
81 * Verify HID and HID Device profiles are not null without running updateUuids()
82 */
83 @Test
84 public void constructor_initiateHidAndHidDeviceProfile() {
85 mProfileManager =
86 new LocalBluetoothProfileManager(mContext, mAdapter, mDeviceManager, mEventManager);
87
88 assertThat(mProfileManager.getHidProfile()).isNotNull();
89 assertThat(mProfileManager.getHidDeviceProfile()).isNotNull();
90 }
91
92 /**
93 * Verify updateLocalProfiles() for a local A2DP source adds A2dpProfile
94 */
95 @Test
96 public void updateLocalProfiles_addA2dpToLocalProfiles() {
97 mProfileManager =
98 new LocalBluetoothProfileManager(mContext, mAdapter, mDeviceManager, mEventManager);
ryanywlin44de3a02018-05-02 15:15:37 +080099 when(mAdapter.getUuids()).thenReturn(new ParcelUuid[]{BluetoothUuid.AudioSource});
Hansong Zhang490d0202018-04-10 16:06:19 -0700100 assertThat(mProfileManager.getA2dpProfile()).isNull();
101 assertThat(mProfileManager.getHeadsetProfile()).isNull();
102
103 ParcelUuid[] uuids = mAdapter.getUuids();
104 mProfileManager.updateLocalProfiles(uuids);
105
106 assertThat(mProfileManager.getA2dpProfile()).isNotNull();
107 assertThat(mProfileManager.getHeadsetProfile()).isNull();
108 }
109
110 /**
111 * Verify updateProfiles() for a remote HID device updates profiles and removedProfiles
112 */
113 @Test
114 public void updateProfiles_addHidProfileForRemoteDevice() {
115 mProfileManager =
116 new LocalBluetoothProfileManager(mContext, mAdapter, mDeviceManager, mEventManager);
117 ParcelUuid[] uuids = new ParcelUuid[]{BluetoothUuid.Hid};
118 ParcelUuid[] localUuids = new ParcelUuid[]{};
119 List<LocalBluetoothProfile> profiles = new ArrayList<>();
120 List<LocalBluetoothProfile> removedProfiles = new ArrayList<>();
121
122 mProfileManager.updateProfiles(uuids, localUuids, profiles, removedProfiles, false,
123 mDevice);
124
125 assertThat(mProfileManager.getHidProfile()).isNotNull();
126 assertThat(profiles.contains(mProfileManager.getHidProfile())).isTrue();
127 assertThat(removedProfiles.contains(mProfileManager.getHidProfile())).isFalse();
128 }
ryanywlin44de3a02018-05-02 15:15:37 +0800129
130 /**
131 * Verify BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED with uuid intent will dispatch to
132 * profile connection state changed callback
133 */
134 @Test
135 public void stateChangedHandler_receiveA2dpConnectionStateChanged_shouldDispatchCallback() {
136 when(mAdapter.getUuids()).thenReturn(new ParcelUuid[]{BluetoothUuid.AudioSource});
137 mProfileManager = new LocalBluetoothProfileManager(mContext, mAdapter, mDeviceManager,
138 mEventManager);
139 // Refer to BluetoothControllerImpl, it will call setReceiverHandler after
140 // LocalBluetoothProfileManager created.
141 mEventManager.setReceiverHandler(null);
142 mIntent = new Intent(BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED);
143 mIntent.putExtra(BluetoothDevice.EXTRA_DEVICE, mDevice);
144 mIntent.putExtra(BluetoothProfile.EXTRA_PREVIOUS_STATE, BluetoothProfile.STATE_CONNECTING);
145 mIntent.putExtra(BluetoothProfile.EXTRA_STATE, BluetoothProfile.STATE_CONNECTED);
146
147 mContext.sendBroadcast(mIntent);
148
149 verify(mEventManager).dispatchProfileConnectionStateChanged(
150 mCachedBluetoothDevice, BluetoothProfile.STATE_CONNECTED, BluetoothProfile.A2DP);
151 }
152
153 /**
154 * Verify BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED with uuid intent will dispatch to
155 * profile connection state changed callback
156 */
157 @Test
158 public void stateChangedHandler_receiveHeadsetConnectionStateChanged_shouldDispatchCallback() {
159 when(mAdapter.getUuids()).thenReturn(new ParcelUuid[]{BluetoothUuid.Handsfree_AG});
160 mProfileManager = new LocalBluetoothProfileManager(mContext, mAdapter, mDeviceManager,
161 mEventManager);
162 // Refer to BluetoothControllerImpl, it will call setReceiverHandler after
163 // LocalBluetoothProfileManager created.
164 mEventManager.setReceiverHandler(null);
165 mIntent = new Intent(BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED);
166 mIntent.putExtra(BluetoothDevice.EXTRA_DEVICE, mDevice);
167 mIntent.putExtra(BluetoothProfile.EXTRA_PREVIOUS_STATE, BluetoothProfile.STATE_CONNECTING);
168 mIntent.putExtra(BluetoothProfile.EXTRA_STATE, BluetoothProfile.STATE_CONNECTED);
169
170 mContext.sendBroadcast(mIntent);
171
172 verify(mEventManager).dispatchProfileConnectionStateChanged(mCachedBluetoothDevice,
173 BluetoothProfile.STATE_CONNECTED, BluetoothProfile.HEADSET);
174 }
175
176 /**
177 * Verify BluetoothHearingAid.ACTION_CONNECTION_STATE_CHANGED with uuid intent will dispatch to
178 * profile connection state changed callback
179 */
180 @Test
181 public void stateChangedHandler_receiveHAPConnectionStateChanged_shouldDispatchCallback() {
182 ArrayList<Integer> supportProfiles = new ArrayList<>();
183 supportProfiles.add(BluetoothProfile.HEARING_AID);
184 when(mAdapter.getSupportedProfiles()).thenReturn(supportProfiles);
185 when(mAdapter.getUuids()).thenReturn(new ParcelUuid[]{BluetoothUuid.HearingAid});
186 mProfileManager = new LocalBluetoothProfileManager(mContext, mAdapter, mDeviceManager,
187 mEventManager);
188 // Refer to BluetoothControllerImpl, it will call setReceiverHandler after
189 // LocalBluetoothProfileManager created.
190 mEventManager.setReceiverHandler(null);
191 mIntent = new Intent(BluetoothHearingAid.ACTION_CONNECTION_STATE_CHANGED);
192 mIntent.putExtra(BluetoothDevice.EXTRA_DEVICE, mDevice);
193 mIntent.putExtra(BluetoothProfile.EXTRA_PREVIOUS_STATE, BluetoothProfile.STATE_CONNECTING);
194 mIntent.putExtra(BluetoothProfile.EXTRA_STATE, BluetoothProfile.STATE_CONNECTED);
195
196 mContext.sendBroadcast(mIntent);
197
198 verify(mEventManager).dispatchProfileConnectionStateChanged(mCachedBluetoothDevice,
199 BluetoothProfile.STATE_CONNECTED, BluetoothProfile.HEARING_AID);
200 }
201
202 /**
203 * Verify BluetoothPan.ACTION_CONNECTION_STATE_CHANGED intent with uuid will dispatch to
204 * profile connection state changed callback
205 */
206 @Test
207 public void stateChangedHandler_receivePanConnectionStateChanged_shouldNotDispatchCallback() {
208 when(mAdapter.getUuids()).thenReturn(new ParcelUuid[]{BluetoothUuid.AudioSource});
209 mProfileManager = new LocalBluetoothProfileManager(mContext, mAdapter, mDeviceManager,
210 mEventManager);
211 // Refer to BluetoothControllerImpl, it will call setReceiverHandler after
212 // LocalBluetoothProfileManager created.
213 mEventManager.setReceiverHandler(null);
214 mIntent = new Intent(BluetoothPan.ACTION_CONNECTION_STATE_CHANGED);
215 mIntent.putExtra(BluetoothDevice.EXTRA_DEVICE, mDevice);
216 mIntent.putExtra(BluetoothProfile.EXTRA_PREVIOUS_STATE, BluetoothProfile.STATE_CONNECTING);
217 mIntent.putExtra(BluetoothProfile.EXTRA_STATE, BluetoothProfile.STATE_CONNECTED);
218
219 mContext.sendBroadcast(mIntent);
220
221 verify(mEventManager).dispatchProfileConnectionStateChanged(
222 any(CachedBluetoothDevice.class), anyInt(), anyInt());
223 }
224
225 /**
226 * Verify BluetoothPan.ACTION_CONNECTION_STATE_CHANGED intent without uuids will not dispatch to
227 * handler and refresh CachedBluetoothDevice
228 */
229 @Test
230 public void stateChangedHandler_receivePanConnectionStateChangedWithoutUuid_shouldNotRefresh() {
231 when(mAdapter.getUuids()).thenReturn(null);
232 mProfileManager = new LocalBluetoothProfileManager(mContext, mAdapter, mDeviceManager,
233 mEventManager);
234 // Refer to BluetoothControllerImpl, it will call setReceiverHandler after
235 // LocalBluetoothProfileManager created.
236 mEventManager.setReceiverHandler(null);
237 mIntent = new Intent(BluetoothPan.ACTION_CONNECTION_STATE_CHANGED);
238 mIntent.putExtra(BluetoothDevice.EXTRA_DEVICE, mDevice);
239 mIntent.putExtra(BluetoothProfile.EXTRA_PREVIOUS_STATE, BluetoothProfile.STATE_CONNECTING);
240 mIntent.putExtra(BluetoothProfile.EXTRA_STATE, BluetoothProfile.STATE_CONNECTED);
241
242 mContext.sendBroadcast(mIntent);
243
244 verify(mCachedBluetoothDevice).refresh();
245 }
246
247 /**
248 * Verify BluetoothPan.ACTION_CONNECTION_STATE_CHANGED intent with uuids will dispatch to
249 * handler and refresh CachedBluetoothDevice
250 */
251 @Test
252 public void stateChangedHandler_receivePanConnectionStateChangedWithUuids_shouldRefresh() {
253 when(mAdapter.getUuids()).thenReturn(new ParcelUuid[]{BluetoothUuid.AudioSource});
254 mProfileManager = new LocalBluetoothProfileManager(mContext, mAdapter, mDeviceManager,
255 mEventManager);
256 // Refer to BluetoothControllerImpl, it will call setReceiverHandler after
257 // LocalBluetoothProfileManager created.
258 mEventManager.setReceiverHandler(null);
259 mIntent = new Intent(BluetoothPan.ACTION_CONNECTION_STATE_CHANGED);
260 mIntent.putExtra(BluetoothDevice.EXTRA_DEVICE, mDevice);
261 mIntent.putExtra(BluetoothProfile.EXTRA_PREVIOUS_STATE, BluetoothProfile.STATE_CONNECTING);
262 mIntent.putExtra(BluetoothProfile.EXTRA_STATE, BluetoothProfile.STATE_CONNECTED);
263
264 mContext.sendBroadcast(mIntent);
265
266 verify(mCachedBluetoothDevice).refresh();
267 }
Hansong Zhang490d0202018-04-10 16:06:19 -0700268}