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