blob: c64fdbe396da0cfdbdf275d0d1a4b66213047a48 [file] [log] [blame]
The Android Open Source Project33897762009-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 Pellydac4c0d2009-09-10 10:21:56 -070019import android.annotation.SdkConstant;
20import android.annotation.SdkConstant.SdkConstantType;
The Android Open Source Project33897762009-03-03 19:31:44 -080021import android.content.ComponentName;
22import android.content.Context;
23import android.content.Intent;
24import android.content.ServiceConnection;
The Android Open Source Project33897762009-03-03 19:31:44 -080025import android.os.IBinder;
Jaikumar Ganeshd8fc4dd2010-10-18 16:41:53 -070026import android.os.RemoteException;
The Android Open Source Project33897762009-03-03 19:31:44 -080027import android.util.Log;
28
Jaikumar Ganeshd8fc4dd2010-10-18 16:41:53 -070029import java.util.ArrayList;
30import java.util.List;
Jaikumar Ganesh2af07762010-08-24 17:36:13 -070031
The Android Open Source Project33897762009-03-03 19:31:44 -080032/**
The Android Open Source Project33897762009-03-03 19:31:44 -080033 * Public API for controlling the Bluetooth Headset Service. This includes both
Jaikumar Ganesh2af07762010-08-24 17:36:13 -070034 * Bluetooth Headset and Handsfree (v1.5) profiles.
The Android Open Source Project33897762009-03-03 19:31:44 -080035 *
Jaikumar Ganesh2af07762010-08-24 17:36:13 -070036 * <p>BluetoothHeadset is a proxy object for controlling the Bluetooth Headset
The Android Open Source Project33897762009-03-03 19:31:44 -080037 * Service via IPC.
38 *
Jaikumar Ganesh2af07762010-08-24 17:36:13 -070039 * <p> Use {@link BluetoothAdapter#getProfileProxy} to get
40 * the BluetoothHeadset proxy object. Use
41 * {@link BluetoothAdapter#closeProfileProxy} to close the service connection.
The Android Open Source Project33897762009-03-03 19:31:44 -080042 *
Jaikumar Ganesh2af07762010-08-24 17:36:13 -070043 * <p> Android only supports one connected Bluetooth Headset at a time.
44 * Each method is protected with its appropriate permission.
The Android Open Source Project33897762009-03-03 19:31:44 -080045 */
Jaikumar Ganesh2af07762010-08-24 17:36:13 -070046public final class BluetoothHeadset implements BluetoothProfile {
The Android Open Source Project33897762009-03-03 19:31:44 -080047 private static final String TAG = "BluetoothHeadset";
48 private static final boolean DBG = false;
49
Nick Pellydac4c0d2009-09-10 10:21:56 -070050 /**
Jaikumar Ganesh2af07762010-08-24 17:36:13 -070051 * Intent used to broadcast the change in connection state of the Headset
52 * profile.
53 *
54 * <p>This intent will have 3 extras:
55 * {@link #EXTRA_STATE} - The current state of the profile.
56 * {@link #EXTRA_PREVIOUS_STATE}- The previous state of the profile
57 * {@link BluetoothDevice#EXTRA_DEVICE} - The remote device.
58 *
59 * {@link #EXTRA_STATE} or {@link #EXTRA_PREVIOUS_STATE} can be any of
60 * {@link #STATE_DISCONNECTED}, {@link #STATE_CONNECTING},
61 * {@link #STATE_CONNECTED}, {@link #STATE_DISCONNECTING}.
62 *
63 * <p>Requires {@link android.Manifest.permission#BLUETOOTH} to receive.
64 */
65 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
66 public static final String ACTION_CONNECTION_STATE_CHANGED =
67 "android.bluetooth.headset.profile.action.CONNECTION_STATE_CHANGED";
68
69 /**
70 * Intent used to broadcast the change in the Audio Connection state of the
71 * A2DP profile.
72 *
73 * <p>This intent will have 3 extras:
74 * {@link #EXTRA_STATE} - The current state of the profile.
75 * {@link #EXTRA_PREVIOUS_STATE}- The previous state of the profile
76 * {@link BluetoothDevice#EXTRA_DEVICE} - The remote device.
77 *
78 * {@link #EXTRA_STATE} or {@link #EXTRA_PREVIOUS_STATE} can be any of
79 * {@link #STATE_AUDIO_CONNECTED}, {@link #STATE_AUDIO_DISCONNECTED},
80 *
81 * <p>Requires {@link android.Manifest.permission#BLUETOOTH} to receive.
Nick Pellydac4c0d2009-09-10 10:21:56 -070082 */
83 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
84 public static final String ACTION_AUDIO_STATE_CHANGED =
Jaikumar Ganesh2af07762010-08-24 17:36:13 -070085 "android.bluetooth.headset.profile.action.AUDIO_STATE_CHANGED";
Nick Pellydac4c0d2009-09-10 10:21:56 -070086
Jaikumar Ganeshf48cda52010-04-02 14:44:43 -070087
Nick Pellydac4c0d2009-09-10 10:21:56 -070088 /**
Herb Jellinekaad41c52010-08-10 13:17:43 -070089 * Broadcast Action: Indicates a headset has posted a vendor-specific event.
90 * <p>Always contains the extra fields {@link #EXTRA_DEVICE},
91 * {@link #EXTRA_VENDOR_SPECIFIC_HEADSET_EVENT_CMD}, and
92 * {@link #EXTRA_VENDOR_SPECIFIC_HEADSET_EVENT_ARGS}.
93 * <p>Requires {@link android.Manifest.permission#BLUETOOTH} to receive.
Jaikumar Ganesh3eda0c42010-08-26 16:03:40 -070094 * @hide
Herb Jellinekaad41c52010-08-10 13:17:43 -070095 */
96 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
97 public static final String ACTION_VENDOR_SPECIFIC_HEADSET_EVENT =
98 "android.bluetooth.headset.action.VENDOR_SPECIFIC_HEADSET_EVENT";
99
100 /**
101 * A String extra field in {@link #ACTION_VENDOR_SPECIFIC_HEADSET_EVENT}
102 * intents that contains the name of the vendor-specific command.
Jaikumar Ganesh3eda0c42010-08-26 16:03:40 -0700103 * @hide
Herb Jellinekaad41c52010-08-10 13:17:43 -0700104 */
105 public static final String EXTRA_VENDOR_SPECIFIC_HEADSET_EVENT_CMD =
106 "android.bluetooth.headset.extra.VENDOR_SPECIFIC_HEADSET_EVENT_CMD";
107
108 /**
109 * An int extra field in {@link #ACTION_VENDOR_SPECIFIC_HEADSET_EVENT}
110 * intents that contains the Company ID of the vendor defining the vendor-specific
111 * command.
112 * @see <a href="https://www.bluetooth.org/Technical/AssignedNumbers/identifiers.htm">
113 * Bluetooth SIG Assigned Numbers - Company Identifiers</a>
Jaikumar Ganesh3eda0c42010-08-26 16:03:40 -0700114 * @hide
Herb Jellinekaad41c52010-08-10 13:17:43 -0700115 */
116 public static final String EXTRA_VENDOR_SPECIFIC_HEADSET_EVENT_COMPANY_ID =
117 "android.bluetooth.headset.extra.VENDOR_SPECIFIC_HEADSET_EVENT_COMPANY_ID";
118
119 /**
120 * A Parcelable String array extra field in
121 * {@link #ACTION_VENDOR_SPECIFIC_HEADSET_EVENT} intents that contains
122 * the arguments to the vendor-specific command.
Jaikumar Ganesh3eda0c42010-08-26 16:03:40 -0700123 * @hide
Herb Jellinekaad41c52010-08-10 13:17:43 -0700124 */
125 public static final String EXTRA_VENDOR_SPECIFIC_HEADSET_EVENT_ARGS =
126 "android.bluetooth.headset.extra.VENDOR_SPECIFIC_HEADSET_EVENT_ARGS";
127
Jaikumar Ganesh2af07762010-08-24 17:36:13 -0700128 /*
129 * Headset state when SCO audio is connected
130 * This state can be one of
131 * {@link #EXTRA_STATE} or {@link #EXTRA_PREVIOUS_STATE} of
132 * {@link #ACTION_AUDIO_STATE_CHANGED} intent.
133 */
134 public static final int STATE_AUDIO_CONNECTED = 10;
Herb Jellinekaad41c52010-08-10 13:17:43 -0700135
136 /**
Jaikumar Ganesh2af07762010-08-24 17:36:13 -0700137 * Headset state when SCO audio is NOT connected
138 * This state can be one of
139 * {@link #EXTRA_STATE} or {@link #EXTRA_PREVIOUS_STATE} of
140 * {@link #ACTION_AUDIO_STATE_CHANGED} intent.
Nick Pellydac4c0d2009-09-10 10:21:56 -0700141 */
Jaikumar Ganesh2af07762010-08-24 17:36:13 -0700142 public static final int STATE_AUDIO_DISCONNECTED = 11;
143
144
145 private Context mContext;
146 private ServiceListener mServiceListener;
The Android Open Source Project33897762009-03-03 19:31:44 -0800147 private IBluetoothHeadset mService;
Jaikumar Ganesh2af07762010-08-24 17:36:13 -0700148 BluetoothAdapter mAdapter;
The Android Open Source Project33897762009-03-03 19:31:44 -0800149
150 /**
151 * Create a BluetoothHeadset proxy object.
152 */
Jaikumar Ganesh2af07762010-08-24 17:36:13 -0700153 /*package*/ BluetoothHeadset(Context context, ServiceListener l) {
The Android Open Source Project33897762009-03-03 19:31:44 -0800154 mContext = context;
155 mServiceListener = l;
Jaikumar Ganesh2af07762010-08-24 17:36:13 -0700156 mAdapter = BluetoothAdapter.getDefaultAdapter();
The Android Open Source Project33897762009-03-03 19:31:44 -0800157 if (!context.bindService(new Intent(IBluetoothHeadset.class.getName()), mConnection, 0)) {
158 Log.e(TAG, "Could not bind to Bluetooth Headset Service");
159 }
160 }
161
The Android Open Source Project33897762009-03-03 19:31:44 -0800162 /**
163 * Close the connection to the backing service.
164 * Other public functions of BluetoothHeadset will return default error
165 * results once close() has been called. Multiple invocations of close()
166 * are ok.
167 */
Jaikumar Ganesh2af07762010-08-24 17:36:13 -0700168 /*package*/ synchronized void close() {
The Android Open Source Project0047a0f2009-03-05 20:00:43 -0800169 if (DBG) log("close()");
The Android Open Source Project33897762009-03-03 19:31:44 -0800170 if (mConnection != null) {
171 mContext.unbindService(mConnection);
172 mConnection = null;
173 }
174 }
175
176 /**
Jaikumar Ganesh2af07762010-08-24 17:36:13 -0700177 * {@inheritDoc}
178 * @hide
The Android Open Source Project33897762009-03-03 19:31:44 -0800179 */
Jaikumar Ganesh2af07762010-08-24 17:36:13 -0700180 public boolean connect(BluetoothDevice device) {
181 if (DBG) log("connect(" + device + ")");
182 if (mService != null && isEnabled() &&
183 isValidDevice(device)) {
The Android Open Source Project33897762009-03-03 19:31:44 -0800184 try {
Jaikumar Ganesh2af07762010-08-24 17:36:13 -0700185 return mService.connect(device);
186 } catch (RemoteException e) {
187 Log.e(TAG, Log.getStackTraceString(new Throwable()));
188 return false;
189 }
The Android Open Source Project33897762009-03-03 19:31:44 -0800190 }
Jaikumar Ganesh2af07762010-08-24 17:36:13 -0700191 if (mService == null) Log.w(TAG, "Proxy not attached to service");
The Android Open Source Project33897762009-03-03 19:31:44 -0800192 return false;
193 }
194
195 /**
Jaikumar Ganesh2af07762010-08-24 17:36:13 -0700196 * {@inheritDoc}
197 * @hide
The Android Open Source Project33897762009-03-03 19:31:44 -0800198 */
Jaikumar Ganesh2af07762010-08-24 17:36:13 -0700199 public boolean disconnect(BluetoothDevice device) {
200 if (DBG) log("disconnect(" + device + ")");
201 if (mService != null && isEnabled() &&
202 isValidDevice(device)) {
The Android Open Source Project33897762009-03-03 19:31:44 -0800203 try {
Jaikumar Ganesh2af07762010-08-24 17:36:13 -0700204 return mService.disconnect(device);
205 } catch (RemoteException e) {
206 Log.e(TAG, Log.getStackTraceString(new Throwable()));
207 return false;
208 }
The Android Open Source Project33897762009-03-03 19:31:44 -0800209 }
Jaikumar Ganesh2af07762010-08-24 17:36:13 -0700210 if (mService == null) Log.w(TAG, "Proxy not attached to service");
The Android Open Source Project33897762009-03-03 19:31:44 -0800211 return false;
212 }
213
214 /**
Jaikumar Ganesh2af07762010-08-24 17:36:13 -0700215 * {@inheritDoc}
The Android Open Source Project33897762009-03-03 19:31:44 -0800216 */
Jaikumar Ganeshd8fc4dd2010-10-18 16:41:53 -0700217 public List<BluetoothDevice> getConnectedDevices() {
Jaikumar Ganesh2af07762010-08-24 17:36:13 -0700218 if (DBG) log("getConnectedDevices()");
219 if (mService != null && isEnabled()) {
The Android Open Source Project33897762009-03-03 19:31:44 -0800220 try {
Jaikumar Ganeshd8fc4dd2010-10-18 16:41:53 -0700221 return mService.getConnectedDevices();
Jaikumar Ganesh2af07762010-08-24 17:36:13 -0700222 } catch (RemoteException e) {
223 Log.e(TAG, Log.getStackTraceString(new Throwable()));
Jaikumar Ganeshd8fc4dd2010-10-18 16:41:53 -0700224 return new ArrayList<BluetoothDevice>();
Jaikumar Ganesh2af07762010-08-24 17:36:13 -0700225 }
The Android Open Source Project33897762009-03-03 19:31:44 -0800226 }
Jaikumar Ganesh2af07762010-08-24 17:36:13 -0700227 if (mService == null) Log.w(TAG, "Proxy not attached to service");
Jaikumar Ganeshd8fc4dd2010-10-18 16:41:53 -0700228 return new ArrayList<BluetoothDevice>();
The Android Open Source Project33897762009-03-03 19:31:44 -0800229 }
230
231 /**
Jaikumar Ganesh2af07762010-08-24 17:36:13 -0700232 * {@inheritDoc}
The Android Open Source Project33897762009-03-03 19:31:44 -0800233 */
Jaikumar Ganeshd8fc4dd2010-10-18 16:41:53 -0700234 public List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) {
Jaikumar Ganesh2af07762010-08-24 17:36:13 -0700235 if (DBG) log("getDevicesMatchingStates()");
236 if (mService != null && isEnabled()) {
The Android Open Source Project33897762009-03-03 19:31:44 -0800237 try {
Jaikumar Ganeshd8fc4dd2010-10-18 16:41:53 -0700238 return mService.getDevicesMatchingConnectionStates(states);
Jaikumar Ganesh2af07762010-08-24 17:36:13 -0700239 } catch (RemoteException e) {
240 Log.e(TAG, Log.getStackTraceString(new Throwable()));
Jaikumar Ganeshd8fc4dd2010-10-18 16:41:53 -0700241 return new ArrayList<BluetoothDevice>();
Jaikumar Ganesh2af07762010-08-24 17:36:13 -0700242 }
The Android Open Source Project33897762009-03-03 19:31:44 -0800243 }
Jaikumar Ganesh2af07762010-08-24 17:36:13 -0700244 if (mService == null) Log.w(TAG, "Proxy not attached to service");
Jaikumar Ganeshd8fc4dd2010-10-18 16:41:53 -0700245 return new ArrayList<BluetoothDevice>();
The Android Open Source Project33897762009-03-03 19:31:44 -0800246 }
247
248 /**
Jaikumar Ganesh2af07762010-08-24 17:36:13 -0700249 * {@inheritDoc}
The Android Open Source Project33897762009-03-03 19:31:44 -0800250 */
Jaikumar Ganesh2af07762010-08-24 17:36:13 -0700251 public int getConnectionState(BluetoothDevice device) {
252 if (DBG) log("getConnectionState(" + device + ")");
253 if (mService != null && isEnabled() &&
254 isValidDevice(device)) {
The Android Open Source Project33897762009-03-03 19:31:44 -0800255 try {
Jaikumar Ganesh2af07762010-08-24 17:36:13 -0700256 return mService.getConnectionState(device);
257 } catch (RemoteException e) {
258 Log.e(TAG, Log.getStackTraceString(new Throwable()));
259 return BluetoothProfile.STATE_DISCONNECTED;
260 }
The Android Open Source Project33897762009-03-03 19:31:44 -0800261 }
Jaikumar Ganesh2af07762010-08-24 17:36:13 -0700262 if (mService == null) Log.w(TAG, "Proxy not attached to service");
263 return BluetoothProfile.STATE_DISCONNECTED;
The Android Open Source Project33897762009-03-03 19:31:44 -0800264 }
265
266 /**
Jaikumar Ganesh2af07762010-08-24 17:36:13 -0700267 * {@inheritDoc}
268 * @hide
The Android Open Source Project33897762009-03-03 19:31:44 -0800269 */
Nick Pelly2d664882009-08-14 18:33:38 -0700270 public boolean setPriority(BluetoothDevice device, int priority) {
271 if (DBG) log("setPriority(" + device + ", " + priority + ")");
Jaikumar Ganesh2af07762010-08-24 17:36:13 -0700272 if (mService != null && isEnabled() &&
273 isValidDevice(device)) {
274 if (priority != BluetoothProfile.PRIORITY_OFF &&
275 priority != BluetoothProfile.PRIORITY_ON) {
276 return false;
277 }
The Android Open Source Project33897762009-03-03 19:31:44 -0800278 try {
Nick Pelly2d664882009-08-14 18:33:38 -0700279 return mService.setPriority(device, priority);
Jaikumar Ganesh2af07762010-08-24 17:36:13 -0700280 } catch (RemoteException e) {
281 Log.e(TAG, Log.getStackTraceString(new Throwable()));
282 return false;
283 }
The Android Open Source Project33897762009-03-03 19:31:44 -0800284 }
Jaikumar Ganesh2af07762010-08-24 17:36:13 -0700285 if (mService == null) Log.w(TAG, "Proxy not attached to service");
The Android Open Source Project33897762009-03-03 19:31:44 -0800286 return false;
287 }
288
289 /**
Jaikumar Ganesh2af07762010-08-24 17:36:13 -0700290 * {@inheritDoc}
291 * @hide
The Android Open Source Project33897762009-03-03 19:31:44 -0800292 */
Nick Pelly2d664882009-08-14 18:33:38 -0700293 public int getPriority(BluetoothDevice device) {
294 if (DBG) log("getPriority(" + device + ")");
Jaikumar Ganesh2af07762010-08-24 17:36:13 -0700295 if (mService != null && isEnabled() &&
296 isValidDevice(device)) {
The Android Open Source Project33897762009-03-03 19:31:44 -0800297 try {
Nick Pelly2d664882009-08-14 18:33:38 -0700298 return mService.getPriority(device);
Jaikumar Ganesh2af07762010-08-24 17:36:13 -0700299 } catch (RemoteException e) {
300 Log.e(TAG, Log.getStackTraceString(new Throwable()));
301 return PRIORITY_OFF;
302 }
The Android Open Source Project33897762009-03-03 19:31:44 -0800303 }
Jaikumar Ganesh2af07762010-08-24 17:36:13 -0700304 if (mService == null) Log.w(TAG, "Proxy not attached to service");
305 return PRIORITY_OFF;
306 }
307
308 /**
309 * Start Bluetooth voice recognition. This methods sends the voice
310 * recognition AT command to the headset and establishes the
311 * audio connection.
312 *
313 * <p> Users can listen to {@link #ACTION_AUDIO_STATE_CHANGED}.
314 * {@link #EXTRA_STATE} will be set to {@link #STATE_AUDIO_CONNECTED}
315 * when the audio connection is established.
316 *
317 * <p>Requires {@link android.Manifest.permission#BLUETOOTH}
318 *
319 * @param device Bluetooth headset
320 * @return false if there is no headset connected of if the
321 * connected headset doesn't support voice recognition
322 * or on error, true otherwise
323 */
324 public boolean startVoiceRecognition(BluetoothDevice device) {
325 if (DBG) log("startVoiceRecognition()");
326 if (mService != null && isEnabled() &&
327 isValidDevice(device)) {
328 try {
329 return mService.startVoiceRecognition(device);
330 } catch (RemoteException e) {
331 Log.e(TAG, Log.getStackTraceString(new Throwable()));
332 }
333 }
334 if (mService == null) Log.w(TAG, "Proxy not attached to service");
335 return false;
336 }
337
338 /**
339 * Stop Bluetooth Voice Recognition mode, and shut down the
340 * Bluetooth audio path.
341 *
342 * <p>Requires {@link android.Manifest.permission#BLUETOOTH}
343 *
344 * @param device Bluetooth headset
345 * @return false if there is no headset connected
346 * or on error, true otherwise
347 */
348 public boolean stopVoiceRecognition(BluetoothDevice device) {
349 if (DBG) log("stopVoiceRecognition()");
350 if (mService != null && isEnabled() &&
351 isValidDevice(device)) {
352 try {
353 return mService.stopVoiceRecognition(device);
354 } catch (RemoteException e) {
355 Log.e(TAG, Log.getStackTraceString(new Throwable()));
356 }
357 }
358 if (mService == null) Log.w(TAG, "Proxy not attached to service");
359 return false;
360 }
361
362 /**
363 * Check if Bluetooth SCO audio is connected.
364 *
365 * <p>Requires {@link android.Manifest.permission#BLUETOOTH}
366 *
367 * @param device Bluetooth headset
368 * @return true if SCO is connected,
369 * false otherwise or on error
370 */
371 public boolean isAudioConnected(BluetoothDevice device) {
372 if (DBG) log("isAudioConnected()");
373 if (mService != null && isEnabled() &&
374 isValidDevice(device)) {
375 try {
376 return mService.isAudioConnected(device);
377 } catch (RemoteException e) {
378 Log.e(TAG, Log.getStackTraceString(new Throwable()));
379 }
380 }
381 if (mService == null) Log.w(TAG, "Proxy not attached to service");
382 return false;
The Android Open Source Project33897762009-03-03 19:31:44 -0800383 }
384
385 /**
Nick Pelly312cd3a2009-06-19 10:08:09 -0700386 * Get battery usage hint for Bluetooth Headset service.
387 * This is a monotonically increasing integer. Wraps to 0 at
388 * Integer.MAX_INT, and at boot.
389 * Current implementation returns the number of AT commands handled since
390 * boot. This is a good indicator for spammy headset/handsfree units that
391 * can keep the device awake by polling for cellular status updates. As a
392 * rule of thumb, each AT command prevents the CPU from sleeping for 500 ms
Jaikumar Ganesh2af07762010-08-24 17:36:13 -0700393 *
394 * @param device the bluetooth headset.
Nick Pelly312cd3a2009-06-19 10:08:09 -0700395 * @return monotonically increasing battery usage hint, or a negative error
396 * code on error
397 * @hide
398 */
Jaikumar Ganesh2af07762010-08-24 17:36:13 -0700399 public int getBatteryUsageHint(BluetoothDevice device) {
Nick Pelly312cd3a2009-06-19 10:08:09 -0700400 if (DBG) log("getBatteryUsageHint()");
Jaikumar Ganesh2af07762010-08-24 17:36:13 -0700401 if (mService != null && isEnabled() &&
402 isValidDevice(device)) {
Nick Pelly312cd3a2009-06-19 10:08:09 -0700403 try {
Jaikumar Ganesh2af07762010-08-24 17:36:13 -0700404 return mService.getBatteryUsageHint(device);
405 } catch (RemoteException e) {
406 Log.e(TAG, Log.getStackTraceString(new Throwable()));
407 }
Nick Pelly312cd3a2009-06-19 10:08:09 -0700408 }
Jaikumar Ganesh2af07762010-08-24 17:36:13 -0700409 if (mService == null) Log.w(TAG, "Proxy not attached to service");
Nick Pelly312cd3a2009-06-19 10:08:09 -0700410 return -1;
411 }
Jaikumar Ganesh2af07762010-08-24 17:36:13 -0700412
Eric Laurent2e66fa22010-03-17 14:59:27 -0700413 /**
414 * Indicates if current platform supports voice dialing over bluetooth SCO.
Jaikumar Ganesh2af07762010-08-24 17:36:13 -0700415 *
Eric Laurent2e66fa22010-03-17 14:59:27 -0700416 * @return true if voice dialing over bluetooth is supported, false otherwise.
417 * @hide
418 */
419 public static boolean isBluetoothVoiceDialingEnabled(Context context) {
420 return context.getResources().getBoolean(
421 com.android.internal.R.bool.config_bluetooth_sco_off_call);
422 }
423
Jaikumar Ganeshb84bbd92010-06-02 14:36:14 -0700424 /**
425 * Cancel the outgoing connection.
Jaikumar Ganesh2af07762010-08-24 17:36:13 -0700426 * Note: This is an internal function and shouldn't be exposed
427 *
Jaikumar Ganeshb84bbd92010-06-02 14:36:14 -0700428 * @hide
429 */
430 public boolean cancelConnectThread() {
431 if (DBG) log("cancelConnectThread");
Jaikumar Ganesh2af07762010-08-24 17:36:13 -0700432 if (mService != null && isEnabled()) {
Jaikumar Ganeshb84bbd92010-06-02 14:36:14 -0700433 try {
434 return mService.cancelConnectThread();
435 } catch (RemoteException e) {Log.e(TAG, e.toString());}
436 } else {
437 Log.w(TAG, "Proxy not attached to service");
438 if (DBG) Log.d(TAG, Log.getStackTraceString(new Throwable()));
439 }
440 return false;
441 }
442
443 /**
444 * Accept the incoming connection.
Jaikumar Ganesh2af07762010-08-24 17:36:13 -0700445 * Note: This is an internal function and shouldn't be exposed
446 *
Jaikumar Ganeshb84bbd92010-06-02 14:36:14 -0700447 * @hide
448 */
449 public boolean acceptIncomingConnect(BluetoothDevice device) {
450 if (DBG) log("acceptIncomingConnect");
Jaikumar Ganesh2af07762010-08-24 17:36:13 -0700451 if (mService != null && isEnabled()) {
Jaikumar Ganeshb84bbd92010-06-02 14:36:14 -0700452 try {
453 return mService.acceptIncomingConnect(device);
454 } catch (RemoteException e) {Log.e(TAG, e.toString());}
455 } else {
456 Log.w(TAG, "Proxy not attached to service");
457 if (DBG) Log.d(TAG, Log.getStackTraceString(new Throwable()));
458 }
459 return false;
460 }
461
462 /**
Jaikumar Ganesh2af07762010-08-24 17:36:13 -0700463 * Create the connect thread for the incoming connection.
464 * Note: This is an internal function and shouldn't be exposed
465 *
Jaikumar Ganeshb84bbd92010-06-02 14:36:14 -0700466 * @hide
467 */
468 public boolean createIncomingConnect(BluetoothDevice device) {
469 if (DBG) log("createIncomingConnect");
Jaikumar Ganesh2af07762010-08-24 17:36:13 -0700470 if (mService != null && isEnabled()) {
Jaikumar Ganeshb84bbd92010-06-02 14:36:14 -0700471 try {
472 return mService.createIncomingConnect(device);
473 } catch (RemoteException e) {Log.e(TAG, e.toString());}
474 } else {
475 Log.w(TAG, "Proxy not attached to service");
476 if (DBG) Log.d(TAG, Log.getStackTraceString(new Throwable()));
477 }
478 return false;
479 }
480
481 /**
482 * Connect to a Bluetooth Headset.
483 * Note: This is an internal function and shouldn't be exposed
Jaikumar Ganesh2af07762010-08-24 17:36:13 -0700484 *
Jaikumar Ganeshb84bbd92010-06-02 14:36:14 -0700485 * @hide
486 */
487 public boolean connectHeadsetInternal(BluetoothDevice device) {
488 if (DBG) log("connectHeadsetInternal");
Jaikumar Ganesh2af07762010-08-24 17:36:13 -0700489 if (mService != null && isEnabled()) {
Jaikumar Ganeshb84bbd92010-06-02 14:36:14 -0700490 try {
491 return mService.connectHeadsetInternal(device);
492 } catch (RemoteException e) {Log.e(TAG, e.toString());}
493 } else {
494 Log.w(TAG, "Proxy not attached to service");
495 if (DBG) Log.d(TAG, Log.getStackTraceString(new Throwable()));
496 }
497 return false;
498 }
499
500 /**
501 * Disconnect a Bluetooth Headset.
502 * Note: This is an internal function and shouldn't be exposed
Jaikumar Ganesh2af07762010-08-24 17:36:13 -0700503 *
Jaikumar Ganeshb84bbd92010-06-02 14:36:14 -0700504 * @hide
505 */
506 public boolean disconnectHeadsetInternal(BluetoothDevice device) {
507 if (DBG) log("disconnectHeadsetInternal");
Jaikumar Ganesh2af07762010-08-24 17:36:13 -0700508 if (mService != null && isEnabled()) {
Jaikumar Ganeshb84bbd92010-06-02 14:36:14 -0700509 try {
510 return mService.disconnectHeadsetInternal(device);
511 } catch (RemoteException e) {Log.e(TAG, e.toString());}
512 } else {
513 Log.w(TAG, "Proxy not attached to service");
514 if (DBG) Log.d(TAG, Log.getStackTraceString(new Throwable()));
515 }
516 return false;
517 }
Jaikumar Ganesh2af07762010-08-24 17:36:13 -0700518
519 /**
520 * Set the audio state of the Headset.
521 * Note: This is an internal function and shouldn't be exposed
522 *
523 * @hide
524 */
525 public boolean setAudioState(BluetoothDevice device, int state) {
526 if (DBG) log("setAudioState");
527 if (mService != null && isEnabled()) {
528 try {
529 return mService.setAudioState(device, state);
530 } catch (RemoteException e) {Log.e(TAG, e.toString());}
531 } else {
532 Log.w(TAG, "Proxy not attached to service");
533 if (DBG) Log.d(TAG, Log.getStackTraceString(new Throwable()));
534 }
535 return false;
536 }
537
The Android Open Source Project33897762009-03-03 19:31:44 -0800538 private ServiceConnection mConnection = new ServiceConnection() {
539 public void onServiceConnected(ComponentName className, IBinder service) {
540 if (DBG) Log.d(TAG, "Proxy object connected");
541 mService = IBluetoothHeadset.Stub.asInterface(service);
Jaikumar Ganesh2af07762010-08-24 17:36:13 -0700542
The Android Open Source Project33897762009-03-03 19:31:44 -0800543 if (mServiceListener != null) {
Jaikumar Ganesh2af07762010-08-24 17:36:13 -0700544 mServiceListener.onServiceConnected(BluetoothProfile.HEADSET, BluetoothHeadset.this);
The Android Open Source Project33897762009-03-03 19:31:44 -0800545 }
546 }
547 public void onServiceDisconnected(ComponentName className) {
548 if (DBG) Log.d(TAG, "Proxy object disconnected");
549 mService = null;
550 if (mServiceListener != null) {
Jaikumar Ganesh2af07762010-08-24 17:36:13 -0700551 mServiceListener.onServiceDisconnected(BluetoothProfile.HEADSET);
The Android Open Source Project33897762009-03-03 19:31:44 -0800552 }
553 }
554 };
The Android Open Source Project0047a0f2009-03-05 20:00:43 -0800555
Jaikumar Ganesh2af07762010-08-24 17:36:13 -0700556 private boolean isEnabled() {
557 if (mAdapter.getState() == BluetoothAdapter.STATE_ON) return true;
558 return false;
559 }
560
561 private boolean isValidDevice(BluetoothDevice device) {
562 if (device == null) return false;
563
564 if (BluetoothAdapter.checkBluetoothAddress(device.getAddress())) return true;
565 return false;
566 }
567
The Android Open Source Project0047a0f2009-03-05 20:00:43 -0800568 private static void log(String msg) {
569 Log.d(TAG, msg);
570 }
The Android Open Source Project33897762009-03-03 19:31:44 -0800571}