blob: 793d79858c6c0ed94b045956b137a9cf9f53e574 [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.annotation.SdkConstant;
20import android.annotation.SdkConstant.SdkConstantType;
The Android Open Source Project9066cfe2009-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 Project9066cfe2009-03-03 19:31:44 -080025import android.os.IBinder;
Jaikumar Ganesh03cd78c2010-10-18 16:41:53 -070026import android.os.RemoteException;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080027import android.util.Log;
28
Jaikumar Ganesh03cd78c2010-10-18 16:41:53 -070029import java.util.ArrayList;
30import java.util.List;
Jaikumar Ganesh62c37ef2010-08-24 17:36:13 -070031
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080032/**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080033 * Public API for controlling the Bluetooth Headset Service. This includes both
Jaikumar Ganesh62c37ef2010-08-24 17:36:13 -070034 * Bluetooth Headset and Handsfree (v1.5) profiles.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080035 *
Jaikumar Ganesh62c37ef2010-08-24 17:36:13 -070036 * <p>BluetoothHeadset is a proxy object for controlling the Bluetooth Headset
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080037 * Service via IPC.
38 *
Jaikumar Ganesh62c37ef2010-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 Project9066cfe2009-03-03 19:31:44 -080042 *
Jaikumar Ganesh62c37ef2010-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 Project9066cfe2009-03-03 19:31:44 -080045 */
Jaikumar Ganesh62c37ef2010-08-24 17:36:13 -070046public final class BluetoothHeadset implements BluetoothProfile {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080047 private static final String TAG = "BluetoothHeadset";
fredc0f420372012-04-12 00:02:00 -070048 private static final boolean DBG = true;
Matthew Xie563e4142012-10-09 22:10:37 -070049 private static final boolean VDBG = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080050
Nick Pelly005b2282009-09-10 10:21:56 -070051 /**
Jaikumar Ganesh62c37ef2010-08-24 17:36:13 -070052 * Intent used to broadcast the change in connection state of the Headset
53 * profile.
54 *
55 * <p>This intent will have 3 extras:
Jaikumar Ganeshc8fa4ff2011-01-25 16:03:13 -080056 * <ul>
57 * <li> {@link #EXTRA_STATE} - The current state of the profile. </li>
58 * <li> {@link #EXTRA_PREVIOUS_STATE}- The previous state of the profile. </li>
59 * <li> {@link BluetoothDevice#EXTRA_DEVICE} - The remote device. </li>
60 * </ul>
Jaikumar Ganesh0706fed2011-01-26 11:46:56 -080061 * <p>{@link #EXTRA_STATE} or {@link #EXTRA_PREVIOUS_STATE} can be any of
Jaikumar Ganesh62c37ef2010-08-24 17:36:13 -070062 * {@link #STATE_DISCONNECTED}, {@link #STATE_CONNECTING},
63 * {@link #STATE_CONNECTED}, {@link #STATE_DISCONNECTING}.
64 *
Jaikumar Ganeshc8fa4ff2011-01-25 16:03:13 -080065 * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission to
66 * receive.
Jaikumar Ganesh62c37ef2010-08-24 17:36:13 -070067 */
68 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
69 public static final String ACTION_CONNECTION_STATE_CHANGED =
70 "android.bluetooth.headset.profile.action.CONNECTION_STATE_CHANGED";
71
72 /**
73 * Intent used to broadcast the change in the Audio Connection state of the
74 * A2DP profile.
75 *
76 * <p>This intent will have 3 extras:
Jaikumar Ganeshc8fa4ff2011-01-25 16:03:13 -080077 * <ul>
78 * <li> {@link #EXTRA_STATE} - The current state of the profile. </li>
79 * <li> {@link #EXTRA_PREVIOUS_STATE}- The previous state of the profile. </li>
80 * <li> {@link BluetoothDevice#EXTRA_DEVICE} - The remote device. </li>
81 * </ul>
Jaikumar Ganesh0706fed2011-01-26 11:46:56 -080082 * <p>{@link #EXTRA_STATE} or {@link #EXTRA_PREVIOUS_STATE} can be any of
Jaikumar Ganesh62c37ef2010-08-24 17:36:13 -070083 * {@link #STATE_AUDIO_CONNECTED}, {@link #STATE_AUDIO_DISCONNECTED},
84 *
Jaikumar Ganeshc8fa4ff2011-01-25 16:03:13 -080085 * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission
86 * to receive.
Nick Pelly005b2282009-09-10 10:21:56 -070087 */
88 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
89 public static final String ACTION_AUDIO_STATE_CHANGED =
Jaikumar Ganesh62c37ef2010-08-24 17:36:13 -070090 "android.bluetooth.headset.profile.action.AUDIO_STATE_CHANGED";
Nick Pelly005b2282009-09-10 10:21:56 -070091
Jaikumar Ganeshc24dbdb2010-04-02 14:44:43 -070092
Nick Pelly005b2282009-09-10 10:21:56 -070093 /**
Jaikumar Ganeshe775b3d2010-09-29 11:34:59 -070094 * Intent used to broadcast that the headset has posted a
95 * vendor-specific event.
96 *
97 * <p>This intent will have 4 extras and 1 category.
Jaikumar Ganeshc8fa4ff2011-01-25 16:03:13 -080098 * <ul>
99 * <li> {@link BluetoothDevice#EXTRA_DEVICE} - The remote Bluetooth Device
100 * </li>
101 * <li> {@link #EXTRA_VENDOR_SPECIFIC_HEADSET_EVENT_CMD} - The vendor
102 * specific command </li>
103 * <li> {@link #EXTRA_VENDOR_SPECIFIC_HEADSET_EVENT_CMD_TYPE} - The AT
104 * command type which can be one of {@link #AT_CMD_TYPE_READ},
105 * {@link #AT_CMD_TYPE_TEST}, or {@link #AT_CMD_TYPE_SET},
Jaikumar Ganesh0706fed2011-01-26 11:46:56 -0800106 * {@link #AT_CMD_TYPE_BASIC},{@link #AT_CMD_TYPE_ACTION}. </li>
Jaikumar Ganeshc8fa4ff2011-01-25 16:03:13 -0800107 * <li> {@link #EXTRA_VENDOR_SPECIFIC_HEADSET_EVENT_ARGS} - Command
108 * arguments. </li>
109 * </ul>
Jaikumar Ganeshe775b3d2010-09-29 11:34:59 -0700110 *
Jaikumar Ganesh0706fed2011-01-26 11:46:56 -0800111 *<p> The category is the Company ID of the vendor defining the
Jaikumar Ganeshe775b3d2010-09-29 11:34:59 -0700112 * vendor-specific command. {@link BluetoothAssignedNumbers}
Jaikumar Ganeshe775b3d2010-09-29 11:34:59 -0700113 *
114 * For example, for Plantronics specific events
115 * Category will be {@link #VENDOR_SPECIFIC_HEADSET_EVENT_COMPANY_ID_CATEGORY}.55
116 *
117 * <p> For example, an AT+XEVENT=foo,3 will get translated into
Jaikumar Ganeshc8fa4ff2011-01-25 16:03:13 -0800118 * <ul>
119 * <li> EXTRA_VENDOR_SPECIFIC_HEADSET_EVENT_CMD = +XEVENT </li>
120 * <li> EXTRA_VENDOR_SPECIFIC_HEADSET_EVENT_CMD_TYPE = AT_CMD_TYPE_SET </li>
Jaikumar Ganesh0706fed2011-01-26 11:46:56 -0800121 * <li> EXTRA_VENDOR_SPECIFIC_HEADSET_EVENT_ARGS = foo, 3 </li>
Jaikumar Ganeshc8fa4ff2011-01-25 16:03:13 -0800122 * </ul>
123 * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission
124 * to receive.
Herb Jellineka4733942010-08-10 13:17:43 -0700125 */
126 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
127 public static final String ACTION_VENDOR_SPECIFIC_HEADSET_EVENT =
128 "android.bluetooth.headset.action.VENDOR_SPECIFIC_HEADSET_EVENT";
129
130 /**
131 * A String extra field in {@link #ACTION_VENDOR_SPECIFIC_HEADSET_EVENT}
132 * intents that contains the name of the vendor-specific command.
133 */
134 public static final String EXTRA_VENDOR_SPECIFIC_HEADSET_EVENT_CMD =
135 "android.bluetooth.headset.extra.VENDOR_SPECIFIC_HEADSET_EVENT_CMD";
136
137 /**
138 * An int extra field in {@link #ACTION_VENDOR_SPECIFIC_HEADSET_EVENT}
Jaikumar Ganeshe775b3d2010-09-29 11:34:59 -0700139 * intents that contains the AT command type of the vendor-specific command.
Herb Jellineka4733942010-08-10 13:17:43 -0700140 */
Jaikumar Ganeshe775b3d2010-09-29 11:34:59 -0700141 public static final String EXTRA_VENDOR_SPECIFIC_HEADSET_EVENT_CMD_TYPE =
142 "android.bluetooth.headset.extra.VENDOR_SPECIFIC_HEADSET_EVENT_CMD_TYPE";
143
144 /**
145 * AT command type READ used with
146 * {@link #EXTRA_VENDOR_SPECIFIC_HEADSET_EVENT_CMD_TYPE}
147 * For example, AT+VGM?. There are no arguments for this command type.
148 */
149 public static final int AT_CMD_TYPE_READ = 0;
150
151 /**
152 * AT command type TEST used with
153 * {@link #EXTRA_VENDOR_SPECIFIC_HEADSET_EVENT_CMD_TYPE}
154 * For example, AT+VGM=?. There are no arguments for this command type.
155 */
156 public static final int AT_CMD_TYPE_TEST = 1;
157
158 /**
159 * AT command type SET used with
160 * {@link #EXTRA_VENDOR_SPECIFIC_HEADSET_EVENT_CMD_TYPE}
161 * For example, AT+VGM=<args>.
162 */
163 public static final int AT_CMD_TYPE_SET = 2;
164
165 /**
166 * AT command type BASIC used with
167 * {@link #EXTRA_VENDOR_SPECIFIC_HEADSET_EVENT_CMD_TYPE}
168 * For example, ATD. Single character commands and everything following the
169 * character are arguments.
170 */
171 public static final int AT_CMD_TYPE_BASIC = 3;
172
173 /**
174 * AT command type ACTION used with
175 * {@link #EXTRA_VENDOR_SPECIFIC_HEADSET_EVENT_CMD_TYPE}
176 * For example, AT+CHUP. There are no arguments for action commands.
177 */
178 public static final int AT_CMD_TYPE_ACTION = 4;
Herb Jellineka4733942010-08-10 13:17:43 -0700179
180 /**
181 * A Parcelable String array extra field in
182 * {@link #ACTION_VENDOR_SPECIFIC_HEADSET_EVENT} intents that contains
183 * the arguments to the vendor-specific command.
184 */
185 public static final String EXTRA_VENDOR_SPECIFIC_HEADSET_EVENT_ARGS =
186 "android.bluetooth.headset.extra.VENDOR_SPECIFIC_HEADSET_EVENT_ARGS";
187
Jaikumar Ganeshe775b3d2010-09-29 11:34:59 -0700188 /**
189 * The intent category to be used with {@link #ACTION_VENDOR_SPECIFIC_HEADSET_EVENT}
190 * for the companyId
191 */
192 public static final String VENDOR_SPECIFIC_HEADSET_EVENT_COMPANY_ID_CATEGORY =
193 "android.bluetooth.headset.intent.category.companyid";
194
Jaikumar Ganesh30d18162010-11-01 11:59:57 -0700195 /**
Jaikumar Ganeshc8fa4ff2011-01-25 16:03:13 -0800196 * Headset state when SCO audio is not connected.
Jaikumar Ganesh62c37ef2010-08-24 17:36:13 -0700197 * This state can be one of
198 * {@link #EXTRA_STATE} or {@link #EXTRA_PREVIOUS_STATE} of
199 * {@link #ACTION_AUDIO_STATE_CHANGED} intent.
200 */
Jaikumar Ganeshb0a1d012010-11-11 10:49:46 -0800201 public static final int STATE_AUDIO_DISCONNECTED = 10;
Herb Jellineka4733942010-08-10 13:17:43 -0700202
203 /**
Jaikumar Ganeshc8fa4ff2011-01-25 16:03:13 -0800204 * Headset state when SCO audio is connecting.
Jaikumar Ganesh30d18162010-11-01 11:59:57 -0700205 * This state can be one of
206 * {@link #EXTRA_STATE} or {@link #EXTRA_PREVIOUS_STATE} of
207 * {@link #ACTION_AUDIO_STATE_CHANGED} intent.
Jaikumar Ganesh30d18162010-11-01 11:59:57 -0700208 */
Jaikumar Ganeshb0a1d012010-11-11 10:49:46 -0800209 public static final int STATE_AUDIO_CONNECTING = 11;
Jaikumar Ganesh30d18162010-11-01 11:59:57 -0700210
211 /**
Jaikumar Ganeshc8fa4ff2011-01-25 16:03:13 -0800212 * Headset state when SCO audio is connected.
Jaikumar Ganesh62c37ef2010-08-24 17:36:13 -0700213 * This state can be one of
214 * {@link #EXTRA_STATE} or {@link #EXTRA_PREVIOUS_STATE} of
215 * {@link #ACTION_AUDIO_STATE_CHANGED} intent.
Nick Pelly005b2282009-09-10 10:21:56 -0700216 */
Jaikumar Ganeshb0a1d012010-11-11 10:49:46 -0800217 public static final int STATE_AUDIO_CONNECTED = 12;
218
Jaikumar Ganesh62c37ef2010-08-24 17:36:13 -0700219
Jaikumar Ganesh62c37ef2010-08-24 17:36:13 -0700220 private Context mContext;
221 private ServiceListener mServiceListener;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800222 private IBluetoothHeadset mService;
Matthew Xiebf246ef2012-03-21 23:15:06 -0700223 private BluetoothAdapter mAdapter;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800224
fredc0f420372012-04-12 00:02:00 -0700225 final private IBluetoothStateChangeCallback mBluetoothStateChangeCallback =
226 new IBluetoothStateChangeCallback.Stub() {
227 public void onBluetoothStateChange(boolean up) {
228 if (DBG) Log.d(TAG, "onBluetoothStateChange: up=" + up);
229 if (!up) {
Matthew Xie563e4142012-10-09 22:10:37 -0700230 if (VDBG) Log.d(TAG,"Unbinding service...");
fredc0f420372012-04-12 00:02:00 -0700231 synchronized (mConnection) {
232 try {
233 mService = null;
234 mContext.unbindService(mConnection);
235 } catch (Exception re) {
236 Log.e(TAG,"",re);
237 }
238 }
239 } else {
240 synchronized (mConnection) {
241 try {
242 if (mService == null) {
Matthew Xie563e4142012-10-09 22:10:37 -0700243 if (VDBG) Log.d(TAG,"Binding service...");
fredc0f420372012-04-12 00:02:00 -0700244 if (!mContext.bindService(new Intent(IBluetoothHeadset.class.getName()), mConnection, 0)) {
245 Log.e(TAG, "Could not bind to Bluetooth Headset Service");
246 }
247 }
248 } catch (Exception re) {
249 Log.e(TAG,"",re);
250 }
251 }
252 }
253 }
254 };
255
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800256 /**
257 * Create a BluetoothHeadset proxy object.
258 */
Jaikumar Ganesh62c37ef2010-08-24 17:36:13 -0700259 /*package*/ BluetoothHeadset(Context context, ServiceListener l) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800260 mContext = context;
261 mServiceListener = l;
Jaikumar Ganesh62c37ef2010-08-24 17:36:13 -0700262 mAdapter = BluetoothAdapter.getDefaultAdapter();
fredc0f420372012-04-12 00:02:00 -0700263
264 IBluetoothManager mgr = mAdapter.getBluetoothManager();
265 if (mgr != null) {
266 try {
267 mgr.registerStateChangeCallback(mBluetoothStateChangeCallback);
268 } catch (RemoteException e) {
269 Log.e(TAG,"",e);
270 }
271 }
272
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800273 if (!context.bindService(new Intent(IBluetoothHeadset.class.getName()), mConnection, 0)) {
274 Log.e(TAG, "Could not bind to Bluetooth Headset Service");
275 }
276 }
277
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800278 /**
279 * Close the connection to the backing service.
280 * Other public functions of BluetoothHeadset will return default error
281 * results once close() has been called. Multiple invocations of close()
282 * are ok.
283 */
Matthew Xie13450df2012-03-22 17:18:37 -0700284 /*package*/ void close() {
Matthew Xie563e4142012-10-09 22:10:37 -0700285 if (VDBG) log("close()");
fredc0f420372012-04-12 00:02:00 -0700286
287 IBluetoothManager mgr = mAdapter.getBluetoothManager();
288 if (mgr != null) {
289 try {
290 mgr.unregisterStateChangeCallback(mBluetoothStateChangeCallback);
291 } catch (Exception e) {
292 Log.e(TAG,"",e);
293 }
294 }
295
296 synchronized (mConnection) {
297 if (mService != null) {
298 try {
299 mService = null;
300 mContext.unbindService(mConnection);
301 } catch (Exception re) {
302 Log.e(TAG,"",re);
303 }
304 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800305 }
Jaikumar Ganesh9bb27512011-11-28 09:59:08 -0800306 mServiceListener = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800307 }
308
309 /**
Jaikumar Ganeshf8789162011-05-26 13:56:40 -0700310 * Initiate connection to a profile of the remote bluetooth device.
311 *
312 * <p> Currently, the system supports only 1 connection to the
313 * headset/handsfree profile. The API will automatically disconnect connected
314 * devices before connecting.
315 *
316 * <p> This API returns false in scenarios like the profile on the
317 * device is already connected or Bluetooth is not turned on.
318 * When this API returns true, it is guaranteed that
319 * connection state intent for the profile will be broadcasted with
320 * the state. Users can get the connection state of the profile
321 * from this intent.
322 *
323 * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN}
324 * permission.
325 *
326 * @param device Remote Bluetooth Device
327 * @return false on immediate error,
328 * true otherwise
Jaikumar Ganesh62c37ef2010-08-24 17:36:13 -0700329 * @hide
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800330 */
Jaikumar Ganesh62c37ef2010-08-24 17:36:13 -0700331 public boolean connect(BluetoothDevice device) {
332 if (DBG) log("connect(" + device + ")");
333 if (mService != null && isEnabled() &&
334 isValidDevice(device)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800335 try {
Jaikumar Ganesh62c37ef2010-08-24 17:36:13 -0700336 return mService.connect(device);
337 } catch (RemoteException e) {
338 Log.e(TAG, Log.getStackTraceString(new Throwable()));
339 return false;
340 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800341 }
Jaikumar Ganesh62c37ef2010-08-24 17:36:13 -0700342 if (mService == null) Log.w(TAG, "Proxy not attached to service");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800343 return false;
344 }
345
346 /**
Jaikumar Ganeshf8789162011-05-26 13:56:40 -0700347 * Initiate disconnection from a profile
348 *
349 * <p> This API will return false in scenarios like the profile on the
350 * Bluetooth device is not in connected state etc. When this API returns,
351 * true, it is guaranteed that the connection state change
352 * intent will be broadcasted with the state. Users can get the
353 * disconnection state of the profile from this intent.
354 *
355 * <p> If the disconnection is initiated by a remote device, the state
356 * will transition from {@link #STATE_CONNECTED} to
357 * {@link #STATE_DISCONNECTED}. If the disconnect is initiated by the
358 * host (local) device the state will transition from
359 * {@link #STATE_CONNECTED} to state {@link #STATE_DISCONNECTING} to
360 * state {@link #STATE_DISCONNECTED}. The transition to
361 * {@link #STATE_DISCONNECTING} can be used to distinguish between the
362 * two scenarios.
363 *
364 * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN}
365 * permission.
366 *
367 * @param device Remote Bluetooth Device
368 * @return false on immediate error,
369 * true otherwise
Jaikumar Ganesh62c37ef2010-08-24 17:36:13 -0700370 * @hide
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800371 */
Jaikumar Ganesh62c37ef2010-08-24 17:36:13 -0700372 public boolean disconnect(BluetoothDevice device) {
373 if (DBG) log("disconnect(" + device + ")");
374 if (mService != null && isEnabled() &&
375 isValidDevice(device)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800376 try {
Jaikumar Ganesh62c37ef2010-08-24 17:36:13 -0700377 return mService.disconnect(device);
378 } catch (RemoteException e) {
379 Log.e(TAG, Log.getStackTraceString(new Throwable()));
380 return false;
381 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800382 }
Jaikumar Ganesh62c37ef2010-08-24 17:36:13 -0700383 if (mService == null) Log.w(TAG, "Proxy not attached to service");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800384 return false;
385 }
386
387 /**
Jaikumar Ganesh62c37ef2010-08-24 17:36:13 -0700388 * {@inheritDoc}
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800389 */
Jaikumar Ganesh03cd78c2010-10-18 16:41:53 -0700390 public List<BluetoothDevice> getConnectedDevices() {
Matthew Xie563e4142012-10-09 22:10:37 -0700391 if (VDBG) log("getConnectedDevices()");
Jaikumar Ganesh62c37ef2010-08-24 17:36:13 -0700392 if (mService != null && isEnabled()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800393 try {
Jaikumar Ganesh03cd78c2010-10-18 16:41:53 -0700394 return mService.getConnectedDevices();
Jaikumar Ganesh62c37ef2010-08-24 17:36:13 -0700395 } catch (RemoteException e) {
396 Log.e(TAG, Log.getStackTraceString(new Throwable()));
Jaikumar Ganesh03cd78c2010-10-18 16:41:53 -0700397 return new ArrayList<BluetoothDevice>();
Jaikumar Ganesh62c37ef2010-08-24 17:36:13 -0700398 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800399 }
Jaikumar Ganesh62c37ef2010-08-24 17:36:13 -0700400 if (mService == null) Log.w(TAG, "Proxy not attached to service");
Jaikumar Ganesh03cd78c2010-10-18 16:41:53 -0700401 return new ArrayList<BluetoothDevice>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800402 }
403
404 /**
Jaikumar Ganesh62c37ef2010-08-24 17:36:13 -0700405 * {@inheritDoc}
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800406 */
Jaikumar Ganesh03cd78c2010-10-18 16:41:53 -0700407 public List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) {
Matthew Xie563e4142012-10-09 22:10:37 -0700408 if (VDBG) log("getDevicesMatchingStates()");
Jaikumar Ganesh62c37ef2010-08-24 17:36:13 -0700409 if (mService != null && isEnabled()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800410 try {
Jaikumar Ganesh03cd78c2010-10-18 16:41:53 -0700411 return mService.getDevicesMatchingConnectionStates(states);
Jaikumar Ganesh62c37ef2010-08-24 17:36:13 -0700412 } catch (RemoteException e) {
413 Log.e(TAG, Log.getStackTraceString(new Throwable()));
Jaikumar Ganesh03cd78c2010-10-18 16:41:53 -0700414 return new ArrayList<BluetoothDevice>();
Jaikumar Ganesh62c37ef2010-08-24 17:36:13 -0700415 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800416 }
Jaikumar Ganesh62c37ef2010-08-24 17:36:13 -0700417 if (mService == null) Log.w(TAG, "Proxy not attached to service");
Jaikumar Ganesh03cd78c2010-10-18 16:41:53 -0700418 return new ArrayList<BluetoothDevice>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800419 }
420
421 /**
Jaikumar Ganesh62c37ef2010-08-24 17:36:13 -0700422 * {@inheritDoc}
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800423 */
Jaikumar Ganesh62c37ef2010-08-24 17:36:13 -0700424 public int getConnectionState(BluetoothDevice device) {
Matthew Xie563e4142012-10-09 22:10:37 -0700425 if (VDBG) log("getConnectionState(" + device + ")");
Jaikumar Ganesh62c37ef2010-08-24 17:36:13 -0700426 if (mService != null && isEnabled() &&
427 isValidDevice(device)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800428 try {
Jaikumar Ganesh62c37ef2010-08-24 17:36:13 -0700429 return mService.getConnectionState(device);
430 } catch (RemoteException e) {
431 Log.e(TAG, Log.getStackTraceString(new Throwable()));
432 return BluetoothProfile.STATE_DISCONNECTED;
433 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800434 }
Jaikumar Ganesh62c37ef2010-08-24 17:36:13 -0700435 if (mService == null) Log.w(TAG, "Proxy not attached to service");
436 return BluetoothProfile.STATE_DISCONNECTED;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800437 }
438
439 /**
Jaikumar Ganeshf8789162011-05-26 13:56:40 -0700440 * Set priority of the profile
441 *
442 * <p> The device should already be paired.
443 * Priority can be one of {@link #PRIORITY_ON} or
444 * {@link #PRIORITY_OFF},
445 *
446 * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN}
447 * permission.
448 *
449 * @param device Paired bluetooth device
450 * @param priority
451 * @return true if priority is set, false on error
Jaikumar Ganesh62c37ef2010-08-24 17:36:13 -0700452 * @hide
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800453 */
Nick Pellybd022f42009-08-14 18:33:38 -0700454 public boolean setPriority(BluetoothDevice device, int priority) {
455 if (DBG) log("setPriority(" + device + ", " + priority + ")");
Jaikumar Ganesh62c37ef2010-08-24 17:36:13 -0700456 if (mService != null && isEnabled() &&
457 isValidDevice(device)) {
458 if (priority != BluetoothProfile.PRIORITY_OFF &&
Ganesh Ganapathi Batta6f6c54512012-07-31 16:08:17 -0700459 priority != BluetoothProfile.PRIORITY_ON) {
Jaikumar Ganesh62c37ef2010-08-24 17:36:13 -0700460 return false;
461 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800462 try {
Nick Pellybd022f42009-08-14 18:33:38 -0700463 return mService.setPriority(device, priority);
Jaikumar Ganesh62c37ef2010-08-24 17:36:13 -0700464 } catch (RemoteException e) {
465 Log.e(TAG, Log.getStackTraceString(new Throwable()));
466 return false;
467 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800468 }
Jaikumar Ganesh62c37ef2010-08-24 17:36:13 -0700469 if (mService == null) Log.w(TAG, "Proxy not attached to service");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800470 return false;
471 }
472
473 /**
Jaikumar Ganeshf8789162011-05-26 13:56:40 -0700474 * Get the priority of the profile.
475 *
476 * <p> The priority can be any of:
477 * {@link #PRIORITY_AUTO_CONNECT}, {@link #PRIORITY_OFF},
478 * {@link #PRIORITY_ON}, {@link #PRIORITY_UNDEFINED}
479 *
480 * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
481 *
482 * @param device Bluetooth device
483 * @return priority of the device
Jaikumar Ganesh62c37ef2010-08-24 17:36:13 -0700484 * @hide
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800485 */
Nick Pellybd022f42009-08-14 18:33:38 -0700486 public int getPriority(BluetoothDevice device) {
Matthew Xie563e4142012-10-09 22:10:37 -0700487 if (VDBG) log("getPriority(" + device + ")");
Jaikumar Ganesh62c37ef2010-08-24 17:36:13 -0700488 if (mService != null && isEnabled() &&
489 isValidDevice(device)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800490 try {
Nick Pellybd022f42009-08-14 18:33:38 -0700491 return mService.getPriority(device);
Jaikumar Ganesh62c37ef2010-08-24 17:36:13 -0700492 } catch (RemoteException e) {
493 Log.e(TAG, Log.getStackTraceString(new Throwable()));
494 return PRIORITY_OFF;
495 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800496 }
Jaikumar Ganesh62c37ef2010-08-24 17:36:13 -0700497 if (mService == null) Log.w(TAG, "Proxy not attached to service");
498 return PRIORITY_OFF;
499 }
500
501 /**
502 * Start Bluetooth voice recognition. This methods sends the voice
503 * recognition AT command to the headset and establishes the
504 * audio connection.
505 *
506 * <p> Users can listen to {@link #ACTION_AUDIO_STATE_CHANGED}.
Jaikumar Ganeshb0a1d012010-11-11 10:49:46 -0800507 * If this function returns true, this intent will be broadcasted with
508 * {@link #EXTRA_STATE} set to {@link #STATE_AUDIO_CONNECTING}.
Jaikumar Ganesh62c37ef2010-08-24 17:36:13 -0700509 *
Jaikumar Ganeshb0a1d012010-11-11 10:49:46 -0800510 * <p> {@link #EXTRA_STATE} will transition from
511 * {@link #STATE_AUDIO_CONNECTING} to {@link #STATE_AUDIO_CONNECTED} when
512 * audio connection is established and to {@link #STATE_AUDIO_DISCONNECTED}
513 * in case of failure to establish the audio connection.
514 *
515 * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
Jaikumar Ganesh62c37ef2010-08-24 17:36:13 -0700516 *
517 * @param device Bluetooth headset
518 * @return false if there is no headset connected of if the
519 * connected headset doesn't support voice recognition
520 * or on error, true otherwise
521 */
522 public boolean startVoiceRecognition(BluetoothDevice device) {
523 if (DBG) log("startVoiceRecognition()");
524 if (mService != null && isEnabled() &&
525 isValidDevice(device)) {
526 try {
527 return mService.startVoiceRecognition(device);
528 } catch (RemoteException e) {
529 Log.e(TAG, Log.getStackTraceString(new Throwable()));
530 }
531 }
532 if (mService == null) Log.w(TAG, "Proxy not attached to service");
533 return false;
534 }
535
536 /**
537 * Stop Bluetooth Voice Recognition mode, and shut down the
538 * Bluetooth audio path.
539 *
Jaikumar Ganeshc8fa4ff2011-01-25 16:03:13 -0800540 * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
Jaikumar Ganesh62c37ef2010-08-24 17:36:13 -0700541 *
542 * @param device Bluetooth headset
543 * @return false if there is no headset connected
544 * or on error, true otherwise
545 */
546 public boolean stopVoiceRecognition(BluetoothDevice device) {
547 if (DBG) log("stopVoiceRecognition()");
548 if (mService != null && isEnabled() &&
549 isValidDevice(device)) {
550 try {
551 return mService.stopVoiceRecognition(device);
552 } catch (RemoteException e) {
553 Log.e(TAG, Log.getStackTraceString(new Throwable()));
554 }
555 }
556 if (mService == null) Log.w(TAG, "Proxy not attached to service");
557 return false;
558 }
559
560 /**
561 * Check if Bluetooth SCO audio is connected.
562 *
Jaikumar Ganeshc8fa4ff2011-01-25 16:03:13 -0800563 * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
Jaikumar Ganesh62c37ef2010-08-24 17:36:13 -0700564 *
565 * @param device Bluetooth headset
566 * @return true if SCO is connected,
567 * false otherwise or on error
568 */
569 public boolean isAudioConnected(BluetoothDevice device) {
Matthew Xie563e4142012-10-09 22:10:37 -0700570 if (VDBG) log("isAudioConnected()");
Jaikumar Ganesh62c37ef2010-08-24 17:36:13 -0700571 if (mService != null && isEnabled() &&
572 isValidDevice(device)) {
573 try {
574 return mService.isAudioConnected(device);
575 } catch (RemoteException e) {
576 Log.e(TAG, Log.getStackTraceString(new Throwable()));
577 }
578 }
579 if (mService == null) Log.w(TAG, "Proxy not attached to service");
580 return false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800581 }
582
583 /**
Nick Pelly6c901db2009-06-19 10:08:09 -0700584 * Get battery usage hint for Bluetooth Headset service.
585 * This is a monotonically increasing integer. Wraps to 0 at
586 * Integer.MAX_INT, and at boot.
587 * Current implementation returns the number of AT commands handled since
588 * boot. This is a good indicator for spammy headset/handsfree units that
589 * can keep the device awake by polling for cellular status updates. As a
590 * rule of thumb, each AT command prevents the CPU from sleeping for 500 ms
Jaikumar Ganesh62c37ef2010-08-24 17:36:13 -0700591 *
592 * @param device the bluetooth headset.
Nick Pelly6c901db2009-06-19 10:08:09 -0700593 * @return monotonically increasing battery usage hint, or a negative error
594 * code on error
595 * @hide
596 */
Jaikumar Ganesh62c37ef2010-08-24 17:36:13 -0700597 public int getBatteryUsageHint(BluetoothDevice device) {
Matthew Xie563e4142012-10-09 22:10:37 -0700598 if (VDBG) log("getBatteryUsageHint()");
Jaikumar Ganesh62c37ef2010-08-24 17:36:13 -0700599 if (mService != null && isEnabled() &&
600 isValidDevice(device)) {
Nick Pelly6c901db2009-06-19 10:08:09 -0700601 try {
Jaikumar Ganesh62c37ef2010-08-24 17:36:13 -0700602 return mService.getBatteryUsageHint(device);
603 } catch (RemoteException e) {
604 Log.e(TAG, Log.getStackTraceString(new Throwable()));
605 }
Nick Pelly6c901db2009-06-19 10:08:09 -0700606 }
Jaikumar Ganesh62c37ef2010-08-24 17:36:13 -0700607 if (mService == null) Log.w(TAG, "Proxy not attached to service");
Nick Pelly6c901db2009-06-19 10:08:09 -0700608 return -1;
609 }
Jaikumar Ganesh62c37ef2010-08-24 17:36:13 -0700610
Eric Laurentd726b352010-03-17 14:59:27 -0700611 /**
612 * Indicates if current platform supports voice dialing over bluetooth SCO.
Jaikumar Ganesh62c37ef2010-08-24 17:36:13 -0700613 *
Eric Laurentd726b352010-03-17 14:59:27 -0700614 * @return true if voice dialing over bluetooth is supported, false otherwise.
615 * @hide
616 */
617 public static boolean isBluetoothVoiceDialingEnabled(Context context) {
618 return context.getResources().getBoolean(
619 com.android.internal.R.bool.config_bluetooth_sco_off_call);
620 }
621
Jaikumar Ganesh9b637e52010-06-02 14:36:14 -0700622 /**
Jaikumar Ganesh9b637e52010-06-02 14:36:14 -0700623 * Accept the incoming connection.
Jaikumar Ganesh62c37ef2010-08-24 17:36:13 -0700624 * Note: This is an internal function and shouldn't be exposed
625 *
Jaikumar Ganesh9b637e52010-06-02 14:36:14 -0700626 * @hide
627 */
628 public boolean acceptIncomingConnect(BluetoothDevice device) {
629 if (DBG) log("acceptIncomingConnect");
Jaikumar Ganesh62c37ef2010-08-24 17:36:13 -0700630 if (mService != null && isEnabled()) {
Jaikumar Ganesh9b637e52010-06-02 14:36:14 -0700631 try {
632 return mService.acceptIncomingConnect(device);
633 } catch (RemoteException e) {Log.e(TAG, e.toString());}
634 } else {
635 Log.w(TAG, "Proxy not attached to service");
636 if (DBG) Log.d(TAG, Log.getStackTraceString(new Throwable()));
637 }
638 return false;
639 }
640
641 /**
Matthew Xiea0c68032011-06-25 21:47:07 -0700642 * Reject the incoming connection.
643 * @hide
644 */
645 public boolean rejectIncomingConnect(BluetoothDevice device) {
646 if (DBG) log("rejectIncomingConnect");
647 if (mService != null) {
648 try {
649 return mService.rejectIncomingConnect(device);
650 } catch (RemoteException e) {Log.e(TAG, e.toString());}
651 } else {
652 Log.w(TAG, "Proxy not attached to service");
653 if (DBG) Log.d(TAG, Log.getStackTraceString(new Throwable()));
654 }
655 return false;
656 }
657
658 /**
Jaikumar Ganesh30d18162010-11-01 11:59:57 -0700659 * Get the current audio state of the Headset.
660 * Note: This is an internal function and shouldn't be exposed
661 *
662 * @hide
663 */
664 public int getAudioState(BluetoothDevice device) {
Matthew Xie563e4142012-10-09 22:10:37 -0700665 if (VDBG) log("getAudioState");
Jaikumar Ganesh6f7a9732011-04-06 11:09:30 -0700666 if (mService != null && !isDisabled()) {
Jaikumar Ganesh30d18162010-11-01 11:59:57 -0700667 try {
668 return mService.getAudioState(device);
669 } catch (RemoteException e) {Log.e(TAG, e.toString());}
670 } else {
671 Log.w(TAG, "Proxy not attached to service");
672 if (DBG) Log.d(TAG, Log.getStackTraceString(new Throwable()));
673 }
674 return BluetoothHeadset.STATE_AUDIO_DISCONNECTED;
675 }
676
Jaikumar Ganeshf2e6b132010-10-26 17:10:09 -0700677 /**
Matthew Xie3e8c82e2012-02-16 16:57:18 -0800678 * Check if Bluetooth SCO audio is connected.
679 *
680 * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
681 *
682 * @return true if SCO is connected,
683 * false otherwise or on error
684 * @hide
685 */
686 public boolean isAudioOn() {
Matthew Xie563e4142012-10-09 22:10:37 -0700687 if (VDBG) log("isAudioOn()");
Matthew Xie3e8c82e2012-02-16 16:57:18 -0800688 if (mService != null && isEnabled()) {
689 try {
690 return mService.isAudioOn();
691 } catch (RemoteException e) {
692 Log.e(TAG, Log.getStackTraceString(new Throwable()));
693 }
694 }
695 if (mService == null) Log.w(TAG, "Proxy not attached to service");
696 return false;
697
698 }
699
700 /**
701 * Initiates a connection of headset audio.
702 * It setup SCO channel with remote connected headset device.
703 *
704 * @return true if successful
705 * false if there was some error such as
706 * there is no connected headset
707 * @hide
708 */
709 public boolean connectAudio() {
710 if (mService != null && isEnabled()) {
711 try {
712 return mService.connectAudio();
713 } catch (RemoteException e) {
714 Log.e(TAG, e.toString());
715 }
716 } else {
717 Log.w(TAG, "Proxy not attached to service");
718 if (DBG) Log.d(TAG, Log.getStackTraceString(new Throwable()));
719 }
720 return false;
721 }
722
723 /**
724 * Initiates a disconnection of headset audio.
725 * It tears down the SCO channel from remote headset device.
726 *
727 * @return true if successful
728 * false if there was some error such as
729 * there is no connected SCO channel
730 * @hide
731 */
732 public boolean disconnectAudio() {
733 if (mService != null && isEnabled()) {
734 try {
735 return mService.disconnectAudio();
736 } catch (RemoteException e) {
737 Log.e(TAG, e.toString());
738 }
739 } else {
740 Log.w(TAG, "Proxy not attached to service");
741 if (DBG) Log.d(TAG, Log.getStackTraceString(new Throwable()));
742 }
743 return false;
744 }
745
746 /**
Jaikumar Ganeshdde68c62011-01-24 13:55:27 -0800747 * Initiates a SCO channel connection with the headset (if connected).
748 * Also initiates a virtual voice call for Handsfree devices as many devices
749 * do not accept SCO audio without a call.
750 * This API allows the handsfree device to be used for routing non-cellular
751 * call audio.
Jaikumar Ganeshf2e6b132010-10-26 17:10:09 -0700752 *
753 * @param device Remote Bluetooth Device
754 * @return true if successful, false if there was some error.
755 * @hide
756 */
Jaikumar Ganeshdde68c62011-01-24 13:55:27 -0800757 public boolean startScoUsingVirtualVoiceCall(BluetoothDevice device) {
758 if (DBG) log("startScoUsingVirtualVoiceCall()");
Jaikumar Ganeshf2e6b132010-10-26 17:10:09 -0700759 if (mService != null && isEnabled() && isValidDevice(device)) {
760 try {
Jaikumar Ganeshdde68c62011-01-24 13:55:27 -0800761 return mService.startScoUsingVirtualVoiceCall(device);
Jaikumar Ganeshf2e6b132010-10-26 17:10:09 -0700762 } catch (RemoteException e) {
763 Log.e(TAG, e.toString());
764 }
765 } else {
766 Log.w(TAG, "Proxy not attached to service");
767 if (DBG) Log.d(TAG, Log.getStackTraceString(new Throwable()));
768 }
769 return false;
770 }
771
772 /**
Jaikumar Ganeshdde68c62011-01-24 13:55:27 -0800773 * Terminates an ongoing SCO connection and the associated virtual
774 * call.
Jaikumar Ganeshf2e6b132010-10-26 17:10:09 -0700775 *
776 * @param device Remote Bluetooth Device
777 * @return true if successful, false if there was some error.
778 * @hide
779 */
Jaikumar Ganeshdde68c62011-01-24 13:55:27 -0800780 public boolean stopScoUsingVirtualVoiceCall(BluetoothDevice device) {
781 if (DBG) log("stopScoUsingVirtualVoiceCall()");
Jaikumar Ganeshf2e6b132010-10-26 17:10:09 -0700782 if (mService != null && isEnabled() && isValidDevice(device)) {
783 try {
Jaikumar Ganeshdde68c62011-01-24 13:55:27 -0800784 return mService.stopScoUsingVirtualVoiceCall(device);
Jaikumar Ganeshf2e6b132010-10-26 17:10:09 -0700785 } catch (RemoteException e) {
786 Log.e(TAG, e.toString());
787 }
788 } else {
789 Log.w(TAG, "Proxy not attached to service");
790 if (DBG) Log.d(TAG, Log.getStackTraceString(new Throwable()));
791 }
792 return false;
793 }
794
Matthew Xie3e8c82e2012-02-16 16:57:18 -0800795 /**
796 * Notify Headset of phone state change.
797 * This is a backdoor for phone app to call BluetoothHeadset since
798 * there is currently not a good way to get precise call state change outside
799 * of phone app.
800 *
801 * @hide
802 */
803 public void phoneStateChanged(int numActive, int numHeld, int callState, String number,
804 int type) {
805 if (mService != null && isEnabled()) {
806 try {
807 mService.phoneStateChanged(numActive, numHeld, callState, number, type);
808 } catch (RemoteException e) {
809 Log.e(TAG, e.toString());
810 }
811 } else {
812 Log.w(TAG, "Proxy not attached to service");
813 if (DBG) Log.d(TAG, Log.getStackTraceString(new Throwable()));
814 }
815 }
816
817 /**
818 * Notify Headset of phone roam state change.
819 * This is a backdoor for phone app to call BluetoothHeadset since
820 * there is currently not a good way to get roaming state change outside
821 * of phone app.
822 *
823 * @hide
824 */
825 public void roamChanged(boolean roaming) {
826 if (mService != null && isEnabled()) {
827 try {
828 mService.roamChanged(roaming);
829 } catch (RemoteException e) {
830 Log.e(TAG, e.toString());
831 }
832 } else {
833 Log.w(TAG, "Proxy not attached to service");
834 if (DBG) Log.d(TAG, Log.getStackTraceString(new Throwable()));
835 }
836 }
837
838 /**
839 * Send Headset of CLCC response
840 *
841 * @hide
842 */
843 public void clccResponse(int index, int direction, int status, int mode, boolean mpty,
844 String number, int type) {
845 if (mService != null && isEnabled()) {
846 try {
847 mService.clccResponse(index, direction, status, mode, mpty, number, type);
848 } catch (RemoteException e) {
849 Log.e(TAG, e.toString());
850 }
851 } else {
852 Log.w(TAG, "Proxy not attached to service");
853 if (DBG) Log.d(TAG, Log.getStackTraceString(new Throwable()));
854 }
855 }
856
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800857 private ServiceConnection mConnection = new ServiceConnection() {
858 public void onServiceConnected(ComponentName className, IBinder service) {
859 if (DBG) Log.d(TAG, "Proxy object connected");
860 mService = IBluetoothHeadset.Stub.asInterface(service);
Jaikumar Ganesh62c37ef2010-08-24 17:36:13 -0700861
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800862 if (mServiceListener != null) {
Jaikumar Ganesh62c37ef2010-08-24 17:36:13 -0700863 mServiceListener.onServiceConnected(BluetoothProfile.HEADSET, BluetoothHeadset.this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800864 }
865 }
866 public void onServiceDisconnected(ComponentName className) {
867 if (DBG) Log.d(TAG, "Proxy object disconnected");
868 mService = null;
869 if (mServiceListener != null) {
Jaikumar Ganesh62c37ef2010-08-24 17:36:13 -0700870 mServiceListener.onServiceDisconnected(BluetoothProfile.HEADSET);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800871 }
872 }
873 };
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -0800874
Jaikumar Ganesh62c37ef2010-08-24 17:36:13 -0700875 private boolean isEnabled() {
876 if (mAdapter.getState() == BluetoothAdapter.STATE_ON) return true;
877 return false;
878 }
879
Jaikumar Ganesh6f7a9732011-04-06 11:09:30 -0700880 private boolean isDisabled() {
881 if (mAdapter.getState() == BluetoothAdapter.STATE_OFF) return true;
882 return false;
883 }
884
Jaikumar Ganesh62c37ef2010-08-24 17:36:13 -0700885 private boolean isValidDevice(BluetoothDevice device) {
886 if (device == null) return false;
887
888 if (BluetoothAdapter.checkBluetoothAddress(device.getAddress())) return true;
889 return false;
890 }
891
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -0800892 private static void log(String msg) {
893 Log.d(TAG, msg);
894 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800895}