1 /* 2 * Copyright (C) 2015 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.le.ScanFilter; 22 import android.bluetooth.le.ScanResult; 23 import android.content.pm.PackageManager; 24 import android.os.Parcel; 25 import android.os.ParcelUuid; 26 import android.test.AndroidTestCase; 27 import android.test.suitebuilder.annotation.SmallTest; 28 29 /** 30 * Unit test cases for Bluetooth LE scan filters. 31 * <p> 32 * To run this test, use adb shell am instrument -e class 'android.bluetooth.ScanFilterTest' -w 33 * 'com.android.bluetooth.tests/android.bluetooth.BluetoothTestRunner' 34 */ 35 public class ScanFilterTest extends AndroidTestCase { 36 37 private static final String LOCAL_NAME = "Ped"; 38 private static final String DEVICE_MAC = "01:02:03:04:05:AB"; 39 private static final String UUID1 = "0000110a-0000-1000-8000-00805f9b34fb"; 40 private static final String UUID2 = "0000110b-0000-1000-8000-00805f9b34fb"; 41 private static final String UUID3 = "0000110c-0000-1000-8000-00805f9b34fb"; 42 43 private ScanResult mScanResult; 44 private ScanFilter.Builder mFilterBuilder; 45 46 @Override 47 protected void setUp() { 48 byte[] scanRecord = new byte[] { 49 0x02, 0x01, 0x1a, // advertising flags 50 0x05, 0x02, 0x0b, 0x11, 0x0a, 0x11, // 16 bit service uuids 51 0x04, 0x09, 0x50, 0x65, 0x64, // setName 52 0x02, 0x0A, (byte) 0xec, // tx power level 53 0x05, 0x16, 0x0b, 0x11, 0x50, 0x64, // service data 54 0x05, (byte) 0xff, (byte) 0xe0, 0x00, 0x02, 0x15, // manufacturer specific data 55 0x03, 0x50, 0x01, 0x02, // an unknown data type won't cause trouble 56 }; 57 58 BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter(); 59 if (adapter == null) { 60 // Bluetooth is not supported 61 assertFalse(mContext.getPackageManager(). 62 hasSystemFeature(PackageManager.FEATURE_BLUETOOTH)); 63 } else { 64 assertTrue(mContext.getPackageManager(). 65 hasSystemFeature(PackageManager.FEATURE_BLUETOOTH)); 66 BluetoothDevice device = adapter.getRemoteDevice(DEVICE_MAC); 67 mScanResult = new ScanResult(device, TestUtils.parseScanRecord(scanRecord), 68 -10, 1397545200000000L); 69 mFilterBuilder = new ScanFilter.Builder(); 70 } 71 } 72 73 @SmallTest 74 public void testsetNameFilter() { 75 if (mFilterBuilder == null) return; 76 77 ScanFilter filter = mFilterBuilder.setDeviceName(LOCAL_NAME).build(); 78 assertEquals(LOCAL_NAME, filter.getDeviceName()); 79 assertTrue("setName filter fails", filter.matches(mScanResult)); 80 81 filter = mFilterBuilder.setDeviceName("Pem").build(); 82 assertFalse("setName filter fails", filter.matches(mScanResult)); 83 } 84 85 @SmallTest 86 public void testDeviceAddressFilter() { 87 if (mFilterBuilder == null) return; 88 89 ScanFilter filter = mFilterBuilder.setDeviceAddress(DEVICE_MAC).build(); 90 assertEquals(DEVICE_MAC, filter.getDeviceAddress()); 91 assertTrue("device filter fails", filter.matches(mScanResult)); 92 93 filter = mFilterBuilder.setDeviceAddress("11:22:33:44:55:66").build(); 94 assertFalse("device filter fails", filter.matches(mScanResult)); 95 } 96 97 @SmallTest 98 public void testsetServiceUuidFilter() { 99 if (mFilterBuilder == null) return; 100 101 ScanFilter filter = mFilterBuilder.setServiceUuid( 102 ParcelUuid.fromString(UUID1)).build(); 103 assertEquals(UUID1, filter.getServiceUuid().toString()); 104 assertTrue("uuid filter fails", filter.matches(mScanResult)); 105 106 filter = mFilterBuilder.setServiceUuid( 107 ParcelUuid.fromString(UUID3)).build(); 108 assertEquals(UUID3, filter.getServiceUuid().toString()); 109 assertFalse("uuid filter fails", filter.matches(mScanResult)); 110 111 ParcelUuid mask = ParcelUuid.fromString("FFFFFFF0-FFFF-FFFF-FFFF-FFFFFFFFFFFF"); 112 filter = mFilterBuilder 113 .setServiceUuid(ParcelUuid.fromString(UUID3), 114 mask) 115 .build(); 116 assertEquals(mask.toString(), filter.getServiceUuidMask().toString()); 117 assertTrue("uuid filter fails", filter.matches(mScanResult)); 118 } 119 120 @SmallTest 121 public void testsetServiceDataFilter() { 122 if (mFilterBuilder == null) return; 123 124 byte[] setServiceData = new byte[] { 125 0x50, 0x64 }; 126 ParcelUuid serviceDataUuid = ParcelUuid.fromString(UUID2); 127 ScanFilter filter = mFilterBuilder.setServiceData(serviceDataUuid, setServiceData).build(); 128 assertEquals(serviceDataUuid, filter.getServiceDataUuid()); 129 assertTrue("service data filter fails", filter.matches(mScanResult)); 130 131 byte[] emptyData = new byte[0]; 132 filter = mFilterBuilder.setServiceData(serviceDataUuid, emptyData).build(); 133 assertTrue("service data filter fails", filter.matches(mScanResult)); 134 135 byte[] prefixData = new byte[] { 136 0x50 }; 137 filter = mFilterBuilder.setServiceData(serviceDataUuid, prefixData).build(); 138 assertTrue("service data filter fails", filter.matches(mScanResult)); 139 140 byte[] nonMatchData = new byte[] { 141 0x51, 0x64 }; 142 byte[] mask = new byte[] { 143 (byte) 0x00, (byte) 0xFF }; 144 filter = mFilterBuilder.setServiceData(serviceDataUuid, nonMatchData, mask).build(); 145 assertEquals(nonMatchData, filter.getServiceData()); 146 assertEquals(mask, filter.getServiceDataMask()); 147 assertTrue("partial service data filter fails", filter.matches(mScanResult)); 148 149 filter = mFilterBuilder.setServiceData(serviceDataUuid, nonMatchData).build(); 150 assertFalse("service data filter fails", filter.matches(mScanResult)); 151 } 152 153 @SmallTest 154 public void testManufacturerSpecificData() { 155 if (mFilterBuilder == null) return; 156 157 byte[] manufacturerData = new byte[] { 158 0x02, 0x15 }; 159 int manufacturerId = 0xE0; 160 ScanFilter filter = 161 mFilterBuilder.setManufacturerData(manufacturerId, manufacturerData).build(); 162 assertEquals(manufacturerId, filter.getManufacturerId()); 163 assertEquals(manufacturerData, filter.getManufacturerData()); 164 assertTrue("manufacturer data filter fails", filter.matches(mScanResult)); 165 166 byte[] emptyData = new byte[0]; 167 filter = mFilterBuilder.setManufacturerData(manufacturerId, emptyData).build(); 168 assertTrue("manufacturer data filter fails", filter.matches(mScanResult)); 169 170 byte[] prefixData = new byte[] { 171 0x02 }; 172 filter = mFilterBuilder.setManufacturerData(manufacturerId, prefixData).build(); 173 assertTrue("manufacturer data filter fails", filter.matches(mScanResult)); 174 175 // Test data mask 176 byte[] nonMatchData = new byte[] { 177 0x02, 0x14 }; 178 filter = mFilterBuilder.setManufacturerData(manufacturerId, nonMatchData).build(); 179 assertFalse("manufacturer data filter fails", filter.matches(mScanResult)); 180 byte[] mask = new byte[] { 181 (byte) 0xFF, (byte) 0x00 182 }; 183 filter = mFilterBuilder.setManufacturerData(manufacturerId, nonMatchData, mask).build(); 184 assertEquals(manufacturerId, filter.getManufacturerId()); 185 assertEquals(nonMatchData, filter.getManufacturerData()); 186 assertEquals(mask, filter.getManufacturerDataMask()); 187 assertTrue("partial setManufacturerData filter fails", filter.matches(mScanResult)); 188 } 189 190 @SmallTest 191 public void testReadWriteParcel() { 192 if (mFilterBuilder == null) return; 193 194 ScanFilter filter = mFilterBuilder.build(); 195 testReadWriteParcelForFilter(filter); 196 197 filter = mFilterBuilder.setDeviceName(LOCAL_NAME).build(); 198 testReadWriteParcelForFilter(filter); 199 200 filter = mFilterBuilder.setDeviceAddress("11:22:33:44:55:66").build(); 201 testReadWriteParcelForFilter(filter); 202 203 filter = mFilterBuilder.setServiceUuid( 204 ParcelUuid.fromString(UUID3)).build(); 205 testReadWriteParcelForFilter(filter); 206 207 filter = mFilterBuilder.setServiceUuid( 208 ParcelUuid.fromString(UUID3), 209 ParcelUuid.fromString("FFFFFFF0-FFFF-FFFF-FFFF-FFFFFFFFFFFF")).build(); 210 testReadWriteParcelForFilter(filter); 211 212 byte[] serviceData = new byte[] { 213 0x50, 0x64 }; 214 215 ParcelUuid serviceDataUuid = ParcelUuid.fromString(UUID2); 216 filter = mFilterBuilder.setServiceData(serviceDataUuid, serviceData).build(); 217 testReadWriteParcelForFilter(filter); 218 219 filter = mFilterBuilder.setServiceData(serviceDataUuid, new byte[0]).build(); 220 testReadWriteParcelForFilter(filter); 221 222 byte[] serviceDataMask = new byte[] { 223 (byte) 0xFF, (byte) 0xFF }; 224 filter = mFilterBuilder.setServiceData(serviceDataUuid, serviceData, serviceDataMask) 225 .build(); 226 testReadWriteParcelForFilter(filter); 227 228 byte[] manufacturerData = new byte[] { 229 0x02, 0x15 }; 230 int manufacturerId = 0xE0; 231 filter = mFilterBuilder.setManufacturerData(manufacturerId, manufacturerData).build(); 232 testReadWriteParcelForFilter(filter); 233 234 filter = mFilterBuilder.setServiceData(serviceDataUuid, new byte[0]).build(); 235 testReadWriteParcelForFilter(filter); 236 237 byte[] manufacturerDataMask = new byte[] { 238 (byte) 0xFF, (byte) 0xFF 239 }; 240 filter = mFilterBuilder.setManufacturerData(manufacturerId, manufacturerData, 241 manufacturerDataMask).build(); 242 testReadWriteParcelForFilter(filter); 243 } 244 245 @SmallTest 246 public void testDescribeContents() { 247 final int expected = 0; 248 assertEquals(expected, new ScanFilter.Builder().build().describeContents()); 249 } 250 251 private void testReadWriteParcelForFilter(ScanFilter filter) { 252 Parcel parcel = Parcel.obtain(); 253 filter.writeToParcel(parcel, 0); 254 parcel.setDataPosition(0); 255 ScanFilter filterFromParcel = 256 ScanFilter.CREATOR.createFromParcel(parcel); 257 assertEquals(filter, filterFromParcel); 258 } 259 } 260