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"; 480f42037eb7b5118015c2caca635538324ccf0ccffredc private static final boolean DBG = true; 49563e414784eb81e4ea4051667d5c8855b17f7534Matthew Xie private static final boolean VDBG = false; 509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5162c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh /** 5262c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * Intent used to broadcast the change in connection state of the Headset 5362c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * profile. 5462c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * 5562c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * <p>This intent will have 3 extras: 56c8fa4ff838a0c3d2c67db65540fa751e5abe27edJaikumar Ganesh * <ul> 57c8fa4ff838a0c3d2c67db65540fa751e5abe27edJaikumar Ganesh * <li> {@link #EXTRA_STATE} - The current state of the profile. </li> 58c8fa4ff838a0c3d2c67db65540fa751e5abe27edJaikumar Ganesh * <li> {@link #EXTRA_PREVIOUS_STATE}- The previous state of the profile. </li> 59c8fa4ff838a0c3d2c67db65540fa751e5abe27edJaikumar Ganesh * <li> {@link BluetoothDevice#EXTRA_DEVICE} - The remote device. </li> 60c8fa4ff838a0c3d2c67db65540fa751e5abe27edJaikumar Ganesh * </ul> 610706fed52075f7f2b25101a40287519ac18d3184Jaikumar Ganesh * <p>{@link #EXTRA_STATE} or {@link #EXTRA_PREVIOUS_STATE} can be any of 6262c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * {@link #STATE_DISCONNECTED}, {@link #STATE_CONNECTING}, 6362c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * {@link #STATE_CONNECTED}, {@link #STATE_DISCONNECTING}. 6462c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * 65c8fa4ff838a0c3d2c67db65540fa751e5abe27edJaikumar Ganesh * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission to 66c8fa4ff838a0c3d2c67db65540fa751e5abe27edJaikumar Ganesh * receive. 6762c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh */ 68005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) 6962c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh public static final String ACTION_CONNECTION_STATE_CHANGED = 7062c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh "android.bluetooth.headset.profile.action.CONNECTION_STATE_CHANGED"; 7162c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh 72005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly /** 7362c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * Intent used to broadcast the change in the Audio Connection state of the 7462c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * A2DP profile. 7562c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * 7662c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * <p>This intent will have 3 extras: 77c8fa4ff838a0c3d2c67db65540fa751e5abe27edJaikumar Ganesh * <ul> 78c8fa4ff838a0c3d2c67db65540fa751e5abe27edJaikumar Ganesh * <li> {@link #EXTRA_STATE} - The current state of the profile. </li> 79c8fa4ff838a0c3d2c67db65540fa751e5abe27edJaikumar Ganesh * <li> {@link #EXTRA_PREVIOUS_STATE}- The previous state of the profile. </li> 80c8fa4ff838a0c3d2c67db65540fa751e5abe27edJaikumar Ganesh * <li> {@link BluetoothDevice#EXTRA_DEVICE} - The remote device. </li> 81c8fa4ff838a0c3d2c67db65540fa751e5abe27edJaikumar Ganesh * </ul> 820706fed52075f7f2b25101a40287519ac18d3184Jaikumar Ganesh * <p>{@link #EXTRA_STATE} or {@link #EXTRA_PREVIOUS_STATE} can be any of 8362c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * {@link #STATE_AUDIO_CONNECTED}, {@link #STATE_AUDIO_DISCONNECTED}, 8462c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * 85c8fa4ff838a0c3d2c67db65540fa751e5abe27edJaikumar Ganesh * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission 86c8fa4ff838a0c3d2c67db65540fa751e5abe27edJaikumar Ganesh * to receive. 87005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly */ 88005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) 89005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly public static final String ACTION_AUDIO_STATE_CHANGED = 9062c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh "android.bluetooth.headset.profile.action.AUDIO_STATE_CHANGED"; 9162c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh 92c24dbdb57b30f9e8fa6b0c5b48372017b5ae46b0Jaikumar Ganesh 93005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly /** 94e775b3daab9766bce9ec2d01fe7d652c4a782b6bJaikumar Ganesh * Intent used to broadcast that the headset has posted a 95e775b3daab9766bce9ec2d01fe7d652c4a782b6bJaikumar Ganesh * vendor-specific event. 96e775b3daab9766bce9ec2d01fe7d652c4a782b6bJaikumar Ganesh * 97e775b3daab9766bce9ec2d01fe7d652c4a782b6bJaikumar Ganesh * <p>This intent will have 4 extras and 1 category. 98c8fa4ff838a0c3d2c67db65540fa751e5abe27edJaikumar Ganesh * <ul> 99c8fa4ff838a0c3d2c67db65540fa751e5abe27edJaikumar Ganesh * <li> {@link BluetoothDevice#EXTRA_DEVICE} - The remote Bluetooth Device 100c8fa4ff838a0c3d2c67db65540fa751e5abe27edJaikumar Ganesh * </li> 101c8fa4ff838a0c3d2c67db65540fa751e5abe27edJaikumar Ganesh * <li> {@link #EXTRA_VENDOR_SPECIFIC_HEADSET_EVENT_CMD} - The vendor 102c8fa4ff838a0c3d2c67db65540fa751e5abe27edJaikumar Ganesh * specific command </li> 103c8fa4ff838a0c3d2c67db65540fa751e5abe27edJaikumar Ganesh * <li> {@link #EXTRA_VENDOR_SPECIFIC_HEADSET_EVENT_CMD_TYPE} - The AT 104c8fa4ff838a0c3d2c67db65540fa751e5abe27edJaikumar Ganesh * command type which can be one of {@link #AT_CMD_TYPE_READ}, 105c8fa4ff838a0c3d2c67db65540fa751e5abe27edJaikumar Ganesh * {@link #AT_CMD_TYPE_TEST}, or {@link #AT_CMD_TYPE_SET}, 1060706fed52075f7f2b25101a40287519ac18d3184Jaikumar Ganesh * {@link #AT_CMD_TYPE_BASIC},{@link #AT_CMD_TYPE_ACTION}. </li> 107c8fa4ff838a0c3d2c67db65540fa751e5abe27edJaikumar Ganesh * <li> {@link #EXTRA_VENDOR_SPECIFIC_HEADSET_EVENT_ARGS} - Command 108c8fa4ff838a0c3d2c67db65540fa751e5abe27edJaikumar Ganesh * arguments. </li> 109c8fa4ff838a0c3d2c67db65540fa751e5abe27edJaikumar Ganesh * </ul> 110e775b3daab9766bce9ec2d01fe7d652c4a782b6bJaikumar Ganesh * 1110706fed52075f7f2b25101a40287519ac18d3184Jaikumar Ganesh *<p> The category is the Company ID of the vendor defining the 112e775b3daab9766bce9ec2d01fe7d652c4a782b6bJaikumar Ganesh * vendor-specific command. {@link BluetoothAssignedNumbers} 113e775b3daab9766bce9ec2d01fe7d652c4a782b6bJaikumar Ganesh * 114e775b3daab9766bce9ec2d01fe7d652c4a782b6bJaikumar Ganesh * For example, for Plantronics specific events 115e775b3daab9766bce9ec2d01fe7d652c4a782b6bJaikumar Ganesh * Category will be {@link #VENDOR_SPECIFIC_HEADSET_EVENT_COMPANY_ID_CATEGORY}.55 116e775b3daab9766bce9ec2d01fe7d652c4a782b6bJaikumar Ganesh * 117e775b3daab9766bce9ec2d01fe7d652c4a782b6bJaikumar Ganesh * <p> For example, an AT+XEVENT=foo,3 will get translated into 118c8fa4ff838a0c3d2c67db65540fa751e5abe27edJaikumar Ganesh * <ul> 119c8fa4ff838a0c3d2c67db65540fa751e5abe27edJaikumar Ganesh * <li> EXTRA_VENDOR_SPECIFIC_HEADSET_EVENT_CMD = +XEVENT </li> 120c8fa4ff838a0c3d2c67db65540fa751e5abe27edJaikumar Ganesh * <li> EXTRA_VENDOR_SPECIFIC_HEADSET_EVENT_CMD_TYPE = AT_CMD_TYPE_SET </li> 1210706fed52075f7f2b25101a40287519ac18d3184Jaikumar Ganesh * <li> EXTRA_VENDOR_SPECIFIC_HEADSET_EVENT_ARGS = foo, 3 </li> 122c8fa4ff838a0c3d2c67db65540fa751e5abe27edJaikumar Ganesh * </ul> 123c8fa4ff838a0c3d2c67db65540fa751e5abe27edJaikumar Ganesh * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission 124c8fa4ff838a0c3d2c67db65540fa751e5abe27edJaikumar Ganesh * to receive. 125a4733941839abd672b1e37edd7f61c8932d4aa48Herb Jellinek */ 126a4733941839abd672b1e37edd7f61c8932d4aa48Herb Jellinek @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) 127a4733941839abd672b1e37edd7f61c8932d4aa48Herb Jellinek public static final String ACTION_VENDOR_SPECIFIC_HEADSET_EVENT = 128a4733941839abd672b1e37edd7f61c8932d4aa48Herb Jellinek "android.bluetooth.headset.action.VENDOR_SPECIFIC_HEADSET_EVENT"; 129a4733941839abd672b1e37edd7f61c8932d4aa48Herb Jellinek 130a4733941839abd672b1e37edd7f61c8932d4aa48Herb Jellinek /** 131a4733941839abd672b1e37edd7f61c8932d4aa48Herb Jellinek * A String extra field in {@link #ACTION_VENDOR_SPECIFIC_HEADSET_EVENT} 132a4733941839abd672b1e37edd7f61c8932d4aa48Herb Jellinek * intents that contains the name of the vendor-specific command. 133a4733941839abd672b1e37edd7f61c8932d4aa48Herb Jellinek */ 134a4733941839abd672b1e37edd7f61c8932d4aa48Herb Jellinek public static final String EXTRA_VENDOR_SPECIFIC_HEADSET_EVENT_CMD = 135a4733941839abd672b1e37edd7f61c8932d4aa48Herb Jellinek "android.bluetooth.headset.extra.VENDOR_SPECIFIC_HEADSET_EVENT_CMD"; 136a4733941839abd672b1e37edd7f61c8932d4aa48Herb Jellinek 137a4733941839abd672b1e37edd7f61c8932d4aa48Herb Jellinek /** 138a4733941839abd672b1e37edd7f61c8932d4aa48Herb Jellinek * An int extra field in {@link #ACTION_VENDOR_SPECIFIC_HEADSET_EVENT} 139e775b3daab9766bce9ec2d01fe7d652c4a782b6bJaikumar Ganesh * intents that contains the AT command type of the vendor-specific command. 140e775b3daab9766bce9ec2d01fe7d652c4a782b6bJaikumar Ganesh */ 141e775b3daab9766bce9ec2d01fe7d652c4a782b6bJaikumar Ganesh public static final String EXTRA_VENDOR_SPECIFIC_HEADSET_EVENT_CMD_TYPE = 142e775b3daab9766bce9ec2d01fe7d652c4a782b6bJaikumar Ganesh "android.bluetooth.headset.extra.VENDOR_SPECIFIC_HEADSET_EVENT_CMD_TYPE"; 143e775b3daab9766bce9ec2d01fe7d652c4a782b6bJaikumar Ganesh 144e775b3daab9766bce9ec2d01fe7d652c4a782b6bJaikumar Ganesh /** 145e775b3daab9766bce9ec2d01fe7d652c4a782b6bJaikumar Ganesh * AT command type READ used with 146e775b3daab9766bce9ec2d01fe7d652c4a782b6bJaikumar Ganesh * {@link #EXTRA_VENDOR_SPECIFIC_HEADSET_EVENT_CMD_TYPE} 147e775b3daab9766bce9ec2d01fe7d652c4a782b6bJaikumar Ganesh * For example, AT+VGM?. There are no arguments for this command type. 148e775b3daab9766bce9ec2d01fe7d652c4a782b6bJaikumar Ganesh */ 149e775b3daab9766bce9ec2d01fe7d652c4a782b6bJaikumar Ganesh public static final int AT_CMD_TYPE_READ = 0; 150e775b3daab9766bce9ec2d01fe7d652c4a782b6bJaikumar Ganesh 151e775b3daab9766bce9ec2d01fe7d652c4a782b6bJaikumar Ganesh /** 152e775b3daab9766bce9ec2d01fe7d652c4a782b6bJaikumar Ganesh * AT command type TEST used with 153e775b3daab9766bce9ec2d01fe7d652c4a782b6bJaikumar Ganesh * {@link #EXTRA_VENDOR_SPECIFIC_HEADSET_EVENT_CMD_TYPE} 154e775b3daab9766bce9ec2d01fe7d652c4a782b6bJaikumar Ganesh * For example, AT+VGM=?. There are no arguments for this command type. 155e775b3daab9766bce9ec2d01fe7d652c4a782b6bJaikumar Ganesh */ 156e775b3daab9766bce9ec2d01fe7d652c4a782b6bJaikumar Ganesh public static final int AT_CMD_TYPE_TEST = 1; 157e775b3daab9766bce9ec2d01fe7d652c4a782b6bJaikumar Ganesh 158e775b3daab9766bce9ec2d01fe7d652c4a782b6bJaikumar Ganesh /** 159e775b3daab9766bce9ec2d01fe7d652c4a782b6bJaikumar Ganesh * AT command type SET used with 160e775b3daab9766bce9ec2d01fe7d652c4a782b6bJaikumar Ganesh * {@link #EXTRA_VENDOR_SPECIFIC_HEADSET_EVENT_CMD_TYPE} 161e775b3daab9766bce9ec2d01fe7d652c4a782b6bJaikumar Ganesh * For example, AT+VGM=<args>. 162e775b3daab9766bce9ec2d01fe7d652c4a782b6bJaikumar Ganesh */ 163e775b3daab9766bce9ec2d01fe7d652c4a782b6bJaikumar Ganesh public static final int AT_CMD_TYPE_SET = 2; 164e775b3daab9766bce9ec2d01fe7d652c4a782b6bJaikumar Ganesh 165e775b3daab9766bce9ec2d01fe7d652c4a782b6bJaikumar Ganesh /** 166e775b3daab9766bce9ec2d01fe7d652c4a782b6bJaikumar Ganesh * AT command type BASIC used with 167e775b3daab9766bce9ec2d01fe7d652c4a782b6bJaikumar Ganesh * {@link #EXTRA_VENDOR_SPECIFIC_HEADSET_EVENT_CMD_TYPE} 168e775b3daab9766bce9ec2d01fe7d652c4a782b6bJaikumar Ganesh * For example, ATD. Single character commands and everything following the 169e775b3daab9766bce9ec2d01fe7d652c4a782b6bJaikumar Ganesh * character are arguments. 170e775b3daab9766bce9ec2d01fe7d652c4a782b6bJaikumar Ganesh */ 171e775b3daab9766bce9ec2d01fe7d652c4a782b6bJaikumar Ganesh public static final int AT_CMD_TYPE_BASIC = 3; 172e775b3daab9766bce9ec2d01fe7d652c4a782b6bJaikumar Ganesh 173e775b3daab9766bce9ec2d01fe7d652c4a782b6bJaikumar Ganesh /** 174e775b3daab9766bce9ec2d01fe7d652c4a782b6bJaikumar Ganesh * AT command type ACTION used with 175e775b3daab9766bce9ec2d01fe7d652c4a782b6bJaikumar Ganesh * {@link #EXTRA_VENDOR_SPECIFIC_HEADSET_EVENT_CMD_TYPE} 176e775b3daab9766bce9ec2d01fe7d652c4a782b6bJaikumar Ganesh * For example, AT+CHUP. There are no arguments for action commands. 177a4733941839abd672b1e37edd7f61c8932d4aa48Herb Jellinek */ 178e775b3daab9766bce9ec2d01fe7d652c4a782b6bJaikumar Ganesh public static final int AT_CMD_TYPE_ACTION = 4; 179a4733941839abd672b1e37edd7f61c8932d4aa48Herb Jellinek 180a4733941839abd672b1e37edd7f61c8932d4aa48Herb Jellinek /** 181a4733941839abd672b1e37edd7f61c8932d4aa48Herb Jellinek * A Parcelable String array extra field in 182a4733941839abd672b1e37edd7f61c8932d4aa48Herb Jellinek * {@link #ACTION_VENDOR_SPECIFIC_HEADSET_EVENT} intents that contains 183a4733941839abd672b1e37edd7f61c8932d4aa48Herb Jellinek * the arguments to the vendor-specific command. 184a4733941839abd672b1e37edd7f61c8932d4aa48Herb Jellinek */ 185a4733941839abd672b1e37edd7f61c8932d4aa48Herb Jellinek public static final String EXTRA_VENDOR_SPECIFIC_HEADSET_EVENT_ARGS = 186a4733941839abd672b1e37edd7f61c8932d4aa48Herb Jellinek "android.bluetooth.headset.extra.VENDOR_SPECIFIC_HEADSET_EVENT_ARGS"; 187a4733941839abd672b1e37edd7f61c8932d4aa48Herb Jellinek 188e775b3daab9766bce9ec2d01fe7d652c4a782b6bJaikumar Ganesh /** 189e775b3daab9766bce9ec2d01fe7d652c4a782b6bJaikumar Ganesh * The intent category to be used with {@link #ACTION_VENDOR_SPECIFIC_HEADSET_EVENT} 190e775b3daab9766bce9ec2d01fe7d652c4a782b6bJaikumar Ganesh * for the companyId 191e775b3daab9766bce9ec2d01fe7d652c4a782b6bJaikumar Ganesh */ 192e775b3daab9766bce9ec2d01fe7d652c4a782b6bJaikumar Ganesh public static final String VENDOR_SPECIFIC_HEADSET_EVENT_COMPANY_ID_CATEGORY = 193e775b3daab9766bce9ec2d01fe7d652c4a782b6bJaikumar Ganesh "android.bluetooth.headset.intent.category.companyid"; 194e775b3daab9766bce9ec2d01fe7d652c4a782b6bJaikumar Ganesh 19530d181690e48b26cdfae3b144d23f1e16c75da37Jaikumar Ganesh /** 196c8fa4ff838a0c3d2c67db65540fa751e5abe27edJaikumar Ganesh * Headset state when SCO audio is not connected. 19762c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * This state can be one of 19862c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * {@link #EXTRA_STATE} or {@link #EXTRA_PREVIOUS_STATE} of 19962c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * {@link #ACTION_AUDIO_STATE_CHANGED} intent. 200005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly */ 201b0a1d01b4c044a0779cfe006e204bac468459802Jaikumar Ganesh public static final int STATE_AUDIO_DISCONNECTED = 10; 2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 204c8fa4ff838a0c3d2c67db65540fa751e5abe27edJaikumar Ganesh * Headset state when SCO audio is connecting. 20562c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * This state can be one of 20662c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * {@link #EXTRA_STATE} or {@link #EXTRA_PREVIOUS_STATE} of 20762c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * {@link #ACTION_AUDIO_STATE_CHANGED} intent. 2089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 209b0a1d01b4c044a0779cfe006e204bac468459802Jaikumar Ganesh public static final int STATE_AUDIO_CONNECTING = 11; 21062c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh 21130d181690e48b26cdfae3b144d23f1e16c75da37Jaikumar Ganesh /** 212c8fa4ff838a0c3d2c67db65540fa751e5abe27edJaikumar Ganesh * Headset state when SCO audio is connected. 21330d181690e48b26cdfae3b144d23f1e16c75da37Jaikumar Ganesh * This state can be one of 21430d181690e48b26cdfae3b144d23f1e16c75da37Jaikumar Ganesh * {@link #EXTRA_STATE} or {@link #EXTRA_PREVIOUS_STATE} of 21530d181690e48b26cdfae3b144d23f1e16c75da37Jaikumar Ganesh * {@link #ACTION_AUDIO_STATE_CHANGED} intent. 21630d181690e48b26cdfae3b144d23f1e16c75da37Jaikumar Ganesh */ 217b0a1d01b4c044a0779cfe006e204bac468459802Jaikumar Ganesh public static final int STATE_AUDIO_CONNECTED = 12; 218b0a1d01b4c044a0779cfe006e204bac468459802Jaikumar Ganesh 21962c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh 22062c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh private Context mContext; 22162c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh private ServiceListener mServiceListener; 22262c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh private IBluetoothHeadset mService; 223bf246ef0abb6ea354fe412b139dec1adb4e5791dMatthew Xie private BluetoothAdapter mAdapter; 2249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2250f42037eb7b5118015c2caca635538324ccf0ccffredc final private IBluetoothStateChangeCallback mBluetoothStateChangeCallback = 2260f42037eb7b5118015c2caca635538324ccf0ccffredc new IBluetoothStateChangeCallback.Stub() { 2270f42037eb7b5118015c2caca635538324ccf0ccffredc public void onBluetoothStateChange(boolean up) { 2280f42037eb7b5118015c2caca635538324ccf0ccffredc if (DBG) Log.d(TAG, "onBluetoothStateChange: up=" + up); 2290f42037eb7b5118015c2caca635538324ccf0ccffredc if (!up) { 230563e414784eb81e4ea4051667d5c8855b17f7534Matthew Xie if (VDBG) Log.d(TAG,"Unbinding service..."); 2310f42037eb7b5118015c2caca635538324ccf0ccffredc synchronized (mConnection) { 2320f42037eb7b5118015c2caca635538324ccf0ccffredc try { 2330f42037eb7b5118015c2caca635538324ccf0ccffredc mService = null; 2340f42037eb7b5118015c2caca635538324ccf0ccffredc mContext.unbindService(mConnection); 2350f42037eb7b5118015c2caca635538324ccf0ccffredc } catch (Exception re) { 2360f42037eb7b5118015c2caca635538324ccf0ccffredc Log.e(TAG,"",re); 2370f42037eb7b5118015c2caca635538324ccf0ccffredc } 2380f42037eb7b5118015c2caca635538324ccf0ccffredc } 2390f42037eb7b5118015c2caca635538324ccf0ccffredc } else { 2400f42037eb7b5118015c2caca635538324ccf0ccffredc synchronized (mConnection) { 2410f42037eb7b5118015c2caca635538324ccf0ccffredc try { 2420f42037eb7b5118015c2caca635538324ccf0ccffredc if (mService == null) { 243563e414784eb81e4ea4051667d5c8855b17f7534Matthew Xie if (VDBG) Log.d(TAG,"Binding service..."); 2440f42037eb7b5118015c2caca635538324ccf0ccffredc if (!mContext.bindService(new Intent(IBluetoothHeadset.class.getName()), mConnection, 0)) { 2450f42037eb7b5118015c2caca635538324ccf0ccffredc Log.e(TAG, "Could not bind to Bluetooth Headset Service"); 2460f42037eb7b5118015c2caca635538324ccf0ccffredc } 2470f42037eb7b5118015c2caca635538324ccf0ccffredc } 2480f42037eb7b5118015c2caca635538324ccf0ccffredc } catch (Exception re) { 2490f42037eb7b5118015c2caca635538324ccf0ccffredc Log.e(TAG,"",re); 2500f42037eb7b5118015c2caca635538324ccf0ccffredc } 2510f42037eb7b5118015c2caca635538324ccf0ccffredc } 2520f42037eb7b5118015c2caca635538324ccf0ccffredc } 2530f42037eb7b5118015c2caca635538324ccf0ccffredc } 2540f42037eb7b5118015c2caca635538324ccf0ccffredc }; 2550f42037eb7b5118015c2caca635538324ccf0ccffredc 2569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Create a BluetoothHeadset proxy object. 2589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 25962c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh /*package*/ BluetoothHeadset(Context context, ServiceListener l) { 2609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mContext = context; 2619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mServiceListener = l; 26262c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh mAdapter = BluetoothAdapter.getDefaultAdapter(); 2630f42037eb7b5118015c2caca635538324ccf0ccffredc 2640f42037eb7b5118015c2caca635538324ccf0ccffredc IBluetoothManager mgr = mAdapter.getBluetoothManager(); 2650f42037eb7b5118015c2caca635538324ccf0ccffredc if (mgr != null) { 2660f42037eb7b5118015c2caca635538324ccf0ccffredc try { 2670f42037eb7b5118015c2caca635538324ccf0ccffredc mgr.registerStateChangeCallback(mBluetoothStateChangeCallback); 2680f42037eb7b5118015c2caca635538324ccf0ccffredc } catch (RemoteException e) { 2690f42037eb7b5118015c2caca635538324ccf0ccffredc Log.e(TAG,"",e); 2700f42037eb7b5118015c2caca635538324ccf0ccffredc } 2710f42037eb7b5118015c2caca635538324ccf0ccffredc } 2720f42037eb7b5118015c2caca635538324ccf0ccffredc 2739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!context.bindService(new Intent(IBluetoothHeadset.class.getName()), mConnection, 0)) { 2749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.e(TAG, "Could not bind to Bluetooth Headset Service"); 2759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Close the connection to the backing service. 2809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Other public functions of BluetoothHeadset will return default error 2819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * results once close() has been called. Multiple invocations of close() 2829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * are ok. 2839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 28413450df2b9264ef2220418f308037c19cec739a9Matthew Xie /*package*/ void close() { 285563e414784eb81e4ea4051667d5c8855b17f7534Matthew Xie if (VDBG) log("close()"); 2860f42037eb7b5118015c2caca635538324ccf0ccffredc 2870f42037eb7b5118015c2caca635538324ccf0ccffredc IBluetoothManager mgr = mAdapter.getBluetoothManager(); 2880f42037eb7b5118015c2caca635538324ccf0ccffredc if (mgr != null) { 2890f42037eb7b5118015c2caca635538324ccf0ccffredc try { 2900f42037eb7b5118015c2caca635538324ccf0ccffredc mgr.unregisterStateChangeCallback(mBluetoothStateChangeCallback); 2910f42037eb7b5118015c2caca635538324ccf0ccffredc } catch (Exception e) { 2920f42037eb7b5118015c2caca635538324ccf0ccffredc Log.e(TAG,"",e); 2930f42037eb7b5118015c2caca635538324ccf0ccffredc } 2940f42037eb7b5118015c2caca635538324ccf0ccffredc } 2950f42037eb7b5118015c2caca635538324ccf0ccffredc 2960f42037eb7b5118015c2caca635538324ccf0ccffredc synchronized (mConnection) { 2970f42037eb7b5118015c2caca635538324ccf0ccffredc if (mService != null) { 2980f42037eb7b5118015c2caca635538324ccf0ccffredc try { 2990f42037eb7b5118015c2caca635538324ccf0ccffredc mService = null; 3000f42037eb7b5118015c2caca635538324ccf0ccffredc mContext.unbindService(mConnection); 3010f42037eb7b5118015c2caca635538324ccf0ccffredc } catch (Exception re) { 3020f42037eb7b5118015c2caca635538324ccf0ccffredc Log.e(TAG,"",re); 3030f42037eb7b5118015c2caca635538324ccf0ccffredc } 3040f42037eb7b5118015c2caca635538324ccf0ccffredc } 3059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3069bb275197df8eb999eab4cdd0a2aff83c2bb2ef6Jaikumar Ganesh mServiceListener = null; 3079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 310f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * Initiate connection to a profile of the remote bluetooth device. 311f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * 312f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * <p> Currently, the system supports only 1 connection to the 313f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * headset/handsfree profile. The API will automatically disconnect connected 314f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * devices before connecting. 315f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * 316f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * <p> This API returns false in scenarios like the profile on the 317f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * device is already connected or Bluetooth is not turned on. 318f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * When this API returns true, it is guaranteed that 319f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * connection state intent for the profile will be broadcasted with 320f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * the state. Users can get the connection state of the profile 321f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * from this intent. 322f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * 323f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN} 324f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * permission. 325f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * 326f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * @param device Remote Bluetooth Device 327f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * @return false on immediate error, 328f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * true otherwise 32962c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * @hide 3309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 33162c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh public boolean connect(BluetoothDevice device) { 33262c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh if (DBG) log("connect(" + device + ")"); 33362c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh if (mService != null && isEnabled() && 33462c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh isValidDevice(device)) { 3359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 33662c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh return mService.connect(device); 33762c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh } catch (RemoteException e) { 33862c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh Log.e(TAG, Log.getStackTraceString(new Throwable())); 33962c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh return false; 34062c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh } 3419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 34262c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh if (mService == null) Log.w(TAG, "Proxy not attached to service"); 34362c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh return false; 3449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 347f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * Initiate disconnection from a profile 348f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * 349f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * <p> This API will return false in scenarios like the profile on the 350f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * Bluetooth device is not in connected state etc. When this API returns, 351f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * true, it is guaranteed that the connection state change 352f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * intent will be broadcasted with the state. Users can get the 353f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * disconnection state of the profile from this intent. 354f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * 355f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * <p> If the disconnection is initiated by a remote device, the state 356f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * will transition from {@link #STATE_CONNECTED} to 357f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * {@link #STATE_DISCONNECTED}. If the disconnect is initiated by the 358f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * host (local) device the state will transition from 359f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * {@link #STATE_CONNECTED} to state {@link #STATE_DISCONNECTING} to 360f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * state {@link #STATE_DISCONNECTED}. The transition to 361f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * {@link #STATE_DISCONNECTING} can be used to distinguish between the 362f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * two scenarios. 363f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * 364f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN} 365f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * permission. 366f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * 367f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * @param device Remote Bluetooth Device 368f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * @return false on immediate error, 369f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * true otherwise 37062c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * @hide 3719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 37262c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh public boolean disconnect(BluetoothDevice device) { 37362c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh if (DBG) log("disconnect(" + device + ")"); 37462c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh if (mService != null && isEnabled() && 37562c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh isValidDevice(device)) { 3769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 37762c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh return mService.disconnect(device); 37862c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh } catch (RemoteException e) { 37962c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh Log.e(TAG, Log.getStackTraceString(new Throwable())); 38062c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh return false; 38162c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh } 3829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 38362c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh if (mService == null) Log.w(TAG, "Proxy not attached to service"); 38462c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh return false; 3859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 38862c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * {@inheritDoc} 3899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 39003cd78cf5e51c3adb78d2e3d314838dcf3e36b26Jaikumar Ganesh public List<BluetoothDevice> getConnectedDevices() { 391563e414784eb81e4ea4051667d5c8855b17f7534Matthew Xie if (VDBG) log("getConnectedDevices()"); 39262c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh if (mService != null && isEnabled()) { 3939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 39403cd78cf5e51c3adb78d2e3d314838dcf3e36b26Jaikumar Ganesh return mService.getConnectedDevices(); 39562c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh } catch (RemoteException e) { 39662c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh Log.e(TAG, Log.getStackTraceString(new Throwable())); 39703cd78cf5e51c3adb78d2e3d314838dcf3e36b26Jaikumar Ganesh return new ArrayList<BluetoothDevice>(); 39862c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh } 3999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 40062c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh if (mService == null) Log.w(TAG, "Proxy not attached to service"); 40103cd78cf5e51c3adb78d2e3d314838dcf3e36b26Jaikumar Ganesh return new ArrayList<BluetoothDevice>(); 4029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 40562c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * {@inheritDoc} 4069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 40703cd78cf5e51c3adb78d2e3d314838dcf3e36b26Jaikumar Ganesh public List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) { 408563e414784eb81e4ea4051667d5c8855b17f7534Matthew Xie if (VDBG) log("getDevicesMatchingStates()"); 40962c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh if (mService != null && isEnabled()) { 4109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 41103cd78cf5e51c3adb78d2e3d314838dcf3e36b26Jaikumar Ganesh return mService.getDevicesMatchingConnectionStates(states); 41262c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh } catch (RemoteException e) { 41362c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh Log.e(TAG, Log.getStackTraceString(new Throwable())); 41403cd78cf5e51c3adb78d2e3d314838dcf3e36b26Jaikumar Ganesh return new ArrayList<BluetoothDevice>(); 41562c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh } 4169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 41762c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh if (mService == null) Log.w(TAG, "Proxy not attached to service"); 41803cd78cf5e51c3adb78d2e3d314838dcf3e36b26Jaikumar Ganesh return new ArrayList<BluetoothDevice>(); 4199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 42262c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * {@inheritDoc} 4239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 42462c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh public int getConnectionState(BluetoothDevice device) { 425563e414784eb81e4ea4051667d5c8855b17f7534Matthew Xie if (VDBG) log("getConnectionState(" + device + ")"); 42662c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh if (mService != null && isEnabled() && 42762c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh isValidDevice(device)) { 4289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 42962c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh return mService.getConnectionState(device); 43062c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh } catch (RemoteException e) { 43162c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh Log.e(TAG, Log.getStackTraceString(new Throwable())); 43262c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh return BluetoothProfile.STATE_DISCONNECTED; 43362c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh } 4349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 43562c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh if (mService == null) Log.w(TAG, "Proxy not attached to service"); 43662c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh return BluetoothProfile.STATE_DISCONNECTED; 4379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 440f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * Set priority of the profile 441f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * 442f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * <p> The device should already be paired. 443f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * Priority can be one of {@link #PRIORITY_ON} or 444f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * {@link #PRIORITY_OFF}, 445f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * 446f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN} 447f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * permission. 448f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * 449f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * @param device Paired bluetooth device 450f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * @param priority 451f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * @return true if priority is set, false on error 45262c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * @hide 4539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 45462c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh public boolean setPriority(BluetoothDevice device, int priority) { 45562c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh if (DBG) log("setPriority(" + device + ", " + priority + ")"); 45662c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh if (mService != null && isEnabled() && 45762c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh isValidDevice(device)) { 45862c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh if (priority != BluetoothProfile.PRIORITY_OFF && 4596f6c54519a9b15379bb79e195655b6bd4fc5967aGanesh Ganapathi Batta priority != BluetoothProfile.PRIORITY_ON) { 46062c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh return false; 46162c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh } 4629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 46362c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh return mService.setPriority(device, priority); 46462c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh } catch (RemoteException e) { 46562c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh Log.e(TAG, Log.getStackTraceString(new Throwable())); 46662c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh return false; 46762c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh } 4689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 46962c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh if (mService == null) Log.w(TAG, "Proxy not attached to service"); 4709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 4719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 474f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * Get the priority of the profile. 475f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * 476f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * <p> The priority can be any of: 477f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * {@link #PRIORITY_AUTO_CONNECT}, {@link #PRIORITY_OFF}, 478f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * {@link #PRIORITY_ON}, {@link #PRIORITY_UNDEFINED} 479f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * 480f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission. 481f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * 482f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * @param device Bluetooth device 483f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * @return priority of the device 48462c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * @hide 4859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 48662c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh public int getPriority(BluetoothDevice device) { 487563e414784eb81e4ea4051667d5c8855b17f7534Matthew Xie if (VDBG) log("getPriority(" + device + ")"); 48862c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh if (mService != null && isEnabled() && 48962c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh isValidDevice(device)) { 4909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 49162c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh return mService.getPriority(device); 49262c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh } catch (RemoteException e) { 49362c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh Log.e(TAG, Log.getStackTraceString(new Throwable())); 49462c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh return PRIORITY_OFF; 49562c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh } 4969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 49762c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh if (mService == null) Log.w(TAG, "Proxy not attached to service"); 49862c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh return PRIORITY_OFF; 49962c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh } 50062c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh 50162c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh /** 50262c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * Start Bluetooth voice recognition. This methods sends the voice 50362c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * recognition AT command to the headset and establishes the 50462c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * audio connection. 50562c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * 50662c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * <p> Users can listen to {@link #ACTION_AUDIO_STATE_CHANGED}. 507b0a1d01b4c044a0779cfe006e204bac468459802Jaikumar Ganesh * If this function returns true, this intent will be broadcasted with 508b0a1d01b4c044a0779cfe006e204bac468459802Jaikumar Ganesh * {@link #EXTRA_STATE} set to {@link #STATE_AUDIO_CONNECTING}. 509b0a1d01b4c044a0779cfe006e204bac468459802Jaikumar Ganesh * 510b0a1d01b4c044a0779cfe006e204bac468459802Jaikumar Ganesh * <p> {@link #EXTRA_STATE} will transition from 511b0a1d01b4c044a0779cfe006e204bac468459802Jaikumar Ganesh * {@link #STATE_AUDIO_CONNECTING} to {@link #STATE_AUDIO_CONNECTED} when 512b0a1d01b4c044a0779cfe006e204bac468459802Jaikumar Ganesh * audio connection is established and to {@link #STATE_AUDIO_DISCONNECTED} 513b0a1d01b4c044a0779cfe006e204bac468459802Jaikumar Ganesh * in case of failure to establish the audio connection. 51462c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * 515b0a1d01b4c044a0779cfe006e204bac468459802Jaikumar Ganesh * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission. 51662c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * 51762c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * @param device Bluetooth headset 51862c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * @return false if there is no headset connected of if the 51962c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * connected headset doesn't support voice recognition 52062c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * or on error, true otherwise 52162c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh */ 52262c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh public boolean startVoiceRecognition(BluetoothDevice device) { 52362c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh if (DBG) log("startVoiceRecognition()"); 52462c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh if (mService != null && isEnabled() && 52562c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh isValidDevice(device)) { 52662c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh try { 52762c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh return mService.startVoiceRecognition(device); 52862c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh } catch (RemoteException e) { 52962c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh Log.e(TAG, Log.getStackTraceString(new Throwable())); 53062c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh } 53162c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh } 53262c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh if (mService == null) Log.w(TAG, "Proxy not attached to service"); 5339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 5349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 53762c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * Stop Bluetooth Voice Recognition mode, and shut down the 53862c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * Bluetooth audio path. 53962c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * 540c8fa4ff838a0c3d2c67db65540fa751e5abe27edJaikumar Ganesh * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission. 54162c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * 54262c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * @param device Bluetooth headset 54362c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * @return false if there is no headset connected 54462c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * or on error, true otherwise 5459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 54662c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh public boolean stopVoiceRecognition(BluetoothDevice device) { 54762c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh if (DBG) log("stopVoiceRecognition()"); 54862c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh if (mService != null && isEnabled() && 54962c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh isValidDevice(device)) { 5509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 55162c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh return mService.stopVoiceRecognition(device); 55262c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh } catch (RemoteException e) { 55362c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh Log.e(TAG, Log.getStackTraceString(new Throwable())); 55462c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh } 5559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 55662c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh if (mService == null) Log.w(TAG, "Proxy not attached to service"); 5579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 5589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 56162c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * Check if Bluetooth SCO audio is connected. 56262c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * 563c8fa4ff838a0c3d2c67db65540fa751e5abe27edJaikumar Ganesh * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission. 56462c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * 56562c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * @param device Bluetooth headset 56662c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * @return true if SCO is connected, 56762c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * false otherwise or on error 5689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 56962c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh public boolean isAudioConnected(BluetoothDevice device) { 570563e414784eb81e4ea4051667d5c8855b17f7534Matthew Xie if (VDBG) log("isAudioConnected()"); 57162c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh if (mService != null && isEnabled() && 57262c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh isValidDevice(device)) { 5739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 57462c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh return mService.isAudioConnected(device); 57562c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh } catch (RemoteException e) { 57662c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh Log.e(TAG, Log.getStackTraceString(new Throwable())); 57762c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh } 5786c901db72dbaf57d8fdf26adae6721de14ecae22Nick Pelly } 57962c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh if (mService == null) Log.w(TAG, "Proxy not attached to service"); 58062c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh return false; 5816c901db72dbaf57d8fdf26adae6721de14ecae22Nick Pelly } 5826c901db72dbaf57d8fdf26adae6721de14ecae22Nick Pelly 5836c901db72dbaf57d8fdf26adae6721de14ecae22Nick Pelly /** 5846c901db72dbaf57d8fdf26adae6721de14ecae22Nick Pelly * Get battery usage hint for Bluetooth Headset service. 5856c901db72dbaf57d8fdf26adae6721de14ecae22Nick Pelly * This is a monotonically increasing integer. Wraps to 0 at 5866c901db72dbaf57d8fdf26adae6721de14ecae22Nick Pelly * Integer.MAX_INT, and at boot. 5876c901db72dbaf57d8fdf26adae6721de14ecae22Nick Pelly * Current implementation returns the number of AT commands handled since 5886c901db72dbaf57d8fdf26adae6721de14ecae22Nick Pelly * boot. This is a good indicator for spammy headset/handsfree units that 5896c901db72dbaf57d8fdf26adae6721de14ecae22Nick Pelly * can keep the device awake by polling for cellular status updates. As a 5906c901db72dbaf57d8fdf26adae6721de14ecae22Nick Pelly * rule of thumb, each AT command prevents the CPU from sleeping for 500 ms 59162c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * 59262c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * @param device the bluetooth headset. 5936c901db72dbaf57d8fdf26adae6721de14ecae22Nick Pelly * @return monotonically increasing battery usage hint, or a negative error 5946c901db72dbaf57d8fdf26adae6721de14ecae22Nick Pelly * code on error 5956c901db72dbaf57d8fdf26adae6721de14ecae22Nick Pelly * @hide 5966c901db72dbaf57d8fdf26adae6721de14ecae22Nick Pelly */ 59762c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh public int getBatteryUsageHint(BluetoothDevice device) { 598563e414784eb81e4ea4051667d5c8855b17f7534Matthew Xie if (VDBG) log("getBatteryUsageHint()"); 59962c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh if (mService != null && isEnabled() && 60062c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh isValidDevice(device)) { 6016c901db72dbaf57d8fdf26adae6721de14ecae22Nick Pelly try { 60262c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh return mService.getBatteryUsageHint(device); 60362c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh } catch (RemoteException e) { 60462c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh Log.e(TAG, Log.getStackTraceString(new Throwable())); 60562c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh } 6069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 60762c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh if (mService == null) Log.w(TAG, "Proxy not attached to service"); 6089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return -1; 6099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 61062c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh 611d726b35ebd8660022dcea706ee6d3ca51886b04eEric Laurent /** 612d726b35ebd8660022dcea706ee6d3ca51886b04eEric Laurent * Indicates if current platform supports voice dialing over bluetooth SCO. 61362c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * 614d726b35ebd8660022dcea706ee6d3ca51886b04eEric Laurent * @return true if voice dialing over bluetooth is supported, false otherwise. 615d726b35ebd8660022dcea706ee6d3ca51886b04eEric Laurent * @hide 616d726b35ebd8660022dcea706ee6d3ca51886b04eEric Laurent */ 617d726b35ebd8660022dcea706ee6d3ca51886b04eEric Laurent public static boolean isBluetoothVoiceDialingEnabled(Context context) { 618d726b35ebd8660022dcea706ee6d3ca51886b04eEric Laurent return context.getResources().getBoolean( 619d726b35ebd8660022dcea706ee6d3ca51886b04eEric Laurent com.android.internal.R.bool.config_bluetooth_sco_off_call); 620d726b35ebd8660022dcea706ee6d3ca51886b04eEric Laurent } 621d726b35ebd8660022dcea706ee6d3ca51886b04eEric Laurent 6229b637e5985f9a86f39d70335c0390ade3716592aJaikumar Ganesh /** 6239b637e5985f9a86f39d70335c0390ade3716592aJaikumar Ganesh * Accept the incoming connection. 62462c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * Note: This is an internal function and shouldn't be exposed 62562c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * 6269b637e5985f9a86f39d70335c0390ade3716592aJaikumar Ganesh * @hide 6279b637e5985f9a86f39d70335c0390ade3716592aJaikumar Ganesh */ 6289b637e5985f9a86f39d70335c0390ade3716592aJaikumar Ganesh public boolean acceptIncomingConnect(BluetoothDevice device) { 6299b637e5985f9a86f39d70335c0390ade3716592aJaikumar Ganesh if (DBG) log("acceptIncomingConnect"); 63062c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh if (mService != null && isEnabled()) { 6319b637e5985f9a86f39d70335c0390ade3716592aJaikumar Ganesh try { 6329b637e5985f9a86f39d70335c0390ade3716592aJaikumar Ganesh return mService.acceptIncomingConnect(device); 6339b637e5985f9a86f39d70335c0390ade3716592aJaikumar Ganesh } catch (RemoteException e) {Log.e(TAG, e.toString());} 6349b637e5985f9a86f39d70335c0390ade3716592aJaikumar Ganesh } else { 6359b637e5985f9a86f39d70335c0390ade3716592aJaikumar Ganesh Log.w(TAG, "Proxy not attached to service"); 6369b637e5985f9a86f39d70335c0390ade3716592aJaikumar Ganesh if (DBG) Log.d(TAG, Log.getStackTraceString(new Throwable())); 6379b637e5985f9a86f39d70335c0390ade3716592aJaikumar Ganesh } 6389b637e5985f9a86f39d70335c0390ade3716592aJaikumar Ganesh return false; 6399b637e5985f9a86f39d70335c0390ade3716592aJaikumar Ganesh } 6409b637e5985f9a86f39d70335c0390ade3716592aJaikumar Ganesh 6419b637e5985f9a86f39d70335c0390ade3716592aJaikumar Ganesh /** 642a0c680393f2dd03a937c598b2cb9abf98a58152cMatthew Xie * Reject the incoming connection. 643a0c680393f2dd03a937c598b2cb9abf98a58152cMatthew Xie * @hide 644a0c680393f2dd03a937c598b2cb9abf98a58152cMatthew Xie */ 645a0c680393f2dd03a937c598b2cb9abf98a58152cMatthew Xie public boolean rejectIncomingConnect(BluetoothDevice device) { 646a0c680393f2dd03a937c598b2cb9abf98a58152cMatthew Xie if (DBG) log("rejectIncomingConnect"); 647a0c680393f2dd03a937c598b2cb9abf98a58152cMatthew Xie if (mService != null) { 648a0c680393f2dd03a937c598b2cb9abf98a58152cMatthew Xie try { 649a0c680393f2dd03a937c598b2cb9abf98a58152cMatthew Xie return mService.rejectIncomingConnect(device); 650a0c680393f2dd03a937c598b2cb9abf98a58152cMatthew Xie } catch (RemoteException e) {Log.e(TAG, e.toString());} 651a0c680393f2dd03a937c598b2cb9abf98a58152cMatthew Xie } else { 652a0c680393f2dd03a937c598b2cb9abf98a58152cMatthew Xie Log.w(TAG, "Proxy not attached to service"); 653a0c680393f2dd03a937c598b2cb9abf98a58152cMatthew Xie if (DBG) Log.d(TAG, Log.getStackTraceString(new Throwable())); 654a0c680393f2dd03a937c598b2cb9abf98a58152cMatthew Xie } 655a0c680393f2dd03a937c598b2cb9abf98a58152cMatthew Xie return false; 656a0c680393f2dd03a937c598b2cb9abf98a58152cMatthew Xie } 657a0c680393f2dd03a937c598b2cb9abf98a58152cMatthew Xie 658a0c680393f2dd03a937c598b2cb9abf98a58152cMatthew Xie /** 6593e8c82edb1feafc796aa52efafedc13f794c4dcdMatthew Xie * Get the current audio state of the Headset. 6609b637e5985f9a86f39d70335c0390ade3716592aJaikumar Ganesh * Note: This is an internal function and shouldn't be exposed 66162c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * 6629b637e5985f9a86f39d70335c0390ade3716592aJaikumar Ganesh * @hide 6639b637e5985f9a86f39d70335c0390ade3716592aJaikumar Ganesh */ 6643e8c82edb1feafc796aa52efafedc13f794c4dcdMatthew Xie public int getAudioState(BluetoothDevice device) { 665563e414784eb81e4ea4051667d5c8855b17f7534Matthew Xie if (VDBG) log("getAudioState"); 6663e8c82edb1feafc796aa52efafedc13f794c4dcdMatthew Xie if (mService != null && !isDisabled()) { 6679b637e5985f9a86f39d70335c0390ade3716592aJaikumar Ganesh try { 6683e8c82edb1feafc796aa52efafedc13f794c4dcdMatthew Xie return mService.getAudioState(device); 6699b637e5985f9a86f39d70335c0390ade3716592aJaikumar Ganesh } catch (RemoteException e) {Log.e(TAG, e.toString());} 6709b637e5985f9a86f39d70335c0390ade3716592aJaikumar Ganesh } else { 6719b637e5985f9a86f39d70335c0390ade3716592aJaikumar Ganesh Log.w(TAG, "Proxy not attached to service"); 6729b637e5985f9a86f39d70335c0390ade3716592aJaikumar Ganesh if (DBG) Log.d(TAG, Log.getStackTraceString(new Throwable())); 6739b637e5985f9a86f39d70335c0390ade3716592aJaikumar Ganesh } 6743e8c82edb1feafc796aa52efafedc13f794c4dcdMatthew Xie return BluetoothHeadset.STATE_AUDIO_DISCONNECTED; 6759b637e5985f9a86f39d70335c0390ade3716592aJaikumar Ganesh } 6769b637e5985f9a86f39d70335c0390ade3716592aJaikumar Ganesh 6779b637e5985f9a86f39d70335c0390ade3716592aJaikumar Ganesh /** 6783e8c82edb1feafc796aa52efafedc13f794c4dcdMatthew Xie * Check if Bluetooth SCO audio is connected. 6793e8c82edb1feafc796aa52efafedc13f794c4dcdMatthew Xie * 6803e8c82edb1feafc796aa52efafedc13f794c4dcdMatthew Xie * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission. 68162c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * 6823e8c82edb1feafc796aa52efafedc13f794c4dcdMatthew Xie * @return true if SCO is connected, 6833e8c82edb1feafc796aa52efafedc13f794c4dcdMatthew Xie * false otherwise or on error 6849b637e5985f9a86f39d70335c0390ade3716592aJaikumar Ganesh * @hide 6859b637e5985f9a86f39d70335c0390ade3716592aJaikumar Ganesh */ 6863e8c82edb1feafc796aa52efafedc13f794c4dcdMatthew Xie public boolean isAudioOn() { 687563e414784eb81e4ea4051667d5c8855b17f7534Matthew Xie if (VDBG) log("isAudioOn()"); 6883e8c82edb1feafc796aa52efafedc13f794c4dcdMatthew Xie if (mService != null && isEnabled()) { 6899b637e5985f9a86f39d70335c0390ade3716592aJaikumar Ganesh try { 6903e8c82edb1feafc796aa52efafedc13f794c4dcdMatthew Xie return mService.isAudioOn(); 6913e8c82edb1feafc796aa52efafedc13f794c4dcdMatthew Xie } catch (RemoteException e) { 6923e8c82edb1feafc796aa52efafedc13f794c4dcdMatthew Xie Log.e(TAG, Log.getStackTraceString(new Throwable())); 6933e8c82edb1feafc796aa52efafedc13f794c4dcdMatthew Xie } 6949b637e5985f9a86f39d70335c0390ade3716592aJaikumar Ganesh } 6953e8c82edb1feafc796aa52efafedc13f794c4dcdMatthew Xie if (mService == null) Log.w(TAG, "Proxy not attached to service"); 6969b637e5985f9a86f39d70335c0390ade3716592aJaikumar Ganesh return false; 6973e8c82edb1feafc796aa52efafedc13f794c4dcdMatthew Xie 6989b637e5985f9a86f39d70335c0390ade3716592aJaikumar Ganesh } 69962c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh 70062c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh /** 7013e8c82edb1feafc796aa52efafedc13f794c4dcdMatthew Xie * Initiates a connection of headset audio. 7023e8c82edb1feafc796aa52efafedc13f794c4dcdMatthew Xie * It setup SCO channel with remote connected headset device. 70362c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * 7043e8c82edb1feafc796aa52efafedc13f794c4dcdMatthew Xie * @return true if successful 7053e8c82edb1feafc796aa52efafedc13f794c4dcdMatthew Xie * false if there was some error such as 7063e8c82edb1feafc796aa52efafedc13f794c4dcdMatthew Xie * there is no connected headset 70762c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * @hide 70862c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh */ 7093e8c82edb1feafc796aa52efafedc13f794c4dcdMatthew Xie public boolean connectAudio() { 7103e8c82edb1feafc796aa52efafedc13f794c4dcdMatthew Xie if (mService != null && isEnabled()) { 71162c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh try { 7123e8c82edb1feafc796aa52efafedc13f794c4dcdMatthew Xie return mService.connectAudio(); 7133e8c82edb1feafc796aa52efafedc13f794c4dcdMatthew Xie } catch (RemoteException e) { 7143e8c82edb1feafc796aa52efafedc13f794c4dcdMatthew Xie Log.e(TAG, e.toString()); 7153e8c82edb1feafc796aa52efafedc13f794c4dcdMatthew Xie } 71662c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh } else { 71762c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh Log.w(TAG, "Proxy not attached to service"); 71862c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh if (DBG) Log.d(TAG, Log.getStackTraceString(new Throwable())); 71962c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh } 72062c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh return false; 72162c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh } 72262c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh 72330d181690e48b26cdfae3b144d23f1e16c75da37Jaikumar Ganesh /** 7243e8c82edb1feafc796aa52efafedc13f794c4dcdMatthew Xie * Initiates a disconnection of headset audio. 7253e8c82edb1feafc796aa52efafedc13f794c4dcdMatthew Xie * It tears down the SCO channel from remote headset device. 72630d181690e48b26cdfae3b144d23f1e16c75da37Jaikumar Ganesh * 7273e8c82edb1feafc796aa52efafedc13f794c4dcdMatthew Xie * @return true if successful 7283e8c82edb1feafc796aa52efafedc13f794c4dcdMatthew Xie * false if there was some error such as 7293e8c82edb1feafc796aa52efafedc13f794c4dcdMatthew Xie * there is no connected SCO channel 73030d181690e48b26cdfae3b144d23f1e16c75da37Jaikumar Ganesh * @hide 73130d181690e48b26cdfae3b144d23f1e16c75da37Jaikumar Ganesh */ 7323e8c82edb1feafc796aa52efafedc13f794c4dcdMatthew Xie public boolean disconnectAudio() { 7333e8c82edb1feafc796aa52efafedc13f794c4dcdMatthew Xie if (mService != null && isEnabled()) { 73430d181690e48b26cdfae3b144d23f1e16c75da37Jaikumar Ganesh try { 7353e8c82edb1feafc796aa52efafedc13f794c4dcdMatthew Xie return mService.disconnectAudio(); 7363e8c82edb1feafc796aa52efafedc13f794c4dcdMatthew Xie } catch (RemoteException e) { 7373e8c82edb1feafc796aa52efafedc13f794c4dcdMatthew Xie Log.e(TAG, e.toString()); 7383e8c82edb1feafc796aa52efafedc13f794c4dcdMatthew Xie } 73930d181690e48b26cdfae3b144d23f1e16c75da37Jaikumar Ganesh } else { 74030d181690e48b26cdfae3b144d23f1e16c75da37Jaikumar Ganesh Log.w(TAG, "Proxy not attached to service"); 74130d181690e48b26cdfae3b144d23f1e16c75da37Jaikumar Ganesh if (DBG) Log.d(TAG, Log.getStackTraceString(new Throwable())); 74230d181690e48b26cdfae3b144d23f1e16c75da37Jaikumar Ganesh } 7433e8c82edb1feafc796aa52efafedc13f794c4dcdMatthew Xie return false; 74430d181690e48b26cdfae3b144d23f1e16c75da37Jaikumar Ganesh } 74530d181690e48b26cdfae3b144d23f1e16c75da37Jaikumar Ganesh 746f2e6b13620f3ebbb94166834abaaabcc08a403b7Jaikumar Ganesh /** 747dde68c64fd8e97a592633ec4c09283ec928e5697Jaikumar Ganesh * Initiates a SCO channel connection with the headset (if connected). 748dde68c64fd8e97a592633ec4c09283ec928e5697Jaikumar Ganesh * Also initiates a virtual voice call for Handsfree devices as many devices 749dde68c64fd8e97a592633ec4c09283ec928e5697Jaikumar Ganesh * do not accept SCO audio without a call. 750dde68c64fd8e97a592633ec4c09283ec928e5697Jaikumar Ganesh * This API allows the handsfree device to be used for routing non-cellular 751dde68c64fd8e97a592633ec4c09283ec928e5697Jaikumar Ganesh * call audio. 752f2e6b13620f3ebbb94166834abaaabcc08a403b7Jaikumar Ganesh * 753f2e6b13620f3ebbb94166834abaaabcc08a403b7Jaikumar Ganesh * @param device Remote Bluetooth Device 754f2e6b13620f3ebbb94166834abaaabcc08a403b7Jaikumar Ganesh * @return true if successful, false if there was some error. 755f2e6b13620f3ebbb94166834abaaabcc08a403b7Jaikumar Ganesh * @hide 756f2e6b13620f3ebbb94166834abaaabcc08a403b7Jaikumar Ganesh */ 757dde68c64fd8e97a592633ec4c09283ec928e5697Jaikumar Ganesh public boolean startScoUsingVirtualVoiceCall(BluetoothDevice device) { 758dde68c64fd8e97a592633ec4c09283ec928e5697Jaikumar Ganesh if (DBG) log("startScoUsingVirtualVoiceCall()"); 759f2e6b13620f3ebbb94166834abaaabcc08a403b7Jaikumar Ganesh if (mService != null && isEnabled() && isValidDevice(device)) { 760f2e6b13620f3ebbb94166834abaaabcc08a403b7Jaikumar Ganesh try { 761dde68c64fd8e97a592633ec4c09283ec928e5697Jaikumar Ganesh return mService.startScoUsingVirtualVoiceCall(device); 762f2e6b13620f3ebbb94166834abaaabcc08a403b7Jaikumar Ganesh } catch (RemoteException e) { 763f2e6b13620f3ebbb94166834abaaabcc08a403b7Jaikumar Ganesh Log.e(TAG, e.toString()); 764f2e6b13620f3ebbb94166834abaaabcc08a403b7Jaikumar Ganesh } 765f2e6b13620f3ebbb94166834abaaabcc08a403b7Jaikumar Ganesh } else { 766f2e6b13620f3ebbb94166834abaaabcc08a403b7Jaikumar Ganesh Log.w(TAG, "Proxy not attached to service"); 767f2e6b13620f3ebbb94166834abaaabcc08a403b7Jaikumar Ganesh if (DBG) Log.d(TAG, Log.getStackTraceString(new Throwable())); 768f2e6b13620f3ebbb94166834abaaabcc08a403b7Jaikumar Ganesh } 769f2e6b13620f3ebbb94166834abaaabcc08a403b7Jaikumar Ganesh return false; 770f2e6b13620f3ebbb94166834abaaabcc08a403b7Jaikumar Ganesh } 771f2e6b13620f3ebbb94166834abaaabcc08a403b7Jaikumar Ganesh 772f2e6b13620f3ebbb94166834abaaabcc08a403b7Jaikumar Ganesh /** 773dde68c64fd8e97a592633ec4c09283ec928e5697Jaikumar Ganesh * Terminates an ongoing SCO connection and the associated virtual 774dde68c64fd8e97a592633ec4c09283ec928e5697Jaikumar Ganesh * call. 775f2e6b13620f3ebbb94166834abaaabcc08a403b7Jaikumar Ganesh * 776f2e6b13620f3ebbb94166834abaaabcc08a403b7Jaikumar Ganesh * @param device Remote Bluetooth Device 777f2e6b13620f3ebbb94166834abaaabcc08a403b7Jaikumar Ganesh * @return true if successful, false if there was some error. 778f2e6b13620f3ebbb94166834abaaabcc08a403b7Jaikumar Ganesh * @hide 779f2e6b13620f3ebbb94166834abaaabcc08a403b7Jaikumar Ganesh */ 780dde68c64fd8e97a592633ec4c09283ec928e5697Jaikumar Ganesh public boolean stopScoUsingVirtualVoiceCall(BluetoothDevice device) { 781dde68c64fd8e97a592633ec4c09283ec928e5697Jaikumar Ganesh if (DBG) log("stopScoUsingVirtualVoiceCall()"); 782f2e6b13620f3ebbb94166834abaaabcc08a403b7Jaikumar Ganesh if (mService != null && isEnabled() && isValidDevice(device)) { 783f2e6b13620f3ebbb94166834abaaabcc08a403b7Jaikumar Ganesh try { 784dde68c64fd8e97a592633ec4c09283ec928e5697Jaikumar Ganesh return mService.stopScoUsingVirtualVoiceCall(device); 785f2e6b13620f3ebbb94166834abaaabcc08a403b7Jaikumar Ganesh } catch (RemoteException e) { 786f2e6b13620f3ebbb94166834abaaabcc08a403b7Jaikumar Ganesh Log.e(TAG, e.toString()); 787f2e6b13620f3ebbb94166834abaaabcc08a403b7Jaikumar Ganesh } 788f2e6b13620f3ebbb94166834abaaabcc08a403b7Jaikumar Ganesh } else { 789f2e6b13620f3ebbb94166834abaaabcc08a403b7Jaikumar Ganesh Log.w(TAG, "Proxy not attached to service"); 790f2e6b13620f3ebbb94166834abaaabcc08a403b7Jaikumar Ganesh if (DBG) Log.d(TAG, Log.getStackTraceString(new Throwable())); 791f2e6b13620f3ebbb94166834abaaabcc08a403b7Jaikumar Ganesh } 792f2e6b13620f3ebbb94166834abaaabcc08a403b7Jaikumar Ganesh return false; 793f2e6b13620f3ebbb94166834abaaabcc08a403b7Jaikumar Ganesh } 794f2e6b13620f3ebbb94166834abaaabcc08a403b7Jaikumar Ganesh 7953e8c82edb1feafc796aa52efafedc13f794c4dcdMatthew Xie /** 7963e8c82edb1feafc796aa52efafedc13f794c4dcdMatthew Xie * Notify Headset of phone state change. 7973e8c82edb1feafc796aa52efafedc13f794c4dcdMatthew Xie * This is a backdoor for phone app to call BluetoothHeadset since 7983e8c82edb1feafc796aa52efafedc13f794c4dcdMatthew Xie * there is currently not a good way to get precise call state change outside 7993e8c82edb1feafc796aa52efafedc13f794c4dcdMatthew Xie * of phone app. 8003e8c82edb1feafc796aa52efafedc13f794c4dcdMatthew Xie * 8013e8c82edb1feafc796aa52efafedc13f794c4dcdMatthew Xie * @hide 8023e8c82edb1feafc796aa52efafedc13f794c4dcdMatthew Xie */ 8033e8c82edb1feafc796aa52efafedc13f794c4dcdMatthew Xie public void phoneStateChanged(int numActive, int numHeld, int callState, String number, 8043e8c82edb1feafc796aa52efafedc13f794c4dcdMatthew Xie int type) { 8053e8c82edb1feafc796aa52efafedc13f794c4dcdMatthew Xie if (mService != null && isEnabled()) { 8063e8c82edb1feafc796aa52efafedc13f794c4dcdMatthew Xie try { 8073e8c82edb1feafc796aa52efafedc13f794c4dcdMatthew Xie mService.phoneStateChanged(numActive, numHeld, callState, number, type); 8083e8c82edb1feafc796aa52efafedc13f794c4dcdMatthew Xie } catch (RemoteException e) { 8093e8c82edb1feafc796aa52efafedc13f794c4dcdMatthew Xie Log.e(TAG, e.toString()); 8103e8c82edb1feafc796aa52efafedc13f794c4dcdMatthew Xie } 8113e8c82edb1feafc796aa52efafedc13f794c4dcdMatthew Xie } else { 8123e8c82edb1feafc796aa52efafedc13f794c4dcdMatthew Xie Log.w(TAG, "Proxy not attached to service"); 8133e8c82edb1feafc796aa52efafedc13f794c4dcdMatthew Xie if (DBG) Log.d(TAG, Log.getStackTraceString(new Throwable())); 8143e8c82edb1feafc796aa52efafedc13f794c4dcdMatthew Xie } 8153e8c82edb1feafc796aa52efafedc13f794c4dcdMatthew Xie } 8163e8c82edb1feafc796aa52efafedc13f794c4dcdMatthew Xie 8173e8c82edb1feafc796aa52efafedc13f794c4dcdMatthew Xie /** 8183e8c82edb1feafc796aa52efafedc13f794c4dcdMatthew Xie * Notify Headset of phone roam state change. 8193e8c82edb1feafc796aa52efafedc13f794c4dcdMatthew Xie * This is a backdoor for phone app to call BluetoothHeadset since 8203e8c82edb1feafc796aa52efafedc13f794c4dcdMatthew Xie * there is currently not a good way to get roaming state change outside 8213e8c82edb1feafc796aa52efafedc13f794c4dcdMatthew Xie * of phone app. 8223e8c82edb1feafc796aa52efafedc13f794c4dcdMatthew Xie * 8233e8c82edb1feafc796aa52efafedc13f794c4dcdMatthew Xie * @hide 8243e8c82edb1feafc796aa52efafedc13f794c4dcdMatthew Xie */ 8253e8c82edb1feafc796aa52efafedc13f794c4dcdMatthew Xie public void roamChanged(boolean roaming) { 8263e8c82edb1feafc796aa52efafedc13f794c4dcdMatthew Xie if (mService != null && isEnabled()) { 8273e8c82edb1feafc796aa52efafedc13f794c4dcdMatthew Xie try { 8283e8c82edb1feafc796aa52efafedc13f794c4dcdMatthew Xie mService.roamChanged(roaming); 8293e8c82edb1feafc796aa52efafedc13f794c4dcdMatthew Xie } catch (RemoteException e) { 8303e8c82edb1feafc796aa52efafedc13f794c4dcdMatthew Xie Log.e(TAG, e.toString()); 8313e8c82edb1feafc796aa52efafedc13f794c4dcdMatthew Xie } 8323e8c82edb1feafc796aa52efafedc13f794c4dcdMatthew Xie } else { 8333e8c82edb1feafc796aa52efafedc13f794c4dcdMatthew Xie Log.w(TAG, "Proxy not attached to service"); 8343e8c82edb1feafc796aa52efafedc13f794c4dcdMatthew Xie if (DBG) Log.d(TAG, Log.getStackTraceString(new Throwable())); 8353e8c82edb1feafc796aa52efafedc13f794c4dcdMatthew Xie } 8363e8c82edb1feafc796aa52efafedc13f794c4dcdMatthew Xie } 8373e8c82edb1feafc796aa52efafedc13f794c4dcdMatthew Xie 8383e8c82edb1feafc796aa52efafedc13f794c4dcdMatthew Xie /** 8393e8c82edb1feafc796aa52efafedc13f794c4dcdMatthew Xie * Send Headset of CLCC response 8403e8c82edb1feafc796aa52efafedc13f794c4dcdMatthew Xie * 8413e8c82edb1feafc796aa52efafedc13f794c4dcdMatthew Xie * @hide 8423e8c82edb1feafc796aa52efafedc13f794c4dcdMatthew Xie */ 8433e8c82edb1feafc796aa52efafedc13f794c4dcdMatthew Xie public void clccResponse(int index, int direction, int status, int mode, boolean mpty, 8443e8c82edb1feafc796aa52efafedc13f794c4dcdMatthew Xie String number, int type) { 8453e8c82edb1feafc796aa52efafedc13f794c4dcdMatthew Xie if (mService != null && isEnabled()) { 8463e8c82edb1feafc796aa52efafedc13f794c4dcdMatthew Xie try { 8473e8c82edb1feafc796aa52efafedc13f794c4dcdMatthew Xie mService.clccResponse(index, direction, status, mode, mpty, number, type); 8483e8c82edb1feafc796aa52efafedc13f794c4dcdMatthew Xie } catch (RemoteException e) { 8493e8c82edb1feafc796aa52efafedc13f794c4dcdMatthew Xie Log.e(TAG, e.toString()); 8503e8c82edb1feafc796aa52efafedc13f794c4dcdMatthew Xie } 8513e8c82edb1feafc796aa52efafedc13f794c4dcdMatthew Xie } else { 8523e8c82edb1feafc796aa52efafedc13f794c4dcdMatthew Xie Log.w(TAG, "Proxy not attached to service"); 8533e8c82edb1feafc796aa52efafedc13f794c4dcdMatthew Xie if (DBG) Log.d(TAG, Log.getStackTraceString(new Throwable())); 8543e8c82edb1feafc796aa52efafedc13f794c4dcdMatthew Xie } 8553e8c82edb1feafc796aa52efafedc13f794c4dcdMatthew Xie } 8563e8c82edb1feafc796aa52efafedc13f794c4dcdMatthew Xie 8579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private ServiceConnection mConnection = new ServiceConnection() { 8589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void onServiceConnected(ComponentName className, IBinder service) { 8599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (DBG) Log.d(TAG, "Proxy object connected"); 8609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mService = IBluetoothHeadset.Stub.asInterface(service); 86162c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh 8629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mServiceListener != null) { 86362c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh mServiceListener.onServiceConnected(BluetoothProfile.HEADSET, BluetoothHeadset.this); 8649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void onServiceDisconnected(ComponentName className) { 8679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (DBG) Log.d(TAG, "Proxy object disconnected"); 8689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mService = null; 8699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mServiceListener != null) { 87062c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh mServiceListener.onServiceDisconnected(BluetoothProfile.HEADSET); 8719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project }; 874f5b4b98fada53d91c4c2ebeb5a1d33ccc95c94d2The Android Open Source Project 87562c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh private boolean isEnabled() { 87662c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh if (mAdapter.getState() == BluetoothAdapter.STATE_ON) return true; 87762c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh return false; 87862c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh } 87962c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh 8806f7a9736602ba1f1dc5a16542aa947861a520ec5Jaikumar Ganesh private boolean isDisabled() { 8816f7a9736602ba1f1dc5a16542aa947861a520ec5Jaikumar Ganesh if (mAdapter.getState() == BluetoothAdapter.STATE_OFF) return true; 8826f7a9736602ba1f1dc5a16542aa947861a520ec5Jaikumar Ganesh return false; 8836f7a9736602ba1f1dc5a16542aa947861a520ec5Jaikumar Ganesh } 8846f7a9736602ba1f1dc5a16542aa947861a520ec5Jaikumar Ganesh 88562c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh private boolean isValidDevice(BluetoothDevice device) { 88662c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh if (device == null) return false; 88762c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh 88862c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh if (BluetoothAdapter.checkBluetoothAddress(device.getAddress())) return true; 88962c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh return false; 89062c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh } 89162c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh 892f5b4b98fada53d91c4c2ebeb5a1d33ccc95c94d2The Android Open Source Project private static void log(String msg) { 893f5b4b98fada53d91c4c2ebeb5a1d33ccc95c94d2The Android Open Source Project Log.d(TAG, msg); 894f5b4b98fada53d91c4c2ebeb5a1d33ccc95c94d2The Android Open Source Project } 8959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 896