blob: e604e6becc9bfa7e8d3f3121ab3c5f81a7595bbe [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001/*
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
17package android.bluetooth;
18
Nick Pelly005b2282009-09-10 10:21:56 -070019import android.os.Parcel;
20import android.os.Parcelable;
21
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080022/**
Scott Main9fab0ae2009-11-03 18:17:59 -080023 * Represents a Bluetooth class, which describes general characteristics
24 * and capabilities of a device. For example, a Bluetooth class will
25 * specify the general device type such as a phone, a computer, or
26 * headset, and whether it's capable of services such as audio or telephony.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080027 *
Scott Main9fab0ae2009-11-03 18:17:59 -080028 * <p>Every Bluetooth class is composed of zero or more service classes, and
Nick Pelly005b2282009-09-10 10:21:56 -070029 * exactly one device class. The device class is further broken down into major
30 * and minor device class components.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080031 *
Scott Main9fab0ae2009-11-03 18:17:59 -080032 * <p>{@link BluetoothClass} is useful as a hint to roughly describe a device
33 * (for example to show an icon in the UI), but does not reliably describe which
34 * Bluetooth profiles or services are actually supported by a device. Accurate
35 * service discovery is done through SDP requests, which are automatically
36 * performed when creating an RFCOMM socket with {@link
Jake Hambyf51eada2010-09-21 13:39:53 -070037 * BluetoothDevice#createRfcommSocketToServiceRecord} and {@link
38 * BluetoothAdapter#listenUsingRfcommWithServiceRecord}</p>
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080039 *
Nick Pelly005b2282009-09-10 10:21:56 -070040 * <p>Use {@link BluetoothDevice#getBluetoothClass} to retrieve the class for
41 * a remote device.
Scott Main9fab0ae2009-11-03 18:17:59 -080042 *
43 * <!--
44 * The Bluetooth class is a 32 bit field. The format of these bits is defined at
45 * http://www.bluetooth.org/Technical/AssignedNumbers/baseband.htm
46 * (login required). This class contains that 32 bit field, and provides
47 * constants and methods to determine which Service Class(es) and Device Class
48 * are encoded in that field.
49 * -->
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080050 */
Nick Pelly005b2282009-09-10 10:21:56 -070051public final class BluetoothClass implements Parcelable {
52 /**
53 * Legacy error value. Applications should use null instead.
54 * @hide
55 */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080056 public static final int ERROR = 0xFF000000;
57
Nick Pelly005b2282009-09-10 10:21:56 -070058 private final int mClass;
Yue Lixina4433af2009-07-09 16:56:43 +080059
Nick Pelly005b2282009-09-10 10:21:56 -070060 /** @hide */
61 public BluetoothClass(int classInt) {
62 mClass = classInt;
63 }
64
65 @Override
66 public boolean equals(Object o) {
67 if (o instanceof BluetoothClass) {
68 return mClass == ((BluetoothClass)o).mClass;
69 }
70 return false;
71 }
72
73 @Override
74 public int hashCode() {
75 return mClass;
76 }
77
78 @Override
79 public String toString() {
80 return Integer.toHexString(mClass);
81 }
82
Nick Pelly005b2282009-09-10 10:21:56 -070083 public int describeContents() {
84 return 0;
85 }
86
Nick Pelly005b2282009-09-10 10:21:56 -070087 public static final Parcelable.Creator<BluetoothClass> CREATOR =
88 new Parcelable.Creator<BluetoothClass>() {
89 public BluetoothClass createFromParcel(Parcel in) {
90 return new BluetoothClass(in.readInt());
91 }
92 public BluetoothClass[] newArray(int size) {
93 return new BluetoothClass[size];
94 }
95 };
96
Nick Pelly005b2282009-09-10 10:21:56 -070097 public void writeToParcel(Parcel out, int flags) {
98 out.writeInt(mClass);
99 }
100
101 /**
Scott Main9fab0ae2009-11-03 18:17:59 -0800102 * Defines all service class constants.
Nick Pelly005b2282009-09-10 10:21:56 -0700103 * <p>Each {@link BluetoothClass} encodes zero or more service classes.
104 */
105 public static final class Service {
106 private static final int BITMASK = 0xFFE000;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800107
108 public static final int LIMITED_DISCOVERABILITY = 0x002000;
109 public static final int POSITIONING = 0x010000;
110 public static final int NETWORKING = 0x020000;
111 public static final int RENDER = 0x040000;
112 public static final int CAPTURE = 0x080000;
113 public static final int OBJECT_TRANSFER = 0x100000;
114 public static final int AUDIO = 0x200000;
115 public static final int TELEPHONY = 0x400000;
116 public static final int INFORMATION = 0x800000;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800117 }
118
Nick Pelly005b2282009-09-10 10:21:56 -0700119 /**
Scott Main9fab0ae2009-11-03 18:17:59 -0800120 * Return true if the specified service class is supported by this
121 * {@link BluetoothClass}.
Nick Pelly005b2282009-09-10 10:21:56 -0700122 * <p>Valid service classes are the public constants in
123 * {@link BluetoothClass.Service}. For example, {@link
124 * BluetoothClass.Service#AUDIO}.
125 *
126 * @param service valid service class
127 * @return true if the service class is supported
128 */
129 public boolean hasService(int service) {
130 return ((mClass & Service.BITMASK & service) != 0);
131 }
132
133 /**
Scott Main9fab0ae2009-11-03 18:17:59 -0800134 * Defines all device class constants.
Nick Pelly005b2282009-09-10 10:21:56 -0700135 * <p>Each {@link BluetoothClass} encodes exactly one device class, with
136 * major and minor components.
137 * <p>The constants in {@link
138 * BluetoothClass.Device} represent a combination of major and minor
Scott Main9fab0ae2009-11-03 18:17:59 -0800139 * device components (the complete device class). The constants in {@link
140 * BluetoothClass.Device.Major} represent only major device classes.
141 * <p>See {@link BluetoothClass.Service} for service class constants.
Nick Pelly005b2282009-09-10 10:21:56 -0700142 */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800143 public static class Device {
Nick Pelly005b2282009-09-10 10:21:56 -0700144 private static final int BITMASK = 0x1FFC;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800145
Scott Main9fab0ae2009-11-03 18:17:59 -0800146 /**
147 * Defines all major device class constants.
148 * <p>See {@link BluetoothClass.Device} for minor classes.
149 */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800150 public static class Major {
Nick Pelly005b2282009-09-10 10:21:56 -0700151 private static final int BITMASK = 0x1F00;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800152
153 public static final int MISC = 0x0000;
154 public static final int COMPUTER = 0x0100;
155 public static final int PHONE = 0x0200;
156 public static final int NETWORKING = 0x0300;
157 public static final int AUDIO_VIDEO = 0x0400;
158 public static final int PERIPHERAL = 0x0500;
159 public static final int IMAGING = 0x0600;
160 public static final int WEARABLE = 0x0700;
161 public static final int TOY = 0x0800;
162 public static final int HEALTH = 0x0900;
163 public static final int UNCATEGORIZED = 0x1F00;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800164 }
165
166 // Devices in the COMPUTER major class
167 public static final int COMPUTER_UNCATEGORIZED = 0x0100;
168 public static final int COMPUTER_DESKTOP = 0x0104;
169 public static final int COMPUTER_SERVER = 0x0108;
170 public static final int COMPUTER_LAPTOP = 0x010C;
171 public static final int COMPUTER_HANDHELD_PC_PDA = 0x0110;
172 public static final int COMPUTER_PALM_SIZE_PC_PDA = 0x0114;
173 public static final int COMPUTER_WEARABLE = 0x0118;
174
175 // Devices in the PHONE major class
176 public static final int PHONE_UNCATEGORIZED = 0x0200;
177 public static final int PHONE_CELLULAR = 0x0204;
178 public static final int PHONE_CORDLESS = 0x0208;
179 public static final int PHONE_SMART = 0x020C;
180 public static final int PHONE_MODEM_OR_GATEWAY = 0x0210;
181 public static final int PHONE_ISDN = 0x0214;
182
183 // Minor classes for the AUDIO_VIDEO major class
184 public static final int AUDIO_VIDEO_UNCATEGORIZED = 0x0400;
185 public static final int AUDIO_VIDEO_WEARABLE_HEADSET = 0x0404;
186 public static final int AUDIO_VIDEO_HANDSFREE = 0x0408;
187 //public static final int AUDIO_VIDEO_RESERVED = 0x040C;
188 public static final int AUDIO_VIDEO_MICROPHONE = 0x0410;
189 public static final int AUDIO_VIDEO_LOUDSPEAKER = 0x0414;
190 public static final int AUDIO_VIDEO_HEADPHONES = 0x0418;
191 public static final int AUDIO_VIDEO_PORTABLE_AUDIO = 0x041C;
192 public static final int AUDIO_VIDEO_CAR_AUDIO = 0x0420;
193 public static final int AUDIO_VIDEO_SET_TOP_BOX = 0x0424;
194 public static final int AUDIO_VIDEO_HIFI_AUDIO = 0x0428;
195 public static final int AUDIO_VIDEO_VCR = 0x042C;
196 public static final int AUDIO_VIDEO_VIDEO_CAMERA = 0x0430;
197 public static final int AUDIO_VIDEO_CAMCORDER = 0x0434;
198 public static final int AUDIO_VIDEO_VIDEO_MONITOR = 0x0438;
199 public static final int AUDIO_VIDEO_VIDEO_DISPLAY_AND_LOUDSPEAKER = 0x043C;
200 public static final int AUDIO_VIDEO_VIDEO_CONFERENCING = 0x0440;
201 //public static final int AUDIO_VIDEO_RESERVED = 0x0444;
202 public static final int AUDIO_VIDEO_VIDEO_GAMING_TOY = 0x0448;
203
204 // Devices in the WEARABLE major class
205 public static final int WEARABLE_UNCATEGORIZED = 0x0700;
206 public static final int WEARABLE_WRIST_WATCH = 0x0704;
207 public static final int WEARABLE_PAGER = 0x0708;
208 public static final int WEARABLE_JACKET = 0x070C;
209 public static final int WEARABLE_HELMET = 0x0710;
210 public static final int WEARABLE_GLASSES = 0x0714;
211
212 // Devices in the TOY major class
213 public static final int TOY_UNCATEGORIZED = 0x0800;
214 public static final int TOY_ROBOT = 0x0804;
215 public static final int TOY_VEHICLE = 0x0808;
216 public static final int TOY_DOLL_ACTION_FIGURE = 0x080C;
217 public static final int TOY_CONTROLLER = 0x0810;
218 public static final int TOY_GAME = 0x0814;
219
220 // Devices in the HEALTH major class
221 public static final int HEALTH_UNCATEGORIZED = 0x0900;
222 public static final int HEALTH_BLOOD_PRESSURE = 0x0904;
223 public static final int HEALTH_THERMOMETER = 0x0908;
224 public static final int HEALTH_WEIGHING = 0x090C;
225 public static final int HEALTH_GLUCOSE = 0x0910;
226 public static final int HEALTH_PULSE_OXIMETER = 0x0914;
227 public static final int HEALTH_PULSE_RATE = 0x0918;
228 public static final int HEALTH_DATA_DISPLAY = 0x091C;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800229 }
Yue Lixina4433af2009-07-09 16:56:43 +0800230
231 /**
Scott Main9fab0ae2009-11-03 18:17:59 -0800232 * Return the major device class component of this {@link BluetoothClass}.
Nick Pelly005b2282009-09-10 10:21:56 -0700233 * <p>Values returned from this function can be compared with the
234 * public constants in {@link BluetoothClass.Device.Major} to determine
235 * which major class is encoded in this Bluetooth class.
236 *
237 * @return major device class component
238 */
239 public int getMajorDeviceClass() {
240 return (mClass & Device.Major.BITMASK);
241 }
242
243 /**
244 * Return the (major and minor) device class component of this
245 * {@link BluetoothClass}.
246 * <p>Values returned from this function can be compared with the
247 * public constants in {@link BluetoothClass.Device} to determine which
248 * device class is encoded in this Bluetooth class.
249 *
250 * @return device class component
251 */
252 public int getDeviceClass() {
253 return (mClass & Device.BITMASK);
254 }
255
256 /** @hide */
257 public static final int PROFILE_HEADSET = 0;
258 /** @hide */
259 public static final int PROFILE_A2DP = 1;
260 /** @hide */
261 public static final int PROFILE_OPP = 2;
Adam Powelldf7627d2010-06-21 16:23:42 -0700262 /** @hide */
263 public static final int PROFILE_HID = 3;
Jaikumar Ganesh33205802010-08-23 11:49:36 -0700264 /** @hide */
265 public static final int PROFILE_PANU = 4;
266 /** @hide */
267 public static final int PROFILE_NAP = 5;
Nick Pelly005b2282009-09-10 10:21:56 -0700268
269 /**
Yue Lixina4433af2009-07-09 16:56:43 +0800270 * Check class bits for possible bluetooth profile support.
271 * This is a simple heuristic that tries to guess if a device with the
272 * given class bits might support specified profile. It is not accurate for all
273 * devices. It tries to err on the side of false positives.
Yue Lixina4433af2009-07-09 16:56:43 +0800274 * @param profile The profile to be checked
275 * @return True if this device might support specified profile.
Nick Pelly005b2282009-09-10 10:21:56 -0700276 * @hide
Yue Lixina4433af2009-07-09 16:56:43 +0800277 */
Nick Pelly005b2282009-09-10 10:21:56 -0700278 public boolean doesClassMatch(int profile) {
Yue Lixina4433af2009-07-09 16:56:43 +0800279 if (profile == PROFILE_A2DP) {
Nick Pelly005b2282009-09-10 10:21:56 -0700280 if (hasService(Service.RENDER)) {
Yue Lixina4433af2009-07-09 16:56:43 +0800281 return true;
282 }
283 // By the A2DP spec, sinks must indicate the RENDER service.
284 // However we found some that do not (Chordette). So lets also
285 // match on some other class bits.
Nick Pelly005b2282009-09-10 10:21:56 -0700286 switch (getDeviceClass()) {
287 case Device.AUDIO_VIDEO_HIFI_AUDIO:
288 case Device.AUDIO_VIDEO_HEADPHONES:
289 case Device.AUDIO_VIDEO_LOUDSPEAKER:
290 case Device.AUDIO_VIDEO_CAR_AUDIO:
Yue Lixina4433af2009-07-09 16:56:43 +0800291 return true;
292 default:
293 return false;
294 }
295 } else if (profile == PROFILE_HEADSET) {
296 // The render service class is required by the spec for HFP, so is a
297 // pretty good signal
Nick Pelly005b2282009-09-10 10:21:56 -0700298 if (hasService(Service.RENDER)) {
Yue Lixina4433af2009-07-09 16:56:43 +0800299 return true;
300 }
301 // Just in case they forgot the render service class
Nick Pelly005b2282009-09-10 10:21:56 -0700302 switch (getDeviceClass()) {
303 case Device.AUDIO_VIDEO_HANDSFREE:
304 case Device.AUDIO_VIDEO_WEARABLE_HEADSET:
305 case Device.AUDIO_VIDEO_CAR_AUDIO:
Yue Lixina4433af2009-07-09 16:56:43 +0800306 return true;
307 default:
308 return false;
309 }
310 } else if (profile == PROFILE_OPP) {
Nick Pelly005b2282009-09-10 10:21:56 -0700311 if (hasService(Service.OBJECT_TRANSFER)) {
Yue Lixina4433af2009-07-09 16:56:43 +0800312 return true;
313 }
314
Nick Pelly005b2282009-09-10 10:21:56 -0700315 switch (getDeviceClass()) {
316 case Device.COMPUTER_UNCATEGORIZED:
317 case Device.COMPUTER_DESKTOP:
318 case Device.COMPUTER_SERVER:
319 case Device.COMPUTER_LAPTOP:
320 case Device.COMPUTER_HANDHELD_PC_PDA:
321 case Device.COMPUTER_PALM_SIZE_PC_PDA:
322 case Device.COMPUTER_WEARABLE:
323 case Device.PHONE_UNCATEGORIZED:
324 case Device.PHONE_CELLULAR:
325 case Device.PHONE_CORDLESS:
326 case Device.PHONE_SMART:
327 case Device.PHONE_MODEM_OR_GATEWAY:
328 case Device.PHONE_ISDN:
Yue Lixina4433af2009-07-09 16:56:43 +0800329 return true;
330 default:
331 return false;
332 }
Adam Powelldf7627d2010-06-21 16:23:42 -0700333 } else if (profile == PROFILE_HID) {
334 return (getDeviceClass() & Device.Major.PERIPHERAL) == Device.Major.PERIPHERAL;
Jaikumar Ganesh33205802010-08-23 11:49:36 -0700335 } else if (profile == PROFILE_PANU || profile == PROFILE_NAP){
336 // No good way to distinguish between the two, based on class bits.
337 if (hasService(Service.NETWORKING)) {
338 return true;
339 }
340 return (getDeviceClass() & Device.Major.NETWORKING) == Device.Major.NETWORKING;
Yue Lixina4433af2009-07-09 16:56:43 +0800341 } else {
342 return false;
343 }
344 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800345}