Loading core/java/android/bluetooth/le/ScanFilter.java +32 −19 Original line number Diff line number Diff line Loading @@ -110,21 +110,27 @@ public final class ScanFilter implements Parcelable { dest.writeInt(mServiceDataUuid == null ? 0 : 1); if (mServiceDataUuid != null) { dest.writeParcelable(mServiceDataUuid, flags); dest.writeInt(mServiceData == null ? 0 : mServiceData.length); dest.writeInt(mServiceData == null ? 0 : 1); if (mServiceData != null) { dest.writeInt(mServiceData.length); dest.writeByteArray(mServiceData); dest.writeInt(mServiceDataMask == null ? 0 : mServiceDataMask.length); dest.writeInt(mServiceDataMask == null ? 0 : 1); if (mServiceDataMask != null) { dest.writeInt(mServiceDataMask.length); dest.writeByteArray(mServiceDataMask); } } } dest.writeInt(mManufacturerId); dest.writeInt(mManufacturerData == null ? 0 : mManufacturerData.length); dest.writeInt(mManufacturerData == null ? 0 : 1); if (mManufacturerData != null) { dest.writeInt(mManufacturerData.length); dest.writeByteArray(mManufacturerData); dest.writeInt(mManufacturerDataMask == null ? 0 : mManufacturerDataMask.length); dest.writeInt(mManufacturerDataMask == null ? 0 : 1); if (mManufacturerDataMask != null) { dest.writeInt(mManufacturerDataMask.length); dest.writeByteArray(mManufacturerDataMask); } } Loading Loading @@ -164,13 +170,14 @@ public final class ScanFilter implements Parcelable { if (in.readInt() == 1) { ParcelUuid servcieDataUuid = in.readParcelable(ParcelUuid.class.getClassLoader()); if (in.readInt() == 1) { int serviceDataLength = in.readInt(); if (serviceDataLength > 0) { byte[] serviceData = new byte[serviceDataLength]; in.readByteArray(serviceData); if (in.readInt() == 0) { builder.setServiceData(servcieDataUuid, serviceData); } else { int serviceDataMaskLength = in.readInt(); if (serviceDataMaskLength > 0) { byte[] serviceDataMask = new byte[serviceDataMaskLength]; in.readByteArray(serviceDataMask); builder.setServiceData( Loading @@ -180,13 +187,14 @@ public final class ScanFilter implements Parcelable { } int manufacturerId = in.readInt(); if (in.readInt() == 1) { int manufacturerDataLength = in.readInt(); if (manufacturerDataLength > 0) { byte[] manufacturerData = new byte[manufacturerDataLength]; in.readByteArray(manufacturerData); if (in.readInt() == 0) { builder.setManufacturerData(manufacturerId, manufacturerData); } else { int manufacturerDataMaskLength = in.readInt(); if (manufacturerDataMaskLength > 0) { byte[] manufacturerDataMask = new byte[manufacturerDataMaskLength]; in.readByteArray(manufacturerDataMask); builder.setManufacturerData(manufacturerId, manufacturerData, Loading Loading @@ -349,12 +357,17 @@ public final class ScanFilter implements Parcelable { // Check whether the data pattern matches the parsed data. private boolean matchesPartialData(byte[] data, byte[] dataMask, byte[] parsedData) { if (dataMask == null) { return Arrays.equals(data, parsedData); if (parsedData == null || parsedData.length < data.length) { return false; } if (parsedData == null) { if (dataMask == null) { for (int i = 0; i < data.length; ++i) { if (parsedData[i] != data[i]) { return false; } } return true; } for (int i = 0; i < data.length; ++i) { if ((dataMask[i] & parsedData[i]) != (dataMask[i] & data[i])) { return false; Loading core/tests/bluetoothtests/src/android/bluetooth/le/ScanFilterTest.java +45 −21 Original line number Diff line number Diff line Loading @@ -96,38 +96,56 @@ public class ScanFilterTest extends TestCase { @SmallTest public void testsetServiceDataFilter() { byte[] setServiceData = new byte[] { 0x0b, 0x11, 0x50, 0x64 }; 0x50, 0x64 }; ParcelUuid serviceDataUuid = ParcelUuid.fromString("0000110B-0000-1000-8000-00805F9B34FB"); ScanFilter filter = mFilterBuilder.setServiceData(serviceDataUuid, setServiceData).build(); assertTrue("service data filter fails", filter.matches(mScanResult)); byte[] nonMatchData = new byte[] { 0x0b, 0x01, 0x50, 0x64 }; filter = mFilterBuilder.setServiceData(serviceDataUuid, nonMatchData).build(); assertFalse("service data filter fails", filter.matches(mScanResult)); byte[] emptyData = new byte[0]; filter = mFilterBuilder.setServiceData(serviceDataUuid, emptyData).build(); assertTrue("service data filter fails", filter.matches(mScanResult)); byte[] prefixData = new byte[] { 0x50 }; filter = mFilterBuilder.setServiceData(serviceDataUuid, prefixData).build(); assertTrue("service data filter fails", filter.matches(mScanResult)); byte[] nonMatchData = new byte[] { 0x51, 0x64 }; byte[] mask = new byte[] { (byte) 0xFF, (byte) 0x00, (byte) 0xFF, (byte) 0xFF }; (byte) 0x00, (byte) 0xFF }; filter = mFilterBuilder.setServiceData(serviceDataUuid, nonMatchData, mask).build(); assertTrue("partial service data filter fails", filter.matches(mScanResult)); filter = mFilterBuilder.setServiceData(serviceDataUuid, nonMatchData).build(); assertFalse("service data filter fails", filter.matches(mScanResult)); } @SmallTest public void testManufacturerSpecificData() { byte[] setManufacturerData = new byte[] { (byte) 0xE0, 0x00, 0x02, 0x15 }; int manufacturerId = 224; 0x02, 0x15 }; int manufacturerId = 0xE0; ScanFilter filter = mFilterBuilder.setManufacturerData(manufacturerId, setManufacturerData).build(); assertTrue("setManufacturerData filter fails", filter.matches(mScanResult)); assertTrue("manufacturer data filter fails", filter.matches(mScanResult)); byte[] emptyData = new byte[0]; filter = mFilterBuilder.setManufacturerData(manufacturerId, emptyData).build(); assertTrue("manufacturer data filter fails", filter.matches(mScanResult)); byte[] prefixData = new byte[] { 0x02 }; filter = mFilterBuilder.setManufacturerData(manufacturerId, prefixData).build(); assertTrue("manufacturer data filter fails", filter.matches(mScanResult)); // Test data mask byte[] nonMatchData = new byte[] { (byte) 0xF0, 0x00, 0x02, 0x15 }; 0x02, 0x14 }; filter = mFilterBuilder.setManufacturerData(manufacturerId, nonMatchData).build(); assertFalse("setManufacturerData filter fails", filter.matches(mScanResult)); assertFalse("manufacturer data filter fails", filter.matches(mScanResult)); byte[] mask = new byte[] { (byte) 0x00, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF (byte) 0xFF, (byte) 0x00 }; filter = mFilterBuilder.setManufacturerData(manufacturerId, nonMatchData, mask).build(); assertTrue("partial setManufacturerData filter fails", filter.matches(mScanResult)); Loading @@ -153,27 +171,33 @@ public class ScanFilterTest extends TestCase { ParcelUuid.fromString("FFFFFFF0-FFFF-FFFF-FFFF-FFFFFFFFFFFF")).build(); testReadWriteParcelForFilter(filter); byte[] setServiceData = new byte[] { 0x0b, 0x11, 0x50, 0x64 }; byte[] serviceData = new byte[] { 0x50, 0x64 }; ParcelUuid serviceDataUuid = ParcelUuid.fromString("0000110B-0000-1000-8000-00805F9B34FB"); filter = mFilterBuilder.setServiceData(serviceDataUuid, setServiceData).build(); filter = mFilterBuilder.setServiceData(serviceDataUuid, serviceData).build(); testReadWriteParcelForFilter(filter); filter = mFilterBuilder.setServiceData(serviceDataUuid, new byte[0]).build(); testReadWriteParcelForFilter(filter); byte[] serviceDataMask = new byte[] { (byte) 0xFF, (byte) 0x00, (byte) 0xFF, (byte) 0xFF }; filter = mFilterBuilder.setServiceData(serviceDataUuid, setServiceData, serviceDataMask) (byte) 0xFF, (byte) 0xFF }; filter = mFilterBuilder.setServiceData(serviceDataUuid, serviceData, serviceDataMask) .build(); testReadWriteParcelForFilter(filter); byte[] manufacturerData = new byte[] { (byte) 0xE0, 0x00, 0x02, 0x15 }; int manufacturerId = 224; 0x02, 0x15 }; int manufacturerId = 0xE0; filter = mFilterBuilder.setManufacturerData(manufacturerId, manufacturerData).build(); testReadWriteParcelForFilter(filter); filter = mFilterBuilder.setServiceData(serviceDataUuid, new byte[0]).build(); testReadWriteParcelForFilter(filter); byte[] manufacturerDataMask = new byte[] { (byte) 0x00, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF (byte) 0xFF, (byte) 0xFF }; filter = mFilterBuilder.setManufacturerData(manufacturerId, manufacturerData, manufacturerDataMask).build(); Loading Loading
core/java/android/bluetooth/le/ScanFilter.java +32 −19 Original line number Diff line number Diff line Loading @@ -110,21 +110,27 @@ public final class ScanFilter implements Parcelable { dest.writeInt(mServiceDataUuid == null ? 0 : 1); if (mServiceDataUuid != null) { dest.writeParcelable(mServiceDataUuid, flags); dest.writeInt(mServiceData == null ? 0 : mServiceData.length); dest.writeInt(mServiceData == null ? 0 : 1); if (mServiceData != null) { dest.writeInt(mServiceData.length); dest.writeByteArray(mServiceData); dest.writeInt(mServiceDataMask == null ? 0 : mServiceDataMask.length); dest.writeInt(mServiceDataMask == null ? 0 : 1); if (mServiceDataMask != null) { dest.writeInt(mServiceDataMask.length); dest.writeByteArray(mServiceDataMask); } } } dest.writeInt(mManufacturerId); dest.writeInt(mManufacturerData == null ? 0 : mManufacturerData.length); dest.writeInt(mManufacturerData == null ? 0 : 1); if (mManufacturerData != null) { dest.writeInt(mManufacturerData.length); dest.writeByteArray(mManufacturerData); dest.writeInt(mManufacturerDataMask == null ? 0 : mManufacturerDataMask.length); dest.writeInt(mManufacturerDataMask == null ? 0 : 1); if (mManufacturerDataMask != null) { dest.writeInt(mManufacturerDataMask.length); dest.writeByteArray(mManufacturerDataMask); } } Loading Loading @@ -164,13 +170,14 @@ public final class ScanFilter implements Parcelable { if (in.readInt() == 1) { ParcelUuid servcieDataUuid = in.readParcelable(ParcelUuid.class.getClassLoader()); if (in.readInt() == 1) { int serviceDataLength = in.readInt(); if (serviceDataLength > 0) { byte[] serviceData = new byte[serviceDataLength]; in.readByteArray(serviceData); if (in.readInt() == 0) { builder.setServiceData(servcieDataUuid, serviceData); } else { int serviceDataMaskLength = in.readInt(); if (serviceDataMaskLength > 0) { byte[] serviceDataMask = new byte[serviceDataMaskLength]; in.readByteArray(serviceDataMask); builder.setServiceData( Loading @@ -180,13 +187,14 @@ public final class ScanFilter implements Parcelable { } int manufacturerId = in.readInt(); if (in.readInt() == 1) { int manufacturerDataLength = in.readInt(); if (manufacturerDataLength > 0) { byte[] manufacturerData = new byte[manufacturerDataLength]; in.readByteArray(manufacturerData); if (in.readInt() == 0) { builder.setManufacturerData(manufacturerId, manufacturerData); } else { int manufacturerDataMaskLength = in.readInt(); if (manufacturerDataMaskLength > 0) { byte[] manufacturerDataMask = new byte[manufacturerDataMaskLength]; in.readByteArray(manufacturerDataMask); builder.setManufacturerData(manufacturerId, manufacturerData, Loading Loading @@ -349,12 +357,17 @@ public final class ScanFilter implements Parcelable { // Check whether the data pattern matches the parsed data. private boolean matchesPartialData(byte[] data, byte[] dataMask, byte[] parsedData) { if (dataMask == null) { return Arrays.equals(data, parsedData); if (parsedData == null || parsedData.length < data.length) { return false; } if (parsedData == null) { if (dataMask == null) { for (int i = 0; i < data.length; ++i) { if (parsedData[i] != data[i]) { return false; } } return true; } for (int i = 0; i < data.length; ++i) { if ((dataMask[i] & parsedData[i]) != (dataMask[i] & data[i])) { return false; Loading
core/tests/bluetoothtests/src/android/bluetooth/le/ScanFilterTest.java +45 −21 Original line number Diff line number Diff line Loading @@ -96,38 +96,56 @@ public class ScanFilterTest extends TestCase { @SmallTest public void testsetServiceDataFilter() { byte[] setServiceData = new byte[] { 0x0b, 0x11, 0x50, 0x64 }; 0x50, 0x64 }; ParcelUuid serviceDataUuid = ParcelUuid.fromString("0000110B-0000-1000-8000-00805F9B34FB"); ScanFilter filter = mFilterBuilder.setServiceData(serviceDataUuid, setServiceData).build(); assertTrue("service data filter fails", filter.matches(mScanResult)); byte[] nonMatchData = new byte[] { 0x0b, 0x01, 0x50, 0x64 }; filter = mFilterBuilder.setServiceData(serviceDataUuid, nonMatchData).build(); assertFalse("service data filter fails", filter.matches(mScanResult)); byte[] emptyData = new byte[0]; filter = mFilterBuilder.setServiceData(serviceDataUuid, emptyData).build(); assertTrue("service data filter fails", filter.matches(mScanResult)); byte[] prefixData = new byte[] { 0x50 }; filter = mFilterBuilder.setServiceData(serviceDataUuid, prefixData).build(); assertTrue("service data filter fails", filter.matches(mScanResult)); byte[] nonMatchData = new byte[] { 0x51, 0x64 }; byte[] mask = new byte[] { (byte) 0xFF, (byte) 0x00, (byte) 0xFF, (byte) 0xFF }; (byte) 0x00, (byte) 0xFF }; filter = mFilterBuilder.setServiceData(serviceDataUuid, nonMatchData, mask).build(); assertTrue("partial service data filter fails", filter.matches(mScanResult)); filter = mFilterBuilder.setServiceData(serviceDataUuid, nonMatchData).build(); assertFalse("service data filter fails", filter.matches(mScanResult)); } @SmallTest public void testManufacturerSpecificData() { byte[] setManufacturerData = new byte[] { (byte) 0xE0, 0x00, 0x02, 0x15 }; int manufacturerId = 224; 0x02, 0x15 }; int manufacturerId = 0xE0; ScanFilter filter = mFilterBuilder.setManufacturerData(manufacturerId, setManufacturerData).build(); assertTrue("setManufacturerData filter fails", filter.matches(mScanResult)); assertTrue("manufacturer data filter fails", filter.matches(mScanResult)); byte[] emptyData = new byte[0]; filter = mFilterBuilder.setManufacturerData(manufacturerId, emptyData).build(); assertTrue("manufacturer data filter fails", filter.matches(mScanResult)); byte[] prefixData = new byte[] { 0x02 }; filter = mFilterBuilder.setManufacturerData(manufacturerId, prefixData).build(); assertTrue("manufacturer data filter fails", filter.matches(mScanResult)); // Test data mask byte[] nonMatchData = new byte[] { (byte) 0xF0, 0x00, 0x02, 0x15 }; 0x02, 0x14 }; filter = mFilterBuilder.setManufacturerData(manufacturerId, nonMatchData).build(); assertFalse("setManufacturerData filter fails", filter.matches(mScanResult)); assertFalse("manufacturer data filter fails", filter.matches(mScanResult)); byte[] mask = new byte[] { (byte) 0x00, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF (byte) 0xFF, (byte) 0x00 }; filter = mFilterBuilder.setManufacturerData(manufacturerId, nonMatchData, mask).build(); assertTrue("partial setManufacturerData filter fails", filter.matches(mScanResult)); Loading @@ -153,27 +171,33 @@ public class ScanFilterTest extends TestCase { ParcelUuid.fromString("FFFFFFF0-FFFF-FFFF-FFFF-FFFFFFFFFFFF")).build(); testReadWriteParcelForFilter(filter); byte[] setServiceData = new byte[] { 0x0b, 0x11, 0x50, 0x64 }; byte[] serviceData = new byte[] { 0x50, 0x64 }; ParcelUuid serviceDataUuid = ParcelUuid.fromString("0000110B-0000-1000-8000-00805F9B34FB"); filter = mFilterBuilder.setServiceData(serviceDataUuid, setServiceData).build(); filter = mFilterBuilder.setServiceData(serviceDataUuid, serviceData).build(); testReadWriteParcelForFilter(filter); filter = mFilterBuilder.setServiceData(serviceDataUuid, new byte[0]).build(); testReadWriteParcelForFilter(filter); byte[] serviceDataMask = new byte[] { (byte) 0xFF, (byte) 0x00, (byte) 0xFF, (byte) 0xFF }; filter = mFilterBuilder.setServiceData(serviceDataUuid, setServiceData, serviceDataMask) (byte) 0xFF, (byte) 0xFF }; filter = mFilterBuilder.setServiceData(serviceDataUuid, serviceData, serviceDataMask) .build(); testReadWriteParcelForFilter(filter); byte[] manufacturerData = new byte[] { (byte) 0xE0, 0x00, 0x02, 0x15 }; int manufacturerId = 224; 0x02, 0x15 }; int manufacturerId = 0xE0; filter = mFilterBuilder.setManufacturerData(manufacturerId, manufacturerData).build(); testReadWriteParcelForFilter(filter); filter = mFilterBuilder.setServiceData(serviceDataUuid, new byte[0]).build(); testReadWriteParcelForFilter(filter); byte[] manufacturerDataMask = new byte[] { (byte) 0x00, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF (byte) 0xFF, (byte) 0xFF }; filter = mFilterBuilder.setManufacturerData(manufacturerId, manufacturerData, manufacturerDataMask).build(); Loading