blob: 8dec86ac36141d1e5153e1cfb84d831130bcd276 [file] [log] [blame]
Jason Monk7ce96b92015-02-02 11:27:58 -05001/*
2 * Copyright (C) 2011 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.settingslib.bluetooth;
18
19import android.bluetooth.BluetoothClass;
20import android.bluetooth.BluetoothDevice;
21import android.bluetooth.BluetoothUuid;
22import android.os.ParcelUuid;
23import android.util.Log;
24
25/**
26 * BluetoothDeviceFilter contains a static method that returns a
27 * Filter object that returns whether or not the BluetoothDevice
28 * passed to it matches the specified filter type constant from
29 * {@link android.bluetooth.BluetoothDevicePicker}.
30 */
31public final class BluetoothDeviceFilter {
32 private static final String TAG = "BluetoothDeviceFilter";
33
34 /** The filter interface to external classes. */
35 public interface Filter {
36 boolean matches(BluetoothDevice device);
37 }
38
39 /** All filter singleton (referenced directly). */
40 public static final Filter ALL_FILTER = new AllFilter();
41
42 /** Bonded devices only filter (referenced directly). */
43 public static final Filter BONDED_DEVICE_FILTER = new BondedDeviceFilter();
44
45 /** Unbonded devices only filter (referenced directly). */
46 public static final Filter UNBONDED_DEVICE_FILTER = new UnbondedDeviceFilter();
47
48 /** Table of singleton filter objects. */
49 private static final Filter[] FILTERS = {
50 ALL_FILTER, // FILTER_TYPE_ALL
51 new AudioFilter(), // FILTER_TYPE_AUDIO
52 new TransferFilter(), // FILTER_TYPE_TRANSFER
53 new PanuFilter(), // FILTER_TYPE_PANU
54 new NapFilter() // FILTER_TYPE_NAP
55 };
56
57 /** Private constructor. */
58 private BluetoothDeviceFilter() {
59 }
60
61 /**
62 * Returns the singleton {@link Filter} object for the specified type,
63 * or {@link #ALL_FILTER} if the type value is out of range.
64 *
65 * @param filterType a constant from BluetoothDevicePicker
66 * @return a singleton object implementing the {@link Filter} interface.
67 */
68 public static Filter getFilter(int filterType) {
69 if (filterType >= 0 && filterType < FILTERS.length) {
70 return FILTERS[filterType];
71 } else {
72 Log.w(TAG, "Invalid filter type " + filterType + " for device picker");
73 return ALL_FILTER;
74 }
75 }
76
77 /** Filter that matches all devices. */
78 private static final class AllFilter implements Filter {
79 public boolean matches(BluetoothDevice device) {
80 return true;
81 }
82 }
83
84 /** Filter that matches only bonded devices. */
85 private static final class BondedDeviceFilter implements Filter {
86 public boolean matches(BluetoothDevice device) {
87 return device.getBondState() == BluetoothDevice.BOND_BONDED;
88 }
89 }
90
91 /** Filter that matches only unbonded devices. */
92 private static final class UnbondedDeviceFilter implements Filter {
93 public boolean matches(BluetoothDevice device) {
94 return device.getBondState() != BluetoothDevice.BOND_BONDED;
95 }
96 }
97
98 /** Parent class of filters based on UUID and/or Bluetooth class. */
99 private abstract static class ClassUuidFilter implements Filter {
100 abstract boolean matches(ParcelUuid[] uuids, BluetoothClass btClass);
101
102 public boolean matches(BluetoothDevice device) {
103 return matches(device.getUuids(), device.getBluetoothClass());
104 }
105 }
106
107 /** Filter that matches devices that support AUDIO profiles. */
108 private static final class AudioFilter extends ClassUuidFilter {
109 @Override
110 boolean matches(ParcelUuid[] uuids, BluetoothClass btClass) {
111 if (uuids != null) {
112 if (BluetoothUuid.containsAnyUuid(uuids, A2dpProfile.SINK_UUIDS)) {
113 return true;
114 }
115 if (BluetoothUuid.containsAnyUuid(uuids, HeadsetProfile.UUIDS)) {
116 return true;
117 }
118 } else if (btClass != null) {
119 if (btClass.doesClassMatch(BluetoothClass.PROFILE_A2DP) ||
120 btClass.doesClassMatch(BluetoothClass.PROFILE_HEADSET)) {
121 return true;
122 }
123 }
124 return false;
125 }
126 }
127
128 /** Filter that matches devices that support Object Transfer. */
129 private static final class TransferFilter extends ClassUuidFilter {
130 @Override
131 boolean matches(ParcelUuid[] uuids, BluetoothClass btClass) {
132 if (uuids != null) {
133 if (BluetoothUuid.isUuidPresent(uuids, BluetoothUuid.ObexObjectPush)) {
134 return true;
135 }
136 }
137 return btClass != null
138 && btClass.doesClassMatch(BluetoothClass.PROFILE_OPP);
139 }
140 }
141
142 /** Filter that matches devices that support PAN User (PANU) profile. */
143 private static final class PanuFilter extends ClassUuidFilter {
144 @Override
145 boolean matches(ParcelUuid[] uuids, BluetoothClass btClass) {
146 if (uuids != null) {
147 if (BluetoothUuid.isUuidPresent(uuids, BluetoothUuid.PANU)) {
148 return true;
149 }
150 }
151 return btClass != null
152 && btClass.doesClassMatch(BluetoothClass.PROFILE_PANU);
153 }
154 }
155
156 /** Filter that matches devices that support NAP profile. */
157 private static final class NapFilter extends ClassUuidFilter {
158 @Override
159 boolean matches(ParcelUuid[] uuids, BluetoothClass btClass) {
160 if (uuids != null) {
161 if (BluetoothUuid.isUuidPresent(uuids, BluetoothUuid.NAP)) {
162 return true;
163 }
164 }
165 return btClass != null
166 && btClass.doesClassMatch(BluetoothClass.PROFILE_NAP);
167 }
168 }
169}