17ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk/* 27ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk * Copyright (C) 2011 The Android Open Source Project 37ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk * 47ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk * Licensed under the Apache License, Version 2.0 (the "License"); 57ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk * you may not use this file except in compliance with the License. 67ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk * You may obtain a copy of the License at 77ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk * 87ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk * http://www.apache.org/licenses/LICENSE-2.0 97ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk * 107ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk * Unless required by applicable law or agreed to in writing, software 117ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk * distributed under the License is distributed on an "AS IS" BASIS, 127ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 137ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk * See the License for the specific language governing permissions and 147ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk * limitations under the License. 157ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk */ 167ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk 177ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monkpackage com.android.settingslib.bluetooth; 187ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk 197ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monkimport android.bluetooth.BluetoothClass; 207ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monkimport android.bluetooth.BluetoothDevice; 217ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monkimport android.bluetooth.BluetoothUuid; 227ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monkimport android.os.ParcelUuid; 237ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monkimport android.util.Log; 247ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk 257ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk/** 267ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk * BluetoothDeviceFilter contains a static method that returns a 277ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk * Filter object that returns whether or not the BluetoothDevice 287ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk * passed to it matches the specified filter type constant from 297ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk * {@link android.bluetooth.BluetoothDevicePicker}. 307ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk */ 317ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monkpublic final class BluetoothDeviceFilter { 327ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk private static final String TAG = "BluetoothDeviceFilter"; 337ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk 347ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk /** The filter interface to external classes. */ 357ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk public interface Filter { 367ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk boolean matches(BluetoothDevice device); 377ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk } 387ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk 397ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk /** All filter singleton (referenced directly). */ 407ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk public static final Filter ALL_FILTER = new AllFilter(); 417ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk 427ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk /** Bonded devices only filter (referenced directly). */ 437ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk public static final Filter BONDED_DEVICE_FILTER = new BondedDeviceFilter(); 447ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk 457ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk /** Unbonded devices only filter (referenced directly). */ 467ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk public static final Filter UNBONDED_DEVICE_FILTER = new UnbondedDeviceFilter(); 477ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk 487ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk /** Table of singleton filter objects. */ 497ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk private static final Filter[] FILTERS = { 507ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk ALL_FILTER, // FILTER_TYPE_ALL 517ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk new AudioFilter(), // FILTER_TYPE_AUDIO 527ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk new TransferFilter(), // FILTER_TYPE_TRANSFER 537ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk new PanuFilter(), // FILTER_TYPE_PANU 547ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk new NapFilter() // FILTER_TYPE_NAP 557ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk }; 567ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk 577ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk /** Private constructor. */ 587ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk private BluetoothDeviceFilter() { 597ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk } 607ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk 617ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk /** 627ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk * Returns the singleton {@link Filter} object for the specified type, 637ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk * or {@link #ALL_FILTER} if the type value is out of range. 647ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk * 657ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk * @param filterType a constant from BluetoothDevicePicker 667ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk * @return a singleton object implementing the {@link Filter} interface. 677ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk */ 687ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk public static Filter getFilter(int filterType) { 697ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk if (filterType >= 0 && filterType < FILTERS.length) { 707ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk return FILTERS[filterType]; 717ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk } else { 727ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk Log.w(TAG, "Invalid filter type " + filterType + " for device picker"); 737ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk return ALL_FILTER; 747ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk } 757ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk } 767ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk 777ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk /** Filter that matches all devices. */ 787ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk private static final class AllFilter implements Filter { 797ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk public boolean matches(BluetoothDevice device) { 807ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk return true; 817ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk } 827ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk } 837ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk 847ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk /** Filter that matches only bonded devices. */ 857ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk private static final class BondedDeviceFilter implements Filter { 867ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk public boolean matches(BluetoothDevice device) { 877ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk return device.getBondState() == BluetoothDevice.BOND_BONDED; 887ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk } 897ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk } 907ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk 917ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk /** Filter that matches only unbonded devices. */ 927ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk private static final class UnbondedDeviceFilter implements Filter { 937ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk public boolean matches(BluetoothDevice device) { 947ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk return device.getBondState() != BluetoothDevice.BOND_BONDED; 957ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk } 967ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk } 977ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk 987ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk /** Parent class of filters based on UUID and/or Bluetooth class. */ 997ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk private abstract static class ClassUuidFilter implements Filter { 1007ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk abstract boolean matches(ParcelUuid[] uuids, BluetoothClass btClass); 1017ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk 1027ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk public boolean matches(BluetoothDevice device) { 1037ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk return matches(device.getUuids(), device.getBluetoothClass()); 1047ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk } 1057ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk } 1067ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk 1077ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk /** Filter that matches devices that support AUDIO profiles. */ 1087ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk private static final class AudioFilter extends ClassUuidFilter { 1097ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk @Override 1107ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk boolean matches(ParcelUuid[] uuids, BluetoothClass btClass) { 1117ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk if (uuids != null) { 1127ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk if (BluetoothUuid.containsAnyUuid(uuids, A2dpProfile.SINK_UUIDS)) { 1137ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk return true; 1147ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk } 1157ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk if (BluetoothUuid.containsAnyUuid(uuids, HeadsetProfile.UUIDS)) { 1167ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk return true; 1177ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk } 1187ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk } else if (btClass != null) { 1197ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk if (btClass.doesClassMatch(BluetoothClass.PROFILE_A2DP) || 1207ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk btClass.doesClassMatch(BluetoothClass.PROFILE_HEADSET)) { 1217ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk return true; 1227ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk } 1237ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk } 1247ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk return false; 1257ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk } 1267ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk } 1277ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk 1287ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk /** Filter that matches devices that support Object Transfer. */ 1297ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk private static final class TransferFilter extends ClassUuidFilter { 1307ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk @Override 1317ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk boolean matches(ParcelUuid[] uuids, BluetoothClass btClass) { 1327ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk if (uuids != null) { 1337ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk if (BluetoothUuid.isUuidPresent(uuids, BluetoothUuid.ObexObjectPush)) { 1347ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk return true; 1357ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk } 1367ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk } 1377ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk return btClass != null 1387ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk && btClass.doesClassMatch(BluetoothClass.PROFILE_OPP); 1397ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk } 1407ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk } 1417ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk 1427ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk /** Filter that matches devices that support PAN User (PANU) profile. */ 1437ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk private static final class PanuFilter extends ClassUuidFilter { 1447ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk @Override 1457ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk boolean matches(ParcelUuid[] uuids, BluetoothClass btClass) { 1467ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk if (uuids != null) { 1477ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk if (BluetoothUuid.isUuidPresent(uuids, BluetoothUuid.PANU)) { 1487ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk return true; 1497ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk } 1507ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk } 1517ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk return btClass != null 1527ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk && btClass.doesClassMatch(BluetoothClass.PROFILE_PANU); 1537ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk } 1547ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk } 1557ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk 1567ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk /** Filter that matches devices that support NAP profile. */ 1577ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk private static final class NapFilter extends ClassUuidFilter { 1587ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk @Override 1597ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk boolean matches(ParcelUuid[] uuids, BluetoothClass btClass) { 1607ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk if (uuids != null) { 1617ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk if (BluetoothUuid.isUuidPresent(uuids, BluetoothUuid.NAP)) { 1627ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk return true; 1637ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk } 1647ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk } 1657ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk return btClass != null 1667ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk && btClass.doesClassMatch(BluetoothClass.PROFILE_NAP); 1677ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk } 1687ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk } 1697ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk} 170