BluetoothDeviceFilter.java revision 436b29e68e6608bed9e8e7d54385b8f62d89208e
1436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby/*
2436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby * Copyright (C) 2011 The Android Open Source Project
3436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby *
4436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby * Licensed under the Apache License, Version 2.0 (the "License");
5436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby * you may not use this file except in compliance with the License.
6436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby * You may obtain a copy of the License at
7436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby *
8436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby *      http://www.apache.org/licenses/LICENSE-2.0
9436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby *
10436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby * Unless required by applicable law or agreed to in writing, software
11436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby * distributed under the License is distributed on an "AS IS" BASIS,
12436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby * See the License for the specific language governing permissions and
14436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby * limitations under the License.
15436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby */
16436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby
17436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hambypackage com.android.settings.bluetooth;
18436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby
19436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hambyimport android.bluetooth.BluetoothClass;
20436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hambyimport android.bluetooth.BluetoothDevice;
21436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hambyimport android.bluetooth.BluetoothUuid;
22436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hambyimport android.os.ParcelUuid;
23436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hambyimport android.util.Log;
24436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby
25436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby/**
26436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby * BluetoothDeviceFilter contains a static method that returns a
27436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby * Filter object that returns whether or not the BluetoothDevice
28436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby * passed to it matches the specified filter type constant from
29436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby * {@link android.bluetooth.BluetoothDevicePicker}.
30436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby */
31436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hambyfinal class BluetoothDeviceFilter {
32436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby    private static final String TAG = "BluetoothDeviceFilter";
33436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby
34436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby    /** The filter interface to external classes. */
35436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby    interface Filter {
36436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby        boolean matches(BluetoothDevice device);
37436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby    }
38436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby
39436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby    /** All filter singleton (referenced directly). */
40436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby    static final Filter ALL_FILTER = new AllFilter();
41436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby
42436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby    /** Bonded devices only filter (referenced directly). */
43436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby    static final Filter BONDED_DEVICE_FILTER = new BondedDeviceFilter();
44436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby
45436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby    /** Table of singleton filter objects. */
46436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby    private static final Filter[] FILTERS = {
47436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby            ALL_FILTER,             // FILTER_TYPE_ALL
48436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby            new AudioFilter(),      // FILTER_TYPE_AUDIO
49436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby            new TransferFilter(),   // FILTER_TYPE_TRANSFER
50436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby            new PanuFilter(),       // FILTER_TYPE_PANU
51436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby            new NapFilter()         // FILTER_TYPE_NAP
52436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby    };
53436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby
54436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby    /** Private constructor. */
55436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby    private BluetoothDeviceFilter() {
56436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby    }
57436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby
58436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby    /**
59436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby     * Returns the singleton {@link Filter} object for the specified type,
60436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby     * or {@link #ALL_FILTER} if the type value is out of range.
61436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby     *
62436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby     * @param filterType a constant from BluetoothDevicePicker
63436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby     * @return a singleton object implementing the {@link Filter} interface.
64436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby     */
65436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby    static Filter getFilter(int filterType) {
66436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby        if (filterType >= 0 && filterType < FILTERS.length) {
67436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby            return FILTERS[filterType];
68436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby        } else {
69436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby            Log.w(TAG, "Invalid filter type " + filterType + " for device picker");
70436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby            return ALL_FILTER;
71436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby        }
72436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby    }
73436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby
74436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby    /** Filter that matches all devices. */
75436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby    private static final class AllFilter implements Filter {
76436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby        public boolean matches(BluetoothDevice device) {
77436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby            return true;
78436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby        }
79436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby    }
80436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby
81436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby    /** Filter that matches only bonded devices. */
82436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby    private static final class BondedDeviceFilter implements Filter {
83436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby        public boolean matches(BluetoothDevice device) {
84436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby            return device.getBondState() == BluetoothDevice.BOND_BONDED;
85436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby        }
86436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby    }
87436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby
88436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby    /** Parent class of filters based on UUID and/or Bluetooth class. */
89436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby    private abstract static class ClassUuidFilter implements Filter {
90436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby        abstract boolean matches(ParcelUuid[] uuids, BluetoothClass btClass);
91436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby
92436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby        public boolean matches(BluetoothDevice device) {
93436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby            return matches(device.getUuids(), device.getBluetoothClass());
94436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby        }
95436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby    }
96436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby
97436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby    /** Filter that matches devices that support AUDIO profiles. */
98436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby    private static final class AudioFilter extends ClassUuidFilter {
99436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby        @Override
100436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby        boolean matches(ParcelUuid[] uuids, BluetoothClass btClass) {
101436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby            if (uuids != null) {
102436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby                if (BluetoothUuid.containsAnyUuid(uuids, A2dpProfile.SINK_UUIDS)) {
103436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby                    return true;
104436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby                }
105436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby                if (BluetoothUuid.containsAnyUuid(uuids, HeadsetProfile.UUIDS)) {
106436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby                    return true;
107436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby                }
108436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby            } else if (btClass != null) {
109436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby                if (btClass.doesClassMatch(BluetoothClass.PROFILE_A2DP) ||
110436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby                        btClass.doesClassMatch(BluetoothClass.PROFILE_HEADSET)) {
111436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby                    return true;
112436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby                }
113436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby            }
114436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby            return false;
115436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby        }
116436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby    }
117436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby
118436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby    /** Filter that matches devices that support Object Transfer. */
119436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby    private static final class TransferFilter extends ClassUuidFilter {
120436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby        @Override
121436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby        boolean matches(ParcelUuid[] uuids, BluetoothClass btClass) {
122436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby            if (uuids != null) {
123436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby                if (BluetoothUuid.isUuidPresent(uuids, BluetoothUuid.ObexObjectPush)) {
124436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby                    return true;
125436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby                }
126436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby            }
127436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby            return btClass != null
128436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby                    && btClass.doesClassMatch(BluetoothClass.PROFILE_OPP);
129436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby        }
130436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby    }
131436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby
132436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby    /** Filter that matches devices that support PAN User (PANU) profile. */
133436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby    private static final class PanuFilter extends ClassUuidFilter {
134436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby        @Override
135436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby        boolean matches(ParcelUuid[] uuids, BluetoothClass btClass) {
136436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby            if (uuids != null) {
137436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby                if (BluetoothUuid.isUuidPresent(uuids, BluetoothUuid.PANU)) {
138436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby                    return true;
139436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby                }
140436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby            }
141436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby            return btClass != null
142436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby                    && btClass.doesClassMatch(BluetoothClass.PROFILE_PANU);
143436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby        }
144436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby    }
145436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby
146436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby    /** Filter that matches devices that support NAP profile. */
147436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby    private static final class NapFilter extends ClassUuidFilter {
148436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby        @Override
149436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby        boolean matches(ParcelUuid[] uuids, BluetoothClass btClass) {
150436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby            if (uuids != null) {
151436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby                if (BluetoothUuid.isUuidPresent(uuids, BluetoothUuid.NAP)) {
152436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby                    return true;
153436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby                }
154436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby            }
155436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby            return btClass != null
156436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby                    && btClass.doesClassMatch(BluetoothClass.PROFILE_NAP);
157436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby        }
158436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby    }
159436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby}
160