• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 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 package com.android.bluetooth.btservice;
17 
18 import static org.mockito.Mockito.*;
19 
20 import android.bluetooth.BluetoothDevice;
21 import android.content.Context;
22 import android.content.Intent;
23 import android.os.HandlerThread;
24 import android.os.ParcelUuid;
25 import android.os.UserHandle;
26 import android.support.test.InstrumentationRegistry;
27 import android.support.test.filters.MediumTest;
28 import android.support.test.runner.AndroidJUnit4;
29 
30 import com.android.bluetooth.TestUtils;
31 
32 import org.junit.After;
33 import org.junit.Assert;
34 import org.junit.Before;
35 import org.junit.Test;
36 import org.junit.runner.RunWith;
37 import org.mockito.ArgumentCaptor;
38 import org.mockito.Mock;
39 import org.mockito.MockitoAnnotations;
40 
41 @MediumTest
42 @RunWith(AndroidJUnit4.class)
43 public class BondStateMachineTest {
44     private static final int TEST_BOND_REASON = 0;
45     private static final byte[] TEST_BT_ADDR_BYTES = {00, 11, 22, 33, 44, 55};
46     private static final ParcelUuid[] TEST_UUIDS =
47             {ParcelUuid.fromString("0000111E-0000-1000-8000-00805F9B34FB")};
48 
49     private static final int BOND_NONE = BluetoothDevice.BOND_NONE;
50     private static final int BOND_BONDING = BluetoothDevice.BOND_BONDING;
51     private static final int BOND_BONDED = BluetoothDevice.BOND_BONDED;
52 
53     private AdapterProperties mAdapterProperties;
54     private BluetoothDevice mDevice;
55     private Context mTargetContext;
56     private RemoteDevices mRemoteDevices;
57     private BondStateMachine mBondStateMachine;
58     private HandlerThread mHandlerThread;
59     private RemoteDevices.DeviceProperties mDeviceProperties;
60     private int mVerifyCount = 0;
61 
62     @Mock private AdapterService mAdapterService;
63 
64     @Before
setUp()65     public void setUp() throws Exception {
66         mTargetContext = InstrumentationRegistry.getTargetContext();
67         MockitoAnnotations.initMocks(this);
68         TestUtils.setAdapterService(mAdapterService);
69         mHandlerThread = new HandlerThread("BondStateMachineTestHandlerThread");
70         mHandlerThread.start();
71 
72         mRemoteDevices = new RemoteDevices(mAdapterService, mHandlerThread.getLooper());
73         mRemoteDevices.reset();
74         when(mAdapterService.getResources()).thenReturn(
75                 mTargetContext.getResources());
76         mAdapterProperties = new AdapterProperties(mAdapterService);
77         mAdapterProperties.init(mRemoteDevices);
78         mBondStateMachine = BondStateMachine.make(mAdapterService, mAdapterProperties,
79                 mRemoteDevices);
80     }
81 
82     @After
tearDown()83     public void tearDown() throws Exception {
84         mHandlerThread.quit();
85         TestUtils.clearAdapterService(mAdapterService);
86     }
87 
88     @Test
testSendIntent()89     public void testSendIntent() {
90         int badBondState = 42;
91         mVerifyCount = 0;
92 
93         // Reset mRemoteDevices for the test.
94         mRemoteDevices.reset();
95         mDeviceProperties = mRemoteDevices.addDeviceProperties(TEST_BT_ADDR_BYTES);
96         mDevice = mDeviceProperties.getDevice();
97         Assert.assertNotNull(mDevice);
98 
99         /* Classic / Dualmode test cases*/
100         // Uuid not available, mPendingBondedDevice is empty.
101         testSendIntentNoPendingDevice(BOND_NONE, BOND_NONE, BOND_NONE,
102                 false, BOND_NONE, BOND_NONE);
103         testSendIntentNoPendingDevice(BOND_NONE, BOND_BONDING, BOND_BONDING,
104                 true, BOND_NONE, BOND_BONDING);
105         testSendIntentNoPendingDevice(BOND_NONE, BOND_BONDED, BOND_BONDED,
106                 true, BOND_NONE, BOND_BONDING);
107         testSendIntentNoPendingDevice(BOND_NONE, badBondState, BOND_NONE,
108                 false, BOND_NONE, BOND_NONE);
109         testSendIntentNoPendingDevice(BOND_BONDING, BOND_NONE, BOND_NONE,
110                 true, BOND_BONDING, BOND_NONE);
111         testSendIntentNoPendingDevice(BOND_BONDING, BOND_BONDING, BOND_BONDING,
112                 false, BOND_NONE, BOND_NONE);
113         testSendIntentNoPendingDevice(BOND_BONDING, BOND_BONDED, BOND_BONDED,
114                 false, BOND_NONE, BOND_NONE);
115         testSendIntentNoPendingDevice(BOND_BONDING, badBondState, BOND_BONDING,
116                 false, BOND_NONE, BOND_NONE);
117         testSendIntentNoPendingDevice(BOND_BONDED, BOND_NONE, BOND_NONE,
118                 true, BOND_BONDED, BOND_NONE);
119         testSendIntentNoPendingDevice(BOND_BONDED, BOND_BONDING, BOND_BONDING,
120                 true, BOND_BONDED, BOND_BONDING);
121         testSendIntentNoPendingDevice(BOND_BONDED, BOND_BONDED, BOND_BONDED,
122                 false, BOND_NONE, BOND_NONE);
123         testSendIntentNoPendingDevice(BOND_BONDED, badBondState, BOND_BONDED,
124                 false, BOND_NONE, BOND_NONE);
125 
126         // Uuid not available, mPendingBondedDevice contains a remote device.
127         testSendIntentPendingDevice(BOND_NONE, BOND_NONE, BOND_NONE,
128                 false, BOND_NONE, BOND_NONE);
129         testSendIntentPendingDevice(BOND_NONE, BOND_BONDING, BOND_NONE,
130                 false, BOND_NONE, BOND_NONE);
131         testSendIntentPendingDevice(BOND_NONE, BOND_BONDED, BOND_NONE,
132                 false, BOND_NONE, BOND_NONE);
133         testSendIntentPendingDevice(BOND_NONE, badBondState, BOND_NONE,
134                 false, BOND_NONE, BOND_NONE);
135         testSendIntentPendingDevice(BOND_BONDING, BOND_NONE, BOND_BONDING,
136                 false, BOND_NONE, BOND_NONE);
137         testSendIntentPendingDevice(BOND_BONDING, BOND_BONDING, BOND_BONDING,
138                 false, BOND_NONE, BOND_NONE);
139         testSendIntentPendingDevice(BOND_BONDING, BOND_BONDED, BOND_BONDING,
140                 false, BOND_NONE, BOND_NONE);
141         testSendIntentPendingDevice(BOND_BONDING, badBondState, BOND_BONDING,
142                 false, BOND_NONE, BOND_NONE);
143         testSendIntentPendingDevice(BOND_BONDED, BOND_NONE, BOND_NONE,
144                 true, BOND_BONDING, BOND_NONE);
145         testSendIntentPendingDevice(BOND_BONDED, BOND_BONDING, BOND_BONDING,
146                 false, BOND_NONE, BOND_NONE);
147         testSendIntentPendingDevice(BOND_BONDED, BOND_BONDED, BOND_BONDED,
148                 false, BOND_NONE, BOND_NONE);
149         testSendIntentPendingDevice(BOND_BONDED, badBondState, BOND_BONDED,
150                 false, BOND_NONE, BOND_NONE);
151 
152         // Uuid available, mPendingBondedDevice is empty.
153         testSendIntentNoPendingDeviceWithUuid(BOND_NONE, BOND_NONE, BOND_NONE,
154                 false, BOND_NONE, BOND_NONE);
155         testSendIntentNoPendingDeviceWithUuid(BOND_NONE, BOND_BONDING, BOND_BONDING,
156                 true, BOND_NONE, BOND_BONDING);
157         testSendIntentNoPendingDeviceWithUuid(BOND_NONE, BOND_BONDED, BOND_BONDED,
158                 true, BOND_NONE, BOND_BONDED);
159         testSendIntentNoPendingDeviceWithUuid(BOND_NONE, badBondState, BOND_NONE,
160                 false, BOND_NONE, BOND_NONE);
161         testSendIntentNoPendingDeviceWithUuid(BOND_BONDING, BOND_NONE, BOND_NONE,
162                 true, BOND_BONDING, BOND_NONE);
163         testSendIntentNoPendingDeviceWithUuid(BOND_BONDING, BOND_BONDING, BOND_BONDING,
164                 false, BOND_NONE, BOND_NONE);
165         testSendIntentNoPendingDeviceWithUuid(BOND_BONDING, BOND_BONDED, BOND_BONDED,
166                 true, BOND_BONDING, BOND_BONDED);
167         testSendIntentNoPendingDeviceWithUuid(BOND_BONDING, badBondState, BOND_BONDING,
168                 false, BOND_NONE, BOND_NONE);
169         testSendIntentNoPendingDeviceWithUuid(BOND_BONDED, BOND_NONE, BOND_NONE,
170                 true, BOND_BONDED, BOND_NONE);
171         testSendIntentNoPendingDeviceWithUuid(BOND_BONDED, BOND_BONDING, BOND_BONDING,
172                 true, BOND_BONDED, BOND_BONDING);
173         testSendIntentNoPendingDeviceWithUuid(BOND_BONDED, BOND_BONDED, BOND_BONDED,
174                 false, BOND_NONE, BOND_NONE);
175         testSendIntentNoPendingDeviceWithUuid(BOND_BONDED, badBondState, BOND_BONDED,
176                 false, BOND_NONE, BOND_NONE);
177 
178         // Uuid available, mPendingBondedDevice contains a remote device.
179         testSendIntentPendingDeviceWithUuid(BOND_NONE, BOND_NONE, BOND_NONE,
180                 false, BOND_NONE, BOND_NONE);
181         testSendIntentPendingDeviceWithUuid(BOND_NONE, BOND_BONDING, BOND_NONE,
182                 false, BOND_NONE, BOND_NONE);
183         testSendIntentPendingDeviceWithUuid(BOND_NONE, BOND_BONDED, BOND_NONE,
184                 false, BOND_NONE, BOND_NONE);
185         testSendIntentPendingDeviceWithUuid(BOND_NONE, badBondState, BOND_NONE,
186                 false, BOND_NONE, BOND_NONE);
187         testSendIntentPendingDeviceWithUuid(BOND_BONDING, BOND_NONE, BOND_BONDING,
188                 false, BOND_NONE, BOND_NONE);
189         testSendIntentPendingDeviceWithUuid(BOND_BONDING, BOND_BONDING, BOND_BONDING,
190                 false, BOND_NONE, BOND_NONE);
191         testSendIntentPendingDeviceWithUuid(BOND_BONDING, BOND_BONDED, BOND_BONDING,
192                 false, BOND_NONE, BOND_NONE);
193         testSendIntentPendingDeviceWithUuid(BOND_BONDING, badBondState, BOND_BONDING,
194                 false, BOND_NONE, BOND_NONE);
195         testSendIntentPendingDeviceWithUuid(BOND_BONDED, BOND_NONE, BOND_NONE,
196                 true, BOND_BONDING, BOND_NONE);
197         testSendIntentPendingDeviceWithUuid(BOND_BONDED, BOND_BONDING, BOND_BONDING,
198                 false, BOND_NONE, BOND_NONE);
199         testSendIntentPendingDeviceWithUuid(BOND_BONDED, BOND_BONDED, BOND_BONDED,
200                 true, BOND_BONDING, BOND_BONDED);
201         testSendIntentPendingDeviceWithUuid(BOND_BONDED, badBondState, BOND_BONDED,
202                 false, BOND_NONE, BOND_NONE);
203 
204         /* Low energy test cases */
205         testSendIntentBle(BOND_NONE, BOND_NONE, BOND_NONE);
206         testSendIntentBle(BOND_NONE, BOND_BONDING, BOND_BONDING);
207         testSendIntentBle(BOND_NONE, BOND_BONDED, BOND_BONDED);
208         testSendIntentBle(BOND_BONDING, BOND_NONE, BOND_NONE);
209         testSendIntentBle(BOND_BONDING, BOND_BONDING, BOND_BONDING);
210         testSendIntentBle(BOND_BONDING, BOND_BONDED, BOND_BONDED);
211         testSendIntentBle(BOND_BONDED, BOND_NONE, BOND_NONE);
212         testSendIntentBle(BOND_BONDED, BOND_BONDING, BOND_BONDING);
213         testSendIntentBle(BOND_BONDED, BOND_BONDED, BOND_BONDED);
214     }
215 
testSendIntentCase(int oldState, int newState, int expectedNewState, boolean shouldBroadcast, int broadcastOldState, int broadcastNewState)216     private void testSendIntentCase(int oldState, int newState, int expectedNewState,
217             boolean shouldBroadcast, int broadcastOldState, int broadcastNewState) {
218         ArgumentCaptor<Intent> intentArgument = ArgumentCaptor.forClass(Intent.class);
219 
220         // Setup old state before start test.
221         mDeviceProperties.mBondState = oldState;
222 
223         try {
224             mBondStateMachine.sendIntent(mDevice, newState, TEST_BOND_REASON);
225         } catch (IllegalArgumentException e) {
226             // Do nothing.
227         }
228         Assert.assertEquals(expectedNewState, mDeviceProperties.getBondState());
229 
230         // Check for bond state Intent status.
231         if (shouldBroadcast) {
232             verify(mAdapterService, times(++mVerifyCount)).sendBroadcastAsUser(
233                     intentArgument.capture(), eq(UserHandle.ALL),
234                     eq(AdapterService.BLUETOOTH_PERM));
235             verifyBondStateChangeIntent(broadcastOldState, broadcastNewState,
236                     intentArgument.getValue());
237         } else {
238             verify(mAdapterService, times(mVerifyCount)).sendBroadcastAsUser(any(Intent.class),
239                     any(UserHandle.class), anyString());
240         }
241     }
242 
testSendIntentNoPendingDeviceWithUuid(int oldState, int newState, int expectedNewState, boolean shouldBroadcast, int broadcastOldState, int broadcastNewState)243     private void testSendIntentNoPendingDeviceWithUuid(int oldState, int newState,
244             int expectedNewState, boolean shouldBroadcast, int broadcastOldState,
245             int broadcastNewState) {
246         // Add dummy UUID for the device.
247         mDeviceProperties.mUuids = TEST_UUIDS;
248         testSendIntentNoPendingDevice(oldState, newState, expectedNewState, shouldBroadcast,
249                 broadcastOldState, broadcastNewState);
250     }
251 
testSendIntentPendingDeviceWithUuid(int oldState, int newState, int expectedNewState, boolean shouldBroadcast, int broadcastOldState, int broadcastNewState)252     private void testSendIntentPendingDeviceWithUuid(int oldState, int newState,
253             int expectedNewState, boolean shouldBroadcast, int broadcastOldState,
254             int broadcastNewState) {
255         // Add dummy UUID for the device.
256         mDeviceProperties.mUuids = TEST_UUIDS;
257         testSendIntentPendingDevice(oldState, newState, expectedNewState, shouldBroadcast,
258                 broadcastOldState, broadcastNewState);
259     }
260 
testSendIntentPendingDevice(int oldState, int newState, int expectedNewState, boolean shouldBroadcast, int broadcastOldState, int broadcastNewState)261     private void testSendIntentPendingDevice(int oldState, int newState, int expectedNewState,
262             boolean shouldBroadcast, int broadcastOldState, int broadcastNewState) {
263         // Test for classic remote device.
264         mDeviceProperties.mDeviceType = BluetoothDevice.DEVICE_TYPE_CLASSIC;
265         mBondStateMachine.mPendingBondedDevices.clear();
266         mBondStateMachine.mPendingBondedDevices.add(mDevice);
267         testSendIntentCase(oldState, newState, expectedNewState, shouldBroadcast,
268                 broadcastOldState, broadcastNewState);
269 
270         // Test for dual-mode remote device.
271         mDeviceProperties.mDeviceType = BluetoothDevice.DEVICE_TYPE_DUAL;
272         mBondStateMachine.mPendingBondedDevices.clear();
273         mBondStateMachine.mPendingBondedDevices.add(mDevice);
274         testSendIntentCase(oldState, newState, expectedNewState, shouldBroadcast,
275                 broadcastOldState, broadcastNewState);
276     }
277 
testSendIntentNoPendingDevice(int oldState, int newState, int expectedNewState, boolean shouldBroadcast, int broadcastOldState, int broadcastNewState)278     private void testSendIntentNoPendingDevice(int oldState, int newState, int expectedNewState,
279             boolean shouldBroadcast, int broadcastOldState, int broadcastNewState) {
280         // Test for classic remote device.
281         mDeviceProperties.mDeviceType = BluetoothDevice.DEVICE_TYPE_CLASSIC;
282         mBondStateMachine.mPendingBondedDevices.clear();
283         testSendIntentCase(oldState, newState, expectedNewState, shouldBroadcast,
284                 broadcastOldState, broadcastNewState);
285 
286         // Test for dual-mode remote device.
287         mDeviceProperties.mDeviceType = BluetoothDevice.DEVICE_TYPE_DUAL;
288         mBondStateMachine.mPendingBondedDevices.clear();
289         testSendIntentCase(oldState, newState, expectedNewState, shouldBroadcast,
290                 broadcastOldState, broadcastNewState);
291     }
292 
testSendIntentBle(int oldState, int newState, int expectedNewState)293     private void testSendIntentBle(int oldState, int newState, int expectedNewState) {
294         // Test for low energy remote device.
295         mDeviceProperties.mDeviceType = BluetoothDevice.DEVICE_TYPE_LE;
296         mBondStateMachine.mPendingBondedDevices.clear();
297         testSendIntentCase(oldState, newState, newState, (oldState != newState),
298                 oldState, newState);
299     }
300 
verifyBondStateChangeIntent(int oldState, int newState, Intent intent)301     private void verifyBondStateChangeIntent(int oldState, int newState, Intent intent) {
302         Assert.assertNotNull(intent);
303         Assert.assertEquals(BluetoothDevice.ACTION_BOND_STATE_CHANGED, intent.getAction());
304         Assert.assertEquals(mDevice, intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE));
305         Assert.assertEquals(newState, intent.getIntExtra(BluetoothDevice.EXTRA_BOND_STATE, -1));
306         Assert.assertEquals(oldState, intent.getIntExtra(BluetoothDevice.EXTRA_PREVIOUS_BOND_STATE,
307                                                           -1));
308         if (newState == BOND_NONE) {
309             Assert.assertEquals(TEST_BOND_REASON, intent.getIntExtra(BluetoothDevice.EXTRA_REASON,
310                                                               -1));
311         } else {
312             Assert.assertEquals(-1, intent.getIntExtra(BluetoothDevice.EXTRA_REASON, -1));
313         }
314     }
315 }
316