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