136e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla/*
236e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla * Copyright (C) 2017 The Android Open Source Project
336e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla *
436e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla * Licensed under the Apache License, Version 2.0 (the "License");
536e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla * you may not use this file except in compliance with the License.
636e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla * You may obtain a copy of the License at
736e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla *
836e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla *      http://www.apache.org/licenses/LICENSE-2.0
936e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla *
1036e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla * Unless required by applicable law or agreed to in writing, software
1136e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla * distributed under the License is distributed on an "AS IS" BASIS,
1236e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1336e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla * See the License for the specific language governing permissions and
1436e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla * limitations under the License.
1536e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla */
1636e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla
1736e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Suslapackage android.companion;
1836e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla
1936e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Suslaimport static android.companion.BluetoothDeviceFilterUtils.getDeviceDisplayNameInternal;
2036e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Suslaimport static android.companion.BluetoothDeviceFilterUtils.patternFromString;
2136e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Suslaimport static android.companion.BluetoothDeviceFilterUtils.patternToString;
2236e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla
2336e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Suslaimport android.annotation.NonNull;
2436e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Suslaimport android.annotation.Nullable;
2536e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Suslaimport android.annotation.SuppressLint;
2636e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Suslaimport android.bluetooth.BluetoothDevice;
2736e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Suslaimport android.bluetooth.le.ScanFilter;
2836e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Suslaimport android.net.wifi.ScanResult;
2936e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Suslaimport android.os.Parcel;
3036e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Suslaimport android.provider.OneTimeUseBuilder;
3136e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla
32a38fbf63fd2a29884637a59387643c801ed4f663Eugene Suslaimport java.util.Objects;
3336e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Suslaimport java.util.regex.Pattern;
3436e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla
3536e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla/**
3636e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla * A filter for Wifi devices
3736e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla *
3836e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla * @see ScanFilter
3936e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla */
4036e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Suslapublic final class WifiDeviceFilter implements DeviceFilter<ScanResult> {
4136e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla
4236e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla    private final Pattern mNamePattern;
4336e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla
4436e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla    private WifiDeviceFilter(Pattern namePattern) {
4536e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla        mNamePattern = namePattern;
4636e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla    }
4736e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla
4836e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla    @SuppressLint("ParcelClassLoader")
4936e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla    private WifiDeviceFilter(Parcel in) {
5036e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla        this(patternFromString(in.readString()));
5136e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla    }
5236e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla
5336e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla    /** @hide */
5436e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla    @Nullable
5536e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla    public Pattern getNamePattern() {
5636e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla        return mNamePattern;
5736e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla    }
5836e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla
5936e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla
6036e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla    /** @hide */
6136e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla    @Override
6236e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla    public boolean matches(ScanResult device) {
6336e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla        return BluetoothDeviceFilterUtils.matchesName(getNamePattern(), device);
6436e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla    }
6536e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla
6636e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla    /** @hide */
6736e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla    @Override
6836e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla    public String getDeviceDisplayName(ScanResult device) {
6936e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla        return getDeviceDisplayNameInternal(device);
7036e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla    }
7136e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla
7236e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla    /** @hide */
7336e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla    @Override
7436e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla    public int getMediumType() {
7536e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla        return MEDIUM_TYPE_WIFI;
7636e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla    }
7736e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla
7836e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla    @Override
79a38fbf63fd2a29884637a59387643c801ed4f663Eugene Susla    public boolean equals(Object o) {
80a38fbf63fd2a29884637a59387643c801ed4f663Eugene Susla        if (this == o) return true;
81a38fbf63fd2a29884637a59387643c801ed4f663Eugene Susla        if (o == null || getClass() != o.getClass()) return false;
82a38fbf63fd2a29884637a59387643c801ed4f663Eugene Susla        WifiDeviceFilter that = (WifiDeviceFilter) o;
83a38fbf63fd2a29884637a59387643c801ed4f663Eugene Susla        return Objects.equals(mNamePattern, that.mNamePattern);
84a38fbf63fd2a29884637a59387643c801ed4f663Eugene Susla    }
85a38fbf63fd2a29884637a59387643c801ed4f663Eugene Susla
86a38fbf63fd2a29884637a59387643c801ed4f663Eugene Susla    @Override
87a38fbf63fd2a29884637a59387643c801ed4f663Eugene Susla    public int hashCode() {
88a38fbf63fd2a29884637a59387643c801ed4f663Eugene Susla        return Objects.hash(mNamePattern);
89a38fbf63fd2a29884637a59387643c801ed4f663Eugene Susla    }
90a38fbf63fd2a29884637a59387643c801ed4f663Eugene Susla
91a38fbf63fd2a29884637a59387643c801ed4f663Eugene Susla    @Override
9236e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla    public void writeToParcel(Parcel dest, int flags) {
9336e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla        dest.writeString(patternToString(getNamePattern()));
9436e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla    }
9536e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla
9636e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla    @Override
9736e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla    public int describeContents() {
9836e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla        return 0;
9936e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla    }
10036e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla
10136e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla    public static final Creator<WifiDeviceFilter> CREATOR
10236e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla            = new Creator<WifiDeviceFilter>() {
10336e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla        @Override
10436e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla        public WifiDeviceFilter createFromParcel(Parcel in) {
10536e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla            return new WifiDeviceFilter(in);
10636e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla        }
10736e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla
10836e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla        @Override
10936e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla        public WifiDeviceFilter[] newArray(int size) {
11036e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla            return new WifiDeviceFilter[size];
11136e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla        }
11236e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla    };
11336e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla
11436e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla    /**
11536e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla     * Builder for {@link WifiDeviceFilter}
11636e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla     */
11736e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla    public static final class Builder extends OneTimeUseBuilder<WifiDeviceFilter> {
11836e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla        private Pattern mNamePattern;
11936e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla
12036e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla        /**
12136e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla         * @param regex if set, only devices with {@link BluetoothDevice#getName name} matching the
12236e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla         *              given regular expression will be shown
12336e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla         * @return self for chaining
12436e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla         */
12536e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla        public Builder setNamePattern(@Nullable Pattern regex) {
12636e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla            checkNotUsed();
12736e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla            mNamePattern = regex;
12836e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla            return this;
12936e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla        }
13036e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla
13136e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla        /** @inheritDoc */
13236e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla        @Override
13336e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla        @NonNull
13436e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla        public WifiDeviceFilter build() {
13536e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla            markUsed();
13636e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla            return new WifiDeviceFilter(mNamePattern);
13736e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla        }
13836e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla    }
13936e866b8e0ec08e45b5e7fbc65aeeb3a9bb7b11eEugene Susla}
140