diff options
Diffstat (limited to 'android/companion/BluetoothDeviceFilter.java')
-rw-r--r-- | android/companion/BluetoothDeviceFilter.java | 216 |
1 files changed, 216 insertions, 0 deletions
diff --git a/android/companion/BluetoothDeviceFilter.java b/android/companion/BluetoothDeviceFilter.java new file mode 100644 index 00000000..84e15364 --- /dev/null +++ b/android/companion/BluetoothDeviceFilter.java @@ -0,0 +1,216 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.companion; + +import static android.companion.BluetoothDeviceFilterUtils.getDeviceDisplayNameInternal; +import static android.companion.BluetoothDeviceFilterUtils.matchesAddress; +import static android.companion.BluetoothDeviceFilterUtils.matchesName; +import static android.companion.BluetoothDeviceFilterUtils.matchesServiceUuids; +import static android.companion.BluetoothDeviceFilterUtils.patternFromString; +import static android.companion.BluetoothDeviceFilterUtils.patternToString; + +import android.annotation.NonNull; +import android.annotation.Nullable; +import android.bluetooth.BluetoothDevice; +import android.os.Parcel; +import android.os.ParcelUuid; +import android.provider.OneTimeUseBuilder; + +import com.android.internal.util.ArrayUtils; +import com.android.internal.util.CollectionUtils; + +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; +import java.util.regex.Pattern; + +/** + * A filter for Bluetooth(non-LE) devices + */ +public final class BluetoothDeviceFilter implements DeviceFilter<BluetoothDevice> { + + private final Pattern mNamePattern; + private final String mAddress; + private final List<ParcelUuid> mServiceUuids; + private final List<ParcelUuid> mServiceUuidMasks; + + private BluetoothDeviceFilter( + Pattern namePattern, + String address, + List<ParcelUuid> serviceUuids, + List<ParcelUuid> serviceUuidMasks) { + mNamePattern = namePattern; + mAddress = address; + mServiceUuids = CollectionUtils.emptyIfNull(serviceUuids); + mServiceUuidMasks = CollectionUtils.emptyIfNull(serviceUuidMasks); + } + + private BluetoothDeviceFilter(Parcel in) { + this( + patternFromString(in.readString()), + in.readString(), + readUuids(in), + readUuids(in)); + } + + private static List<ParcelUuid> readUuids(Parcel in) { + return in.readParcelableList(new ArrayList<>(), ParcelUuid.class.getClassLoader()); + } + + /** @hide */ + @Override + public boolean matches(BluetoothDevice device) { + return matchesAddress(mAddress, device) + && matchesServiceUuids(mServiceUuids, mServiceUuidMasks, device) + && matchesName(getNamePattern(), device); + } + + /** @hide */ + @Override + public String getDeviceDisplayName(BluetoothDevice device) { + return getDeviceDisplayNameInternal(device); + } + + /** @hide */ + @Override + public int getMediumType() { + return DeviceFilter.MEDIUM_TYPE_BLUETOOTH; + } + + /** @hide */ + @Nullable + public Pattern getNamePattern() { + return mNamePattern; + } + + /** @hide */ + @Nullable + public String getAddress() { + return mAddress; + } + + /** @hide */ + @NonNull + public List<ParcelUuid> getServiceUuids() { + return mServiceUuids; + } + + /** @hide */ + @NonNull + public List<ParcelUuid> getServiceUuidMasks() { + return mServiceUuidMasks; + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + dest.writeString(patternToString(getNamePattern())); + dest.writeString(mAddress); + dest.writeParcelableList(mServiceUuids, flags); + dest.writeParcelableList(mServiceUuidMasks, flags); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + BluetoothDeviceFilter that = (BluetoothDeviceFilter) o; + return Objects.equals(mNamePattern, that.mNamePattern) && + Objects.equals(mAddress, that.mAddress) && + Objects.equals(mServiceUuids, that.mServiceUuids) && + Objects.equals(mServiceUuidMasks, that.mServiceUuidMasks); + } + + @Override + public int hashCode() { + return Objects.hash(mNamePattern, mAddress, mServiceUuids, mServiceUuidMasks); + } + + @Override + public int describeContents() { + return 0; + } + + public static final Creator<BluetoothDeviceFilter> CREATOR + = new Creator<BluetoothDeviceFilter>() { + @Override + public BluetoothDeviceFilter createFromParcel(Parcel in) { + return new BluetoothDeviceFilter(in); + } + + @Override + public BluetoothDeviceFilter[] newArray(int size) { + return new BluetoothDeviceFilter[size]; + } + }; + + /** + * A builder for {@link BluetoothDeviceFilter} + */ + public static final class Builder extends OneTimeUseBuilder<BluetoothDeviceFilter> { + private Pattern mNamePattern; + private String mAddress; + private ArrayList<ParcelUuid> mServiceUuid; + private ArrayList<ParcelUuid> mServiceUuidMask; + + /** + * @param regex if set, only devices with {@link BluetoothDevice#getName name} matching the + * given regular expression will be shown + */ + public Builder setNamePattern(@Nullable Pattern regex) { + checkNotUsed(); + mNamePattern = regex; + return this; + } + + /** + * @param address if set, only devices with MAC address exactly matching the given one will + * pass the filter + */ + @NonNull + public Builder setAddress(@Nullable String address) { + checkNotUsed(); + mAddress = address; + return this; + } + + /** + * Add filtering by certain bits of {@link BluetoothDevice#getUuids()} + * + * A device with any uuid matching the given bits is considered passing + * + * @param serviceUuid the values for the bits to match + * @param serviceUuidMask if provided, only those bits would have to match. + */ + @NonNull + public Builder addServiceUuid( + @Nullable ParcelUuid serviceUuid, @Nullable ParcelUuid serviceUuidMask) { + checkNotUsed(); + mServiceUuid = ArrayUtils.add(mServiceUuid, serviceUuid); + mServiceUuidMask = ArrayUtils.add(mServiceUuidMask, serviceUuidMask); + return this; + } + + /** @inheritDoc */ + @Override + @NonNull + public BluetoothDeviceFilter build() { + markUsed(); + return new BluetoothDeviceFilter( + mNamePattern, mAddress, mServiceUuid, mServiceUuidMask); + } + } +} |