The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 1 | /* |
| 2 | * Copyright (C) 2008 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 | |
| 17 | package android.bluetooth; |
| 18 | |
Ralph Nathan | 29335fd | 2018-07-23 09:35:18 -0700 | [diff] [blame] | 19 | import android.annotation.TestApi; |
Mathew Inwood | 4dc66d3 | 2018-08-01 15:07:20 +0100 | [diff] [blame] | 20 | import android.annotation.UnsupportedAppUsage; |
Mathew Inwood | 31755f9 | 2018-12-20 13:53:36 +0000 | [diff] [blame] | 21 | import android.os.Build; |
Nick Pelly | 005b228 | 2009-09-10 10:21:56 -0700 | [diff] [blame] | 22 | import android.os.Parcel; |
| 23 | import android.os.Parcelable; |
| 24 | |
Pulkit Bhuwalka | 66d6123 | 2017-08-16 21:52:04 -0700 | [diff] [blame] | 25 | import java.nio.ByteBuffer; |
| 26 | import java.nio.ByteOrder; |
| 27 | import java.util.Arrays; |
| 28 | |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 29 | /** |
Scott Main | 9fab0ae | 2009-11-03 18:17:59 -0800 | [diff] [blame] | 30 | * Represents a Bluetooth class, which describes general characteristics |
| 31 | * and capabilities of a device. For example, a Bluetooth class will |
| 32 | * specify the general device type such as a phone, a computer, or |
| 33 | * headset, and whether it's capable of services such as audio or telephony. |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 34 | * |
Scott Main | 9fab0ae | 2009-11-03 18:17:59 -0800 | [diff] [blame] | 35 | * <p>Every Bluetooth class is composed of zero or more service classes, and |
Nick Pelly | 005b228 | 2009-09-10 10:21:56 -0700 | [diff] [blame] | 36 | * exactly one device class. The device class is further broken down into major |
| 37 | * and minor device class components. |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 38 | * |
Scott Main | 9fab0ae | 2009-11-03 18:17:59 -0800 | [diff] [blame] | 39 | * <p>{@link BluetoothClass} is useful as a hint to roughly describe a device |
| 40 | * (for example to show an icon in the UI), but does not reliably describe which |
| 41 | * Bluetooth profiles or services are actually supported by a device. Accurate |
| 42 | * service discovery is done through SDP requests, which are automatically |
| 43 | * performed when creating an RFCOMM socket with {@link |
Jake Hamby | f51eada | 2010-09-21 13:39:53 -0700 | [diff] [blame] | 44 | * BluetoothDevice#createRfcommSocketToServiceRecord} and {@link |
| 45 | * BluetoothAdapter#listenUsingRfcommWithServiceRecord}</p> |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 46 | * |
Nick Pelly | 005b228 | 2009-09-10 10:21:56 -0700 | [diff] [blame] | 47 | * <p>Use {@link BluetoothDevice#getBluetoothClass} to retrieve the class for |
| 48 | * a remote device. |
Scott Main | 9fab0ae | 2009-11-03 18:17:59 -0800 | [diff] [blame] | 49 | * |
| 50 | * <!-- |
| 51 | * The Bluetooth class is a 32 bit field. The format of these bits is defined at |
| 52 | * http://www.bluetooth.org/Technical/AssignedNumbers/baseband.htm |
| 53 | * (login required). This class contains that 32 bit field, and provides |
| 54 | * constants and methods to determine which Service Class(es) and Device Class |
| 55 | * are encoded in that field. |
| 56 | * --> |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 57 | */ |
Nick Pelly | 005b228 | 2009-09-10 10:21:56 -0700 | [diff] [blame] | 58 | public final class BluetoothClass implements Parcelable { |
| 59 | /** |
| 60 | * Legacy error value. Applications should use null instead. |
Jack He | a355e5e | 2017-08-22 16:06:54 -0700 | [diff] [blame] | 61 | * |
Nick Pelly | 005b228 | 2009-09-10 10:21:56 -0700 | [diff] [blame] | 62 | * @hide |
| 63 | */ |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 64 | public static final int ERROR = 0xFF000000; |
| 65 | |
Nick Pelly | 005b228 | 2009-09-10 10:21:56 -0700 | [diff] [blame] | 66 | private final int mClass; |
Yue Lixin | a4433af | 2009-07-09 16:56:43 +0800 | [diff] [blame] | 67 | |
Nick Pelly | 005b228 | 2009-09-10 10:21:56 -0700 | [diff] [blame] | 68 | /** @hide */ |
Mathew Inwood | 31755f9 | 2018-12-20 13:53:36 +0000 | [diff] [blame] | 69 | @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) |
Nick Pelly | 005b228 | 2009-09-10 10:21:56 -0700 | [diff] [blame] | 70 | public BluetoothClass(int classInt) { |
| 71 | mClass = classInt; |
| 72 | } |
| 73 | |
| 74 | @Override |
| 75 | public boolean equals(Object o) { |
| 76 | if (o instanceof BluetoothClass) { |
Jack He | a355e5e | 2017-08-22 16:06:54 -0700 | [diff] [blame] | 77 | return mClass == ((BluetoothClass) o).mClass; |
Nick Pelly | 005b228 | 2009-09-10 10:21:56 -0700 | [diff] [blame] | 78 | } |
| 79 | return false; |
| 80 | } |
| 81 | |
| 82 | @Override |
| 83 | public int hashCode() { |
| 84 | return mClass; |
| 85 | } |
| 86 | |
| 87 | @Override |
| 88 | public String toString() { |
| 89 | return Integer.toHexString(mClass); |
| 90 | } |
| 91 | |
Jack He | 2992cd0 | 2017-08-22 21:21:23 -0700 | [diff] [blame] | 92 | @Override |
Nick Pelly | 005b228 | 2009-09-10 10:21:56 -0700 | [diff] [blame] | 93 | public int describeContents() { |
| 94 | return 0; |
| 95 | } |
| 96 | |
Jeff Sharkey | 9e8f83d | 2019-02-28 12:06:45 -0700 | [diff] [blame] | 97 | public static final @android.annotation.NonNull Parcelable.Creator<BluetoothClass> CREATOR = |
Nick Pelly | 005b228 | 2009-09-10 10:21:56 -0700 | [diff] [blame] | 98 | new Parcelable.Creator<BluetoothClass>() { |
Jack He | a355e5e | 2017-08-22 16:06:54 -0700 | [diff] [blame] | 99 | public BluetoothClass createFromParcel(Parcel in) { |
| 100 | return new BluetoothClass(in.readInt()); |
| 101 | } |
| 102 | |
| 103 | public BluetoothClass[] newArray(int size) { |
| 104 | return new BluetoothClass[size]; |
| 105 | } |
| 106 | }; |
Nick Pelly | 005b228 | 2009-09-10 10:21:56 -0700 | [diff] [blame] | 107 | |
Jack He | 2992cd0 | 2017-08-22 21:21:23 -0700 | [diff] [blame] | 108 | @Override |
Nick Pelly | 005b228 | 2009-09-10 10:21:56 -0700 | [diff] [blame] | 109 | public void writeToParcel(Parcel out, int flags) { |
| 110 | out.writeInt(mClass); |
| 111 | } |
| 112 | |
| 113 | /** |
Scott Main | 9fab0ae | 2009-11-03 18:17:59 -0800 | [diff] [blame] | 114 | * Defines all service class constants. |
Nick Pelly | 005b228 | 2009-09-10 10:21:56 -0700 | [diff] [blame] | 115 | * <p>Each {@link BluetoothClass} encodes zero or more service classes. |
| 116 | */ |
| 117 | public static final class Service { |
Jack He | a355e5e | 2017-08-22 16:06:54 -0700 | [diff] [blame] | 118 | private static final int BITMASK = 0xFFE000; |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 119 | |
| 120 | public static final int LIMITED_DISCOVERABILITY = 0x002000; |
Jack He | a355e5e | 2017-08-22 16:06:54 -0700 | [diff] [blame] | 121 | public static final int POSITIONING = 0x010000; |
| 122 | public static final int NETWORKING = 0x020000; |
| 123 | public static final int RENDER = 0x040000; |
| 124 | public static final int CAPTURE = 0x080000; |
| 125 | public static final int OBJECT_TRANSFER = 0x100000; |
| 126 | public static final int AUDIO = 0x200000; |
| 127 | public static final int TELEPHONY = 0x400000; |
| 128 | public static final int INFORMATION = 0x800000; |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 129 | } |
| 130 | |
Nick Pelly | 005b228 | 2009-09-10 10:21:56 -0700 | [diff] [blame] | 131 | /** |
Scott Main | 9fab0ae | 2009-11-03 18:17:59 -0800 | [diff] [blame] | 132 | * Return true if the specified service class is supported by this |
| 133 | * {@link BluetoothClass}. |
Nick Pelly | 005b228 | 2009-09-10 10:21:56 -0700 | [diff] [blame] | 134 | * <p>Valid service classes are the public constants in |
| 135 | * {@link BluetoothClass.Service}. For example, {@link |
| 136 | * BluetoothClass.Service#AUDIO}. |
| 137 | * |
| 138 | * @param service valid service class |
| 139 | * @return true if the service class is supported |
| 140 | */ |
| 141 | public boolean hasService(int service) { |
| 142 | return ((mClass & Service.BITMASK & service) != 0); |
| 143 | } |
| 144 | |
| 145 | /** |
Scott Main | 9fab0ae | 2009-11-03 18:17:59 -0800 | [diff] [blame] | 146 | * Defines all device class constants. |
Nick Pelly | 005b228 | 2009-09-10 10:21:56 -0700 | [diff] [blame] | 147 | * <p>Each {@link BluetoothClass} encodes exactly one device class, with |
| 148 | * major and minor components. |
| 149 | * <p>The constants in {@link |
| 150 | * BluetoothClass.Device} represent a combination of major and minor |
Scott Main | 9fab0ae | 2009-11-03 18:17:59 -0800 | [diff] [blame] | 151 | * device components (the complete device class). The constants in {@link |
| 152 | * BluetoothClass.Device.Major} represent only major device classes. |
| 153 | * <p>See {@link BluetoothClass.Service} for service class constants. |
Nick Pelly | 005b228 | 2009-09-10 10:21:56 -0700 | [diff] [blame] | 154 | */ |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 155 | public static class Device { |
Jack He | a355e5e | 2017-08-22 16:06:54 -0700 | [diff] [blame] | 156 | private static final int BITMASK = 0x1FFC; |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 157 | |
Scott Main | 9fab0ae | 2009-11-03 18:17:59 -0800 | [diff] [blame] | 158 | /** |
| 159 | * Defines all major device class constants. |
| 160 | * <p>See {@link BluetoothClass.Device} for minor classes. |
| 161 | */ |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 162 | public static class Major { |
Jack He | a355e5e | 2017-08-22 16:06:54 -0700 | [diff] [blame] | 163 | private static final int BITMASK = 0x1F00; |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 164 | |
Jack He | a355e5e | 2017-08-22 16:06:54 -0700 | [diff] [blame] | 165 | public static final int MISC = 0x0000; |
| 166 | public static final int COMPUTER = 0x0100; |
| 167 | public static final int PHONE = 0x0200; |
| 168 | public static final int NETWORKING = 0x0300; |
| 169 | public static final int AUDIO_VIDEO = 0x0400; |
| 170 | public static final int PERIPHERAL = 0x0500; |
| 171 | public static final int IMAGING = 0x0600; |
| 172 | public static final int WEARABLE = 0x0700; |
| 173 | public static final int TOY = 0x0800; |
| 174 | public static final int HEALTH = 0x0900; |
| 175 | public static final int UNCATEGORIZED = 0x1F00; |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 176 | } |
| 177 | |
| 178 | // Devices in the COMPUTER major class |
Jack He | a355e5e | 2017-08-22 16:06:54 -0700 | [diff] [blame] | 179 | public static final int COMPUTER_UNCATEGORIZED = 0x0100; |
| 180 | public static final int COMPUTER_DESKTOP = 0x0104; |
| 181 | public static final int COMPUTER_SERVER = 0x0108; |
| 182 | public static final int COMPUTER_LAPTOP = 0x010C; |
| 183 | public static final int COMPUTER_HANDHELD_PC_PDA = 0x0110; |
| 184 | public static final int COMPUTER_PALM_SIZE_PC_PDA = 0x0114; |
| 185 | public static final int COMPUTER_WEARABLE = 0x0118; |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 186 | |
| 187 | // Devices in the PHONE major class |
Jack He | a355e5e | 2017-08-22 16:06:54 -0700 | [diff] [blame] | 188 | public static final int PHONE_UNCATEGORIZED = 0x0200; |
| 189 | public static final int PHONE_CELLULAR = 0x0204; |
| 190 | public static final int PHONE_CORDLESS = 0x0208; |
| 191 | public static final int PHONE_SMART = 0x020C; |
| 192 | public static final int PHONE_MODEM_OR_GATEWAY = 0x0210; |
| 193 | public static final int PHONE_ISDN = 0x0214; |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 194 | |
| 195 | // Minor classes for the AUDIO_VIDEO major class |
Jack He | a355e5e | 2017-08-22 16:06:54 -0700 | [diff] [blame] | 196 | public static final int AUDIO_VIDEO_UNCATEGORIZED = 0x0400; |
| 197 | public static final int AUDIO_VIDEO_WEARABLE_HEADSET = 0x0404; |
| 198 | public static final int AUDIO_VIDEO_HANDSFREE = 0x0408; |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 199 | //public static final int AUDIO_VIDEO_RESERVED = 0x040C; |
Jack He | a355e5e | 2017-08-22 16:06:54 -0700 | [diff] [blame] | 200 | public static final int AUDIO_VIDEO_MICROPHONE = 0x0410; |
| 201 | public static final int AUDIO_VIDEO_LOUDSPEAKER = 0x0414; |
| 202 | public static final int AUDIO_VIDEO_HEADPHONES = 0x0418; |
| 203 | public static final int AUDIO_VIDEO_PORTABLE_AUDIO = 0x041C; |
| 204 | public static final int AUDIO_VIDEO_CAR_AUDIO = 0x0420; |
| 205 | public static final int AUDIO_VIDEO_SET_TOP_BOX = 0x0424; |
| 206 | public static final int AUDIO_VIDEO_HIFI_AUDIO = 0x0428; |
| 207 | public static final int AUDIO_VIDEO_VCR = 0x042C; |
| 208 | public static final int AUDIO_VIDEO_VIDEO_CAMERA = 0x0430; |
| 209 | public static final int AUDIO_VIDEO_CAMCORDER = 0x0434; |
| 210 | public static final int AUDIO_VIDEO_VIDEO_MONITOR = 0x0438; |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 211 | public static final int AUDIO_VIDEO_VIDEO_DISPLAY_AND_LOUDSPEAKER = 0x043C; |
Jack He | a355e5e | 2017-08-22 16:06:54 -0700 | [diff] [blame] | 212 | public static final int AUDIO_VIDEO_VIDEO_CONFERENCING = 0x0440; |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 213 | //public static final int AUDIO_VIDEO_RESERVED = 0x0444; |
Jack He | a355e5e | 2017-08-22 16:06:54 -0700 | [diff] [blame] | 214 | public static final int AUDIO_VIDEO_VIDEO_GAMING_TOY = 0x0448; |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 215 | |
| 216 | // Devices in the WEARABLE major class |
Jack He | a355e5e | 2017-08-22 16:06:54 -0700 | [diff] [blame] | 217 | public static final int WEARABLE_UNCATEGORIZED = 0x0700; |
| 218 | public static final int WEARABLE_WRIST_WATCH = 0x0704; |
| 219 | public static final int WEARABLE_PAGER = 0x0708; |
| 220 | public static final int WEARABLE_JACKET = 0x070C; |
| 221 | public static final int WEARABLE_HELMET = 0x0710; |
| 222 | public static final int WEARABLE_GLASSES = 0x0714; |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 223 | |
| 224 | // Devices in the TOY major class |
Jack He | a355e5e | 2017-08-22 16:06:54 -0700 | [diff] [blame] | 225 | public static final int TOY_UNCATEGORIZED = 0x0800; |
| 226 | public static final int TOY_ROBOT = 0x0804; |
| 227 | public static final int TOY_VEHICLE = 0x0808; |
| 228 | public static final int TOY_DOLL_ACTION_FIGURE = 0x080C; |
| 229 | public static final int TOY_CONTROLLER = 0x0810; |
| 230 | public static final int TOY_GAME = 0x0814; |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 231 | |
| 232 | // Devices in the HEALTH major class |
Jack He | a355e5e | 2017-08-22 16:06:54 -0700 | [diff] [blame] | 233 | public static final int HEALTH_UNCATEGORIZED = 0x0900; |
| 234 | public static final int HEALTH_BLOOD_PRESSURE = 0x0904; |
| 235 | public static final int HEALTH_THERMOMETER = 0x0908; |
| 236 | public static final int HEALTH_WEIGHING = 0x090C; |
| 237 | public static final int HEALTH_GLUCOSE = 0x0910; |
| 238 | public static final int HEALTH_PULSE_OXIMETER = 0x0914; |
| 239 | public static final int HEALTH_PULSE_RATE = 0x0918; |
| 240 | public static final int HEALTH_DATA_DISPLAY = 0x091C; |
Jaikumar Ganesh | c88b0c6 | 2011-01-05 13:49:00 -0800 | [diff] [blame] | 241 | |
| 242 | // Devices in PERIPHERAL major class |
| 243 | /** |
| 244 | * @hide |
| 245 | */ |
| 246 | public static final int PERIPHERAL_NON_KEYBOARD_NON_POINTING = 0x0500; |
| 247 | /** |
| 248 | * @hide |
| 249 | */ |
Jack He | a355e5e | 2017-08-22 16:06:54 -0700 | [diff] [blame] | 250 | public static final int PERIPHERAL_KEYBOARD = 0x0540; |
Jaikumar Ganesh | c88b0c6 | 2011-01-05 13:49:00 -0800 | [diff] [blame] | 251 | /** |
| 252 | * @hide |
| 253 | */ |
Jack He | a355e5e | 2017-08-22 16:06:54 -0700 | [diff] [blame] | 254 | public static final int PERIPHERAL_POINTING = 0x0580; |
Jaikumar Ganesh | c88b0c6 | 2011-01-05 13:49:00 -0800 | [diff] [blame] | 255 | /** |
| 256 | * @hide |
| 257 | */ |
Jack He | a355e5e | 2017-08-22 16:06:54 -0700 | [diff] [blame] | 258 | public static final int PERIPHERAL_KEYBOARD_POINTING = 0x05C0; |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 259 | } |
Yue Lixin | a4433af | 2009-07-09 16:56:43 +0800 | [diff] [blame] | 260 | |
| 261 | /** |
Scott Main | 9fab0ae | 2009-11-03 18:17:59 -0800 | [diff] [blame] | 262 | * Return the major device class component of this {@link BluetoothClass}. |
Nick Pelly | 005b228 | 2009-09-10 10:21:56 -0700 | [diff] [blame] | 263 | * <p>Values returned from this function can be compared with the |
| 264 | * public constants in {@link BluetoothClass.Device.Major} to determine |
| 265 | * which major class is encoded in this Bluetooth class. |
| 266 | * |
| 267 | * @return major device class component |
| 268 | */ |
| 269 | public int getMajorDeviceClass() { |
| 270 | return (mClass & Device.Major.BITMASK); |
| 271 | } |
| 272 | |
| 273 | /** |
| 274 | * Return the (major and minor) device class component of this |
| 275 | * {@link BluetoothClass}. |
| 276 | * <p>Values returned from this function can be compared with the |
| 277 | * public constants in {@link BluetoothClass.Device} to determine which |
| 278 | * device class is encoded in this Bluetooth class. |
| 279 | * |
| 280 | * @return device class component |
| 281 | */ |
| 282 | public int getDeviceClass() { |
| 283 | return (mClass & Device.BITMASK); |
| 284 | } |
| 285 | |
Pulkit Bhuwalka | 66d6123 | 2017-08-16 21:52:04 -0700 | [diff] [blame] | 286 | /** |
| 287 | * Return the Bluetooth Class of Device (CoD) value including the |
| 288 | * {@link BluetoothClass.Service}, {@link BluetoothClass.Device.Major} and |
| 289 | * minor device fields. |
| 290 | * |
| 291 | * <p>This value is an integer representation of Bluetooth CoD as in |
| 292 | * Bluetooth specification. |
| 293 | * |
| 294 | * @see <a href="Bluetooth CoD">https://www.bluetooth.com/specifications/assigned-numbers/baseband</a> |
| 295 | * |
| 296 | * @hide |
| 297 | */ |
Ralph Nathan | 29335fd | 2018-07-23 09:35:18 -0700 | [diff] [blame] | 298 | @TestApi |
Pulkit Bhuwalka | 66d6123 | 2017-08-16 21:52:04 -0700 | [diff] [blame] | 299 | public int getClassOfDevice() { |
| 300 | return mClass; |
| 301 | } |
| 302 | |
| 303 | /** |
| 304 | * Return the Bluetooth Class of Device (CoD) value including the |
| 305 | * {@link BluetoothClass.Service}, {@link BluetoothClass.Device.Major} and |
| 306 | * minor device fields. |
| 307 | * |
| 308 | * <p>This value is a byte array representation of Bluetooth CoD as in |
| 309 | * Bluetooth specification. |
| 310 | * |
| 311 | * <p>Bluetooth COD information is 3 bytes, but stored as an int. Hence the |
| 312 | * MSB is useless and needs to be thrown away. The lower 3 bytes are |
| 313 | * converted into a byte array MSB to LSB. Hence, using BIG_ENDIAN. |
| 314 | * |
| 315 | * @see <a href="Bluetooth CoD">https://www.bluetooth.com/specifications/assigned-numbers/baseband</a> |
| 316 | * |
| 317 | * @hide |
| 318 | */ |
| 319 | public byte[] getClassOfDeviceBytes() { |
| 320 | byte[] bytes = ByteBuffer.allocate(4) |
| 321 | .order(ByteOrder.BIG_ENDIAN) |
| 322 | .putInt(mClass) |
| 323 | .array(); |
| 324 | |
| 325 | // Discard the top byte |
| 326 | return Arrays.copyOfRange(bytes, 1, bytes.length); |
| 327 | } |
| 328 | |
Nick Pelly | 005b228 | 2009-09-10 10:21:56 -0700 | [diff] [blame] | 329 | /** @hide */ |
Mathew Inwood | 4dc66d3 | 2018-08-01 15:07:20 +0100 | [diff] [blame] | 330 | @UnsupportedAppUsage |
Nick Pelly | 005b228 | 2009-09-10 10:21:56 -0700 | [diff] [blame] | 331 | public static final int PROFILE_HEADSET = 0; |
| 332 | /** @hide */ |
Mathew Inwood | 4dc66d3 | 2018-08-01 15:07:20 +0100 | [diff] [blame] | 333 | @UnsupportedAppUsage |
Nick Pelly | 005b228 | 2009-09-10 10:21:56 -0700 | [diff] [blame] | 334 | public static final int PROFILE_A2DP = 1; |
| 335 | /** @hide */ |
| 336 | public static final int PROFILE_OPP = 2; |
Adam Powell | df7627d | 2010-06-21 16:23:42 -0700 | [diff] [blame] | 337 | /** @hide */ |
| 338 | public static final int PROFILE_HID = 3; |
Jaikumar Ganesh | 3320580 | 2010-08-23 11:49:36 -0700 | [diff] [blame] | 339 | /** @hide */ |
| 340 | public static final int PROFILE_PANU = 4; |
| 341 | /** @hide */ |
| 342 | public static final int PROFILE_NAP = 5; |
Sanket Agarwal | 1bec6a5 | 2015-10-21 18:23:27 -0700 | [diff] [blame] | 343 | /** @hide */ |
| 344 | public static final int PROFILE_A2DP_SINK = 6; |
Nick Pelly | 005b228 | 2009-09-10 10:21:56 -0700 | [diff] [blame] | 345 | |
| 346 | /** |
Yue Lixin | a4433af | 2009-07-09 16:56:43 +0800 | [diff] [blame] | 347 | * Check class bits for possible bluetooth profile support. |
| 348 | * This is a simple heuristic that tries to guess if a device with the |
| 349 | * given class bits might support specified profile. It is not accurate for all |
| 350 | * devices. It tries to err on the side of false positives. |
Jack He | a355e5e | 2017-08-22 16:06:54 -0700 | [diff] [blame] | 351 | * |
Yue Lixin | a4433af | 2009-07-09 16:56:43 +0800 | [diff] [blame] | 352 | * @param profile The profile to be checked |
| 353 | * @return True if this device might support specified profile. |
Nick Pelly | 005b228 | 2009-09-10 10:21:56 -0700 | [diff] [blame] | 354 | * @hide |
Yue Lixin | a4433af | 2009-07-09 16:56:43 +0800 | [diff] [blame] | 355 | */ |
Mathew Inwood | 4dc66d3 | 2018-08-01 15:07:20 +0100 | [diff] [blame] | 356 | @UnsupportedAppUsage |
Nick Pelly | 005b228 | 2009-09-10 10:21:56 -0700 | [diff] [blame] | 357 | public boolean doesClassMatch(int profile) { |
Yue Lixin | a4433af | 2009-07-09 16:56:43 +0800 | [diff] [blame] | 358 | if (profile == PROFILE_A2DP) { |
Nick Pelly | 005b228 | 2009-09-10 10:21:56 -0700 | [diff] [blame] | 359 | if (hasService(Service.RENDER)) { |
Yue Lixin | a4433af | 2009-07-09 16:56:43 +0800 | [diff] [blame] | 360 | return true; |
| 361 | } |
| 362 | // By the A2DP spec, sinks must indicate the RENDER service. |
| 363 | // However we found some that do not (Chordette). So lets also |
| 364 | // match on some other class bits. |
Nick Pelly | 005b228 | 2009-09-10 10:21:56 -0700 | [diff] [blame] | 365 | switch (getDeviceClass()) { |
| 366 | case Device.AUDIO_VIDEO_HIFI_AUDIO: |
| 367 | case Device.AUDIO_VIDEO_HEADPHONES: |
| 368 | case Device.AUDIO_VIDEO_LOUDSPEAKER: |
| 369 | case Device.AUDIO_VIDEO_CAR_AUDIO: |
Yue Lixin | a4433af | 2009-07-09 16:56:43 +0800 | [diff] [blame] | 370 | return true; |
| 371 | default: |
| 372 | return false; |
| 373 | } |
Sanket Agarwal | 1bec6a5 | 2015-10-21 18:23:27 -0700 | [diff] [blame] | 374 | } else if (profile == PROFILE_A2DP_SINK) { |
| 375 | if (hasService(Service.CAPTURE)) { |
| 376 | return true; |
| 377 | } |
| 378 | // By the A2DP spec, srcs must indicate the CAPTURE service. |
| 379 | // However if some device that do not, we try to |
| 380 | // match on some other class bits. |
| 381 | switch (getDeviceClass()) { |
| 382 | case Device.AUDIO_VIDEO_HIFI_AUDIO: |
| 383 | case Device.AUDIO_VIDEO_SET_TOP_BOX: |
Jack He | a355e5e | 2017-08-22 16:06:54 -0700 | [diff] [blame] | 384 | case Device.AUDIO_VIDEO_VCR: |
Sanket Agarwal | 1bec6a5 | 2015-10-21 18:23:27 -0700 | [diff] [blame] | 385 | return true; |
| 386 | default: |
| 387 | return false; |
| 388 | } |
Yue Lixin | a4433af | 2009-07-09 16:56:43 +0800 | [diff] [blame] | 389 | } else if (profile == PROFILE_HEADSET) { |
| 390 | // The render service class is required by the spec for HFP, so is a |
| 391 | // pretty good signal |
Nick Pelly | 005b228 | 2009-09-10 10:21:56 -0700 | [diff] [blame] | 392 | if (hasService(Service.RENDER)) { |
Yue Lixin | a4433af | 2009-07-09 16:56:43 +0800 | [diff] [blame] | 393 | return true; |
| 394 | } |
| 395 | // Just in case they forgot the render service class |
Nick Pelly | 005b228 | 2009-09-10 10:21:56 -0700 | [diff] [blame] | 396 | switch (getDeviceClass()) { |
| 397 | case Device.AUDIO_VIDEO_HANDSFREE: |
| 398 | case Device.AUDIO_VIDEO_WEARABLE_HEADSET: |
| 399 | case Device.AUDIO_VIDEO_CAR_AUDIO: |
Yue Lixin | a4433af | 2009-07-09 16:56:43 +0800 | [diff] [blame] | 400 | return true; |
| 401 | default: |
| 402 | return false; |
| 403 | } |
| 404 | } else if (profile == PROFILE_OPP) { |
Nick Pelly | 005b228 | 2009-09-10 10:21:56 -0700 | [diff] [blame] | 405 | if (hasService(Service.OBJECT_TRANSFER)) { |
Yue Lixin | a4433af | 2009-07-09 16:56:43 +0800 | [diff] [blame] | 406 | return true; |
| 407 | } |
| 408 | |
Nick Pelly | 005b228 | 2009-09-10 10:21:56 -0700 | [diff] [blame] | 409 | switch (getDeviceClass()) { |
| 410 | case Device.COMPUTER_UNCATEGORIZED: |
| 411 | case Device.COMPUTER_DESKTOP: |
| 412 | case Device.COMPUTER_SERVER: |
| 413 | case Device.COMPUTER_LAPTOP: |
| 414 | case Device.COMPUTER_HANDHELD_PC_PDA: |
| 415 | case Device.COMPUTER_PALM_SIZE_PC_PDA: |
| 416 | case Device.COMPUTER_WEARABLE: |
| 417 | case Device.PHONE_UNCATEGORIZED: |
| 418 | case Device.PHONE_CELLULAR: |
| 419 | case Device.PHONE_CORDLESS: |
| 420 | case Device.PHONE_SMART: |
| 421 | case Device.PHONE_MODEM_OR_GATEWAY: |
| 422 | case Device.PHONE_ISDN: |
Yue Lixin | a4433af | 2009-07-09 16:56:43 +0800 | [diff] [blame] | 423 | return true; |
| 424 | default: |
| 425 | return false; |
| 426 | } |
Adam Powell | df7627d | 2010-06-21 16:23:42 -0700 | [diff] [blame] | 427 | } else if (profile == PROFILE_HID) { |
| 428 | return (getDeviceClass() & Device.Major.PERIPHERAL) == Device.Major.PERIPHERAL; |
Jack He | a355e5e | 2017-08-22 16:06:54 -0700 | [diff] [blame] | 429 | } else if (profile == PROFILE_PANU || profile == PROFILE_NAP) { |
Jaikumar Ganesh | 3320580 | 2010-08-23 11:49:36 -0700 | [diff] [blame] | 430 | // No good way to distinguish between the two, based on class bits. |
| 431 | if (hasService(Service.NETWORKING)) { |
| 432 | return true; |
| 433 | } |
| 434 | return (getDeviceClass() & Device.Major.NETWORKING) == Device.Major.NETWORKING; |
Yue Lixin | a4433af | 2009-07-09 16:56:43 +0800 | [diff] [blame] | 435 | } else { |
| 436 | return false; |
| 437 | } |
| 438 | } |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 439 | } |