16ed45d8cd33c297e608aba94fc1f61dace7a7ccaEugene Susla/* 26ed45d8cd33c297e608aba94fc1f61dace7a7ccaEugene Susla * Copyright (C) 2017 The Android Open Source Project 36ed45d8cd33c297e608aba94fc1f61dace7a7ccaEugene Susla * 46ed45d8cd33c297e608aba94fc1f61dace7a7ccaEugene Susla * Licensed under the Apache License, Version 2.0 (the "License"); 56ed45d8cd33c297e608aba94fc1f61dace7a7ccaEugene Susla * you may not use this file except in compliance with the License. 66ed45d8cd33c297e608aba94fc1f61dace7a7ccaEugene Susla * You may obtain a copy of the License at 76ed45d8cd33c297e608aba94fc1f61dace7a7ccaEugene Susla * 86ed45d8cd33c297e608aba94fc1f61dace7a7ccaEugene Susla * http://www.apache.org/licenses/LICENSE-2.0 96ed45d8cd33c297e608aba94fc1f61dace7a7ccaEugene Susla * 106ed45d8cd33c297e608aba94fc1f61dace7a7ccaEugene Susla * Unless required by applicable law or agreed to in writing, software 116ed45d8cd33c297e608aba94fc1f61dace7a7ccaEugene Susla * distributed under the License is distributed on an "AS IS" BASIS, 126ed45d8cd33c297e608aba94fc1f61dace7a7ccaEugene Susla * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 136ed45d8cd33c297e608aba94fc1f61dace7a7ccaEugene Susla * See the License for the specific language governing permissions and 146ed45d8cd33c297e608aba94fc1f61dace7a7ccaEugene Susla * limitations under the License. 156ed45d8cd33c297e608aba94fc1f61dace7a7ccaEugene Susla */ 166ed45d8cd33c297e608aba94fc1f61dace7a7ccaEugene Susla 176ed45d8cd33c297e608aba94fc1f61dace7a7ccaEugene Suslapackage android.companion; 186ed45d8cd33c297e608aba94fc1f61dace7a7ccaEugene Susla 1936e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Suslaimport static android.companion.BluetoothDeviceFilterUtils.getDeviceDisplayNameInternal; 206ed45d8cd33c297e608aba94fc1f61dace7a7ccaEugene Suslaimport static android.companion.BluetoothDeviceFilterUtils.patternFromString; 216ed45d8cd33c297e608aba94fc1f61dace7a7ccaEugene Suslaimport static android.companion.BluetoothDeviceFilterUtils.patternToString; 226ed45d8cd33c297e608aba94fc1f61dace7a7ccaEugene Susla 2336e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Suslaimport static com.android.internal.util.Preconditions.checkArgument; 2475fb821029f789cf8f306dbd72805d1581214785Eugene Suslaimport static com.android.internal.util.Preconditions.checkState; 2536e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla 266ed45d8cd33c297e608aba94fc1f61dace7a7ccaEugene Suslaimport android.annotation.NonNull; 276ed45d8cd33c297e608aba94fc1f61dace7a7ccaEugene Suslaimport android.annotation.Nullable; 286ed45d8cd33c297e608aba94fc1f61dace7a7ccaEugene Suslaimport android.bluetooth.BluetoothDevice; 296ed45d8cd33c297e608aba94fc1f61dace7a7ccaEugene Suslaimport android.bluetooth.le.ScanFilter; 3036e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Suslaimport android.bluetooth.le.ScanRecord; 3136e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Suslaimport android.bluetooth.le.ScanResult; 326ed45d8cd33c297e608aba94fc1f61dace7a7ccaEugene Suslaimport android.os.Parcel; 336ed45d8cd33c297e608aba94fc1f61dace7a7ccaEugene Suslaimport android.provider.OneTimeUseBuilder; 3436e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Suslaimport android.text.TextUtils; 353c9aa1767ca0ddc881f53c2ce7eb3135670efef3Eugene Suslaimport android.util.Log; 366ed45d8cd33c297e608aba94fc1f61dace7a7ccaEugene Susla 3736e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Suslaimport com.android.internal.util.BitUtils; 386ed45d8cd33c297e608aba94fc1f61dace7a7ccaEugene Suslaimport com.android.internal.util.ObjectUtils; 3936e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Suslaimport com.android.internal.util.Preconditions; 406ed45d8cd33c297e608aba94fc1f61dace7a7ccaEugene Susla 4120bd9fc81e32cafc86f3972b182b65ebdf5b1999Eugene Suslaimport java.nio.ByteOrder; 42a38fbf63fd2a29884637a59387643c801ed4f663Eugene Suslaimport java.util.Arrays; 43a38fbf63fd2a29884637a59387643c801ed4f663Eugene Suslaimport java.util.Objects; 446ed45d8cd33c297e608aba94fc1f61dace7a7ccaEugene Suslaimport java.util.regex.Pattern; 456ed45d8cd33c297e608aba94fc1f61dace7a7ccaEugene Susla 466ed45d8cd33c297e608aba94fc1f61dace7a7ccaEugene Susla/** 476ed45d8cd33c297e608aba94fc1f61dace7a7ccaEugene Susla * A filter for Bluetooth LE devices 486ed45d8cd33c297e608aba94fc1f61dace7a7ccaEugene Susla * 496ed45d8cd33c297e608aba94fc1f61dace7a7ccaEugene Susla * @see ScanFilter 506ed45d8cd33c297e608aba94fc1f61dace7a7ccaEugene Susla */ 51722463ff953168ae27bedf61a586f296813fc9feEugene Suslapublic final class BluetoothLeDeviceFilter implements DeviceFilter<ScanResult> { 526ed45d8cd33c297e608aba94fc1f61dace7a7ccaEugene Susla 533c9aa1767ca0ddc881f53c2ce7eb3135670efef3Eugene Susla private static final boolean DEBUG = false; 54722463ff953168ae27bedf61a586f296813fc9feEugene Susla private static final String LOG_TAG = "BluetoothLeDeviceFilter"; 553c9aa1767ca0ddc881f53c2ce7eb3135670efef3Eugene Susla 5636e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla private static final int RENAME_PREFIX_LENGTH_LIMIT = 10; 576ed45d8cd33c297e608aba94fc1f61dace7a7ccaEugene Susla 586ed45d8cd33c297e608aba94fc1f61dace7a7ccaEugene Susla private final Pattern mNamePattern; 596ed45d8cd33c297e608aba94fc1f61dace7a7ccaEugene Susla private final ScanFilter mScanFilter; 6036e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla private final byte[] mRawDataFilter; 6136e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla private final byte[] mRawDataFilterMask; 6236e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla private final String mRenamePrefix; 6336e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla private final String mRenameSuffix; 6436e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla private final int mRenameBytesFrom; 6520bd9fc81e32cafc86f3972b182b65ebdf5b1999Eugene Susla private final int mRenameBytesLength; 6675fb821029f789cf8f306dbd72805d1581214785Eugene Susla private final int mRenameNameFrom; 6720bd9fc81e32cafc86f3972b182b65ebdf5b1999Eugene Susla private final int mRenameNameLength; 6836e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla private final boolean mRenameBytesReverseOrder; 696ed45d8cd33c297e608aba94fc1f61dace7a7ccaEugene Susla 70722463ff953168ae27bedf61a586f296813fc9feEugene Susla private BluetoothLeDeviceFilter(Pattern namePattern, ScanFilter scanFilter, 7136e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla byte[] rawDataFilter, byte[] rawDataFilterMask, String renamePrefix, 7220bd9fc81e32cafc86f3972b182b65ebdf5b1999Eugene Susla String renameSuffix, int renameBytesFrom, int renameBytesLength, 7320bd9fc81e32cafc86f3972b182b65ebdf5b1999Eugene Susla int renameNameFrom, int renameNameLength, boolean renameBytesReverseOrder) { 746ed45d8cd33c297e608aba94fc1f61dace7a7ccaEugene Susla mNamePattern = namePattern; 756ed45d8cd33c297e608aba94fc1f61dace7a7ccaEugene Susla mScanFilter = ObjectUtils.firstNotNull(scanFilter, ScanFilter.EMPTY); 7636e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla mRawDataFilter = rawDataFilter; 7736e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla mRawDataFilterMask = rawDataFilterMask; 7836e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla mRenamePrefix = renamePrefix; 7936e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla mRenameSuffix = renameSuffix; 8036e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla mRenameBytesFrom = renameBytesFrom; 8120bd9fc81e32cafc86f3972b182b65ebdf5b1999Eugene Susla mRenameBytesLength = renameBytesLength; 8275fb821029f789cf8f306dbd72805d1581214785Eugene Susla mRenameNameFrom = renameNameFrom; 8320bd9fc81e32cafc86f3972b182b65ebdf5b1999Eugene Susla mRenameNameLength = renameNameLength; 8436e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla mRenameBytesReverseOrder = renameBytesReverseOrder; 856ed45d8cd33c297e608aba94fc1f61dace7a7ccaEugene Susla } 866ed45d8cd33c297e608aba94fc1f61dace7a7ccaEugene Susla 8736e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla /** @hide */ 8836e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla @Nullable 8936e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla public Pattern getNamePattern() { 9036e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla return mNamePattern; 916ed45d8cd33c297e608aba94fc1f61dace7a7ccaEugene Susla } 926ed45d8cd33c297e608aba94fc1f61dace7a7ccaEugene Susla 936ed45d8cd33c297e608aba94fc1f61dace7a7ccaEugene Susla /** @hide */ 946ed45d8cd33c297e608aba94fc1f61dace7a7ccaEugene Susla @NonNull 9536e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla public ScanFilter getScanFilter() { 9636e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla return mScanFilter; 976ed45d8cd33c297e608aba94fc1f61dace7a7ccaEugene Susla } 986ed45d8cd33c297e608aba94fc1f61dace7a7ccaEugene Susla 996ed45d8cd33c297e608aba94fc1f61dace7a7ccaEugene Susla /** @hide */ 10036e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla @Nullable 10136e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla public byte[] getRawDataFilter() { 10236e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla return mRawDataFilter; 103e70e6aa62c6f3a9a79624a4f9d97df95edda0364Eugene Susla } 104e70e6aa62c6f3a9a79624a4f9d97df95edda0364Eugene Susla 105e70e6aa62c6f3a9a79624a4f9d97df95edda0364Eugene Susla /** @hide */ 106e70e6aa62c6f3a9a79624a4f9d97df95edda0364Eugene Susla @Nullable 10736e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla public byte[] getRawDataFilterMask() { 10836e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla return mRawDataFilterMask; 109e70e6aa62c6f3a9a79624a4f9d97df95edda0364Eugene Susla } 110e70e6aa62c6f3a9a79624a4f9d97df95edda0364Eugene Susla 111e70e6aa62c6f3a9a79624a4f9d97df95edda0364Eugene Susla /** @hide */ 11236e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla @Nullable 11336e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla public String getRenamePrefix() { 11436e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla return mRenamePrefix; 11536e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla } 11636e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla 11736e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla /** @hide */ 11836e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla @Nullable 11936e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla public String getRenameSuffix() { 12036e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla return mRenameSuffix; 12136e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla } 12236e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla 12336e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla /** @hide */ 12436e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla public int getRenameBytesFrom() { 12536e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla return mRenameBytesFrom; 12636e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla } 12736e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla 12836e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla /** @hide */ 12920bd9fc81e32cafc86f3972b182b65ebdf5b1999Eugene Susla public int getRenameBytesLength() { 13020bd9fc81e32cafc86f3972b182b65ebdf5b1999Eugene Susla return mRenameBytesLength; 13136e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla } 13236e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla 13336e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla /** @hide */ 13436e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla public boolean isRenameBytesReverseOrder() { 13536e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla return mRenameBytesReverseOrder; 13636e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla } 13736e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla 13836e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla /** @hide */ 13936e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla @Override 14036e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla @Nullable 14136e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla public String getDeviceDisplayName(ScanResult sr) { 14275fb821029f789cf8f306dbd72805d1581214785Eugene Susla if (mRenameBytesFrom < 0 && mRenameNameFrom < 0) { 14375fb821029f789cf8f306dbd72805d1581214785Eugene Susla return getDeviceDisplayNameInternal(sr.getDevice()); 14475fb821029f789cf8f306dbd72805d1581214785Eugene Susla } 14536e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla final StringBuilder sb = new StringBuilder(TextUtils.emptyIfNull(mRenamePrefix)); 14675fb821029f789cf8f306dbd72805d1581214785Eugene Susla if (mRenameBytesFrom >= 0) { 14775fb821029f789cf8f306dbd72805d1581214785Eugene Susla final byte[] bytes = sr.getScanRecord().getBytes(); 14875fb821029f789cf8f306dbd72805d1581214785Eugene Susla int startInclusive = mRenameBytesFrom; 14920bd9fc81e32cafc86f3972b182b65ebdf5b1999Eugene Susla int endInclusive = mRenameBytesFrom + mRenameBytesLength -1; 15075fb821029f789cf8f306dbd72805d1581214785Eugene Susla int initial = mRenameBytesReverseOrder ? endInclusive : startInclusive; 15175fb821029f789cf8f306dbd72805d1581214785Eugene Susla int step = mRenameBytesReverseOrder ? -1 : 1; 15275fb821029f789cf8f306dbd72805d1581214785Eugene Susla for (int i = initial; startInclusive <= i && i <= endInclusive; i += step) { 15375fb821029f789cf8f306dbd72805d1581214785Eugene Susla sb.append(Byte.toHexString(bytes[i], true)); 15475fb821029f789cf8f306dbd72805d1581214785Eugene Susla } 15575fb821029f789cf8f306dbd72805d1581214785Eugene Susla } else { 15675fb821029f789cf8f306dbd72805d1581214785Eugene Susla sb.append( 15775fb821029f789cf8f306dbd72805d1581214785Eugene Susla getDeviceDisplayNameInternal(sr.getDevice()) 15820bd9fc81e32cafc86f3972b182b65ebdf5b1999Eugene Susla .substring(mRenameNameFrom, mRenameNameFrom + mRenameNameLength)); 15936e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla } 16036e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla return sb.append(TextUtils.emptyIfNull(mRenameSuffix)).toString(); 1616ed45d8cd33c297e608aba94fc1f61dace7a7ccaEugene Susla } 1626ed45d8cd33c297e608aba94fc1f61dace7a7ccaEugene Susla 1636ed45d8cd33c297e608aba94fc1f61dace7a7ccaEugene Susla /** @hide */ 1646ed45d8cd33c297e608aba94fc1f61dace7a7ccaEugene Susla @Override 16536e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla public boolean matches(ScanResult device) { 1663c9aa1767ca0ddc881f53c2ce7eb3135670efef3Eugene Susla boolean result = matches(device.getDevice()) 1673c9aa1767ca0ddc881f53c2ce7eb3135670efef3Eugene Susla && (mRawDataFilter == null 1683c9aa1767ca0ddc881f53c2ce7eb3135670efef3Eugene Susla || BitUtils.maskedEquals(device.getScanRecord().getBytes(), 1693c9aa1767ca0ddc881f53c2ce7eb3135670efef3Eugene Susla mRawDataFilter, mRawDataFilterMask)); 1703c9aa1767ca0ddc881f53c2ce7eb3135670efef3Eugene Susla if (DEBUG) Log.i(LOG_TAG, "matches(this = " + this + ", device = " + device + 1713c9aa1767ca0ddc881f53c2ce7eb3135670efef3Eugene Susla ") -> " + result); 1723c9aa1767ca0ddc881f53c2ce7eb3135670efef3Eugene Susla return result; 17336e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla } 17436e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla 17536e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla private boolean matches(BluetoothDevice device) { 1766ed45d8cd33c297e608aba94fc1f61dace7a7ccaEugene Susla return BluetoothDeviceFilterUtils.matches(getScanFilter(), device) 1776ed45d8cd33c297e608aba94fc1f61dace7a7ccaEugene Susla && BluetoothDeviceFilterUtils.matchesName(getNamePattern(), device); 1786ed45d8cd33c297e608aba94fc1f61dace7a7ccaEugene Susla } 1796ed45d8cd33c297e608aba94fc1f61dace7a7ccaEugene Susla 18036e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla /** @hide */ 18136e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla @Override 18236e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla public int getMediumType() { 18336e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla return DeviceFilter.MEDIUM_TYPE_BLUETOOTH_LE; 18436e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla } 18536e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla 1866ed45d8cd33c297e608aba94fc1f61dace7a7ccaEugene Susla @Override 187a38fbf63fd2a29884637a59387643c801ed4f663Eugene Susla public boolean equals(Object o) { 188a38fbf63fd2a29884637a59387643c801ed4f663Eugene Susla if (this == o) return true; 189a38fbf63fd2a29884637a59387643c801ed4f663Eugene Susla if (o == null || getClass() != o.getClass()) return false; 190722463ff953168ae27bedf61a586f296813fc9feEugene Susla BluetoothLeDeviceFilter that = (BluetoothLeDeviceFilter) o; 191a38fbf63fd2a29884637a59387643c801ed4f663Eugene Susla return mRenameBytesFrom == that.mRenameBytesFrom && 19220bd9fc81e32cafc86f3972b182b65ebdf5b1999Eugene Susla mRenameBytesLength == that.mRenameBytesLength && 19320bd9fc81e32cafc86f3972b182b65ebdf5b1999Eugene Susla mRenameNameFrom == that.mRenameNameFrom && 19420bd9fc81e32cafc86f3972b182b65ebdf5b1999Eugene Susla mRenameNameLength == that.mRenameNameLength && 195a38fbf63fd2a29884637a59387643c801ed4f663Eugene Susla mRenameBytesReverseOrder == that.mRenameBytesReverseOrder && 196a38fbf63fd2a29884637a59387643c801ed4f663Eugene Susla Objects.equals(mNamePattern, that.mNamePattern) && 197a38fbf63fd2a29884637a59387643c801ed4f663Eugene Susla Objects.equals(mScanFilter, that.mScanFilter) && 198a38fbf63fd2a29884637a59387643c801ed4f663Eugene Susla Arrays.equals(mRawDataFilter, that.mRawDataFilter) && 199a38fbf63fd2a29884637a59387643c801ed4f663Eugene Susla Arrays.equals(mRawDataFilterMask, that.mRawDataFilterMask) && 200a38fbf63fd2a29884637a59387643c801ed4f663Eugene Susla Objects.equals(mRenamePrefix, that.mRenamePrefix) && 201a38fbf63fd2a29884637a59387643c801ed4f663Eugene Susla Objects.equals(mRenameSuffix, that.mRenameSuffix); 202a38fbf63fd2a29884637a59387643c801ed4f663Eugene Susla } 203a38fbf63fd2a29884637a59387643c801ed4f663Eugene Susla 204a38fbf63fd2a29884637a59387643c801ed4f663Eugene Susla @Override 205a38fbf63fd2a29884637a59387643c801ed4f663Eugene Susla public int hashCode() { 206a38fbf63fd2a29884637a59387643c801ed4f663Eugene Susla return Objects.hash(mNamePattern, mScanFilter, mRawDataFilter, mRawDataFilterMask, 20720bd9fc81e32cafc86f3972b182b65ebdf5b1999Eugene Susla mRenamePrefix, mRenameSuffix, mRenameBytesFrom, mRenameBytesLength, 20820bd9fc81e32cafc86f3972b182b65ebdf5b1999Eugene Susla mRenameNameFrom, mRenameNameLength, mRenameBytesReverseOrder); 209a38fbf63fd2a29884637a59387643c801ed4f663Eugene Susla } 210a38fbf63fd2a29884637a59387643c801ed4f663Eugene Susla 211a38fbf63fd2a29884637a59387643c801ed4f663Eugene Susla @Override 2126ed45d8cd33c297e608aba94fc1f61dace7a7ccaEugene Susla public void writeToParcel(Parcel dest, int flags) { 2136ed45d8cd33c297e608aba94fc1f61dace7a7ccaEugene Susla dest.writeString(patternToString(getNamePattern())); 2146ed45d8cd33c297e608aba94fc1f61dace7a7ccaEugene Susla dest.writeParcelable(mScanFilter, flags); 215a38fbf63fd2a29884637a59387643c801ed4f663Eugene Susla dest.writeByteArray(mRawDataFilter); 216a38fbf63fd2a29884637a59387643c801ed4f663Eugene Susla dest.writeByteArray(mRawDataFilterMask); 217a38fbf63fd2a29884637a59387643c801ed4f663Eugene Susla dest.writeString(mRenamePrefix); 218a38fbf63fd2a29884637a59387643c801ed4f663Eugene Susla dest.writeString(mRenameSuffix); 219a38fbf63fd2a29884637a59387643c801ed4f663Eugene Susla dest.writeInt(mRenameBytesFrom); 22020bd9fc81e32cafc86f3972b182b65ebdf5b1999Eugene Susla dest.writeInt(mRenameBytesLength); 22175fb821029f789cf8f306dbd72805d1581214785Eugene Susla dest.writeInt(mRenameNameFrom); 22220bd9fc81e32cafc86f3972b182b65ebdf5b1999Eugene Susla dest.writeInt(mRenameNameLength); 223a38fbf63fd2a29884637a59387643c801ed4f663Eugene Susla dest.writeBoolean(mRenameBytesReverseOrder); 2246ed45d8cd33c297e608aba94fc1f61dace7a7ccaEugene Susla } 2256ed45d8cd33c297e608aba94fc1f61dace7a7ccaEugene Susla 2266ed45d8cd33c297e608aba94fc1f61dace7a7ccaEugene Susla @Override 2276ed45d8cd33c297e608aba94fc1f61dace7a7ccaEugene Susla public int describeContents() { 2286ed45d8cd33c297e608aba94fc1f61dace7a7ccaEugene Susla return 0; 2296ed45d8cd33c297e608aba94fc1f61dace7a7ccaEugene Susla } 2306ed45d8cd33c297e608aba94fc1f61dace7a7ccaEugene Susla 231a7717e3072acad6cd6256ce3fdbb2bb94ecb06caEugene Susla @Override 232a7717e3072acad6cd6256ce3fdbb2bb94ecb06caEugene Susla public String toString() { 233a7717e3072acad6cd6256ce3fdbb2bb94ecb06caEugene Susla return "BluetoothLEDeviceFilter{" + 234a7717e3072acad6cd6256ce3fdbb2bb94ecb06caEugene Susla "mNamePattern=" + mNamePattern + 235a7717e3072acad6cd6256ce3fdbb2bb94ecb06caEugene Susla ", mScanFilter=" + mScanFilter + 236a7717e3072acad6cd6256ce3fdbb2bb94ecb06caEugene Susla ", mRawDataFilter=" + Arrays.toString(mRawDataFilter) + 237a7717e3072acad6cd6256ce3fdbb2bb94ecb06caEugene Susla ", mRawDataFilterMask=" + Arrays.toString(mRawDataFilterMask) + 238a7717e3072acad6cd6256ce3fdbb2bb94ecb06caEugene Susla ", mRenamePrefix='" + mRenamePrefix + '\'' + 239a7717e3072acad6cd6256ce3fdbb2bb94ecb06caEugene Susla ", mRenameSuffix='" + mRenameSuffix + '\'' + 240a7717e3072acad6cd6256ce3fdbb2bb94ecb06caEugene Susla ", mRenameBytesFrom=" + mRenameBytesFrom + 24120bd9fc81e32cafc86f3972b182b65ebdf5b1999Eugene Susla ", mRenameBytesLength=" + mRenameBytesLength + 242a7717e3072acad6cd6256ce3fdbb2bb94ecb06caEugene Susla ", mRenameNameFrom=" + mRenameNameFrom + 24320bd9fc81e32cafc86f3972b182b65ebdf5b1999Eugene Susla ", mRenameNameLength=" + mRenameNameLength + 244a7717e3072acad6cd6256ce3fdbb2bb94ecb06caEugene Susla ", mRenameBytesReverseOrder=" + mRenameBytesReverseOrder + 245a7717e3072acad6cd6256ce3fdbb2bb94ecb06caEugene Susla '}'; 246a7717e3072acad6cd6256ce3fdbb2bb94ecb06caEugene Susla } 247a7717e3072acad6cd6256ce3fdbb2bb94ecb06caEugene Susla 248722463ff953168ae27bedf61a586f296813fc9feEugene Susla public static final Creator<BluetoothLeDeviceFilter> CREATOR 249722463ff953168ae27bedf61a586f296813fc9feEugene Susla = new Creator<BluetoothLeDeviceFilter>() { 2506ed45d8cd33c297e608aba94fc1f61dace7a7ccaEugene Susla @Override 251722463ff953168ae27bedf61a586f296813fc9feEugene Susla public BluetoothLeDeviceFilter createFromParcel(Parcel in) { 252a38fbf63fd2a29884637a59387643c801ed4f663Eugene Susla Builder builder = new Builder() 25336e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla .setNamePattern(patternFromString(in.readString())) 254a38fbf63fd2a29884637a59387643c801ed4f663Eugene Susla .setScanFilter(in.readParcelable(null)); 255a38fbf63fd2a29884637a59387643c801ed4f663Eugene Susla byte[] rawDataFilter = in.createByteArray(); 256a38fbf63fd2a29884637a59387643c801ed4f663Eugene Susla byte[] rawDataFilterMask = in.createByteArray(); 257a38fbf63fd2a29884637a59387643c801ed4f663Eugene Susla if (rawDataFilter != null) { 258a38fbf63fd2a29884637a59387643c801ed4f663Eugene Susla builder.setRawDataFilter(rawDataFilter, rawDataFilterMask); 259a38fbf63fd2a29884637a59387643c801ed4f663Eugene Susla } 260a38fbf63fd2a29884637a59387643c801ed4f663Eugene Susla String renamePrefix = in.readString(); 261a38fbf63fd2a29884637a59387643c801ed4f663Eugene Susla String suffix = in.readString(); 262a38fbf63fd2a29884637a59387643c801ed4f663Eugene Susla int bytesFrom = in.readInt(); 263a38fbf63fd2a29884637a59387643c801ed4f663Eugene Susla int bytesTo = in.readInt(); 26475fb821029f789cf8f306dbd72805d1581214785Eugene Susla int nameFrom = in.readInt(); 26575fb821029f789cf8f306dbd72805d1581214785Eugene Susla int nameTo = in.readInt(); 266a38fbf63fd2a29884637a59387643c801ed4f663Eugene Susla boolean bytesReverseOrder = in.readBoolean(); 267a38fbf63fd2a29884637a59387643c801ed4f663Eugene Susla if (renamePrefix != null) { 26875fb821029f789cf8f306dbd72805d1581214785Eugene Susla if (bytesFrom >= 0) { 26975fb821029f789cf8f306dbd72805d1581214785Eugene Susla builder.setRenameFromBytes(renamePrefix, suffix, bytesFrom, bytesTo, 27020bd9fc81e32cafc86f3972b182b65ebdf5b1999Eugene Susla bytesReverseOrder ? ByteOrder.LITTLE_ENDIAN : ByteOrder.BIG_ENDIAN); 27175fb821029f789cf8f306dbd72805d1581214785Eugene Susla } else { 27275fb821029f789cf8f306dbd72805d1581214785Eugene Susla builder.setRenameFromName(renamePrefix, suffix, nameFrom, nameTo); 27375fb821029f789cf8f306dbd72805d1581214785Eugene Susla } 274a38fbf63fd2a29884637a59387643c801ed4f663Eugene Susla } 275a38fbf63fd2a29884637a59387643c801ed4f663Eugene Susla return builder.build(); 2766ed45d8cd33c297e608aba94fc1f61dace7a7ccaEugene Susla } 2776ed45d8cd33c297e608aba94fc1f61dace7a7ccaEugene Susla 2786ed45d8cd33c297e608aba94fc1f61dace7a7ccaEugene Susla @Override 279722463ff953168ae27bedf61a586f296813fc9feEugene Susla public BluetoothLeDeviceFilter[] newArray(int size) { 280722463ff953168ae27bedf61a586f296813fc9feEugene Susla return new BluetoothLeDeviceFilter[size]; 2816ed45d8cd33c297e608aba94fc1f61dace7a7ccaEugene Susla } 2826ed45d8cd33c297e608aba94fc1f61dace7a7ccaEugene Susla }; 2836ed45d8cd33c297e608aba94fc1f61dace7a7ccaEugene Susla 28436e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla public static int getRenamePrefixLengthLimit() { 28536e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla return RENAME_PREFIX_LENGTH_LIMIT; 28636e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla } 28736e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla 2886ed45d8cd33c297e608aba94fc1f61dace7a7ccaEugene Susla /** 289722463ff953168ae27bedf61a586f296813fc9feEugene Susla * Builder for {@link BluetoothLeDeviceFilter} 2906ed45d8cd33c297e608aba94fc1f61dace7a7ccaEugene Susla */ 291722463ff953168ae27bedf61a586f296813fc9feEugene Susla public static final class Builder extends OneTimeUseBuilder<BluetoothLeDeviceFilter> { 2926ed45d8cd33c297e608aba94fc1f61dace7a7ccaEugene Susla private ScanFilter mScanFilter; 2936ed45d8cd33c297e608aba94fc1f61dace7a7ccaEugene Susla private Pattern mNamePattern; 29436e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla private byte[] mRawDataFilter; 29536e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla private byte[] mRawDataFilterMask; 29636e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla private String mRenamePrefix; 29736e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla private String mRenameSuffix; 29836e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla private int mRenameBytesFrom = -1; 29920bd9fc81e32cafc86f3972b182b65ebdf5b1999Eugene Susla private int mRenameBytesLength; 30075fb821029f789cf8f306dbd72805d1581214785Eugene Susla private int mRenameNameFrom = -1; 30120bd9fc81e32cafc86f3972b182b65ebdf5b1999Eugene Susla private int mRenameNameLength; 30236e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla private boolean mRenameBytesReverseOrder = false; 3036ed45d8cd33c297e608aba94fc1f61dace7a7ccaEugene Susla 3046ed45d8cd33c297e608aba94fc1f61dace7a7ccaEugene Susla /** 3056ed45d8cd33c297e608aba94fc1f61dace7a7ccaEugene Susla * @param regex if set, only devices with {@link BluetoothDevice#getName name} matching the 3066ed45d8cd33c297e608aba94fc1f61dace7a7ccaEugene Susla * given regular expression will be shown 30736e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla * @return self for chaining 3086ed45d8cd33c297e608aba94fc1f61dace7a7ccaEugene Susla */ 3096ed45d8cd33c297e608aba94fc1f61dace7a7ccaEugene Susla public Builder setNamePattern(@Nullable Pattern regex) { 3106ed45d8cd33c297e608aba94fc1f61dace7a7ccaEugene Susla checkNotUsed(); 3116ed45d8cd33c297e608aba94fc1f61dace7a7ccaEugene Susla mNamePattern = regex; 3126ed45d8cd33c297e608aba94fc1f61dace7a7ccaEugene Susla return this; 3136ed45d8cd33c297e608aba94fc1f61dace7a7ccaEugene Susla } 3146ed45d8cd33c297e608aba94fc1f61dace7a7ccaEugene Susla 3156ed45d8cd33c297e608aba94fc1f61dace7a7ccaEugene Susla /** 3166ed45d8cd33c297e608aba94fc1f61dace7a7ccaEugene Susla * @param scanFilter a {@link ScanFilter} to filter devices by 3176ed45d8cd33c297e608aba94fc1f61dace7a7ccaEugene Susla * 31836e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla * @return self for chaining 3196ed45d8cd33c297e608aba94fc1f61dace7a7ccaEugene Susla * @see ScanFilter for specific details on its various fields 3206ed45d8cd33c297e608aba94fc1f61dace7a7ccaEugene Susla */ 3216ed45d8cd33c297e608aba94fc1f61dace7a7ccaEugene Susla @NonNull 3226ed45d8cd33c297e608aba94fc1f61dace7a7ccaEugene Susla public Builder setScanFilter(@Nullable ScanFilter scanFilter) { 3236ed45d8cd33c297e608aba94fc1f61dace7a7ccaEugene Susla checkNotUsed(); 3246ed45d8cd33c297e608aba94fc1f61dace7a7ccaEugene Susla mScanFilter = scanFilter; 3256ed45d8cd33c297e608aba94fc1f61dace7a7ccaEugene Susla return this; 3266ed45d8cd33c297e608aba94fc1f61dace7a7ccaEugene Susla } 3276ed45d8cd33c297e608aba94fc1f61dace7a7ccaEugene Susla 32836e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla /** 32936e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla * Filter devices by raw advertisement data, as obtained by {@link ScanRecord#getBytes} 33036e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla * 33136e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla * @param rawDataFilter bit values that have to match against advertized data 33236e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla * @param rawDataFilterMask bits that have to be matched 33336e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla * @return self for chaining 33436e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla */ 33536e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla @NonNull 33636e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla public Builder setRawDataFilter(@NonNull byte[] rawDataFilter, 337a38fbf63fd2a29884637a59387643c801ed4f663Eugene Susla @Nullable byte[] rawDataFilterMask) { 33836e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla checkNotUsed(); 339a38fbf63fd2a29884637a59387643c801ed4f663Eugene Susla Preconditions.checkNotNull(rawDataFilter); 340a38fbf63fd2a29884637a59387643c801ed4f663Eugene Susla checkArgument(rawDataFilterMask == null || 341a38fbf63fd2a29884637a59387643c801ed4f663Eugene Susla rawDataFilter.length == rawDataFilterMask.length, 34236e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla "Mask and filter should be the same length"); 343a38fbf63fd2a29884637a59387643c801ed4f663Eugene Susla mRawDataFilter = rawDataFilter; 344a38fbf63fd2a29884637a59387643c801ed4f663Eugene Susla mRawDataFilterMask = rawDataFilterMask; 34536e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla return this; 34636e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla } 34736e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla 34836e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla /** 34936e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla * Rename the devices shown in the list, using specific bytes from the raw advertisement 35036e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla * data ({@link ScanRecord#getBytes}) in hexadecimal format, as well as a custom 35136e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla * prefix/suffix around them 35236e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla * 35336e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla * Note that the prefix length is limited to {@link #getRenamePrefixLengthLimit} characters 35436e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla * to ensure that there's enough space to display the byte data 35536e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla * 35636e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla * The range of bytes to be displayed cannot be empty 35736e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla * 35836e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla * @param prefix to be displayed before the byte data 35936e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla * @param suffix to be displayed after the byte data 36036e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla * @param bytesFrom the start byte index to be displayed (inclusive) 36120bd9fc81e32cafc86f3972b182b65ebdf5b1999Eugene Susla * @param bytesLength the number of bytes to be displayed from the given index 36220bd9fc81e32cafc86f3972b182b65ebdf5b1999Eugene Susla * @param byteOrder whether the given range of bytes is big endian (will be displayed 36320bd9fc81e32cafc86f3972b182b65ebdf5b1999Eugene Susla * in same order) or little endian (will be flipped before displaying) 36436e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla * @return self for chaining 36536e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla */ 36636e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla @NonNull 36775fb821029f789cf8f306dbd72805d1581214785Eugene Susla public Builder setRenameFromBytes(@NonNull String prefix, @NonNull String suffix, 36820bd9fc81e32cafc86f3972b182b65ebdf5b1999Eugene Susla int bytesFrom, int bytesLength, ByteOrder byteOrder) { 36975fb821029f789cf8f306dbd72805d1581214785Eugene Susla checkRenameNotSet(); 37020bd9fc81e32cafc86f3972b182b65ebdf5b1999Eugene Susla checkRangeNotEmpty(bytesLength); 37136e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla mRenameBytesFrom = bytesFrom; 37220bd9fc81e32cafc86f3972b182b65ebdf5b1999Eugene Susla mRenameBytesLength = bytesLength; 37320bd9fc81e32cafc86f3972b182b65ebdf5b1999Eugene Susla mRenameBytesReverseOrder = byteOrder == ByteOrder.LITTLE_ENDIAN; 37475fb821029f789cf8f306dbd72805d1581214785Eugene Susla return setRename(prefix, suffix); 37575fb821029f789cf8f306dbd72805d1581214785Eugene Susla } 37675fb821029f789cf8f306dbd72805d1581214785Eugene Susla 37775fb821029f789cf8f306dbd72805d1581214785Eugene Susla /** 37875fb821029f789cf8f306dbd72805d1581214785Eugene Susla * Rename the devices shown in the list, using specific characters from the advertised name, 37975fb821029f789cf8f306dbd72805d1581214785Eugene Susla * as well as a custom prefix/suffix around them 38075fb821029f789cf8f306dbd72805d1581214785Eugene Susla * 38175fb821029f789cf8f306dbd72805d1581214785Eugene Susla * Note that the prefix length is limited to {@link #getRenamePrefixLengthLimit} characters 38275fb821029f789cf8f306dbd72805d1581214785Eugene Susla * to ensure that there's enough space to display the byte data 38375fb821029f789cf8f306dbd72805d1581214785Eugene Susla * 38475fb821029f789cf8f306dbd72805d1581214785Eugene Susla * The range of name characters to be displayed cannot be empty 38575fb821029f789cf8f306dbd72805d1581214785Eugene Susla * 38675fb821029f789cf8f306dbd72805d1581214785Eugene Susla * @param prefix to be displayed before the byte data 38775fb821029f789cf8f306dbd72805d1581214785Eugene Susla * @param suffix to be displayed after the byte data 38875fb821029f789cf8f306dbd72805d1581214785Eugene Susla * @param nameFrom the start name character index to be displayed (inclusive) 38920bd9fc81e32cafc86f3972b182b65ebdf5b1999Eugene Susla * @param nameLength the number of characters to be displayed from the given index 39075fb821029f789cf8f306dbd72805d1581214785Eugene Susla * @return self for chaining 39175fb821029f789cf8f306dbd72805d1581214785Eugene Susla */ 39275fb821029f789cf8f306dbd72805d1581214785Eugene Susla @NonNull 39375fb821029f789cf8f306dbd72805d1581214785Eugene Susla public Builder setRenameFromName(@NonNull String prefix, @NonNull String suffix, 39420bd9fc81e32cafc86f3972b182b65ebdf5b1999Eugene Susla int nameFrom, int nameLength) { 39575fb821029f789cf8f306dbd72805d1581214785Eugene Susla checkRenameNotSet(); 39620bd9fc81e32cafc86f3972b182b65ebdf5b1999Eugene Susla checkRangeNotEmpty(nameLength); 39775fb821029f789cf8f306dbd72805d1581214785Eugene Susla mRenameNameFrom = nameFrom; 39820bd9fc81e32cafc86f3972b182b65ebdf5b1999Eugene Susla mRenameNameLength = nameLength; 39975fb821029f789cf8f306dbd72805d1581214785Eugene Susla mRenameBytesReverseOrder = false; 40075fb821029f789cf8f306dbd72805d1581214785Eugene Susla return setRename(prefix, suffix); 40175fb821029f789cf8f306dbd72805d1581214785Eugene Susla } 40275fb821029f789cf8f306dbd72805d1581214785Eugene Susla 40375fb821029f789cf8f306dbd72805d1581214785Eugene Susla private void checkRenameNotSet() { 40475fb821029f789cf8f306dbd72805d1581214785Eugene Susla checkState(mRenamePrefix == null, "Renaming rule can only be set once"); 40575fb821029f789cf8f306dbd72805d1581214785Eugene Susla } 40675fb821029f789cf8f306dbd72805d1581214785Eugene Susla 40720bd9fc81e32cafc86f3972b182b65ebdf5b1999Eugene Susla private void checkRangeNotEmpty(int length) { 40820bd9fc81e32cafc86f3972b182b65ebdf5b1999Eugene Susla checkArgument(length > 0, "Range must be non-empty"); 40975fb821029f789cf8f306dbd72805d1581214785Eugene Susla } 41075fb821029f789cf8f306dbd72805d1581214785Eugene Susla 41175fb821029f789cf8f306dbd72805d1581214785Eugene Susla @NonNull 41275fb821029f789cf8f306dbd72805d1581214785Eugene Susla private Builder setRename(@NonNull String prefix, @NonNull String suffix) { 41375fb821029f789cf8f306dbd72805d1581214785Eugene Susla checkNotUsed(); 41475fb821029f789cf8f306dbd72805d1581214785Eugene Susla checkArgument(TextUtils.length(prefix) <= getRenamePrefixLengthLimit(), 41575fb821029f789cf8f306dbd72805d1581214785Eugene Susla "Prefix is too long"); 41675fb821029f789cf8f306dbd72805d1581214785Eugene Susla mRenamePrefix = prefix; 41775fb821029f789cf8f306dbd72805d1581214785Eugene Susla mRenameSuffix = suffix; 41836e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla return this; 41936e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla } 42036e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla 4216ed45d8cd33c297e608aba94fc1f61dace7a7ccaEugene Susla /** @inheritDoc */ 4226ed45d8cd33c297e608aba94fc1f61dace7a7ccaEugene Susla @Override 4236ed45d8cd33c297e608aba94fc1f61dace7a7ccaEugene Susla @NonNull 424722463ff953168ae27bedf61a586f296813fc9feEugene Susla public BluetoothLeDeviceFilter build() { 4256ed45d8cd33c297e608aba94fc1f61dace7a7ccaEugene Susla markUsed(); 426722463ff953168ae27bedf61a586f296813fc9feEugene Susla return new BluetoothLeDeviceFilter(mNamePattern, mScanFilter, 42736e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla mRawDataFilter, mRawDataFilterMask, 42836e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla mRenamePrefix, mRenameSuffix, 42920bd9fc81e32cafc86f3972b182b65ebdf5b1999Eugene Susla mRenameBytesFrom, mRenameBytesLength, 43020bd9fc81e32cafc86f3972b182b65ebdf5b1999Eugene Susla mRenameNameFrom, mRenameNameLength, 43175fb821029f789cf8f306dbd72805d1581214785Eugene Susla mRenameBytesReverseOrder); 4326ed45d8cd33c297e608aba94fc1f61dace7a7ccaEugene Susla } 4336ed45d8cd33c297e608aba94fc1f61dace7a7ccaEugene Susla } 4346ed45d8cd33c297e608aba94fc1f61dace7a7ccaEugene Susla} 435