blob: 07757278944603736cc14a9d9a6627dd30854992 [file] [log] [blame]
Jack He6258aae2017-06-29 17:01:23 -07001/*
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 */
16package com.android.settingslib.bluetooth;
17
18import static com.google.common.truth.Truth.assertThat;
Jack Hec219bc92017-07-24 14:55:59 -070019import static org.mockito.Matchers.any;
20import static org.mockito.Matchers.anyString;
Jack He6258aae2017-06-29 17:01:23 -070021import static org.mockito.Mockito.doAnswer;
Jack Hec219bc92017-07-24 14:55:59 -070022import static org.mockito.Mockito.never;
Jack He6258aae2017-06-29 17:01:23 -070023import static org.mockito.Mockito.spy;
Jack Hec219bc92017-07-24 14:55:59 -070024import static org.mockito.Mockito.verify;
Jack He6258aae2017-06-29 17:01:23 -070025import static org.mockito.Mockito.when;
26
27import android.bluetooth.BluetoothAdapter;
28import android.bluetooth.BluetoothDevice;
29import android.bluetooth.BluetoothProfile;
30import android.content.Context;
31
Jack He6258aae2017-06-29 17:01:23 -070032import org.junit.Before;
33import org.junit.Test;
34import org.junit.runner.RunWith;
35import org.mockito.Mock;
36import org.mockito.MockitoAnnotations;
37import org.robolectric.RobolectricTestRunner;
38import org.robolectric.RuntimeEnvironment;
39import org.robolectric.annotation.Config;
40
41@RunWith(RobolectricTestRunner.class)
James Lemieux5c50dc12018-02-12 01:30:32 -080042@Config(resourceDir = "../../res")
Jack He6258aae2017-06-29 17:01:23 -070043public class CachedBluetoothDeviceTest {
Jack Hec219bc92017-07-24 14:55:59 -070044 private final static String DEVICE_NAME = "TestName";
45 private final static String DEVICE_ALIAS = "TestAlias";
46 private final static String DEVICE_ADDRESS = "AA:BB:CC:DD:EE:FF";
47 private final static String DEVICE_ALIAS_NEW = "TestAliasNew";
Jack He6258aae2017-06-29 17:01:23 -070048 @Mock
49 private LocalBluetoothAdapter mAdapter;
50 @Mock
51 private LocalBluetoothProfileManager mProfileManager;
52 @Mock
53 private HeadsetProfile mHfpProfile;
54 @Mock
55 private A2dpProfile mA2dpProfile;
56 @Mock
Hansong Zhang1c1bc252017-10-30 16:38:16 -070057 private PanProfile mPanProfile;
Jack He6258aae2017-06-29 17:01:23 -070058 @Mock
59 private BluetoothDevice mDevice;
60 private CachedBluetoothDevice mCachedDevice;
61 private Context mContext;
62 private int mBatteryLevel = BluetoothDevice.BATTERY_LEVEL_UNKNOWN;
63
64 @Before
65 public void setUp() {
66 MockitoAnnotations.initMocks(this);
67 mContext = RuntimeEnvironment.application;
Jack Hec219bc92017-07-24 14:55:59 -070068 when(mDevice.getAddress()).thenReturn(DEVICE_ADDRESS);
Jack He6258aae2017-06-29 17:01:23 -070069 when(mAdapter.getBluetoothState()).thenReturn(BluetoothAdapter.STATE_ON);
70 when(mHfpProfile.isProfileReady()).thenReturn(true);
71 when(mA2dpProfile.isProfileReady()).thenReturn(true);
Hansong Zhang1c1bc252017-10-30 16:38:16 -070072 when(mPanProfile.isProfileReady()).thenReturn(true);
Jack He6258aae2017-06-29 17:01:23 -070073 mCachedDevice = spy(
74 new CachedBluetoothDevice(mContext, mAdapter, mProfileManager, mDevice));
75 doAnswer((invocation) -> mBatteryLevel).when(mCachedDevice).getBatteryLevel();
76 }
77
Jack He6258aae2017-06-29 17:01:23 -070078 @Test
79 public void testGetConnectionSummary_testSingleProfileConnectDisconnect() {
80 // Test without battery level
Hansong Zhang1c1bc252017-10-30 16:38:16 -070081 // Set PAN profile to be connected and test connection state summary
82 mCachedDevice.onProfileStateChanged(mPanProfile, BluetoothProfile.STATE_CONNECTED);
Pavlin Radoslavove6e080f2018-02-06 12:21:34 -080083 assertThat(mCachedDevice.getConnectionSummary()).isEqualTo("Connected");
Jack He6258aae2017-06-29 17:01:23 -070084
Hansong Zhang1c1bc252017-10-30 16:38:16 -070085 // Set PAN profile to be disconnected and test connection state summary
86 mCachedDevice.onProfileStateChanged(mPanProfile, BluetoothProfile.STATE_DISCONNECTED);
Jack He6258aae2017-06-29 17:01:23 -070087 assertThat(mCachedDevice.getConnectionSummary()).isNull();
88
89 // Test with battery level
90 mBatteryLevel = 10;
Hansong Zhang1c1bc252017-10-30 16:38:16 -070091 // Set PAN profile to be connected and test connection state summary
92 mCachedDevice.onProfileStateChanged(mPanProfile, BluetoothProfile.STATE_CONNECTED);
Pavlin Radoslavove6e080f2018-02-06 12:21:34 -080093 assertThat(mCachedDevice.getConnectionSummary()).isEqualTo("Connected, battery 10%");
Jack He6258aae2017-06-29 17:01:23 -070094
Hansong Zhang1c1bc252017-10-30 16:38:16 -070095 // Set PAN profile to be disconnected and test connection state summary
96 mCachedDevice.onProfileStateChanged(mPanProfile, BluetoothProfile.STATE_DISCONNECTED);
Jack He6258aae2017-06-29 17:01:23 -070097 assertThat(mCachedDevice.getConnectionSummary()).isNull();
98
99 // Test with BluetoothDevice.BATTERY_LEVEL_UNKNOWN battery level
100 mBatteryLevel = BluetoothDevice.BATTERY_LEVEL_UNKNOWN;
101
Hansong Zhang1c1bc252017-10-30 16:38:16 -0700102 // Set PAN profile to be connected and test connection state summary
103 mCachedDevice.onProfileStateChanged(mPanProfile, BluetoothProfile.STATE_CONNECTED);
Pavlin Radoslavove6e080f2018-02-06 12:21:34 -0800104 assertThat(mCachedDevice.getConnectionSummary()).isEqualTo("Connected");
Jack He6258aae2017-06-29 17:01:23 -0700105
Hansong Zhang1c1bc252017-10-30 16:38:16 -0700106 // Set PAN profile to be disconnected and test connection state summary
107 mCachedDevice.onProfileStateChanged(mPanProfile, BluetoothProfile.STATE_DISCONNECTED);
Jack He6258aae2017-06-29 17:01:23 -0700108 assertThat(mCachedDevice.getConnectionSummary()).isNull();
109 }
110
111 @Test
112 public void testGetConnectionSummary_testMultipleProfileConnectDisconnect() {
113 mBatteryLevel = 10;
114
Hansong Zhang1c1bc252017-10-30 16:38:16 -0700115 // Set HFP, A2DP and PAN profile to be connected and test connection state summary
Jack He6258aae2017-06-29 17:01:23 -0700116 mCachedDevice.onProfileStateChanged(mHfpProfile, BluetoothProfile.STATE_CONNECTED);
117 mCachedDevice.onProfileStateChanged(mA2dpProfile, BluetoothProfile.STATE_CONNECTED);
Hansong Zhang1c1bc252017-10-30 16:38:16 -0700118 mCachedDevice.onProfileStateChanged(mPanProfile, BluetoothProfile.STATE_CONNECTED);
Pavlin Radoslavove6e080f2018-02-06 12:21:34 -0800119 assertThat(mCachedDevice.getConnectionSummary()).isEqualTo("Connected, battery 10%");
Jack He6258aae2017-06-29 17:01:23 -0700120
121 // Disconnect HFP only and test connection state summary
122 mCachedDevice.onProfileStateChanged(mHfpProfile, BluetoothProfile.STATE_DISCONNECTED);
Pavlin Radoslavove6e080f2018-02-06 12:21:34 -0800123 assertThat(mCachedDevice.getConnectionSummary()).isEqualTo(
124 "Connected (no phone), battery 10%");
Jack He6258aae2017-06-29 17:01:23 -0700125
126 // Disconnect A2DP only and test connection state summary
127 mCachedDevice.onProfileStateChanged(mHfpProfile, BluetoothProfile.STATE_CONNECTED);
128 mCachedDevice.onProfileStateChanged(mA2dpProfile, BluetoothProfile.STATE_DISCONNECTED);
Pavlin Radoslavove6e080f2018-02-06 12:21:34 -0800129 assertThat(mCachedDevice.getConnectionSummary()).isEqualTo(
130 "Connected (no media), battery 10%");
Jack He6258aae2017-06-29 17:01:23 -0700131
132 // Disconnect both HFP and A2DP and test connection state summary
133 mCachedDevice.onProfileStateChanged(mHfpProfile, BluetoothProfile.STATE_DISCONNECTED);
Pavlin Radoslavove6e080f2018-02-06 12:21:34 -0800134 assertThat(mCachedDevice.getConnectionSummary()).isEqualTo(
135 "Connected (no phone or media), battery 10%");
Jack He6258aae2017-06-29 17:01:23 -0700136
137 // Disconnect all profiles and test connection state summary
Hansong Zhang1c1bc252017-10-30 16:38:16 -0700138 mCachedDevice.onProfileStateChanged(mPanProfile, BluetoothProfile.STATE_DISCONNECTED);
Jack He6258aae2017-06-29 17:01:23 -0700139 assertThat(mCachedDevice.getConnectionSummary()).isNull();
140 }
Jack Hec219bc92017-07-24 14:55:59 -0700141
142 @Test
Pavlin Radoslavove6e080f2018-02-06 12:21:34 -0800143 public void testGetConnectionSummary_testSingleProfileActiveDeviceA2dp() {
144 // Test without battery level
145 // Set A2DP profile to be connected and test connection state summary
146 mCachedDevice.onProfileStateChanged(mA2dpProfile, BluetoothProfile.STATE_CONNECTED);
147 assertThat(mCachedDevice.getConnectionSummary()).isEqualTo("Connected");
148
149 // Set device as Active for A2DP and test connection state summary
Pavlin Radoslavovc285d552018-02-06 16:14:00 -0800150 mCachedDevice.onActiveDeviceChanged(true, BluetoothProfile.A2DP);
Pavlin Radoslavove6e080f2018-02-06 12:21:34 -0800151 assertThat(mCachedDevice.getConnectionSummary()).isEqualTo("Connected, active(media)");
152
153 // Test with battery level
154 mBatteryLevel = 10;
155 assertThat(mCachedDevice.getConnectionSummary()).isEqualTo(
156 "Connected, battery 10%, active(media)");
157
158 // Set A2DP profile to be disconnected and test connection state summary
159 mCachedDevice.onProfileStateChanged(mA2dpProfile, BluetoothProfile.STATE_DISCONNECTED);
160 assertThat(mCachedDevice.getConnectionSummary()).isNull();
161
162 // Test with BluetoothDevice.BATTERY_LEVEL_UNKNOWN battery level
163 mBatteryLevel = BluetoothDevice.BATTERY_LEVEL_UNKNOWN;
164 // Set A2DP profile to be connected, Active and test connection state summary
165 mCachedDevice.onProfileStateChanged(mA2dpProfile, BluetoothProfile.STATE_CONNECTED);
Pavlin Radoslavovc285d552018-02-06 16:14:00 -0800166 mCachedDevice.onActiveDeviceChanged(true, BluetoothProfile.A2DP);
Pavlin Radoslavove6e080f2018-02-06 12:21:34 -0800167 assertThat(mCachedDevice.getConnectionSummary()).isEqualTo("Connected, active(media)");
168
169 // Set A2DP profile to be disconnected and test connection state summary
170 mCachedDevice.onProfileStateChanged(mA2dpProfile, BluetoothProfile.STATE_DISCONNECTED);
171 assertThat(mCachedDevice.getConnectionSummary()).isNull();
172 }
173
174 @Test
175 public void testGetConnectionSummary_testSingleProfileActiveDeviceHfp() {
176 // Test without battery level
177 // Set HFP profile to be connected and test connection state summary
178 mCachedDevice.onProfileStateChanged(mHfpProfile, BluetoothProfile.STATE_CONNECTED);
179 assertThat(mCachedDevice.getConnectionSummary()).isEqualTo("Connected");
180
181 // Set device as Active for HFP and test connection state summary
Pavlin Radoslavovc285d552018-02-06 16:14:00 -0800182 mCachedDevice.onActiveDeviceChanged(true, BluetoothProfile.HEADSET);
Pavlin Radoslavove6e080f2018-02-06 12:21:34 -0800183 assertThat(mCachedDevice.getConnectionSummary()).isEqualTo("Connected, active(phone)");
184
185 // Test with battery level
186 mBatteryLevel = 10;
187 assertThat(mCachedDevice.getConnectionSummary()).isEqualTo(
188 "Connected, battery 10%, active(phone)");
189
190 // Set HFP profile to be disconnected and test connection state summary
191 mCachedDevice.onProfileStateChanged(mHfpProfile, BluetoothProfile.STATE_DISCONNECTED);
192 assertThat(mCachedDevice.getConnectionSummary()).isNull();
193
194 // Test with BluetoothDevice.BATTERY_LEVEL_UNKNOWN battery level
195 mBatteryLevel = BluetoothDevice.BATTERY_LEVEL_UNKNOWN;
196 // Set HFP profile to be connected, Active and test connection state summary
197 mCachedDevice.onProfileStateChanged(mHfpProfile, BluetoothProfile.STATE_CONNECTED);
Pavlin Radoslavovc285d552018-02-06 16:14:00 -0800198 mCachedDevice.onActiveDeviceChanged(true, BluetoothProfile.HEADSET);
Pavlin Radoslavove6e080f2018-02-06 12:21:34 -0800199 assertThat(mCachedDevice.getConnectionSummary()).isEqualTo("Connected, active(phone)");
200
201 // Set HFP profile to be disconnected and test connection state summary
202 mCachedDevice.onProfileStateChanged(mHfpProfile, BluetoothProfile.STATE_DISCONNECTED);
203 assertThat(mCachedDevice.getConnectionSummary()).isNull();
204 }
205
206 @Test
207 public void testGetConnectionSummary_testMultipleProfilesActiveDevice() {
208 // Test without battery level
209 // Set A2DP and HFP profiles to be connected and test connection state summary
210 mCachedDevice.onProfileStateChanged(mA2dpProfile, BluetoothProfile.STATE_CONNECTED);
211 mCachedDevice.onProfileStateChanged(mHfpProfile, BluetoothProfile.STATE_CONNECTED);
212 assertThat(mCachedDevice.getConnectionSummary()).isEqualTo("Connected");
213
214 // Set device as Active for A2DP and HFP and test connection state summary
Pavlin Radoslavovc285d552018-02-06 16:14:00 -0800215 mCachedDevice.onActiveDeviceChanged(true, BluetoothProfile.A2DP);
216 mCachedDevice.onActiveDeviceChanged(true, BluetoothProfile.HEADSET);
Pavlin Radoslavove6e080f2018-02-06 12:21:34 -0800217 assertThat(mCachedDevice.getConnectionSummary()).isEqualTo("Connected, active");
218
219 // Test with battery level
220 mBatteryLevel = 10;
221 assertThat(mCachedDevice.getConnectionSummary()).isEqualTo(
222 "Connected, battery 10%, active");
223
224 // Disconnect A2DP only and test connection state summary
Pavlin Radoslavovc285d552018-02-06 16:14:00 -0800225 mCachedDevice.onActiveDeviceChanged(false, BluetoothProfile.A2DP);
Pavlin Radoslavove6e080f2018-02-06 12:21:34 -0800226 mCachedDevice.onProfileStateChanged(mA2dpProfile, BluetoothProfile.STATE_DISCONNECTED);
227 assertThat(mCachedDevice.getConnectionSummary()).isEqualTo(
228 "Connected (no media), battery 10%, active(phone)");
229
230 // Disconnect HFP only and test connection state summary
Pavlin Radoslavovc285d552018-02-06 16:14:00 -0800231 mCachedDevice.onActiveDeviceChanged(false, BluetoothProfile.HEADSET);
Pavlin Radoslavove6e080f2018-02-06 12:21:34 -0800232 mCachedDevice.onProfileStateChanged(mHfpProfile, BluetoothProfile.STATE_DISCONNECTED);
233 mCachedDevice.onProfileStateChanged(mA2dpProfile, BluetoothProfile.STATE_CONNECTED);
Pavlin Radoslavovc285d552018-02-06 16:14:00 -0800234 mCachedDevice.onActiveDeviceChanged(true, BluetoothProfile.A2DP);
Pavlin Radoslavove6e080f2018-02-06 12:21:34 -0800235 assertThat(mCachedDevice.getConnectionSummary()).isEqualTo(
236 "Connected (no phone), battery 10%, active(media)");
237
238 // Test with BluetoothDevice.BATTERY_LEVEL_UNKNOWN battery level
239 mBatteryLevel = BluetoothDevice.BATTERY_LEVEL_UNKNOWN;
240 // Set A2DP and HFP profiles to be connected, Active and test connection state summary
241 mCachedDevice.onProfileStateChanged(mA2dpProfile, BluetoothProfile.STATE_CONNECTED);
242 mCachedDevice.onProfileStateChanged(mHfpProfile, BluetoothProfile.STATE_CONNECTED);
Pavlin Radoslavovc285d552018-02-06 16:14:00 -0800243 mCachedDevice.onActiveDeviceChanged(true, BluetoothProfile.A2DP);
244 mCachedDevice.onActiveDeviceChanged(true, BluetoothProfile.HEADSET);
Pavlin Radoslavove6e080f2018-02-06 12:21:34 -0800245 assertThat(mCachedDevice.getConnectionSummary()).isEqualTo("Connected, active");
246
247 // Set A2DP and HFP profiles to be disconnected and test connection state summary
248 mCachedDevice.onProfileStateChanged(mA2dpProfile, BluetoothProfile.STATE_DISCONNECTED);
249 mCachedDevice.onProfileStateChanged(mHfpProfile, BluetoothProfile.STATE_DISCONNECTED);
250 assertThat(mCachedDevice.getConnectionSummary()).isNull();
251 }
252
253 @Test
Jack Hec219bc92017-07-24 14:55:59 -0700254 public void testDeviceName_testAliasNameAvailable() {
255 when(mDevice.getAliasName()).thenReturn(DEVICE_ALIAS);
256 when(mDevice.getName()).thenReturn(DEVICE_NAME);
257 CachedBluetoothDevice cachedBluetoothDevice =
258 new CachedBluetoothDevice(mContext, mAdapter, mProfileManager, mDevice);
259 // Verify alias is returned on getName
260 assertThat(cachedBluetoothDevice.getName()).isEqualTo(DEVICE_ALIAS);
261 // Verify device is visible
262 assertThat(cachedBluetoothDevice.hasHumanReadableName()).isTrue();
263 }
264
265 @Test
266 public void testDeviceName_testNameNotAvailable() {
267 CachedBluetoothDevice cachedBluetoothDevice =
268 new CachedBluetoothDevice(mContext, mAdapter, mProfileManager, mDevice);
269 // Verify device address is returned on getName
270 assertThat(cachedBluetoothDevice.getName()).isEqualTo(DEVICE_ADDRESS);
271 // Verify device is not visible
272 assertThat(cachedBluetoothDevice.hasHumanReadableName()).isFalse();
273 }
274
275 @Test
276 public void testDeviceName_testRenameDevice() {
277 final String[] alias = {DEVICE_ALIAS};
278 doAnswer(invocation -> alias[0]).when(mDevice).getAliasName();
279 doAnswer(invocation -> {
280 alias[0] = (String) invocation.getArguments()[0];
281 return true;
282 }).when(mDevice).setAlias(anyString());
283 when(mDevice.getName()).thenReturn(DEVICE_NAME);
284 CachedBluetoothDevice cachedBluetoothDevice =
285 new CachedBluetoothDevice(mContext, mAdapter, mProfileManager, mDevice);
286 // Verify alias is returned on getName
287 assertThat(cachedBluetoothDevice.getName()).isEqualTo(DEVICE_ALIAS);
288 // Verify null name does not get set
289 cachedBluetoothDevice.setName(null);
290 verify(mDevice, never()).setAlias(any());
291 // Verify new name is set properly
292 cachedBluetoothDevice.setName(DEVICE_ALIAS_NEW);
293 verify(mDevice).setAlias(DEVICE_ALIAS_NEW);
294 // Verify new alias is returned on getName
295 assertThat(cachedBluetoothDevice.getName()).isEqualTo(DEVICE_ALIAS_NEW);
296 }
Jack He6258aae2017-06-29 17:01:23 -0700297}