19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/*
29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2008 The Android Open Source Project
39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License.
69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at
79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and
149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License.
159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpackage android.bluetooth;
189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
19005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pellyimport android.annotation.SdkConstant;
20005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pellyimport android.annotation.SdkConstant.SdkConstantType;
219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.ComponentName;
229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.Context;
239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.Intent;
249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.ServiceConnection;
259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.IBinder;
2603cd78cf5e51c3adb78d2e3d314838dcf3e36b26Jaikumar Ganeshimport android.os.RemoteException;
279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.Log;
289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2903cd78cf5e51c3adb78d2e3d314838dcf3e36b26Jaikumar Ganeshimport java.util.ArrayList;
3003cd78cf5e51c3adb78d2e3d314838dcf3e36b26Jaikumar Ganeshimport java.util.List;
3162c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh
329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/**
339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Public API for controlling the Bluetooth Headset Service. This includes both
3462c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * Bluetooth Headset and Handsfree (v1.5) profiles.
359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
3662c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * <p>BluetoothHeadset is a proxy object for controlling the Bluetooth Headset
379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Service via IPC.
389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
3962c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * <p> Use {@link BluetoothAdapter#getProfileProxy} to get
4062c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * the BluetoothHeadset proxy object. Use
4162c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * {@link BluetoothAdapter#closeProfileProxy} to close the service connection.
429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
4362c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * <p> Android only supports one connected Bluetooth Headset at a time.
4462c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * Each method is protected with its appropriate permission.
459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
4662c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganeshpublic final class BluetoothHeadset implements BluetoothProfile {
479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static final String TAG = "BluetoothHeadset";
489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static final boolean DBG = false;
499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5062c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh    /**
5162c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh     * Intent used to broadcast the change in connection state of the Headset
5262c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh     * profile.
5362c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh     *
5462c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh     * <p>This intent will have 3 extras:
55c8fa4ff838a0c3d2c67db65540fa751e5abe27edJaikumar Ganesh     * <ul>
56c8fa4ff838a0c3d2c67db65540fa751e5abe27edJaikumar Ganesh     *   <li> {@link #EXTRA_STATE} - The current state of the profile. </li>
57c8fa4ff838a0c3d2c67db65540fa751e5abe27edJaikumar Ganesh     *   <li> {@link #EXTRA_PREVIOUS_STATE}- The previous state of the profile. </li>
58c8fa4ff838a0c3d2c67db65540fa751e5abe27edJaikumar Ganesh     *   <li> {@link BluetoothDevice#EXTRA_DEVICE} - The remote device. </li>
59c8fa4ff838a0c3d2c67db65540fa751e5abe27edJaikumar Ganesh     * </ul>
600706fed52075f7f2b25101a40287519ac18d3184Jaikumar Ganesh     * <p>{@link #EXTRA_STATE} or {@link #EXTRA_PREVIOUS_STATE} can be any of
6162c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh     * {@link #STATE_DISCONNECTED}, {@link #STATE_CONNECTING},
6262c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh     * {@link #STATE_CONNECTED}, {@link #STATE_DISCONNECTING}.
6362c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh     *
64c8fa4ff838a0c3d2c67db65540fa751e5abe27edJaikumar Ganesh     * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission to
65c8fa4ff838a0c3d2c67db65540fa751e5abe27edJaikumar Ganesh     * receive.
6662c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh     */
67005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
6862c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh    public static final String ACTION_CONNECTION_STATE_CHANGED =
6962c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh        "android.bluetooth.headset.profile.action.CONNECTION_STATE_CHANGED";
7062c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh
71005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly    /**
7262c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh     * Intent used to broadcast the change in the Audio Connection state of the
7362c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh     * A2DP profile.
7462c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh     *
7562c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh     * <p>This intent will have 3 extras:
76c8fa4ff838a0c3d2c67db65540fa751e5abe27edJaikumar Ganesh     * <ul>
77c8fa4ff838a0c3d2c67db65540fa751e5abe27edJaikumar Ganesh     *   <li> {@link #EXTRA_STATE} - The current state of the profile. </li>
78c8fa4ff838a0c3d2c67db65540fa751e5abe27edJaikumar Ganesh     *   <li> {@link #EXTRA_PREVIOUS_STATE}- The previous state of the profile. </li>
79c8fa4ff838a0c3d2c67db65540fa751e5abe27edJaikumar Ganesh     *   <li> {@link BluetoothDevice#EXTRA_DEVICE} - The remote device. </li>
80c8fa4ff838a0c3d2c67db65540fa751e5abe27edJaikumar Ganesh     * </ul>
810706fed52075f7f2b25101a40287519ac18d3184Jaikumar Ganesh     * <p>{@link #EXTRA_STATE} or {@link #EXTRA_PREVIOUS_STATE} can be any of
8262c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh     * {@link #STATE_AUDIO_CONNECTED}, {@link #STATE_AUDIO_DISCONNECTED},
8362c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh     *
84c8fa4ff838a0c3d2c67db65540fa751e5abe27edJaikumar Ganesh     * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission
85c8fa4ff838a0c3d2c67db65540fa751e5abe27edJaikumar Ganesh     * to receive.
86005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly     */
87005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
88005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly    public static final String ACTION_AUDIO_STATE_CHANGED =
8962c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh        "android.bluetooth.headset.profile.action.AUDIO_STATE_CHANGED";
9062c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh
91c24dbdb57b30f9e8fa6b0c5b48372017b5ae46b0Jaikumar Ganesh
92005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly    /**
93e775b3daab9766bce9ec2d01fe7d652c4a782b6bJaikumar Ganesh     * Intent used to broadcast that the headset has posted a
94e775b3daab9766bce9ec2d01fe7d652c4a782b6bJaikumar Ganesh     * vendor-specific event.
95e775b3daab9766bce9ec2d01fe7d652c4a782b6bJaikumar Ganesh     *
96e775b3daab9766bce9ec2d01fe7d652c4a782b6bJaikumar Ganesh     * <p>This intent will have 4 extras and 1 category.
97c8fa4ff838a0c3d2c67db65540fa751e5abe27edJaikumar Ganesh     * <ul>
98c8fa4ff838a0c3d2c67db65540fa751e5abe27edJaikumar Ganesh     *  <li> {@link BluetoothDevice#EXTRA_DEVICE} - The remote Bluetooth Device
99c8fa4ff838a0c3d2c67db65540fa751e5abe27edJaikumar Ganesh     *       </li>
100c8fa4ff838a0c3d2c67db65540fa751e5abe27edJaikumar Ganesh     *  <li> {@link #EXTRA_VENDOR_SPECIFIC_HEADSET_EVENT_CMD} - The vendor
101c8fa4ff838a0c3d2c67db65540fa751e5abe27edJaikumar Ganesh     *       specific command </li>
102c8fa4ff838a0c3d2c67db65540fa751e5abe27edJaikumar Ganesh     *  <li> {@link #EXTRA_VENDOR_SPECIFIC_HEADSET_EVENT_CMD_TYPE} - The AT
103c8fa4ff838a0c3d2c67db65540fa751e5abe27edJaikumar Ganesh     *       command type which can be one of  {@link #AT_CMD_TYPE_READ},
104c8fa4ff838a0c3d2c67db65540fa751e5abe27edJaikumar Ganesh     *       {@link #AT_CMD_TYPE_TEST}, or {@link #AT_CMD_TYPE_SET},
1050706fed52075f7f2b25101a40287519ac18d3184Jaikumar Ganesh     *       {@link #AT_CMD_TYPE_BASIC},{@link #AT_CMD_TYPE_ACTION}. </li>
106c8fa4ff838a0c3d2c67db65540fa751e5abe27edJaikumar Ganesh     *  <li> {@link #EXTRA_VENDOR_SPECIFIC_HEADSET_EVENT_ARGS} - Command
107c8fa4ff838a0c3d2c67db65540fa751e5abe27edJaikumar Ganesh     *       arguments. </li>
108c8fa4ff838a0c3d2c67db65540fa751e5abe27edJaikumar Ganesh     * </ul>
109e775b3daab9766bce9ec2d01fe7d652c4a782b6bJaikumar Ganesh     *
1100706fed52075f7f2b25101a40287519ac18d3184Jaikumar Ganesh     *<p> The category is the Company ID of the vendor defining the
111e775b3daab9766bce9ec2d01fe7d652c4a782b6bJaikumar Ganesh     * vendor-specific command. {@link BluetoothAssignedNumbers}
112e775b3daab9766bce9ec2d01fe7d652c4a782b6bJaikumar Ganesh     *
113e775b3daab9766bce9ec2d01fe7d652c4a782b6bJaikumar Ganesh     * For example, for Plantronics specific events
114e775b3daab9766bce9ec2d01fe7d652c4a782b6bJaikumar Ganesh     * Category will be {@link #VENDOR_SPECIFIC_HEADSET_EVENT_COMPANY_ID_CATEGORY}.55
115e775b3daab9766bce9ec2d01fe7d652c4a782b6bJaikumar Ganesh     *
116e775b3daab9766bce9ec2d01fe7d652c4a782b6bJaikumar Ganesh     * <p> For example, an AT+XEVENT=foo,3 will get translated into
117c8fa4ff838a0c3d2c67db65540fa751e5abe27edJaikumar Ganesh     * <ul>
118c8fa4ff838a0c3d2c67db65540fa751e5abe27edJaikumar Ganesh     *   <li> EXTRA_VENDOR_SPECIFIC_HEADSET_EVENT_CMD = +XEVENT </li>
119c8fa4ff838a0c3d2c67db65540fa751e5abe27edJaikumar Ganesh     *   <li> EXTRA_VENDOR_SPECIFIC_HEADSET_EVENT_CMD_TYPE = AT_CMD_TYPE_SET </li>
1200706fed52075f7f2b25101a40287519ac18d3184Jaikumar Ganesh     *   <li> EXTRA_VENDOR_SPECIFIC_HEADSET_EVENT_ARGS = foo, 3 </li>
121c8fa4ff838a0c3d2c67db65540fa751e5abe27edJaikumar Ganesh     * </ul>
122c8fa4ff838a0c3d2c67db65540fa751e5abe27edJaikumar Ganesh     * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission
123c8fa4ff838a0c3d2c67db65540fa751e5abe27edJaikumar Ganesh     * to receive.
124a4733941839abd672b1e37edd7f61c8932d4aa48Herb Jellinek     */
125a4733941839abd672b1e37edd7f61c8932d4aa48Herb Jellinek    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
126a4733941839abd672b1e37edd7f61c8932d4aa48Herb Jellinek    public static final String ACTION_VENDOR_SPECIFIC_HEADSET_EVENT =
127a4733941839abd672b1e37edd7f61c8932d4aa48Herb Jellinek            "android.bluetooth.headset.action.VENDOR_SPECIFIC_HEADSET_EVENT";
128a4733941839abd672b1e37edd7f61c8932d4aa48Herb Jellinek
129a4733941839abd672b1e37edd7f61c8932d4aa48Herb Jellinek    /**
130a4733941839abd672b1e37edd7f61c8932d4aa48Herb Jellinek     * A String extra field in {@link #ACTION_VENDOR_SPECIFIC_HEADSET_EVENT}
131a4733941839abd672b1e37edd7f61c8932d4aa48Herb Jellinek     * intents that contains the name of the vendor-specific command.
132a4733941839abd672b1e37edd7f61c8932d4aa48Herb Jellinek     */
133a4733941839abd672b1e37edd7f61c8932d4aa48Herb Jellinek    public static final String EXTRA_VENDOR_SPECIFIC_HEADSET_EVENT_CMD =
134a4733941839abd672b1e37edd7f61c8932d4aa48Herb Jellinek            "android.bluetooth.headset.extra.VENDOR_SPECIFIC_HEADSET_EVENT_CMD";
135a4733941839abd672b1e37edd7f61c8932d4aa48Herb Jellinek
136a4733941839abd672b1e37edd7f61c8932d4aa48Herb Jellinek    /**
137a4733941839abd672b1e37edd7f61c8932d4aa48Herb Jellinek     * An int extra field in {@link #ACTION_VENDOR_SPECIFIC_HEADSET_EVENT}
138e775b3daab9766bce9ec2d01fe7d652c4a782b6bJaikumar Ganesh     * intents that contains the AT command type of the vendor-specific command.
139e775b3daab9766bce9ec2d01fe7d652c4a782b6bJaikumar Ganesh     */
140e775b3daab9766bce9ec2d01fe7d652c4a782b6bJaikumar Ganesh    public static final String EXTRA_VENDOR_SPECIFIC_HEADSET_EVENT_CMD_TYPE =
141e775b3daab9766bce9ec2d01fe7d652c4a782b6bJaikumar Ganesh            "android.bluetooth.headset.extra.VENDOR_SPECIFIC_HEADSET_EVENT_CMD_TYPE";
142e775b3daab9766bce9ec2d01fe7d652c4a782b6bJaikumar Ganesh
143e775b3daab9766bce9ec2d01fe7d652c4a782b6bJaikumar Ganesh    /**
144e775b3daab9766bce9ec2d01fe7d652c4a782b6bJaikumar Ganesh     * AT command type READ used with
145e775b3daab9766bce9ec2d01fe7d652c4a782b6bJaikumar Ganesh     * {@link #EXTRA_VENDOR_SPECIFIC_HEADSET_EVENT_CMD_TYPE}
146e775b3daab9766bce9ec2d01fe7d652c4a782b6bJaikumar Ganesh     * For example, AT+VGM?. There are no arguments for this command type.
147e775b3daab9766bce9ec2d01fe7d652c4a782b6bJaikumar Ganesh     */
148e775b3daab9766bce9ec2d01fe7d652c4a782b6bJaikumar Ganesh    public static final int AT_CMD_TYPE_READ = 0;
149e775b3daab9766bce9ec2d01fe7d652c4a782b6bJaikumar Ganesh
150e775b3daab9766bce9ec2d01fe7d652c4a782b6bJaikumar Ganesh    /**
151e775b3daab9766bce9ec2d01fe7d652c4a782b6bJaikumar Ganesh     * AT command type TEST used with
152e775b3daab9766bce9ec2d01fe7d652c4a782b6bJaikumar Ganesh     * {@link #EXTRA_VENDOR_SPECIFIC_HEADSET_EVENT_CMD_TYPE}
153e775b3daab9766bce9ec2d01fe7d652c4a782b6bJaikumar Ganesh     * For example, AT+VGM=?. There are no arguments for this command type.
154e775b3daab9766bce9ec2d01fe7d652c4a782b6bJaikumar Ganesh     */
155e775b3daab9766bce9ec2d01fe7d652c4a782b6bJaikumar Ganesh    public static final int AT_CMD_TYPE_TEST = 1;
156e775b3daab9766bce9ec2d01fe7d652c4a782b6bJaikumar Ganesh
157e775b3daab9766bce9ec2d01fe7d652c4a782b6bJaikumar Ganesh    /**
158e775b3daab9766bce9ec2d01fe7d652c4a782b6bJaikumar Ganesh     * AT command type SET used with
159e775b3daab9766bce9ec2d01fe7d652c4a782b6bJaikumar Ganesh     * {@link #EXTRA_VENDOR_SPECIFIC_HEADSET_EVENT_CMD_TYPE}
160e775b3daab9766bce9ec2d01fe7d652c4a782b6bJaikumar Ganesh     * For example, AT+VGM=<args>.
161e775b3daab9766bce9ec2d01fe7d652c4a782b6bJaikumar Ganesh     */
162e775b3daab9766bce9ec2d01fe7d652c4a782b6bJaikumar Ganesh    public static final int AT_CMD_TYPE_SET = 2;
163e775b3daab9766bce9ec2d01fe7d652c4a782b6bJaikumar Ganesh
164e775b3daab9766bce9ec2d01fe7d652c4a782b6bJaikumar Ganesh    /**
165e775b3daab9766bce9ec2d01fe7d652c4a782b6bJaikumar Ganesh     * AT command type BASIC used with
166e775b3daab9766bce9ec2d01fe7d652c4a782b6bJaikumar Ganesh     * {@link #EXTRA_VENDOR_SPECIFIC_HEADSET_EVENT_CMD_TYPE}
167e775b3daab9766bce9ec2d01fe7d652c4a782b6bJaikumar Ganesh     * For example, ATD. Single character commands and everything following the
168e775b3daab9766bce9ec2d01fe7d652c4a782b6bJaikumar Ganesh     * character are arguments.
169e775b3daab9766bce9ec2d01fe7d652c4a782b6bJaikumar Ganesh     */
170e775b3daab9766bce9ec2d01fe7d652c4a782b6bJaikumar Ganesh    public static final int AT_CMD_TYPE_BASIC = 3;
171e775b3daab9766bce9ec2d01fe7d652c4a782b6bJaikumar Ganesh
172e775b3daab9766bce9ec2d01fe7d652c4a782b6bJaikumar Ganesh    /**
173e775b3daab9766bce9ec2d01fe7d652c4a782b6bJaikumar Ganesh     * AT command type ACTION used with
174e775b3daab9766bce9ec2d01fe7d652c4a782b6bJaikumar Ganesh     * {@link #EXTRA_VENDOR_SPECIFIC_HEADSET_EVENT_CMD_TYPE}
175e775b3daab9766bce9ec2d01fe7d652c4a782b6bJaikumar Ganesh     * For example, AT+CHUP. There are no arguments for action commands.
176a4733941839abd672b1e37edd7f61c8932d4aa48Herb Jellinek     */
177e775b3daab9766bce9ec2d01fe7d652c4a782b6bJaikumar Ganesh    public static final int AT_CMD_TYPE_ACTION = 4;
178a4733941839abd672b1e37edd7f61c8932d4aa48Herb Jellinek
179a4733941839abd672b1e37edd7f61c8932d4aa48Herb Jellinek    /**
180a4733941839abd672b1e37edd7f61c8932d4aa48Herb Jellinek     * A Parcelable String array extra field in
181a4733941839abd672b1e37edd7f61c8932d4aa48Herb Jellinek     * {@link #ACTION_VENDOR_SPECIFIC_HEADSET_EVENT} intents that contains
182a4733941839abd672b1e37edd7f61c8932d4aa48Herb Jellinek     * the arguments to the vendor-specific command.
183a4733941839abd672b1e37edd7f61c8932d4aa48Herb Jellinek     */
184a4733941839abd672b1e37edd7f61c8932d4aa48Herb Jellinek    public static final String EXTRA_VENDOR_SPECIFIC_HEADSET_EVENT_ARGS =
185a4733941839abd672b1e37edd7f61c8932d4aa48Herb Jellinek            "android.bluetooth.headset.extra.VENDOR_SPECIFIC_HEADSET_EVENT_ARGS";
186a4733941839abd672b1e37edd7f61c8932d4aa48Herb Jellinek
187e775b3daab9766bce9ec2d01fe7d652c4a782b6bJaikumar Ganesh    /**
188e775b3daab9766bce9ec2d01fe7d652c4a782b6bJaikumar Ganesh     * The intent category to be used with {@link #ACTION_VENDOR_SPECIFIC_HEADSET_EVENT}
189e775b3daab9766bce9ec2d01fe7d652c4a782b6bJaikumar Ganesh     * for the companyId
190e775b3daab9766bce9ec2d01fe7d652c4a782b6bJaikumar Ganesh     */
191e775b3daab9766bce9ec2d01fe7d652c4a782b6bJaikumar Ganesh    public static final String VENDOR_SPECIFIC_HEADSET_EVENT_COMPANY_ID_CATEGORY  =
192e775b3daab9766bce9ec2d01fe7d652c4a782b6bJaikumar Ganesh            "android.bluetooth.headset.intent.category.companyid";
193e775b3daab9766bce9ec2d01fe7d652c4a782b6bJaikumar Ganesh
19430d181690e48b26cdfae3b144d23f1e16c75da37Jaikumar Ganesh    /**
195c8fa4ff838a0c3d2c67db65540fa751e5abe27edJaikumar Ganesh     * Headset state when SCO audio is not connected.
19662c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh     * This state can be one of
19762c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh     * {@link #EXTRA_STATE} or {@link #EXTRA_PREVIOUS_STATE} of
19862c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh     * {@link #ACTION_AUDIO_STATE_CHANGED} intent.
199005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly     */
200b0a1d01b4c044a0779cfe006e204bac468459802Jaikumar Ganesh    public static final int STATE_AUDIO_DISCONNECTED = 10;
2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
203c8fa4ff838a0c3d2c67db65540fa751e5abe27edJaikumar Ganesh     * Headset state when SCO audio is connecting.
20462c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh     * This state can be one of
20562c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh     * {@link #EXTRA_STATE} or {@link #EXTRA_PREVIOUS_STATE} of
20662c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh     * {@link #ACTION_AUDIO_STATE_CHANGED} intent.
2079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
208b0a1d01b4c044a0779cfe006e204bac468459802Jaikumar Ganesh    public static final int STATE_AUDIO_CONNECTING = 11;
20962c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh
21030d181690e48b26cdfae3b144d23f1e16c75da37Jaikumar Ganesh    /**
211c8fa4ff838a0c3d2c67db65540fa751e5abe27edJaikumar Ganesh     * Headset state when SCO audio is connected.
21230d181690e48b26cdfae3b144d23f1e16c75da37Jaikumar Ganesh     * This state can be one of
21330d181690e48b26cdfae3b144d23f1e16c75da37Jaikumar Ganesh     * {@link #EXTRA_STATE} or {@link #EXTRA_PREVIOUS_STATE} of
21430d181690e48b26cdfae3b144d23f1e16c75da37Jaikumar Ganesh     * {@link #ACTION_AUDIO_STATE_CHANGED} intent.
21530d181690e48b26cdfae3b144d23f1e16c75da37Jaikumar Ganesh     */
216b0a1d01b4c044a0779cfe006e204bac468459802Jaikumar Ganesh    public static final int STATE_AUDIO_CONNECTED = 12;
217b0a1d01b4c044a0779cfe006e204bac468459802Jaikumar Ganesh
21862c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh
21962c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh    private Context mContext;
22062c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh    private ServiceListener mServiceListener;
22162c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh    private IBluetoothHeadset mService;
22262c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh    BluetoothAdapter mAdapter;
2239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
2259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Create a BluetoothHeadset proxy object.
2269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
22762c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh    /*package*/ BluetoothHeadset(Context context, ServiceListener l) {
2289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mContext = context;
2299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mServiceListener = l;
23062c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh        mAdapter = BluetoothAdapter.getDefaultAdapter();
2319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (!context.bindService(new Intent(IBluetoothHeadset.class.getName()), mConnection, 0)) {
2329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            Log.e(TAG, "Could not bind to Bluetooth Headset Service");
2339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
2379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Close the connection to the backing service.
2389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Other public functions of BluetoothHeadset will return default error
2399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * results once close() has been called. Multiple invocations of close()
2409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * are ok.
2419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
24262c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh    /*package*/ synchronized void close() {
243f5b4b98fada53d91c4c2ebeb5a1d33ccc95c94d2The Android Open Source Project        if (DBG) log("close()");
2449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mConnection != null) {
2459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mContext.unbindService(mConnection);
2469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mConnection = null;
2479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2489bb275197df8eb999eab4cdd0a2aff83c2bb2ef6Jaikumar Ganesh        mServiceListener = null;
2499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
252f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     * Initiate connection to a profile of the remote bluetooth device.
253f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     *
254f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     * <p> Currently, the system supports only 1 connection to the
255f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     * headset/handsfree profile. The API will automatically disconnect connected
256f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     * devices before connecting.
257f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     *
258f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     * <p> This API returns false in scenarios like the profile on the
259f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     * device is already connected or Bluetooth is not turned on.
260f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     * When this API returns true, it is guaranteed that
261f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     * connection state intent for the profile will be broadcasted with
262f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     * the state. Users can get the connection state of the profile
263f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     * from this intent.
264f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     *
265f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN}
266f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     * permission.
267f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     *
268f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     * @param device Remote Bluetooth Device
269f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     * @return false on immediate error,
270f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     *               true otherwise
27162c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh     * @hide
2729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
27362c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh    public boolean connect(BluetoothDevice device) {
27462c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh        if (DBG) log("connect(" + device + ")");
27562c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh        if (mService != null && isEnabled() &&
27662c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh            isValidDevice(device)) {
2779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            try {
27862c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh                return mService.connect(device);
27962c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh            } catch (RemoteException e) {
28062c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh                Log.e(TAG, Log.getStackTraceString(new Throwable()));
28162c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh                return false;
28262c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh            }
2839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
28462c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh        if (mService == null) Log.w(TAG, "Proxy not attached to service");
28562c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh        return false;
2869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
289f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     * Initiate disconnection from a profile
290f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     *
291f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     * <p> This API will return false in scenarios like the profile on the
292f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     * Bluetooth device is not in connected state etc. When this API returns,
293f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     * true, it is guaranteed that the connection state change
294f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     * intent will be broadcasted with the state. Users can get the
295f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     * disconnection state of the profile from this intent.
296f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     *
297f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     * <p> If the disconnection is initiated by a remote device, the state
298f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     * will transition from {@link #STATE_CONNECTED} to
299f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     * {@link #STATE_DISCONNECTED}. If the disconnect is initiated by the
300f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     * host (local) device the state will transition from
301f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     * {@link #STATE_CONNECTED} to state {@link #STATE_DISCONNECTING} to
302f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     * state {@link #STATE_DISCONNECTED}. The transition to
303f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     * {@link #STATE_DISCONNECTING} can be used to distinguish between the
304f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     * two scenarios.
305f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     *
306f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN}
307f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     * permission.
308f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     *
309f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     * @param device Remote Bluetooth Device
310f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     * @return false on immediate error,
311f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     *               true otherwise
31262c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh     * @hide
3139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
31462c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh    public boolean disconnect(BluetoothDevice device) {
31562c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh        if (DBG) log("disconnect(" + device + ")");
31662c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh        if (mService != null && isEnabled() &&
31762c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh            isValidDevice(device)) {
3189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            try {
31962c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh                return mService.disconnect(device);
32062c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh            } catch (RemoteException e) {
32162c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh              Log.e(TAG, Log.getStackTraceString(new Throwable()));
32262c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh              return false;
32362c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh            }
3249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
32562c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh        if (mService == null) Log.w(TAG, "Proxy not attached to service");
32662c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh        return false;
3279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
33062c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh     * {@inheritDoc}
3319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
33203cd78cf5e51c3adb78d2e3d314838dcf3e36b26Jaikumar Ganesh    public List<BluetoothDevice> getConnectedDevices() {
33362c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh        if (DBG) log("getConnectedDevices()");
33462c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh        if (mService != null && isEnabled()) {
3359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            try {
33603cd78cf5e51c3adb78d2e3d314838dcf3e36b26Jaikumar Ganesh                return mService.getConnectedDevices();
33762c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh            } catch (RemoteException e) {
33862c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh                Log.e(TAG, Log.getStackTraceString(new Throwable()));
33903cd78cf5e51c3adb78d2e3d314838dcf3e36b26Jaikumar Ganesh                return new ArrayList<BluetoothDevice>();
34062c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh            }
3419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
34262c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh        if (mService == null) Log.w(TAG, "Proxy not attached to service");
34303cd78cf5e51c3adb78d2e3d314838dcf3e36b26Jaikumar Ganesh        return new ArrayList<BluetoothDevice>();
3449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
34762c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh     * {@inheritDoc}
3489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
34903cd78cf5e51c3adb78d2e3d314838dcf3e36b26Jaikumar Ganesh    public List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) {
35062c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh        if (DBG) log("getDevicesMatchingStates()");
35162c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh        if (mService != null && isEnabled()) {
3529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            try {
35303cd78cf5e51c3adb78d2e3d314838dcf3e36b26Jaikumar Ganesh                return mService.getDevicesMatchingConnectionStates(states);
35462c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh            } catch (RemoteException e) {
35562c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh                Log.e(TAG, Log.getStackTraceString(new Throwable()));
35603cd78cf5e51c3adb78d2e3d314838dcf3e36b26Jaikumar Ganesh                return new ArrayList<BluetoothDevice>();
35762c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh            }
3589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
35962c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh        if (mService == null) Log.w(TAG, "Proxy not attached to service");
36003cd78cf5e51c3adb78d2e3d314838dcf3e36b26Jaikumar Ganesh        return new ArrayList<BluetoothDevice>();
3619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
36462c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh     * {@inheritDoc}
3659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
36662c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh    public int getConnectionState(BluetoothDevice device) {
36762c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh        if (DBG) log("getConnectionState(" + device + ")");
36862c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh        if (mService != null && isEnabled() &&
36962c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh            isValidDevice(device)) {
3709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            try {
37162c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh                return mService.getConnectionState(device);
37262c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh            } catch (RemoteException e) {
37362c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh                Log.e(TAG, Log.getStackTraceString(new Throwable()));
37462c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh                return BluetoothProfile.STATE_DISCONNECTED;
37562c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh            }
3769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
37762c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh        if (mService == null) Log.w(TAG, "Proxy not attached to service");
37862c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh        return BluetoothProfile.STATE_DISCONNECTED;
3799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
382f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     * Set priority of the profile
383f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     *
384f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     * <p> The device should already be paired.
385f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     *  Priority can be one of {@link #PRIORITY_ON} or
386f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     * {@link #PRIORITY_OFF},
387f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     *
388f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN}
389f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     * permission.
390f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     *
391f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     * @param device Paired bluetooth device
392f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     * @param priority
393f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     * @return true if priority is set, false on error
39462c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh     * @hide
3959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
39662c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh    public boolean setPriority(BluetoothDevice device, int priority) {
39762c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh        if (DBG) log("setPriority(" + device + ", " + priority + ")");
39862c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh        if (mService != null && isEnabled() &&
39962c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh            isValidDevice(device)) {
40062c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh            if (priority != BluetoothProfile.PRIORITY_OFF &&
40162c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh                priority != BluetoothProfile.PRIORITY_ON) {
40262c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh              return false;
40362c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh            }
4049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            try {
40562c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh                return mService.setPriority(device, priority);
40662c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh            } catch (RemoteException e) {
40762c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh                Log.e(TAG, Log.getStackTraceString(new Throwable()));
40862c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh                return false;
40962c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh            }
4109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
41162c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh        if (mService == null) Log.w(TAG, "Proxy not attached to service");
4129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return false;
4139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
416f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     * Get the priority of the profile.
417f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     *
418f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     * <p> The priority can be any of:
419f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     * {@link #PRIORITY_AUTO_CONNECT}, {@link #PRIORITY_OFF},
420f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     * {@link #PRIORITY_ON}, {@link #PRIORITY_UNDEFINED}
421f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     *
422f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
423f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     *
424f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     * @param device Bluetooth device
425f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh     * @return priority of the device
42662c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh     * @hide
4279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
42862c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh    public int getPriority(BluetoothDevice device) {
42962c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh        if (DBG) log("getPriority(" + device + ")");
43062c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh        if (mService != null && isEnabled() &&
43162c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh            isValidDevice(device)) {
4329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            try {
43362c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh                return mService.getPriority(device);
43462c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh            } catch (RemoteException e) {
43562c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh                Log.e(TAG, Log.getStackTraceString(new Throwable()));
43662c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh                return PRIORITY_OFF;
43762c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh            }
4389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
43962c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh        if (mService == null) Log.w(TAG, "Proxy not attached to service");
44062c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh        return PRIORITY_OFF;
44162c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh    }
44262c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh
44362c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh    /**
44462c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh     * Start Bluetooth voice recognition. This methods sends the voice
44562c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh     * recognition AT command to the headset and establishes the
44662c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh     * audio connection.
44762c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh     *
44862c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh     * <p> Users can listen to {@link #ACTION_AUDIO_STATE_CHANGED}.
449b0a1d01b4c044a0779cfe006e204bac468459802Jaikumar Ganesh     * If this function returns true, this intent will be broadcasted with
450b0a1d01b4c044a0779cfe006e204bac468459802Jaikumar Ganesh     * {@link #EXTRA_STATE} set to {@link #STATE_AUDIO_CONNECTING}.
451b0a1d01b4c044a0779cfe006e204bac468459802Jaikumar Ganesh     *
452b0a1d01b4c044a0779cfe006e204bac468459802Jaikumar Ganesh     * <p> {@link #EXTRA_STATE} will transition from
453b0a1d01b4c044a0779cfe006e204bac468459802Jaikumar Ganesh     * {@link #STATE_AUDIO_CONNECTING} to {@link #STATE_AUDIO_CONNECTED} when
454b0a1d01b4c044a0779cfe006e204bac468459802Jaikumar Ganesh     * audio connection is established and to {@link #STATE_AUDIO_DISCONNECTED}
455b0a1d01b4c044a0779cfe006e204bac468459802Jaikumar Ganesh     * in case of failure to establish the audio connection.
45662c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh     *
457b0a1d01b4c044a0779cfe006e204bac468459802Jaikumar Ganesh     * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
45862c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh     *
45962c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh     * @param device Bluetooth headset
46062c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh     * @return false if there is no headset connected of if the
46162c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh     *               connected headset doesn't support voice recognition
46262c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh     *               or on error, true otherwise
46362c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh     */
46462c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh    public boolean startVoiceRecognition(BluetoothDevice device) {
46562c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh        if (DBG) log("startVoiceRecognition()");
46662c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh        if (mService != null && isEnabled() &&
46762c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh            isValidDevice(device)) {
46862c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh            try {
46962c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh                return mService.startVoiceRecognition(device);
47062c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh            } catch (RemoteException e) {
47162c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh                Log.e(TAG,  Log.getStackTraceString(new Throwable()));
47262c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh            }
47362c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh        }
47462c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh        if (mService == null) Log.w(TAG, "Proxy not attached to service");
4759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return false;
4769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
47962c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh     * Stop Bluetooth Voice Recognition mode, and shut down the
48062c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh     * Bluetooth audio path.
48162c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh     *
482c8fa4ff838a0c3d2c67db65540fa751e5abe27edJaikumar Ganesh     * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
48362c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh     *
48462c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh     * @param device Bluetooth headset
48562c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh     * @return false if there is no headset connected
48662c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh     *               or on error, true otherwise
4879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
48862c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh    public boolean stopVoiceRecognition(BluetoothDevice device) {
48962c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh        if (DBG) log("stopVoiceRecognition()");
49062c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh        if (mService != null && isEnabled() &&
49162c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh            isValidDevice(device)) {
4929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            try {
49362c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh                return mService.stopVoiceRecognition(device);
49462c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh            } catch (RemoteException e) {
49562c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh                Log.e(TAG,  Log.getStackTraceString(new Throwable()));
49662c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh            }
4979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
49862c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh        if (mService == null) Log.w(TAG, "Proxy not attached to service");
4999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return false;
5009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
50362c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh     * Check if Bluetooth SCO audio is connected.
50462c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh     *
505c8fa4ff838a0c3d2c67db65540fa751e5abe27edJaikumar Ganesh     * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
50662c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh     *
50762c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh     * @param device Bluetooth headset
50862c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh     * @return true if SCO is connected,
50962c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh     *         false otherwise or on error
5109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
51162c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh    public boolean isAudioConnected(BluetoothDevice device) {
51262c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh        if (DBG) log("isAudioConnected()");
51362c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh        if (mService != null && isEnabled() &&
51462c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh            isValidDevice(device)) {
5159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            try {
51662c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh              return mService.isAudioConnected(device);
51762c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh            } catch (RemoteException e) {
51862c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh              Log.e(TAG,  Log.getStackTraceString(new Throwable()));
51962c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh            }
5206c901db72dbaf57d8fdf26adae6721de14ecae22Nick Pelly        }
52162c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh        if (mService == null) Log.w(TAG, "Proxy not attached to service");
52262c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh        return false;
5236c901db72dbaf57d8fdf26adae6721de14ecae22Nick Pelly    }
5246c901db72dbaf57d8fdf26adae6721de14ecae22Nick Pelly
5256c901db72dbaf57d8fdf26adae6721de14ecae22Nick Pelly    /**
5266c901db72dbaf57d8fdf26adae6721de14ecae22Nick Pelly     * Get battery usage hint for Bluetooth Headset service.
5276c901db72dbaf57d8fdf26adae6721de14ecae22Nick Pelly     * This is a monotonically increasing integer. Wraps to 0 at
5286c901db72dbaf57d8fdf26adae6721de14ecae22Nick Pelly     * Integer.MAX_INT, and at boot.
5296c901db72dbaf57d8fdf26adae6721de14ecae22Nick Pelly     * Current implementation returns the number of AT commands handled since
5306c901db72dbaf57d8fdf26adae6721de14ecae22Nick Pelly     * boot. This is a good indicator for spammy headset/handsfree units that
5316c901db72dbaf57d8fdf26adae6721de14ecae22Nick Pelly     * can keep the device awake by polling for cellular status updates. As a
5326c901db72dbaf57d8fdf26adae6721de14ecae22Nick Pelly     * rule of thumb, each AT command prevents the CPU from sleeping for 500 ms
53362c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh     *
53462c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh     * @param device the bluetooth headset.
5356c901db72dbaf57d8fdf26adae6721de14ecae22Nick Pelly     * @return monotonically increasing battery usage hint, or a negative error
5366c901db72dbaf57d8fdf26adae6721de14ecae22Nick Pelly     *         code on error
5376c901db72dbaf57d8fdf26adae6721de14ecae22Nick Pelly     * @hide
5386c901db72dbaf57d8fdf26adae6721de14ecae22Nick Pelly     */
53962c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh    public int getBatteryUsageHint(BluetoothDevice device) {
5406c901db72dbaf57d8fdf26adae6721de14ecae22Nick Pelly        if (DBG) log("getBatteryUsageHint()");
54162c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh        if (mService != null && isEnabled() &&
54262c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh            isValidDevice(device)) {
5436c901db72dbaf57d8fdf26adae6721de14ecae22Nick Pelly            try {
54462c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh                return mService.getBatteryUsageHint(device);
54562c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh            } catch (RemoteException e) {
54662c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh                Log.e(TAG,  Log.getStackTraceString(new Throwable()));
54762c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh            }
5489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
54962c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh        if (mService == null) Log.w(TAG, "Proxy not attached to service");
5509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return -1;
5519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
55262c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh
553d726b35ebd8660022dcea706ee6d3ca51886b04eEric Laurent    /**
554d726b35ebd8660022dcea706ee6d3ca51886b04eEric Laurent     * Indicates if current platform supports voice dialing over bluetooth SCO.
55562c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh     *
556d726b35ebd8660022dcea706ee6d3ca51886b04eEric Laurent     * @return true if voice dialing over bluetooth is supported, false otherwise.
557d726b35ebd8660022dcea706ee6d3ca51886b04eEric Laurent     * @hide
558d726b35ebd8660022dcea706ee6d3ca51886b04eEric Laurent     */
559d726b35ebd8660022dcea706ee6d3ca51886b04eEric Laurent    public static boolean isBluetoothVoiceDialingEnabled(Context context) {
560d726b35ebd8660022dcea706ee6d3ca51886b04eEric Laurent        return context.getResources().getBoolean(
561d726b35ebd8660022dcea706ee6d3ca51886b04eEric Laurent                com.android.internal.R.bool.config_bluetooth_sco_off_call);
562d726b35ebd8660022dcea706ee6d3ca51886b04eEric Laurent    }
563d726b35ebd8660022dcea706ee6d3ca51886b04eEric Laurent
5649b637e5985f9a86f39d70335c0390ade3716592aJaikumar Ganesh    /**
5659b637e5985f9a86f39d70335c0390ade3716592aJaikumar Ganesh     * Cancel the outgoing connection.
56662c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh     * Note: This is an internal function and shouldn't be exposed
56762c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh     *
5689b637e5985f9a86f39d70335c0390ade3716592aJaikumar Ganesh     * @hide
5699b637e5985f9a86f39d70335c0390ade3716592aJaikumar Ganesh     */
5709b637e5985f9a86f39d70335c0390ade3716592aJaikumar Ganesh    public boolean cancelConnectThread() {
5719b637e5985f9a86f39d70335c0390ade3716592aJaikumar Ganesh        if (DBG) log("cancelConnectThread");
57262c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh        if (mService != null && isEnabled()) {
5739b637e5985f9a86f39d70335c0390ade3716592aJaikumar Ganesh            try {
5749b637e5985f9a86f39d70335c0390ade3716592aJaikumar Ganesh                return mService.cancelConnectThread();
5759b637e5985f9a86f39d70335c0390ade3716592aJaikumar Ganesh            } catch (RemoteException e) {Log.e(TAG, e.toString());}
5769b637e5985f9a86f39d70335c0390ade3716592aJaikumar Ganesh        } else {
5779b637e5985f9a86f39d70335c0390ade3716592aJaikumar Ganesh            Log.w(TAG, "Proxy not attached to service");
5789b637e5985f9a86f39d70335c0390ade3716592aJaikumar Ganesh            if (DBG) Log.d(TAG, Log.getStackTraceString(new Throwable()));
5799b637e5985f9a86f39d70335c0390ade3716592aJaikumar Ganesh        }
5809b637e5985f9a86f39d70335c0390ade3716592aJaikumar Ganesh        return false;
5819b637e5985f9a86f39d70335c0390ade3716592aJaikumar Ganesh    }
5829b637e5985f9a86f39d70335c0390ade3716592aJaikumar Ganesh
5839b637e5985f9a86f39d70335c0390ade3716592aJaikumar Ganesh    /**
5849b637e5985f9a86f39d70335c0390ade3716592aJaikumar Ganesh     * Accept the incoming connection.
58562c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh     * Note: This is an internal function and shouldn't be exposed
58662c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh     *
5879b637e5985f9a86f39d70335c0390ade3716592aJaikumar Ganesh     * @hide
5889b637e5985f9a86f39d70335c0390ade3716592aJaikumar Ganesh     */
5899b637e5985f9a86f39d70335c0390ade3716592aJaikumar Ganesh    public boolean acceptIncomingConnect(BluetoothDevice device) {
5909b637e5985f9a86f39d70335c0390ade3716592aJaikumar Ganesh        if (DBG) log("acceptIncomingConnect");
59162c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh        if (mService != null && isEnabled()) {
5929b637e5985f9a86f39d70335c0390ade3716592aJaikumar Ganesh            try {
5939b637e5985f9a86f39d70335c0390ade3716592aJaikumar Ganesh                return mService.acceptIncomingConnect(device);
5949b637e5985f9a86f39d70335c0390ade3716592aJaikumar Ganesh            } catch (RemoteException e) {Log.e(TAG, e.toString());}
5959b637e5985f9a86f39d70335c0390ade3716592aJaikumar Ganesh        } else {
5969b637e5985f9a86f39d70335c0390ade3716592aJaikumar Ganesh            Log.w(TAG, "Proxy not attached to service");
5979b637e5985f9a86f39d70335c0390ade3716592aJaikumar Ganesh            if (DBG) Log.d(TAG, Log.getStackTraceString(new Throwable()));
5989b637e5985f9a86f39d70335c0390ade3716592aJaikumar Ganesh        }
5999b637e5985f9a86f39d70335c0390ade3716592aJaikumar Ganesh        return false;
6009b637e5985f9a86f39d70335c0390ade3716592aJaikumar Ganesh    }
6019b637e5985f9a86f39d70335c0390ade3716592aJaikumar Ganesh
6029b637e5985f9a86f39d70335c0390ade3716592aJaikumar Ganesh    /**
60362c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh     * Create the connect thread for the incoming connection.
60462c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh     * Note: This is an internal function and shouldn't be exposed
60562c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh     *
6069b637e5985f9a86f39d70335c0390ade3716592aJaikumar Ganesh     * @hide
6079b637e5985f9a86f39d70335c0390ade3716592aJaikumar Ganesh     */
6089b637e5985f9a86f39d70335c0390ade3716592aJaikumar Ganesh    public boolean createIncomingConnect(BluetoothDevice device) {
6099b637e5985f9a86f39d70335c0390ade3716592aJaikumar Ganesh        if (DBG) log("createIncomingConnect");
61062c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh        if (mService != null && isEnabled()) {
6119b637e5985f9a86f39d70335c0390ade3716592aJaikumar Ganesh            try {
6129b637e5985f9a86f39d70335c0390ade3716592aJaikumar Ganesh                return mService.createIncomingConnect(device);
6139b637e5985f9a86f39d70335c0390ade3716592aJaikumar Ganesh            } catch (RemoteException e) {Log.e(TAG, e.toString());}
6149b637e5985f9a86f39d70335c0390ade3716592aJaikumar Ganesh        } else {
6159b637e5985f9a86f39d70335c0390ade3716592aJaikumar Ganesh            Log.w(TAG, "Proxy not attached to service");
6169b637e5985f9a86f39d70335c0390ade3716592aJaikumar Ganesh            if (DBG) Log.d(TAG, Log.getStackTraceString(new Throwable()));
6179b637e5985f9a86f39d70335c0390ade3716592aJaikumar Ganesh        }
6189b637e5985f9a86f39d70335c0390ade3716592aJaikumar Ganesh        return false;
6199b637e5985f9a86f39d70335c0390ade3716592aJaikumar Ganesh    }
6209b637e5985f9a86f39d70335c0390ade3716592aJaikumar Ganesh
6219b637e5985f9a86f39d70335c0390ade3716592aJaikumar Ganesh    /**
622a0c680393f2dd03a937c598b2cb9abf98a58152cMatthew Xie     * Reject the incoming connection.
623a0c680393f2dd03a937c598b2cb9abf98a58152cMatthew Xie     * @hide
624a0c680393f2dd03a937c598b2cb9abf98a58152cMatthew Xie     */
625a0c680393f2dd03a937c598b2cb9abf98a58152cMatthew Xie    public boolean rejectIncomingConnect(BluetoothDevice device) {
626a0c680393f2dd03a937c598b2cb9abf98a58152cMatthew Xie        if (DBG) log("rejectIncomingConnect");
627a0c680393f2dd03a937c598b2cb9abf98a58152cMatthew Xie        if (mService != null) {
628a0c680393f2dd03a937c598b2cb9abf98a58152cMatthew Xie            try {
629a0c680393f2dd03a937c598b2cb9abf98a58152cMatthew Xie                return mService.rejectIncomingConnect(device);
630a0c680393f2dd03a937c598b2cb9abf98a58152cMatthew Xie            } catch (RemoteException e) {Log.e(TAG, e.toString());}
631a0c680393f2dd03a937c598b2cb9abf98a58152cMatthew Xie        } else {
632a0c680393f2dd03a937c598b2cb9abf98a58152cMatthew Xie            Log.w(TAG, "Proxy not attached to service");
633a0c680393f2dd03a937c598b2cb9abf98a58152cMatthew Xie            if (DBG) Log.d(TAG, Log.getStackTraceString(new Throwable()));
634a0c680393f2dd03a937c598b2cb9abf98a58152cMatthew Xie        }
635a0c680393f2dd03a937c598b2cb9abf98a58152cMatthew Xie        return false;
636a0c680393f2dd03a937c598b2cb9abf98a58152cMatthew Xie    }
637a0c680393f2dd03a937c598b2cb9abf98a58152cMatthew Xie
638a0c680393f2dd03a937c598b2cb9abf98a58152cMatthew Xie    /**
6399b637e5985f9a86f39d70335c0390ade3716592aJaikumar Ganesh     * Connect to a Bluetooth Headset.
6409b637e5985f9a86f39d70335c0390ade3716592aJaikumar Ganesh     * Note: This is an internal function and shouldn't be exposed
64162c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh     *
6429b637e5985f9a86f39d70335c0390ade3716592aJaikumar Ganesh     * @hide
6439b637e5985f9a86f39d70335c0390ade3716592aJaikumar Ganesh     */
6449b637e5985f9a86f39d70335c0390ade3716592aJaikumar Ganesh    public boolean connectHeadsetInternal(BluetoothDevice device) {
6459b637e5985f9a86f39d70335c0390ade3716592aJaikumar Ganesh        if (DBG) log("connectHeadsetInternal");
64662c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh        if (mService != null && isEnabled()) {
6479b637e5985f9a86f39d70335c0390ade3716592aJaikumar Ganesh            try {
6489b637e5985f9a86f39d70335c0390ade3716592aJaikumar Ganesh                return mService.connectHeadsetInternal(device);
6499b637e5985f9a86f39d70335c0390ade3716592aJaikumar Ganesh            } catch (RemoteException e) {Log.e(TAG, e.toString());}
6509b637e5985f9a86f39d70335c0390ade3716592aJaikumar Ganesh        } else {
6519b637e5985f9a86f39d70335c0390ade3716592aJaikumar Ganesh            Log.w(TAG, "Proxy not attached to service");
6529b637e5985f9a86f39d70335c0390ade3716592aJaikumar Ganesh            if (DBG) Log.d(TAG, Log.getStackTraceString(new Throwable()));
6539b637e5985f9a86f39d70335c0390ade3716592aJaikumar Ganesh        }
6549b637e5985f9a86f39d70335c0390ade3716592aJaikumar Ganesh        return false;
6559b637e5985f9a86f39d70335c0390ade3716592aJaikumar Ganesh    }
6569b637e5985f9a86f39d70335c0390ade3716592aJaikumar Ganesh
6579b637e5985f9a86f39d70335c0390ade3716592aJaikumar Ganesh    /**
6589b637e5985f9a86f39d70335c0390ade3716592aJaikumar Ganesh     * Disconnect a Bluetooth Headset.
6599b637e5985f9a86f39d70335c0390ade3716592aJaikumar Ganesh     * Note: This is an internal function and shouldn't be exposed
66062c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh     *
6619b637e5985f9a86f39d70335c0390ade3716592aJaikumar Ganesh     * @hide
6629b637e5985f9a86f39d70335c0390ade3716592aJaikumar Ganesh     */
6639b637e5985f9a86f39d70335c0390ade3716592aJaikumar Ganesh    public boolean disconnectHeadsetInternal(BluetoothDevice device) {
6649b637e5985f9a86f39d70335c0390ade3716592aJaikumar Ganesh        if (DBG) log("disconnectHeadsetInternal");
665e3dc975acb716eede4abb0d1f4a5f969f92fc307Matthew Xie        if (mService != null && !isDisabled()) {
6669b637e5985f9a86f39d70335c0390ade3716592aJaikumar Ganesh            try {
6679b637e5985f9a86f39d70335c0390ade3716592aJaikumar Ganesh                 return mService.disconnectHeadsetInternal(device);
6689b637e5985f9a86f39d70335c0390ade3716592aJaikumar Ganesh            } catch (RemoteException e) {Log.e(TAG, e.toString());}
6699b637e5985f9a86f39d70335c0390ade3716592aJaikumar Ganesh        } else {
6709b637e5985f9a86f39d70335c0390ade3716592aJaikumar Ganesh            Log.w(TAG, "Proxy not attached to service");
6719b637e5985f9a86f39d70335c0390ade3716592aJaikumar Ganesh            if (DBG) Log.d(TAG, Log.getStackTraceString(new Throwable()));
6729b637e5985f9a86f39d70335c0390ade3716592aJaikumar Ganesh        }
6739b637e5985f9a86f39d70335c0390ade3716592aJaikumar Ganesh        return false;
6749b637e5985f9a86f39d70335c0390ade3716592aJaikumar Ganesh    }
67562c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh
67662c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh    /**
67762c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh     * Set the audio state of the Headset.
67862c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh     * Note: This is an internal function and shouldn't be exposed
67962c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh     *
68062c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh     * @hide
68162c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh     */
68262c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh    public boolean setAudioState(BluetoothDevice device, int state) {
68362c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh        if (DBG) log("setAudioState");
6846f7a9736602ba1f1dc5a16542aa947861a520ec5Jaikumar Ganesh        if (mService != null && !isDisabled()) {
68562c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh            try {
68662c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh                return mService.setAudioState(device, state);
68762c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh            } catch (RemoteException e) {Log.e(TAG, e.toString());}
68862c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh        } else {
68962c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh            Log.w(TAG, "Proxy not attached to service");
69062c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh            if (DBG) Log.d(TAG, Log.getStackTraceString(new Throwable()));
69162c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh        }
69262c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh        return false;
69362c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh    }
69462c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh
69530d181690e48b26cdfae3b144d23f1e16c75da37Jaikumar Ganesh    /**
69630d181690e48b26cdfae3b144d23f1e16c75da37Jaikumar Ganesh     * Get the current audio state of the Headset.
69730d181690e48b26cdfae3b144d23f1e16c75da37Jaikumar Ganesh     * Note: This is an internal function and shouldn't be exposed
69830d181690e48b26cdfae3b144d23f1e16c75da37Jaikumar Ganesh     *
69930d181690e48b26cdfae3b144d23f1e16c75da37Jaikumar Ganesh     * @hide
70030d181690e48b26cdfae3b144d23f1e16c75da37Jaikumar Ganesh     */
70130d181690e48b26cdfae3b144d23f1e16c75da37Jaikumar Ganesh    public int getAudioState(BluetoothDevice device) {
70230d181690e48b26cdfae3b144d23f1e16c75da37Jaikumar Ganesh        if (DBG) log("getAudioState");
7036f7a9736602ba1f1dc5a16542aa947861a520ec5Jaikumar Ganesh        if (mService != null && !isDisabled()) {
70430d181690e48b26cdfae3b144d23f1e16c75da37Jaikumar Ganesh            try {
70530d181690e48b26cdfae3b144d23f1e16c75da37Jaikumar Ganesh                return mService.getAudioState(device);
70630d181690e48b26cdfae3b144d23f1e16c75da37Jaikumar Ganesh            } catch (RemoteException e) {Log.e(TAG, e.toString());}
70730d181690e48b26cdfae3b144d23f1e16c75da37Jaikumar Ganesh        } else {
70830d181690e48b26cdfae3b144d23f1e16c75da37Jaikumar Ganesh            Log.w(TAG, "Proxy not attached to service");
70930d181690e48b26cdfae3b144d23f1e16c75da37Jaikumar Ganesh            if (DBG) Log.d(TAG, Log.getStackTraceString(new Throwable()));
71030d181690e48b26cdfae3b144d23f1e16c75da37Jaikumar Ganesh        }
71130d181690e48b26cdfae3b144d23f1e16c75da37Jaikumar Ganesh        return BluetoothHeadset.STATE_AUDIO_DISCONNECTED;
71230d181690e48b26cdfae3b144d23f1e16c75da37Jaikumar Ganesh    }
71330d181690e48b26cdfae3b144d23f1e16c75da37Jaikumar Ganesh
714f2e6b13620f3ebbb94166834abaaabcc08a403b7Jaikumar Ganesh    /**
715dde68c64fd8e97a592633ec4c09283ec928e5697Jaikumar Ganesh     * Initiates a SCO channel connection with the headset (if connected).
716dde68c64fd8e97a592633ec4c09283ec928e5697Jaikumar Ganesh     * Also initiates a virtual voice call for Handsfree devices as many devices
717dde68c64fd8e97a592633ec4c09283ec928e5697Jaikumar Ganesh     * do not accept SCO audio without a call.
718dde68c64fd8e97a592633ec4c09283ec928e5697Jaikumar Ganesh     * This API allows the handsfree device to be used for routing non-cellular
719dde68c64fd8e97a592633ec4c09283ec928e5697Jaikumar Ganesh     * call audio.
720f2e6b13620f3ebbb94166834abaaabcc08a403b7Jaikumar Ganesh     *
721f2e6b13620f3ebbb94166834abaaabcc08a403b7Jaikumar Ganesh     * @param device Remote Bluetooth Device
722f2e6b13620f3ebbb94166834abaaabcc08a403b7Jaikumar Ganesh     * @return true if successful, false if there was some error.
723f2e6b13620f3ebbb94166834abaaabcc08a403b7Jaikumar Ganesh     * @hide
724f2e6b13620f3ebbb94166834abaaabcc08a403b7Jaikumar Ganesh     */
725dde68c64fd8e97a592633ec4c09283ec928e5697Jaikumar Ganesh    public boolean startScoUsingVirtualVoiceCall(BluetoothDevice device) {
726dde68c64fd8e97a592633ec4c09283ec928e5697Jaikumar Ganesh        if (DBG) log("startScoUsingVirtualVoiceCall()");
727f2e6b13620f3ebbb94166834abaaabcc08a403b7Jaikumar Ganesh        if (mService != null && isEnabled() && isValidDevice(device)) {
728f2e6b13620f3ebbb94166834abaaabcc08a403b7Jaikumar Ganesh            try {
729dde68c64fd8e97a592633ec4c09283ec928e5697Jaikumar Ganesh                return mService.startScoUsingVirtualVoiceCall(device);
730f2e6b13620f3ebbb94166834abaaabcc08a403b7Jaikumar Ganesh            } catch (RemoteException e) {
731f2e6b13620f3ebbb94166834abaaabcc08a403b7Jaikumar Ganesh                Log.e(TAG, e.toString());
732f2e6b13620f3ebbb94166834abaaabcc08a403b7Jaikumar Ganesh            }
733f2e6b13620f3ebbb94166834abaaabcc08a403b7Jaikumar Ganesh        } else {
734f2e6b13620f3ebbb94166834abaaabcc08a403b7Jaikumar Ganesh            Log.w(TAG, "Proxy not attached to service");
735f2e6b13620f3ebbb94166834abaaabcc08a403b7Jaikumar Ganesh            if (DBG) Log.d(TAG, Log.getStackTraceString(new Throwable()));
736f2e6b13620f3ebbb94166834abaaabcc08a403b7Jaikumar Ganesh        }
737f2e6b13620f3ebbb94166834abaaabcc08a403b7Jaikumar Ganesh        return false;
738f2e6b13620f3ebbb94166834abaaabcc08a403b7Jaikumar Ganesh    }
739f2e6b13620f3ebbb94166834abaaabcc08a403b7Jaikumar Ganesh
740f2e6b13620f3ebbb94166834abaaabcc08a403b7Jaikumar Ganesh    /**
741dde68c64fd8e97a592633ec4c09283ec928e5697Jaikumar Ganesh     * Terminates an ongoing SCO connection and the associated virtual
742dde68c64fd8e97a592633ec4c09283ec928e5697Jaikumar Ganesh     * call.
743f2e6b13620f3ebbb94166834abaaabcc08a403b7Jaikumar Ganesh     *
744f2e6b13620f3ebbb94166834abaaabcc08a403b7Jaikumar Ganesh     * @param device Remote Bluetooth Device
745f2e6b13620f3ebbb94166834abaaabcc08a403b7Jaikumar Ganesh     * @return true if successful, false if there was some error.
746f2e6b13620f3ebbb94166834abaaabcc08a403b7Jaikumar Ganesh     * @hide
747f2e6b13620f3ebbb94166834abaaabcc08a403b7Jaikumar Ganesh     */
748dde68c64fd8e97a592633ec4c09283ec928e5697Jaikumar Ganesh    public boolean stopScoUsingVirtualVoiceCall(BluetoothDevice device) {
749dde68c64fd8e97a592633ec4c09283ec928e5697Jaikumar Ganesh        if (DBG) log("stopScoUsingVirtualVoiceCall()");
750f2e6b13620f3ebbb94166834abaaabcc08a403b7Jaikumar Ganesh        if (mService != null && isEnabled() && isValidDevice(device)) {
751f2e6b13620f3ebbb94166834abaaabcc08a403b7Jaikumar Ganesh            try {
752dde68c64fd8e97a592633ec4c09283ec928e5697Jaikumar Ganesh                return mService.stopScoUsingVirtualVoiceCall(device);
753f2e6b13620f3ebbb94166834abaaabcc08a403b7Jaikumar Ganesh            } catch (RemoteException e) {
754f2e6b13620f3ebbb94166834abaaabcc08a403b7Jaikumar Ganesh                Log.e(TAG, e.toString());
755f2e6b13620f3ebbb94166834abaaabcc08a403b7Jaikumar Ganesh            }
756f2e6b13620f3ebbb94166834abaaabcc08a403b7Jaikumar Ganesh        } else {
757f2e6b13620f3ebbb94166834abaaabcc08a403b7Jaikumar Ganesh            Log.w(TAG, "Proxy not attached to service");
758f2e6b13620f3ebbb94166834abaaabcc08a403b7Jaikumar Ganesh            if (DBG) Log.d(TAG, Log.getStackTraceString(new Throwable()));
759f2e6b13620f3ebbb94166834abaaabcc08a403b7Jaikumar Ganesh        }
760f2e6b13620f3ebbb94166834abaaabcc08a403b7Jaikumar Ganesh        return false;
761f2e6b13620f3ebbb94166834abaaabcc08a403b7Jaikumar Ganesh    }
762f2e6b13620f3ebbb94166834abaaabcc08a403b7Jaikumar Ganesh
7639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private ServiceConnection mConnection = new ServiceConnection() {
7649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void onServiceConnected(ComponentName className, IBinder service) {
7659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (DBG) Log.d(TAG, "Proxy object connected");
7669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mService = IBluetoothHeadset.Stub.asInterface(service);
76762c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh
7689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (mServiceListener != null) {
76962c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh                mServiceListener.onServiceConnected(BluetoothProfile.HEADSET, BluetoothHeadset.this);
7709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
7719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
7729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void onServiceDisconnected(ComponentName className) {
7739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (DBG) Log.d(TAG, "Proxy object disconnected");
7749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mService = null;
7759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (mServiceListener != null) {
77662c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh                mServiceListener.onServiceDisconnected(BluetoothProfile.HEADSET);
7779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
7789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
7799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    };
780f5b4b98fada53d91c4c2ebeb5a1d33ccc95c94d2The Android Open Source Project
78162c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh    private boolean isEnabled() {
78262c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh       if (mAdapter.getState() == BluetoothAdapter.STATE_ON) return true;
78362c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh       return false;
78462c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh    }
78562c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh
7866f7a9736602ba1f1dc5a16542aa947861a520ec5Jaikumar Ganesh    private boolean isDisabled() {
7876f7a9736602ba1f1dc5a16542aa947861a520ec5Jaikumar Ganesh       if (mAdapter.getState() == BluetoothAdapter.STATE_OFF) return true;
7886f7a9736602ba1f1dc5a16542aa947861a520ec5Jaikumar Ganesh       return false;
7896f7a9736602ba1f1dc5a16542aa947861a520ec5Jaikumar Ganesh    }
7906f7a9736602ba1f1dc5a16542aa947861a520ec5Jaikumar Ganesh
79162c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh    private boolean isValidDevice(BluetoothDevice device) {
79262c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh       if (device == null) return false;
79362c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh
79462c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh       if (BluetoothAdapter.checkBluetoothAddress(device.getAddress())) return true;
79562c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh       return false;
79662c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh    }
79762c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh
798f5b4b98fada53d91c4c2ebeb5a1d33ccc95c94d2The Android Open Source Project    private static void log(String msg) {
799f5b4b98fada53d91c4c2ebeb5a1d33ccc95c94d2The Android Open Source Project        Log.d(TAG, msg);
800f5b4b98fada53d91c4c2ebeb5a1d33ccc95c94d2The Android Open Source Project    }
8019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
802