1 /*
2  * Copyright (C) 2009 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 android.bluetooth.cts;
18 
19 import android.bluetooth.BluetoothAdapter;
20 import android.bluetooth.BluetoothDevice;
21 import android.bluetooth.BluetoothServerSocket;
22 import android.content.pm.PackageManager;
23 import android.test.AndroidTestCase;
24 
25 import java.io.IOException;
26 import java.util.Set;
27 import java.util.UUID;
28 
29 /**
30  * Very basic test, just of the static methods of {@link
31  * BluetoothAdapter}.
32  */
33 public class BasicAdapterTest extends AndroidTestCase {
34     private static final int DISABLE_TIMEOUT = 8000;  // ms timeout for BT disable
35     private static final int ENABLE_TIMEOUT = 10000;  // ms timeout for BT enable
36     private static final int POLL_TIME = 400;         // ms to poll BT state
37     private static final int CHECK_WAIT_TIME = 1000;  // ms to wait before enable/disable
38 
39     private boolean mHasBluetooth;
40 
setUp()41     public void setUp() throws Exception {
42         super.setUp();
43 
44         mHasBluetooth = getContext().getPackageManager().hasSystemFeature(
45                 PackageManager.FEATURE_BLUETOOTH);
46     }
47 
test_getDefaultAdapter()48     public void test_getDefaultAdapter() {
49         /*
50          * Note: If the target doesn't support Bluetooth at all, then
51          * this method should return null.
52          */
53         if (mHasBluetooth) {
54             assertNotNull(BluetoothAdapter.getDefaultAdapter());
55         } else {
56             assertNull(BluetoothAdapter.getDefaultAdapter());
57         }
58     }
59 
test_checkBluetoothAddress()60     public void test_checkBluetoothAddress() {
61         // Can't be null.
62         assertFalse(BluetoothAdapter.checkBluetoothAddress(null));
63 
64         // Must be 17 characters long.
65         assertFalse(BluetoothAdapter.checkBluetoothAddress(""));
66         assertFalse(BluetoothAdapter.checkBluetoothAddress("0"));
67         assertFalse(BluetoothAdapter.checkBluetoothAddress("00"));
68         assertFalse(BluetoothAdapter.checkBluetoothAddress("00:"));
69         assertFalse(BluetoothAdapter.checkBluetoothAddress("00:0"));
70         assertFalse(BluetoothAdapter.checkBluetoothAddress("00:00"));
71         assertFalse(BluetoothAdapter.checkBluetoothAddress("00:00:"));
72         assertFalse(BluetoothAdapter.checkBluetoothAddress("00:00:0"));
73         assertFalse(BluetoothAdapter.checkBluetoothAddress("00:00:00"));
74         assertFalse(BluetoothAdapter.checkBluetoothAddress("00:00:00:"));
75         assertFalse(BluetoothAdapter.checkBluetoothAddress("00:00:00:0"));
76         assertFalse(BluetoothAdapter.checkBluetoothAddress("00:00:00:00"));
77         assertFalse(BluetoothAdapter.checkBluetoothAddress("00:00:00:00:"));
78         assertFalse(BluetoothAdapter.checkBluetoothAddress("00:00:00:00:0"));
79         assertFalse(BluetoothAdapter.checkBluetoothAddress("00:00:00:00:00"));
80         assertFalse(BluetoothAdapter.checkBluetoothAddress("00:00:00:00:00:"));
81         assertFalse(BluetoothAdapter.checkBluetoothAddress(
82             "00:00:00:00:00:0"));
83 
84         // Must have colons between octets.
85         assertFalse(BluetoothAdapter.checkBluetoothAddress(
86             "00x00:00:00:00:00"));
87         assertFalse(BluetoothAdapter.checkBluetoothAddress(
88             "00:00.00:00:00:00"));
89         assertFalse(BluetoothAdapter.checkBluetoothAddress(
90             "00:00:00-00:00:00"));
91         assertFalse(BluetoothAdapter.checkBluetoothAddress(
92             "00:00:00:00900:00"));
93         assertFalse(BluetoothAdapter.checkBluetoothAddress(
94             "00:00:00:00:00?00"));
95 
96         // Hex letters must be uppercase.
97         assertFalse(BluetoothAdapter.checkBluetoothAddress(
98             "a0:00:00:00:00:00"));
99         assertFalse(BluetoothAdapter.checkBluetoothAddress(
100             "0b:00:00:00:00:00"));
101         assertFalse(BluetoothAdapter.checkBluetoothAddress(
102             "00:c0:00:00:00:00"));
103         assertFalse(BluetoothAdapter.checkBluetoothAddress(
104             "00:0d:00:00:00:00"));
105         assertFalse(BluetoothAdapter.checkBluetoothAddress(
106             "00:00:e0:00:00:00"));
107         assertFalse(BluetoothAdapter.checkBluetoothAddress(
108             "00:00:0f:00:00:00"));
109 
110         assertTrue(BluetoothAdapter.checkBluetoothAddress(
111             "00:00:00:00:00:00"));
112         assertTrue(BluetoothAdapter.checkBluetoothAddress(
113             "12:34:56:78:9A:BC"));
114         assertTrue(BluetoothAdapter.checkBluetoothAddress(
115             "DE:F0:FE:DC:B8:76"));
116     }
117 
118     /** Checks enable(), disable(), getState(), isEnabled() */
test_enableDisable()119     public void test_enableDisable() {
120         if (!mHasBluetooth) {
121             // Skip the test if bluetooth is not present.
122             return;
123         }
124         BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
125 
126         for (int i=0; i<5; i++) {
127             disable(adapter);
128             enable(adapter);
129         }
130     }
131 
test_getAddress()132     public void test_getAddress() {
133         if (!mHasBluetooth) {
134             // Skip the test if bluetooth is not present.
135             return;
136         }
137         BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
138         enable(adapter);
139 
140         assertTrue(BluetoothAdapter.checkBluetoothAddress(adapter.getAddress()));
141     }
142 
test_getName()143     public void test_getName() {
144         if (!mHasBluetooth) {
145             // Skip the test if bluetooth is not present.
146             return;
147         }
148         BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
149         enable(adapter);
150 
151         String name = adapter.getName();
152         assertNotNull(name);
153     }
154 
test_getBondedDevices()155     public void test_getBondedDevices() {
156         if (!mHasBluetooth) {
157             // Skip the test if bluetooth is not present.
158             return;
159         }
160         BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
161         enable(adapter);
162 
163         Set<BluetoothDevice> devices = adapter.getBondedDevices();
164         assertNotNull(devices);
165         for (BluetoothDevice device : devices) {
166             assertTrue(BluetoothAdapter.checkBluetoothAddress(device.getAddress()));
167         }
168     }
169 
test_getRemoteDevice()170     public void test_getRemoteDevice() {
171         if (!mHasBluetooth) {
172             // Skip the test if bluetooth is not present.
173             return;
174         }
175         // getRemoteDevice() should work even with Bluetooth disabled
176         BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
177         disable(adapter);
178 
179         // test bad addresses
180         try {
181             adapter.getRemoteDevice((String)null);
182             fail("IllegalArgumentException not thrown");
183         } catch (IllegalArgumentException e) {}
184         try {
185             adapter.getRemoteDevice("00:00:00:00:00:00:00:00");
186             fail("IllegalArgumentException not thrown");
187         } catch (IllegalArgumentException e) {}
188         try {
189             adapter.getRemoteDevice((byte[])null);
190             fail("IllegalArgumentException not thrown");
191         } catch (IllegalArgumentException e) {}
192         try {
193             adapter.getRemoteDevice(new byte[] {0x00, 0x00, 0x00, 0x00, 0x00});
194             fail("IllegalArgumentException not thrown");
195         } catch (IllegalArgumentException e) {}
196 
197         // test success
198         BluetoothDevice device = adapter.getRemoteDevice("00:11:22:AA:BB:CC");
199         assertNotNull(device);
200         assertEquals("00:11:22:AA:BB:CC", device.getAddress());
201         device = adapter.getRemoteDevice(
202                 new byte[] {0x01, 0x02, 0x03, 0x04, 0x05, 0x06});
203         assertNotNull(device);
204         assertEquals("01:02:03:04:05:06", device.getAddress());
205     }
206 
test_listenUsingRfcommWithServiceRecord()207     public void test_listenUsingRfcommWithServiceRecord() throws IOException {
208         if (!mHasBluetooth) {
209             // Skip the test if bluetooth is not present.
210             return;
211         }
212         BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
213         enable(adapter);
214 
215         BluetoothServerSocket socket = adapter.listenUsingRfcommWithServiceRecord(
216                 "test", UUID.randomUUID());
217         assertNotNull(socket);
218         socket.close();
219     }
220 
221     /** Helper to turn BT off.
222      * This method will either fail on an assert, or return with BT turned off.
223      * Behavior of getState() and isEnabled() are validated along the way.
224      */
disable(BluetoothAdapter adapter)225     private void disable(BluetoothAdapter adapter) {
226         sleep(CHECK_WAIT_TIME);
227         if (adapter.getState() == BluetoothAdapter.STATE_OFF) {
228             assertFalse(adapter.isEnabled());
229             return;
230         }
231 
232         assertEquals(BluetoothAdapter.STATE_ON, adapter.getState());
233         assertTrue(adapter.isEnabled());
234         adapter.disable();
235         boolean turnOff = false;
236         for (int i=0; i<DISABLE_TIMEOUT/POLL_TIME; i++) {
237             sleep(POLL_TIME);
238             int state = adapter.getState();
239             switch (state) {
240             case BluetoothAdapter.STATE_OFF:
241                 assertFalse(adapter.isEnabled());
242                 return;
243             default:
244                 if (state != BluetoothAdapter.STATE_ON || turnOff) {
245                     assertEquals(BluetoothAdapter.STATE_TURNING_OFF, state);
246                     turnOff = true;
247                 }
248                 break;
249             }
250         }
251         fail("disable() timeout");
252     }
253 
254     /** Helper to turn BT on.
255      * This method will either fail on an assert, or return with BT turned on.
256      * Behavior of getState() and isEnabled() are validated along the way.
257      */
enable(BluetoothAdapter adapter)258     private void enable(BluetoothAdapter adapter) {
259         sleep(CHECK_WAIT_TIME);
260         if (adapter.getState() == BluetoothAdapter.STATE_ON) {
261             assertTrue(adapter.isEnabled());
262             return;
263         }
264 
265         assertEquals(BluetoothAdapter.STATE_OFF, adapter.getState());
266         assertFalse(adapter.isEnabled());
267         adapter.enable();
268         boolean turnOn = false;
269         for (int i=0; i<ENABLE_TIMEOUT/POLL_TIME; i++) {
270             sleep(POLL_TIME);
271             int state = adapter.getState();
272             switch (state) {
273             case BluetoothAdapter.STATE_ON:
274                 assertTrue(adapter.isEnabled());
275                 return;
276             default:
277                 if (state != BluetoothAdapter.STATE_OFF || turnOn) {
278                     assertEquals(BluetoothAdapter.STATE_TURNING_ON, state);
279                     turnOn = true;
280                 }
281                 break;
282             }
283         }
284         fail("enable() timeout");
285     }
286 
sleep(long t)287     private static void sleep(long t) {
288         try {
289             Thread.sleep(t);
290         } catch (InterruptedException e) {}
291     }
292 }
293