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 192d49752ee050ab7f1cd848933f6c62a73707e2d9Tor Norbyeimport android.Manifest; 202d49752ee050ab7f1cd848933f6c62a73707e2d9Tor Norbyeimport android.annotation.RequiresPermission; 219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.annotation.SdkConstant; 229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.annotation.SdkConstant.SdkConstantType; 233e8c82edb1feafc796aa52efafedc13f794c4dcdMatthew Xieimport android.content.ComponentName; 249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.Context; 253e8c82edb1feafc796aa52efafedc13f794c4dcdMatthew Xieimport android.content.Intent; 263e8c82edb1feafc796aa52efafedc13f794c4dcdMatthew Xieimport android.content.ServiceConnection; 274197cb60bc74629fe4c04ab10cb3b1c9a7427d24RoboErikimport android.media.AudioManager; 280a17db1cc5942ea000ca87bb72853de57a15ec64Jeff Sharkeyimport android.os.Binder; 299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.IBinder; 3041d5c805d96aef0aaa9a2aaa86ccc4b77ca75e11Jaikumar Ganeshimport android.os.ParcelUuid; 3162c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganeshimport android.os.RemoteException; 329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.Log; 339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 34d7d16b9f372116da1658f589df213aed33c2ded6Calvin Onimport com.android.internal.annotations.GuardedBy; 35d7d16b9f372116da1658f589df213aed33c2ded6Calvin On 3603cd78cf5e51c3adb78d2e3d314838dcf3e36b26Jaikumar Ganeshimport java.util.ArrayList; 3703cd78cf5e51c3adb78d2e3d314838dcf3e36b26Jaikumar Ganeshimport java.util.List; 38d7d16b9f372116da1658f589df213aed33c2ded6Calvin Onimport java.util.concurrent.locks.ReentrantReadWriteLock; 3962c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh 409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/** 4262c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * This class provides the public APIs to control the Bluetooth A2DP 4362c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * profile. 449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 4562c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh *<p>BluetoothA2dp is a proxy object for controlling the Bluetooth A2DP 4662c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * Service via IPC. Use {@link BluetoothAdapter#getProfileProxy} to get 4762c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * the BluetoothA2dp proxy object. 489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 4962c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * <p> Android only supports one connected Bluetooth A2dp device at a time. 5062c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * Each method is protected with its appropriate permission. 519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 5262c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganeshpublic final class BluetoothA2dp implements BluetoothProfile { 539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final String TAG = "BluetoothA2dp"; 543e8c82edb1feafc796aa52efafedc13f794c4dcdMatthew Xie private static final boolean DBG = true; 55563e414784eb81e4ea4051667d5c8855b17f7534Matthew Xie private static final boolean VDBG = false; 569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5762c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh /** 5862c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * Intent used to broadcast the change in connection state of the A2DP 5962c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * profile. 6062c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * 6162c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * <p>This intent will have 3 extras: 62c8fa4ff838a0c3d2c67db65540fa751e5abe27edJaikumar Ganesh * <ul> 63c8fa4ff838a0c3d2c67db65540fa751e5abe27edJaikumar Ganesh * <li> {@link #EXTRA_STATE} - The current state of the profile. </li> 64c8fa4ff838a0c3d2c67db65540fa751e5abe27edJaikumar Ganesh * <li> {@link #EXTRA_PREVIOUS_STATE}- The previous state of the profile.</li> 65c8fa4ff838a0c3d2c67db65540fa751e5abe27edJaikumar Ganesh * <li> {@link BluetoothDevice#EXTRA_DEVICE} - The remote device. </li> 66c8fa4ff838a0c3d2c67db65540fa751e5abe27edJaikumar Ganesh * </ul> 6762c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * 680706fed52075f7f2b25101a40287519ac18d3184Jaikumar Ganesh * <p>{@link #EXTRA_STATE} or {@link #EXTRA_PREVIOUS_STATE} can be any of 6962c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * {@link #STATE_DISCONNECTED}, {@link #STATE_CONNECTING}, 7062c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * {@link #STATE_CONNECTED}, {@link #STATE_DISCONNECTING}. 7162c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * 72c8fa4ff838a0c3d2c67db65540fa751e5abe27edJaikumar Ganesh * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission to 73c8fa4ff838a0c3d2c67db65540fa751e5abe27edJaikumar Ganesh * receive. 7462c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh */ 7562c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) 7662c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh public static final String ACTION_CONNECTION_STATE_CHANGED = 7762c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh "android.bluetooth.a2dp.profile.action.CONNECTION_STATE_CHANGED"; 789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7962c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh /** 8062c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * Intent used to broadcast the change in the Playing state of the A2DP 8162c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * profile. 8262c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * 8362c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * <p>This intent will have 3 extras: 84c8fa4ff838a0c3d2c67db65540fa751e5abe27edJaikumar Ganesh * <ul> 85c8fa4ff838a0c3d2c67db65540fa751e5abe27edJaikumar Ganesh * <li> {@link #EXTRA_STATE} - The current state of the profile. </li> 86c8fa4ff838a0c3d2c67db65540fa751e5abe27edJaikumar Ganesh * <li> {@link #EXTRA_PREVIOUS_STATE}- The previous state of the profile. </li> 870706fed52075f7f2b25101a40287519ac18d3184Jaikumar Ganesh * <li> {@link BluetoothDevice#EXTRA_DEVICE} - The remote device. </li> 88c8fa4ff838a0c3d2c67db65540fa751e5abe27edJaikumar Ganesh * </ul> 8962c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * 900706fed52075f7f2b25101a40287519ac18d3184Jaikumar Ganesh * <p>{@link #EXTRA_STATE} or {@link #EXTRA_PREVIOUS_STATE} can be any of 9162c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * {@link #STATE_PLAYING}, {@link #STATE_NOT_PLAYING}, 9262c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * 93c8fa4ff838a0c3d2c67db65540fa751e5abe27edJaikumar Ganesh * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission to 94c8fa4ff838a0c3d2c67db65540fa751e5abe27edJaikumar Ganesh * receive. 959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) 9762c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh public static final String ACTION_PLAYING_STATE_CHANGED = 9862c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh "android.bluetooth.a2dp.profile.action.PLAYING_STATE_CHANGED"; 999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1003b76a4b2b62e9539e2629dc569d7e9a934e65dfbHemant Gupta /** @hide */ 1013b76a4b2b62e9539e2629dc569d7e9a934e65dfbHemant Gupta @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) 1023b76a4b2b62e9539e2629dc569d7e9a934e65dfbHemant Gupta public static final String ACTION_AVRCP_CONNECTION_STATE_CHANGED = 1033b76a4b2b62e9539e2629dc569d7e9a934e65dfbHemant Gupta "android.bluetooth.a2dp.profile.action.AVRCP_CONNECTION_STATE_CHANGED"; 1043b76a4b2b62e9539e2629dc569d7e9a934e65dfbHemant Gupta 10562c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh /** 10644a4ef0aa93ebb2912f36d65af42ffbb1bcdbc0fPavlin Radoslavov * Intent used to broadcast the change in the Audio Codec state of the 10744a4ef0aa93ebb2912f36d65af42ffbb1bcdbc0fPavlin Radoslavov * A2DP Source profile. 10844a4ef0aa93ebb2912f36d65af42ffbb1bcdbc0fPavlin Radoslavov * 109b37f181c9853bd0d55d360db95d3bf1bba0b5a6fPavlin Radoslavov * <p>This intent will have 2 extras: 11044a4ef0aa93ebb2912f36d65af42ffbb1bcdbc0fPavlin Radoslavov * <ul> 111b37f181c9853bd0d55d360db95d3bf1bba0b5a6fPavlin Radoslavov * <li> {@link BluetoothCodecStatus#EXTRA_CODEC_STATUS} - The codec status. </li> 11244a4ef0aa93ebb2912f36d65af42ffbb1bcdbc0fPavlin Radoslavov * <li> {@link BluetoothDevice#EXTRA_DEVICE} - The remote device if the device is currently 11344a4ef0aa93ebb2912f36d65af42ffbb1bcdbc0fPavlin Radoslavov * connected, otherwise it is not included.</li> 11444a4ef0aa93ebb2912f36d65af42ffbb1bcdbc0fPavlin Radoslavov * </ul> 11544a4ef0aa93ebb2912f36d65af42ffbb1bcdbc0fPavlin Radoslavov * 11644a4ef0aa93ebb2912f36d65af42ffbb1bcdbc0fPavlin Radoslavov * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission to 11744a4ef0aa93ebb2912f36d65af42ffbb1bcdbc0fPavlin Radoslavov * receive. 11844a4ef0aa93ebb2912f36d65af42ffbb1bcdbc0fPavlin Radoslavov * 11944a4ef0aa93ebb2912f36d65af42ffbb1bcdbc0fPavlin Radoslavov * @hide 12044a4ef0aa93ebb2912f36d65af42ffbb1bcdbc0fPavlin Radoslavov */ 12144a4ef0aa93ebb2912f36d65af42ffbb1bcdbc0fPavlin Radoslavov @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) 12244a4ef0aa93ebb2912f36d65af42ffbb1bcdbc0fPavlin Radoslavov public static final String ACTION_CODEC_CONFIG_CHANGED = 12344a4ef0aa93ebb2912f36d65af42ffbb1bcdbc0fPavlin Radoslavov "android.bluetooth.a2dp.profile.action.CODEC_CONFIG_CHANGED"; 12444a4ef0aa93ebb2912f36d65af42ffbb1bcdbc0fPavlin Radoslavov 12544a4ef0aa93ebb2912f36d65af42ffbb1bcdbc0fPavlin Radoslavov /** 12662c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * A2DP sink device is streaming music. This state can be one of 12762c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * {@link #EXTRA_STATE} or {@link #EXTRA_PREVIOUS_STATE} of 12862c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * {@link #ACTION_PLAYING_STATE_CHANGED} intent. 12962c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh */ 13062c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh public static final int STATE_PLAYING = 10; 1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 13262c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh /** 13362c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * A2DP sink device is NOT streaming music. This state can be one of 13462c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * {@link #EXTRA_STATE} or {@link #EXTRA_PREVIOUS_STATE} of 13562c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * {@link #ACTION_PLAYING_STATE_CHANGED} intent. 13662c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh */ 13762c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh public static final int STATE_NOT_PLAYING = 11; 138bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pelly 139f5772c6121ee1f5f2aa06711e2762c0f07fb61ccAntony Sargent /** 140f5772c6121ee1f5f2aa06711e2762c0f07fb61ccAntony Sargent * We don't have a stored preference for whether or not the given A2DP sink device supports 141f5772c6121ee1f5f2aa06711e2762c0f07fb61ccAntony Sargent * optional codecs. 142f5772c6121ee1f5f2aa06711e2762c0f07fb61ccAntony Sargent * @hide */ 143f5772c6121ee1f5f2aa06711e2762c0f07fb61ccAntony Sargent public static final int OPTIONAL_CODECS_SUPPORT_UNKNOWN = -1; 144f5772c6121ee1f5f2aa06711e2762c0f07fb61ccAntony Sargent 145f5772c6121ee1f5f2aa06711e2762c0f07fb61ccAntony Sargent /** 146f5772c6121ee1f5f2aa06711e2762c0f07fb61ccAntony Sargent * The given A2DP sink device does not support optional codecs. 147f5772c6121ee1f5f2aa06711e2762c0f07fb61ccAntony Sargent * @hide */ 148f5772c6121ee1f5f2aa06711e2762c0f07fb61ccAntony Sargent public static final int OPTIONAL_CODECS_NOT_SUPPORTED = 0; 149f5772c6121ee1f5f2aa06711e2762c0f07fb61ccAntony Sargent 150f5772c6121ee1f5f2aa06711e2762c0f07fb61ccAntony Sargent /** 151f5772c6121ee1f5f2aa06711e2762c0f07fb61ccAntony Sargent * The given A2DP sink device does support optional codecs. 152f5772c6121ee1f5f2aa06711e2762c0f07fb61ccAntony Sargent * @hide */ 153f5772c6121ee1f5f2aa06711e2762c0f07fb61ccAntony Sargent public static final int OPTIONAL_CODECS_SUPPORTED = 1; 154f5772c6121ee1f5f2aa06711e2762c0f07fb61ccAntony Sargent 155f5772c6121ee1f5f2aa06711e2762c0f07fb61ccAntony Sargent /** 156f5772c6121ee1f5f2aa06711e2762c0f07fb61ccAntony Sargent * We don't have a stored preference for whether optional codecs should be enabled or disabled 157f5772c6121ee1f5f2aa06711e2762c0f07fb61ccAntony Sargent * for the given A2DP device. 158f5772c6121ee1f5f2aa06711e2762c0f07fb61ccAntony Sargent * @hide */ 159f5772c6121ee1f5f2aa06711e2762c0f07fb61ccAntony Sargent public static final int OPTIONAL_CODECS_PREF_UNKNOWN = -1; 160f5772c6121ee1f5f2aa06711e2762c0f07fb61ccAntony Sargent 161f5772c6121ee1f5f2aa06711e2762c0f07fb61ccAntony Sargent /** 162f5772c6121ee1f5f2aa06711e2762c0f07fb61ccAntony Sargent * Optional codecs should be disabled for the given A2DP device. 163f5772c6121ee1f5f2aa06711e2762c0f07fb61ccAntony Sargent * @hide */ 164f5772c6121ee1f5f2aa06711e2762c0f07fb61ccAntony Sargent public static final int OPTIONAL_CODECS_PREF_DISABLED = 0; 165f5772c6121ee1f5f2aa06711e2762c0f07fb61ccAntony Sargent 166f5772c6121ee1f5f2aa06711e2762c0f07fb61ccAntony Sargent /** 167f5772c6121ee1f5f2aa06711e2762c0f07fb61ccAntony Sargent * Optional codecs should be enabled for the given A2DP device. 168f5772c6121ee1f5f2aa06711e2762c0f07fb61ccAntony Sargent * @hide */ 169f5772c6121ee1f5f2aa06711e2762c0f07fb61ccAntony Sargent public static final int OPTIONAL_CODECS_PREF_ENABLED = 1; 170f5772c6121ee1f5f2aa06711e2762c0f07fb61ccAntony Sargent 1713e8c82edb1feafc796aa52efafedc13f794c4dcdMatthew Xie private Context mContext; 17262c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh private ServiceListener mServiceListener; 173d7d16b9f372116da1658f589df213aed33c2ded6Calvin On private final ReentrantReadWriteLock mServiceLock = new ReentrantReadWriteLock(); 174d7d16b9f372116da1658f589df213aed33c2ded6Calvin On @GuardedBy("mServiceLock") private IBluetoothA2dp mService; 17562c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh private BluetoothAdapter mAdapter; 1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1770f42037eb7b5118015c2caca635538324ccf0ccffredc final private IBluetoothStateChangeCallback mBluetoothStateChangeCallback = 1780f42037eb7b5118015c2caca635538324ccf0ccffredc new IBluetoothStateChangeCallback.Stub() { 1790f42037eb7b5118015c2caca635538324ccf0ccffredc public void onBluetoothStateChange(boolean up) { 1800f42037eb7b5118015c2caca635538324ccf0ccffredc if (DBG) Log.d(TAG, "onBluetoothStateChange: up=" + up); 1810f42037eb7b5118015c2caca635538324ccf0ccffredc if (!up) { 182d7d16b9f372116da1658f589df213aed33c2ded6Calvin On if (VDBG) Log.d(TAG, "Unbinding service..."); 183d7d16b9f372116da1658f589df213aed33c2ded6Calvin On try { 184d7d16b9f372116da1658f589df213aed33c2ded6Calvin On mServiceLock.writeLock().lock(); 185d7d16b9f372116da1658f589df213aed33c2ded6Calvin On mService = null; 186d7d16b9f372116da1658f589df213aed33c2ded6Calvin On mContext.unbindService(mConnection); 187d7d16b9f372116da1658f589df213aed33c2ded6Calvin On } catch (Exception re) { 188d7d16b9f372116da1658f589df213aed33c2ded6Calvin On Log.e(TAG, "", re); 189d7d16b9f372116da1658f589df213aed33c2ded6Calvin On } finally { 190d7d16b9f372116da1658f589df213aed33c2ded6Calvin On mServiceLock.writeLock().unlock(); 1910f42037eb7b5118015c2caca635538324ccf0ccffredc } 1920f42037eb7b5118015c2caca635538324ccf0ccffredc } else { 193d7d16b9f372116da1658f589df213aed33c2ded6Calvin On try { 194d7d16b9f372116da1658f589df213aed33c2ded6Calvin On mServiceLock.readLock().lock(); 195d7d16b9f372116da1658f589df213aed33c2ded6Calvin On if (mService == null) { 196d7d16b9f372116da1658f589df213aed33c2ded6Calvin On if (VDBG) Log.d(TAG,"Binding service..."); 197d7d16b9f372116da1658f589df213aed33c2ded6Calvin On doBind(); 1980f42037eb7b5118015c2caca635538324ccf0ccffredc } 199d7d16b9f372116da1658f589df213aed33c2ded6Calvin On } catch (Exception re) { 200d7d16b9f372116da1658f589df213aed33c2ded6Calvin On Log.e(TAG,"",re); 201d7d16b9f372116da1658f589df213aed33c2ded6Calvin On } finally { 202d7d16b9f372116da1658f589df213aed33c2ded6Calvin On mServiceLock.readLock().unlock(); 2030f42037eb7b5118015c2caca635538324ccf0ccffredc } 2040f42037eb7b5118015c2caca635538324ccf0ccffredc } 2050f42037eb7b5118015c2caca635538324ccf0ccffredc } 2060f42037eb7b5118015c2caca635538324ccf0ccffredc }; 2079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Create a BluetoothA2dp proxy object for interacting with the local 2099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Bluetooth A2DP service. 21062c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * 2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2123e8c82edb1feafc796aa52efafedc13f794c4dcdMatthew Xie /*package*/ BluetoothA2dp(Context context, ServiceListener l) { 2133e8c82edb1feafc796aa52efafedc13f794c4dcdMatthew Xie mContext = context; 21462c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh mServiceListener = l; 21562c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh mAdapter = BluetoothAdapter.getDefaultAdapter(); 2160f42037eb7b5118015c2caca635538324ccf0ccffredc IBluetoothManager mgr = mAdapter.getBluetoothManager(); 2170f42037eb7b5118015c2caca635538324ccf0ccffredc if (mgr != null) { 2180f42037eb7b5118015c2caca635538324ccf0ccffredc try { 2190f42037eb7b5118015c2caca635538324ccf0ccffredc mgr.registerStateChangeCallback(mBluetoothStateChangeCallback); 2200f42037eb7b5118015c2caca635538324ccf0ccffredc } catch (RemoteException e) { 2210f42037eb7b5118015c2caca635538324ccf0ccffredc Log.e(TAG,"",e); 2220f42037eb7b5118015c2caca635538324ccf0ccffredc } 2230f42037eb7b5118015c2caca635538324ccf0ccffredc } 2240f42037eb7b5118015c2caca635538324ccf0ccffredc 225221ea892dcc661bd07d6f36ff012edca2c48aed4Dianne Hackborn doBind(); 226221ea892dcc661bd07d6f36ff012edca2c48aed4Dianne Hackborn } 227221ea892dcc661bd07d6f36ff012edca2c48aed4Dianne Hackborn 228221ea892dcc661bd07d6f36ff012edca2c48aed4Dianne Hackborn boolean doBind() { 229221ea892dcc661bd07d6f36ff012edca2c48aed4Dianne Hackborn Intent intent = new Intent(IBluetoothA2dp.class.getName()); 230221ea892dcc661bd07d6f36ff012edca2c48aed4Dianne Hackborn ComponentName comp = intent.resolveSystemService(mContext.getPackageManager(), 0); 231221ea892dcc661bd07d6f36ff012edca2c48aed4Dianne Hackborn intent.setComponent(comp); 232466ce96da8ca7ea8c97e716b02a7d55007179aa1Dianne Hackborn if (comp == null || !mContext.bindServiceAsUser(intent, mConnection, 0, 233466ce96da8ca7ea8c97e716b02a7d55007179aa1Dianne Hackborn android.os.Process.myUserHandle())) { 234221ea892dcc661bd07d6f36ff012edca2c48aed4Dianne Hackborn Log.e(TAG, "Could not bind to Bluetooth A2DP Service with " + intent); 235221ea892dcc661bd07d6f36ff012edca2c48aed4Dianne Hackborn return false; 2369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 237221ea892dcc661bd07d6f36ff012edca2c48aed4Dianne Hackborn return true; 2389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2409bb275197df8eb999eab4cdd0a2aff83c2bb2ef6Jaikumar Ganesh /*package*/ void close() { 2419bb275197df8eb999eab4cdd0a2aff83c2bb2ef6Jaikumar Ganesh mServiceListener = null; 2420f42037eb7b5118015c2caca635538324ccf0ccffredc IBluetoothManager mgr = mAdapter.getBluetoothManager(); 2430f42037eb7b5118015c2caca635538324ccf0ccffredc if (mgr != null) { 2440f42037eb7b5118015c2caca635538324ccf0ccffredc try { 2450f42037eb7b5118015c2caca635538324ccf0ccffredc mgr.unregisterStateChangeCallback(mBluetoothStateChangeCallback); 2460f42037eb7b5118015c2caca635538324ccf0ccffredc } catch (Exception e) { 2470f42037eb7b5118015c2caca635538324ccf0ccffredc Log.e(TAG,"",e); 2480f42037eb7b5118015c2caca635538324ccf0ccffredc } 2490f42037eb7b5118015c2caca635538324ccf0ccffredc } 2500f42037eb7b5118015c2caca635538324ccf0ccffredc 251d7d16b9f372116da1658f589df213aed33c2ded6Calvin On try { 252d7d16b9f372116da1658f589df213aed33c2ded6Calvin On mServiceLock.writeLock().lock(); 2530f42037eb7b5118015c2caca635538324ccf0ccffredc if (mService != null) { 254d7d16b9f372116da1658f589df213aed33c2ded6Calvin On mService = null; 255d7d16b9f372116da1658f589df213aed33c2ded6Calvin On mContext.unbindService(mConnection); 2560f42037eb7b5118015c2caca635538324ccf0ccffredc } 257d7d16b9f372116da1658f589df213aed33c2ded6Calvin On } catch (Exception re) { 258d7d16b9f372116da1658f589df213aed33c2ded6Calvin On Log.e(TAG, "", re); 259d7d16b9f372116da1658f589df213aed33c2ded6Calvin On } finally { 260d7d16b9f372116da1658f589df213aed33c2ded6Calvin On mServiceLock.writeLock().unlock(); 2610f42037eb7b5118015c2caca635538324ccf0ccffredc } 2629bb275197df8eb999eab4cdd0a2aff83c2bb2ef6Jaikumar Ganesh } 2639bb275197df8eb999eab4cdd0a2aff83c2bb2ef6Jaikumar Ganesh 2640f42037eb7b5118015c2caca635538324ccf0ccffredc public void finalize() { 2652d2d8c28545c687dbb105006ef4554eac8480313Mathias Jeppsson // The empty finalize needs to be kept or the 2662d2d8c28545c687dbb105006ef4554eac8480313Mathias Jeppsson // cts signature tests would fail. 2670f42037eb7b5118015c2caca635538324ccf0ccffredc } 26862c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh /** 269f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * Initiate connection to a profile of the remote bluetooth device. 270f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * 271f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * <p> Currently, the system supports only 1 connection to the 272f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * A2DP profile. The API will automatically disconnect connected 273f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * devices before connecting. 274f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * 275f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * <p> This API returns false in scenarios like the profile on the 276f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * device is already connected or Bluetooth is not turned on. 277f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * When this API returns true, it is guaranteed that 278f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * connection state intent for the profile will be broadcasted with 279f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * the state. Users can get the connection state of the profile 280f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * from this intent. 281f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * 282f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN} 283f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * permission. 284f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * 285f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * @param device Remote Bluetooth Device 286f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * @return false on immediate error, 287f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * true otherwise 28862c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * @hide 2899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 29062c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh public boolean connect(BluetoothDevice device) { 29162c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh if (DBG) log("connect(" + device + ")"); 292d7d16b9f372116da1658f589df213aed33c2ded6Calvin On try { 293d7d16b9f372116da1658f589df213aed33c2ded6Calvin On mServiceLock.readLock().lock(); 294d7d16b9f372116da1658f589df213aed33c2ded6Calvin On if (mService != null && isEnabled() && 295d7d16b9f372116da1658f589df213aed33c2ded6Calvin On isValidDevice(device)) { 29662c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh return mService.connect(device); 29762c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh } 298d7d16b9f372116da1658f589df213aed33c2ded6Calvin On if (mService == null) Log.w(TAG, "Proxy not attached to service"); 299d7d16b9f372116da1658f589df213aed33c2ded6Calvin On return false; 300d7d16b9f372116da1658f589df213aed33c2ded6Calvin On } catch (RemoteException e) { 301d7d16b9f372116da1658f589df213aed33c2ded6Calvin On Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable())); 302d7d16b9f372116da1658f589df213aed33c2ded6Calvin On return false; 303d7d16b9f372116da1658f589df213aed33c2ded6Calvin On } finally { 304d7d16b9f372116da1658f589df213aed33c2ded6Calvin On mServiceLock.readLock().unlock(); 3059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 30862c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh /** 309f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * Initiate disconnection from a profile 310f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * 311f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * <p> This API will return false in scenarios like the profile on the 312f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * Bluetooth device is not in connected state etc. When this API returns, 313f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * true, it is guaranteed that the connection state change 314f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * intent will be broadcasted with the state. Users can get the 315f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * disconnection state of the profile from this intent. 316f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * 317f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * <p> If the disconnection is initiated by a remote device, the state 318f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * will transition from {@link #STATE_CONNECTED} to 319f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * {@link #STATE_DISCONNECTED}. If the disconnect is initiated by the 320f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * host (local) device the state will transition from 321f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * {@link #STATE_CONNECTED} to state {@link #STATE_DISCONNECTING} to 322f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * state {@link #STATE_DISCONNECTED}. The transition to 323f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * {@link #STATE_DISCONNECTING} can be used to distinguish between the 324f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * two scenarios. 325f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * 326f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN} 327f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * permission. 328f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * 329f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * @param device Remote Bluetooth Device 330f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * @return false on immediate error, 331f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * true otherwise 33262c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * @hide 3339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 33462c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh public boolean disconnect(BluetoothDevice device) { 33562c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh if (DBG) log("disconnect(" + device + ")"); 336d7d16b9f372116da1658f589df213aed33c2ded6Calvin On try { 337d7d16b9f372116da1658f589df213aed33c2ded6Calvin On mServiceLock.readLock().lock(); 338d7d16b9f372116da1658f589df213aed33c2ded6Calvin On if (mService != null && isEnabled() && 339d7d16b9f372116da1658f589df213aed33c2ded6Calvin On isValidDevice(device)) { 34062c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh return mService.disconnect(device); 34162c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh } 342d7d16b9f372116da1658f589df213aed33c2ded6Calvin On if (mService == null) Log.w(TAG, "Proxy not attached to service"); 343d7d16b9f372116da1658f589df213aed33c2ded6Calvin On return false; 344d7d16b9f372116da1658f589df213aed33c2ded6Calvin On } catch (RemoteException e) { 345d7d16b9f372116da1658f589df213aed33c2ded6Calvin On Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable())); 346d7d16b9f372116da1658f589df213aed33c2ded6Calvin On return false; 347d7d16b9f372116da1658f589df213aed33c2ded6Calvin On } finally { 348d7d16b9f372116da1658f589df213aed33c2ded6Calvin On mServiceLock.readLock().unlock(); 3499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 35262c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh /** 35362c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * {@inheritDoc} 354f9bbe1e71a502fe7bd1f4a23ba5bbe4dde0d9d57Zhu Lan */ 35503cd78cf5e51c3adb78d2e3d314838dcf3e36b26Jaikumar Ganesh public List<BluetoothDevice> getConnectedDevices() { 356563e414784eb81e4ea4051667d5c8855b17f7534Matthew Xie if (VDBG) log("getConnectedDevices()"); 357d7d16b9f372116da1658f589df213aed33c2ded6Calvin On try { 358d7d16b9f372116da1658f589df213aed33c2ded6Calvin On mServiceLock.readLock().lock(); 359d7d16b9f372116da1658f589df213aed33c2ded6Calvin On if (mService != null && isEnabled()) { 36003cd78cf5e51c3adb78d2e3d314838dcf3e36b26Jaikumar Ganesh return mService.getConnectedDevices(); 36162c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh } 362d7d16b9f372116da1658f589df213aed33c2ded6Calvin On if (mService == null) Log.w(TAG, "Proxy not attached to service"); 363d7d16b9f372116da1658f589df213aed33c2ded6Calvin On return new ArrayList<BluetoothDevice>(); 364d7d16b9f372116da1658f589df213aed33c2ded6Calvin On } catch (RemoteException e) { 365d7d16b9f372116da1658f589df213aed33c2ded6Calvin On Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable())); 366d7d16b9f372116da1658f589df213aed33c2ded6Calvin On return new ArrayList<BluetoothDevice>(); 367d7d16b9f372116da1658f589df213aed33c2ded6Calvin On } finally { 368d7d16b9f372116da1658f589df213aed33c2ded6Calvin On mServiceLock.readLock().unlock(); 369f9bbe1e71a502fe7bd1f4a23ba5bbe4dde0d9d57Zhu Lan } 370f9bbe1e71a502fe7bd1f4a23ba5bbe4dde0d9d57Zhu Lan } 371f9bbe1e71a502fe7bd1f4a23ba5bbe4dde0d9d57Zhu Lan 37262c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh /** 37362c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * {@inheritDoc} 374f9bbe1e71a502fe7bd1f4a23ba5bbe4dde0d9d57Zhu Lan */ 37503cd78cf5e51c3adb78d2e3d314838dcf3e36b26Jaikumar Ganesh public List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) { 376563e414784eb81e4ea4051667d5c8855b17f7534Matthew Xie if (VDBG) log("getDevicesMatchingStates()"); 377d7d16b9f372116da1658f589df213aed33c2ded6Calvin On try { 378d7d16b9f372116da1658f589df213aed33c2ded6Calvin On mServiceLock.readLock().lock(); 379d7d16b9f372116da1658f589df213aed33c2ded6Calvin On if (mService != null && isEnabled()) { 38003cd78cf5e51c3adb78d2e3d314838dcf3e36b26Jaikumar Ganesh return mService.getDevicesMatchingConnectionStates(states); 38162c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh } 382d7d16b9f372116da1658f589df213aed33c2ded6Calvin On if (mService == null) Log.w(TAG, "Proxy not attached to service"); 383d7d16b9f372116da1658f589df213aed33c2ded6Calvin On return new ArrayList<BluetoothDevice>(); 384d7d16b9f372116da1658f589df213aed33c2ded6Calvin On } catch (RemoteException e) { 385d7d16b9f372116da1658f589df213aed33c2ded6Calvin On Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable())); 386d7d16b9f372116da1658f589df213aed33c2ded6Calvin On return new ArrayList<BluetoothDevice>(); 387d7d16b9f372116da1658f589df213aed33c2ded6Calvin On } finally { 388d7d16b9f372116da1658f589df213aed33c2ded6Calvin On mServiceLock.readLock().unlock(); 389f9bbe1e71a502fe7bd1f4a23ba5bbe4dde0d9d57Zhu Lan } 390f9bbe1e71a502fe7bd1f4a23ba5bbe4dde0d9d57Zhu Lan } 391f9bbe1e71a502fe7bd1f4a23ba5bbe4dde0d9d57Zhu Lan 39262c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh /** 39362c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * {@inheritDoc} 3949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 39562c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh public int getConnectionState(BluetoothDevice device) { 396563e414784eb81e4ea4051667d5c8855b17f7534Matthew Xie if (VDBG) log("getState(" + device + ")"); 397d7d16b9f372116da1658f589df213aed33c2ded6Calvin On try { 398d7d16b9f372116da1658f589df213aed33c2ded6Calvin On mServiceLock.readLock().lock(); 399d7d16b9f372116da1658f589df213aed33c2ded6Calvin On if (mService != null && isEnabled() 400d7d16b9f372116da1658f589df213aed33c2ded6Calvin On && isValidDevice(device)) { 40162c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh return mService.getConnectionState(device); 40262c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh } 403d7d16b9f372116da1658f589df213aed33c2ded6Calvin On if (mService == null) Log.w(TAG, "Proxy not attached to service"); 404d7d16b9f372116da1658f589df213aed33c2ded6Calvin On return BluetoothProfile.STATE_DISCONNECTED; 405d7d16b9f372116da1658f589df213aed33c2ded6Calvin On } catch (RemoteException e) { 406d7d16b9f372116da1658f589df213aed33c2ded6Calvin On Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable())); 407d7d16b9f372116da1658f589df213aed33c2ded6Calvin On return BluetoothProfile.STATE_DISCONNECTED; 408d7d16b9f372116da1658f589df213aed33c2ded6Calvin On } finally { 409d7d16b9f372116da1658f589df213aed33c2ded6Calvin On mServiceLock.readLock().unlock(); 41062c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh } 4119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 41362c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh /** 414f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * Set priority of the profile 415f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * 416f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * <p> The device should already be paired. 4170f42037eb7b5118015c2caca635538324ccf0ccffredc * Priority can be one of {@link #PRIORITY_ON} orgetBluetoothManager 418f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * {@link #PRIORITY_OFF}, 419f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * 420f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN} 421f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * permission. 422f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * 423f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * @param device Paired bluetooth device 424f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * @param priority 425f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * @return true if priority is set, false on error 4269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @hide 4279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 42862c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh public boolean setPriority(BluetoothDevice device, int priority) { 42962c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh if (DBG) log("setPriority(" + device + ", " + priority + ")"); 430d7d16b9f372116da1658f589df213aed33c2ded6Calvin On try { 431d7d16b9f372116da1658f589df213aed33c2ded6Calvin On mServiceLock.readLock().lock(); 432d7d16b9f372116da1658f589df213aed33c2ded6Calvin On if (mService != null && isEnabled() 433d7d16b9f372116da1658f589df213aed33c2ded6Calvin On && isValidDevice(device)) { 434d7d16b9f372116da1658f589df213aed33c2ded6Calvin On if (priority != BluetoothProfile.PRIORITY_OFF && 435d7d16b9f372116da1658f589df213aed33c2ded6Calvin On priority != BluetoothProfile.PRIORITY_ON) { 436d7d16b9f372116da1658f589df213aed33c2ded6Calvin On return false; 437d7d16b9f372116da1658f589df213aed33c2ded6Calvin On } 43862c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh return mService.setPriority(device, priority); 43962c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh } 440d7d16b9f372116da1658f589df213aed33c2ded6Calvin On if (mService == null) Log.w(TAG, "Proxy not attached to service"); 441d7d16b9f372116da1658f589df213aed33c2ded6Calvin On return false; 442d7d16b9f372116da1658f589df213aed33c2ded6Calvin On } catch (RemoteException e) { 443d7d16b9f372116da1658f589df213aed33c2ded6Calvin On Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable())); 444d7d16b9f372116da1658f589df213aed33c2ded6Calvin On return false; 445d7d16b9f372116da1658f589df213aed33c2ded6Calvin On } finally { 446d7d16b9f372116da1658f589df213aed33c2ded6Calvin On mServiceLock.readLock().unlock(); 4479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 45062c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh /** 451f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * Get the priority of the profile. 452f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * 453f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * <p> The priority can be any of: 454f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * {@link #PRIORITY_AUTO_CONNECT}, {@link #PRIORITY_OFF}, 455f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * {@link #PRIORITY_ON}, {@link #PRIORITY_UNDEFINED} 456f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * 457f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * @param device Bluetooth device 458f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * @return priority of the device 459b16c4f7dd92dabf0cc27438a5d3d9ebd203a38b3Jaikumar Ganesh * @hide 460b16c4f7dd92dabf0cc27438a5d3d9ebd203a38b3Jaikumar Ganesh */ 4612d49752ee050ab7f1cd848933f6c62a73707e2d9Tor Norbye @RequiresPermission(Manifest.permission.BLUETOOTH) 46262c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh public int getPriority(BluetoothDevice device) { 463563e414784eb81e4ea4051667d5c8855b17f7534Matthew Xie if (VDBG) log("getPriority(" + device + ")"); 464d7d16b9f372116da1658f589df213aed33c2ded6Calvin On try { 465d7d16b9f372116da1658f589df213aed33c2ded6Calvin On mServiceLock.readLock().lock(); 466d7d16b9f372116da1658f589df213aed33c2ded6Calvin On if (mService != null && isEnabled() 467d7d16b9f372116da1658f589df213aed33c2ded6Calvin On && isValidDevice(device)) { 46862c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh return mService.getPriority(device); 46962c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh } 470d7d16b9f372116da1658f589df213aed33c2ded6Calvin On if (mService == null) Log.w(TAG, "Proxy not attached to service"); 471d7d16b9f372116da1658f589df213aed33c2ded6Calvin On return BluetoothProfile.PRIORITY_OFF; 472d7d16b9f372116da1658f589df213aed33c2ded6Calvin On } catch (RemoteException e) { 473d7d16b9f372116da1658f589df213aed33c2ded6Calvin On Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable())); 474d7d16b9f372116da1658f589df213aed33c2ded6Calvin On return BluetoothProfile.PRIORITY_OFF; 475d7d16b9f372116da1658f589df213aed33c2ded6Calvin On } finally { 476d7d16b9f372116da1658f589df213aed33c2ded6Calvin On mServiceLock.readLock().unlock(); 477b16c4f7dd92dabf0cc27438a5d3d9ebd203a38b3Jaikumar Ganesh } 478b16c4f7dd92dabf0cc27438a5d3d9ebd203a38b3Jaikumar Ganesh } 479b16c4f7dd92dabf0cc27438a5d3d9ebd203a38b3Jaikumar Ganesh 48062c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh /** 4815a0cf7a27f3953a1266af48543ccd9024f4cd89fJohn Du * Checks if Avrcp device supports the absolute volume feature. 4825a0cf7a27f3953a1266af48543ccd9024f4cd89fJohn Du * 4835a0cf7a27f3953a1266af48543ccd9024f4cd89fJohn Du * @return true if device supports absolute volume 4845a0cf7a27f3953a1266af48543ccd9024f4cd89fJohn Du * @hide 4855a0cf7a27f3953a1266af48543ccd9024f4cd89fJohn Du */ 4865a0cf7a27f3953a1266af48543ccd9024f4cd89fJohn Du public boolean isAvrcpAbsoluteVolumeSupported() { 4875a0cf7a27f3953a1266af48543ccd9024f4cd89fJohn Du if (DBG) Log.d(TAG, "isAvrcpAbsoluteVolumeSupported"); 488d7d16b9f372116da1658f589df213aed33c2ded6Calvin On try { 489d7d16b9f372116da1658f589df213aed33c2ded6Calvin On mServiceLock.readLock().lock(); 490d7d16b9f372116da1658f589df213aed33c2ded6Calvin On if (mService != null && isEnabled()) { 4915a0cf7a27f3953a1266af48543ccd9024f4cd89fJohn Du return mService.isAvrcpAbsoluteVolumeSupported(); 4925a0cf7a27f3953a1266af48543ccd9024f4cd89fJohn Du } 493d7d16b9f372116da1658f589df213aed33c2ded6Calvin On if (mService == null) Log.w(TAG, "Proxy not attached to service"); 494d7d16b9f372116da1658f589df213aed33c2ded6Calvin On return false; 495d7d16b9f372116da1658f589df213aed33c2ded6Calvin On } catch (RemoteException e) { 496d7d16b9f372116da1658f589df213aed33c2ded6Calvin On Log.e(TAG, "Error talking to BT service in isAvrcpAbsoluteVolumeSupported()", e); 497d7d16b9f372116da1658f589df213aed33c2ded6Calvin On return false; 498d7d16b9f372116da1658f589df213aed33c2ded6Calvin On } finally { 499d7d16b9f372116da1658f589df213aed33c2ded6Calvin On mServiceLock.readLock().unlock(); 5005a0cf7a27f3953a1266af48543ccd9024f4cd89fJohn Du } 5015a0cf7a27f3953a1266af48543ccd9024f4cd89fJohn Du } 5025a0cf7a27f3953a1266af48543ccd9024f4cd89fJohn Du 5035a0cf7a27f3953a1266af48543ccd9024f4cd89fJohn Du /** 5044197cb60bc74629fe4c04ab10cb3b1c9a7427d24RoboErik * Tells remote device to adjust volume. Only if absolute volume is 5054197cb60bc74629fe4c04ab10cb3b1c9a7427d24RoboErik * supported. Uses the following values: 5064197cb60bc74629fe4c04ab10cb3b1c9a7427d24RoboErik * <ul> 5074197cb60bc74629fe4c04ab10cb3b1c9a7427d24RoboErik * <li>{@link AudioManager#ADJUST_LOWER}</li> 5084197cb60bc74629fe4c04ab10cb3b1c9a7427d24RoboErik * <li>{@link AudioManager#ADJUST_RAISE}</li> 5094197cb60bc74629fe4c04ab10cb3b1c9a7427d24RoboErik * <li>{@link AudioManager#ADJUST_MUTE}</li> 5104197cb60bc74629fe4c04ab10cb3b1c9a7427d24RoboErik * <li>{@link AudioManager#ADJUST_UNMUTE}</li> 5114197cb60bc74629fe4c04ab10cb3b1c9a7427d24RoboErik * </ul> 5125a0cf7a27f3953a1266af48543ccd9024f4cd89fJohn Du * 5134197cb60bc74629fe4c04ab10cb3b1c9a7427d24RoboErik * @param direction One of the supported adjust values. 5145a0cf7a27f3953a1266af48543ccd9024f4cd89fJohn Du * @hide 5155a0cf7a27f3953a1266af48543ccd9024f4cd89fJohn Du */ 5165a0cf7a27f3953a1266af48543ccd9024f4cd89fJohn Du public void adjustAvrcpAbsoluteVolume(int direction) { 5175a0cf7a27f3953a1266af48543ccd9024f4cd89fJohn Du if (DBG) Log.d(TAG, "adjustAvrcpAbsoluteVolume"); 518d7d16b9f372116da1658f589df213aed33c2ded6Calvin On try { 519d7d16b9f372116da1658f589df213aed33c2ded6Calvin On mServiceLock.readLock().lock(); 520d7d16b9f372116da1658f589df213aed33c2ded6Calvin On if (mService != null && isEnabled()) { 5215a0cf7a27f3953a1266af48543ccd9024f4cd89fJohn Du mService.adjustAvrcpAbsoluteVolume(direction); 5225a0cf7a27f3953a1266af48543ccd9024f4cd89fJohn Du } 523d7d16b9f372116da1658f589df213aed33c2ded6Calvin On if (mService == null) Log.w(TAG, "Proxy not attached to service"); 524d7d16b9f372116da1658f589df213aed33c2ded6Calvin On } catch (RemoteException e) { 525d7d16b9f372116da1658f589df213aed33c2ded6Calvin On Log.e(TAG, "Error talking to BT service in adjustAvrcpAbsoluteVolume()", e); 526d7d16b9f372116da1658f589df213aed33c2ded6Calvin On } finally { 527d7d16b9f372116da1658f589df213aed33c2ded6Calvin On mServiceLock.readLock().unlock(); 5285a0cf7a27f3953a1266af48543ccd9024f4cd89fJohn Du } 5295a0cf7a27f3953a1266af48543ccd9024f4cd89fJohn Du } 5305a0cf7a27f3953a1266af48543ccd9024f4cd89fJohn Du 5315a0cf7a27f3953a1266af48543ccd9024f4cd89fJohn Du /** 5325a0cf7a27f3953a1266af48543ccd9024f4cd89fJohn Du * Tells remote device to set an absolute volume. Only if absolute volume is supported 5335a0cf7a27f3953a1266af48543ccd9024f4cd89fJohn Du * 5345a0cf7a27f3953a1266af48543ccd9024f4cd89fJohn Du * @param volume Absolute volume to be set on AVRCP side 5355a0cf7a27f3953a1266af48543ccd9024f4cd89fJohn Du * @hide 5365a0cf7a27f3953a1266af48543ccd9024f4cd89fJohn Du */ 5375a0cf7a27f3953a1266af48543ccd9024f4cd89fJohn Du public void setAvrcpAbsoluteVolume(int volume) { 5385a0cf7a27f3953a1266af48543ccd9024f4cd89fJohn Du if (DBG) Log.d(TAG, "setAvrcpAbsoluteVolume"); 539d7d16b9f372116da1658f589df213aed33c2ded6Calvin On try { 540d7d16b9f372116da1658f589df213aed33c2ded6Calvin On mServiceLock.readLock().lock(); 541d7d16b9f372116da1658f589df213aed33c2ded6Calvin On if (mService != null && isEnabled()) { 5425a0cf7a27f3953a1266af48543ccd9024f4cd89fJohn Du mService.setAvrcpAbsoluteVolume(volume); 5435a0cf7a27f3953a1266af48543ccd9024f4cd89fJohn Du } 544d7d16b9f372116da1658f589df213aed33c2ded6Calvin On if (mService == null) Log.w(TAG, "Proxy not attached to service"); 545d7d16b9f372116da1658f589df213aed33c2ded6Calvin On } catch (RemoteException e) { 546d7d16b9f372116da1658f589df213aed33c2ded6Calvin On Log.e(TAG, "Error talking to BT service in setAvrcpAbsoluteVolume()", e); 547d7d16b9f372116da1658f589df213aed33c2ded6Calvin On } finally { 548d7d16b9f372116da1658f589df213aed33c2ded6Calvin On mServiceLock.readLock().unlock(); 5495a0cf7a27f3953a1266af48543ccd9024f4cd89fJohn Du } 5505a0cf7a27f3953a1266af48543ccd9024f4cd89fJohn Du } 5515a0cf7a27f3953a1266af48543ccd9024f4cd89fJohn Du 5525a0cf7a27f3953a1266af48543ccd9024f4cd89fJohn Du /** 55362c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * Check if A2DP profile is streaming music. 55462c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * 555c8fa4ff838a0c3d2c67db65540fa751e5abe27edJaikumar Ganesh * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission. 55662c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * 55762c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * @param device BluetoothDevice device 5589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 55962c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh public boolean isA2dpPlaying(BluetoothDevice device) { 560d7d16b9f372116da1658f589df213aed33c2ded6Calvin On try { 561d7d16b9f372116da1658f589df213aed33c2ded6Calvin On mServiceLock.readLock().lock(); 562d7d16b9f372116da1658f589df213aed33c2ded6Calvin On if (mService != null && isEnabled() 563d7d16b9f372116da1658f589df213aed33c2ded6Calvin On && isValidDevice(device)) { 56462c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh return mService.isA2dpPlaying(device); 56562c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh } 566d7d16b9f372116da1658f589df213aed33c2ded6Calvin On if (mService == null) Log.w(TAG, "Proxy not attached to service"); 567d7d16b9f372116da1658f589df213aed33c2ded6Calvin On return false; 568d7d16b9f372116da1658f589df213aed33c2ded6Calvin On } catch (RemoteException e) { 569d7d16b9f372116da1658f589df213aed33c2ded6Calvin On Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable())); 570d7d16b9f372116da1658f589df213aed33c2ded6Calvin On return false; 571d7d16b9f372116da1658f589df213aed33c2ded6Calvin On } finally { 572d7d16b9f372116da1658f589df213aed33c2ded6Calvin On mServiceLock.readLock().unlock(); 5739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 57741d5c805d96aef0aaa9a2aaa86ccc4b77ca75e11Jaikumar Ganesh * This function checks if the remote device is an AVCRP 57841d5c805d96aef0aaa9a2aaa86ccc4b77ca75e11Jaikumar Ganesh * target and thus whether we should send volume keys 57941d5c805d96aef0aaa9a2aaa86ccc4b77ca75e11Jaikumar Ganesh * changes or not. 58041d5c805d96aef0aaa9a2aaa86ccc4b77ca75e11Jaikumar Ganesh * @hide 58141d5c805d96aef0aaa9a2aaa86ccc4b77ca75e11Jaikumar Ganesh */ 58241d5c805d96aef0aaa9a2aaa86ccc4b77ca75e11Jaikumar Ganesh public boolean shouldSendVolumeKeys(BluetoothDevice device) { 58341d5c805d96aef0aaa9a2aaa86ccc4b77ca75e11Jaikumar Ganesh if (isEnabled() && isValidDevice(device)) { 58441d5c805d96aef0aaa9a2aaa86ccc4b77ca75e11Jaikumar Ganesh ParcelUuid[] uuids = device.getUuids(); 58541d5c805d96aef0aaa9a2aaa86ccc4b77ca75e11Jaikumar Ganesh if (uuids == null) return false; 58641d5c805d96aef0aaa9a2aaa86ccc4b77ca75e11Jaikumar Ganesh 58741d5c805d96aef0aaa9a2aaa86ccc4b77ca75e11Jaikumar Ganesh for (ParcelUuid uuid: uuids) { 58841d5c805d96aef0aaa9a2aaa86ccc4b77ca75e11Jaikumar Ganesh if (BluetoothUuid.isAvrcpTarget(uuid)) { 58941d5c805d96aef0aaa9a2aaa86ccc4b77ca75e11Jaikumar Ganesh return true; 59041d5c805d96aef0aaa9a2aaa86ccc4b77ca75e11Jaikumar Ganesh } 59141d5c805d96aef0aaa9a2aaa86ccc4b77ca75e11Jaikumar Ganesh } 59241d5c805d96aef0aaa9a2aaa86ccc4b77ca75e11Jaikumar Ganesh } 59341d5c805d96aef0aaa9a2aaa86ccc4b77ca75e11Jaikumar Ganesh return false; 59441d5c805d96aef0aaa9a2aaa86ccc4b77ca75e11Jaikumar Ganesh } 59541d5c805d96aef0aaa9a2aaa86ccc4b77ca75e11Jaikumar Ganesh 596a0c680393f2dd03a937c598b2cb9abf98a58152cMatthew Xie /** 597b37f181c9853bd0d55d360db95d3bf1bba0b5a6fPavlin Radoslavov * Gets the current codec status (configuration and capability). 59844a4ef0aa93ebb2912f36d65af42ffbb1bcdbc0fPavlin Radoslavov * 599b37f181c9853bd0d55d360db95d3bf1bba0b5a6fPavlin Radoslavov * @return the current codec status 60044a4ef0aa93ebb2912f36d65af42ffbb1bcdbc0fPavlin Radoslavov * @hide 60144a4ef0aa93ebb2912f36d65af42ffbb1bcdbc0fPavlin Radoslavov */ 602b37f181c9853bd0d55d360db95d3bf1bba0b5a6fPavlin Radoslavov public BluetoothCodecStatus getCodecStatus() { 603b37f181c9853bd0d55d360db95d3bf1bba0b5a6fPavlin Radoslavov if (DBG) Log.d(TAG, "getCodecStatus"); 60444a4ef0aa93ebb2912f36d65af42ffbb1bcdbc0fPavlin Radoslavov try { 60544a4ef0aa93ebb2912f36d65af42ffbb1bcdbc0fPavlin Radoslavov mServiceLock.readLock().lock(); 60644a4ef0aa93ebb2912f36d65af42ffbb1bcdbc0fPavlin Radoslavov if (mService != null && isEnabled()) { 607b37f181c9853bd0d55d360db95d3bf1bba0b5a6fPavlin Radoslavov return mService.getCodecStatus(); 60844a4ef0aa93ebb2912f36d65af42ffbb1bcdbc0fPavlin Radoslavov } 60944a4ef0aa93ebb2912f36d65af42ffbb1bcdbc0fPavlin Radoslavov if (mService == null) { 61044a4ef0aa93ebb2912f36d65af42ffbb1bcdbc0fPavlin Radoslavov Log.w(TAG, "Proxy not attached to service"); 61144a4ef0aa93ebb2912f36d65af42ffbb1bcdbc0fPavlin Radoslavov } 61244a4ef0aa93ebb2912f36d65af42ffbb1bcdbc0fPavlin Radoslavov return null; 61344a4ef0aa93ebb2912f36d65af42ffbb1bcdbc0fPavlin Radoslavov } catch (RemoteException e) { 614b37f181c9853bd0d55d360db95d3bf1bba0b5a6fPavlin Radoslavov Log.e(TAG, "Error talking to BT service in getCodecStatus()", e); 61544a4ef0aa93ebb2912f36d65af42ffbb1bcdbc0fPavlin Radoslavov return null; 61644a4ef0aa93ebb2912f36d65af42ffbb1bcdbc0fPavlin Radoslavov } finally { 61744a4ef0aa93ebb2912f36d65af42ffbb1bcdbc0fPavlin Radoslavov mServiceLock.readLock().unlock(); 61844a4ef0aa93ebb2912f36d65af42ffbb1bcdbc0fPavlin Radoslavov } 61944a4ef0aa93ebb2912f36d65af42ffbb1bcdbc0fPavlin Radoslavov } 62044a4ef0aa93ebb2912f36d65af42ffbb1bcdbc0fPavlin Radoslavov 62144a4ef0aa93ebb2912f36d65af42ffbb1bcdbc0fPavlin Radoslavov /** 62244a4ef0aa93ebb2912f36d65af42ffbb1bcdbc0fPavlin Radoslavov * Sets the codec configuration preference. 62344a4ef0aa93ebb2912f36d65af42ffbb1bcdbc0fPavlin Radoslavov * 62444a4ef0aa93ebb2912f36d65af42ffbb1bcdbc0fPavlin Radoslavov * @param codecConfig the codec configuration preference 62544a4ef0aa93ebb2912f36d65af42ffbb1bcdbc0fPavlin Radoslavov * @hide 62644a4ef0aa93ebb2912f36d65af42ffbb1bcdbc0fPavlin Radoslavov */ 62744a4ef0aa93ebb2912f36d65af42ffbb1bcdbc0fPavlin Radoslavov public void setCodecConfigPreference(BluetoothCodecConfig codecConfig) { 62844a4ef0aa93ebb2912f36d65af42ffbb1bcdbc0fPavlin Radoslavov if (DBG) Log.d(TAG, "setCodecConfigPreference"); 62944a4ef0aa93ebb2912f36d65af42ffbb1bcdbc0fPavlin Radoslavov try { 63044a4ef0aa93ebb2912f36d65af42ffbb1bcdbc0fPavlin Radoslavov mServiceLock.readLock().lock(); 63144a4ef0aa93ebb2912f36d65af42ffbb1bcdbc0fPavlin Radoslavov if (mService != null && isEnabled()) { 63244a4ef0aa93ebb2912f36d65af42ffbb1bcdbc0fPavlin Radoslavov mService.setCodecConfigPreference(codecConfig); 63344a4ef0aa93ebb2912f36d65af42ffbb1bcdbc0fPavlin Radoslavov } 63444a4ef0aa93ebb2912f36d65af42ffbb1bcdbc0fPavlin Radoslavov if (mService == null) Log.w(TAG, "Proxy not attached to service"); 63544a4ef0aa93ebb2912f36d65af42ffbb1bcdbc0fPavlin Radoslavov return; 63644a4ef0aa93ebb2912f36d65af42ffbb1bcdbc0fPavlin Radoslavov } catch (RemoteException e) { 63744a4ef0aa93ebb2912f36d65af42ffbb1bcdbc0fPavlin Radoslavov Log.e(TAG, "Error talking to BT service in setCodecConfigPreference()", e); 63844a4ef0aa93ebb2912f36d65af42ffbb1bcdbc0fPavlin Radoslavov return; 63944a4ef0aa93ebb2912f36d65af42ffbb1bcdbc0fPavlin Radoslavov } finally { 64044a4ef0aa93ebb2912f36d65af42ffbb1bcdbc0fPavlin Radoslavov mServiceLock.readLock().unlock(); 64144a4ef0aa93ebb2912f36d65af42ffbb1bcdbc0fPavlin Radoslavov } 64244a4ef0aa93ebb2912f36d65af42ffbb1bcdbc0fPavlin Radoslavov } 64344a4ef0aa93ebb2912f36d65af42ffbb1bcdbc0fPavlin Radoslavov 64444a4ef0aa93ebb2912f36d65af42ffbb1bcdbc0fPavlin Radoslavov /** 645011597b5a933e8291d0bca9c3f3b17b9e816d654Pavlin Radoslavov * Enables the optional codecs. 646011597b5a933e8291d0bca9c3f3b17b9e816d654Pavlin Radoslavov * 647011597b5a933e8291d0bca9c3f3b17b9e816d654Pavlin Radoslavov * @hide 648011597b5a933e8291d0bca9c3f3b17b9e816d654Pavlin Radoslavov */ 649011597b5a933e8291d0bca9c3f3b17b9e816d654Pavlin Radoslavov public void enableOptionalCodecs() { 650011597b5a933e8291d0bca9c3f3b17b9e816d654Pavlin Radoslavov if (DBG) Log.d(TAG, "enableOptionalCodecs"); 651011597b5a933e8291d0bca9c3f3b17b9e816d654Pavlin Radoslavov enableDisableOptionalCodecs(true); 652011597b5a933e8291d0bca9c3f3b17b9e816d654Pavlin Radoslavov } 653011597b5a933e8291d0bca9c3f3b17b9e816d654Pavlin Radoslavov 654011597b5a933e8291d0bca9c3f3b17b9e816d654Pavlin Radoslavov /** 655011597b5a933e8291d0bca9c3f3b17b9e816d654Pavlin Radoslavov * Disables the optional codecs. 656011597b5a933e8291d0bca9c3f3b17b9e816d654Pavlin Radoslavov * 657011597b5a933e8291d0bca9c3f3b17b9e816d654Pavlin Radoslavov * @hide 658011597b5a933e8291d0bca9c3f3b17b9e816d654Pavlin Radoslavov */ 659011597b5a933e8291d0bca9c3f3b17b9e816d654Pavlin Radoslavov public void disableOptionalCodecs() { 660011597b5a933e8291d0bca9c3f3b17b9e816d654Pavlin Radoslavov if (DBG) Log.d(TAG, "disableOptionalCodecs"); 661011597b5a933e8291d0bca9c3f3b17b9e816d654Pavlin Radoslavov enableDisableOptionalCodecs(false); 662011597b5a933e8291d0bca9c3f3b17b9e816d654Pavlin Radoslavov } 663011597b5a933e8291d0bca9c3f3b17b9e816d654Pavlin Radoslavov 664011597b5a933e8291d0bca9c3f3b17b9e816d654Pavlin Radoslavov /** 665011597b5a933e8291d0bca9c3f3b17b9e816d654Pavlin Radoslavov * Enables or disables the optional codecs. 666011597b5a933e8291d0bca9c3f3b17b9e816d654Pavlin Radoslavov * 667011597b5a933e8291d0bca9c3f3b17b9e816d654Pavlin Radoslavov * @param enable if true, enable the optional codecs, other disable them 668011597b5a933e8291d0bca9c3f3b17b9e816d654Pavlin Radoslavov */ 669011597b5a933e8291d0bca9c3f3b17b9e816d654Pavlin Radoslavov private void enableDisableOptionalCodecs(boolean enable) { 670011597b5a933e8291d0bca9c3f3b17b9e816d654Pavlin Radoslavov try { 671011597b5a933e8291d0bca9c3f3b17b9e816d654Pavlin Radoslavov mServiceLock.readLock().lock(); 672011597b5a933e8291d0bca9c3f3b17b9e816d654Pavlin Radoslavov if (mService != null && isEnabled()) { 673011597b5a933e8291d0bca9c3f3b17b9e816d654Pavlin Radoslavov if (enable) { 674011597b5a933e8291d0bca9c3f3b17b9e816d654Pavlin Radoslavov mService.enableOptionalCodecs(); 675011597b5a933e8291d0bca9c3f3b17b9e816d654Pavlin Radoslavov } else { 676011597b5a933e8291d0bca9c3f3b17b9e816d654Pavlin Radoslavov mService.disableOptionalCodecs(); 677011597b5a933e8291d0bca9c3f3b17b9e816d654Pavlin Radoslavov } 678011597b5a933e8291d0bca9c3f3b17b9e816d654Pavlin Radoslavov } 679011597b5a933e8291d0bca9c3f3b17b9e816d654Pavlin Radoslavov if (mService == null) Log.w(TAG, "Proxy not attached to service"); 680011597b5a933e8291d0bca9c3f3b17b9e816d654Pavlin Radoslavov return; 681011597b5a933e8291d0bca9c3f3b17b9e816d654Pavlin Radoslavov } catch (RemoteException e) { 682011597b5a933e8291d0bca9c3f3b17b9e816d654Pavlin Radoslavov Log.e(TAG, "Error talking to BT service in enableDisableOptionalCodecs()", e); 683011597b5a933e8291d0bca9c3f3b17b9e816d654Pavlin Radoslavov return; 684011597b5a933e8291d0bca9c3f3b17b9e816d654Pavlin Radoslavov } finally { 685011597b5a933e8291d0bca9c3f3b17b9e816d654Pavlin Radoslavov mServiceLock.readLock().unlock(); 686011597b5a933e8291d0bca9c3f3b17b9e816d654Pavlin Radoslavov } 687011597b5a933e8291d0bca9c3f3b17b9e816d654Pavlin Radoslavov } 688011597b5a933e8291d0bca9c3f3b17b9e816d654Pavlin Radoslavov 689011597b5a933e8291d0bca9c3f3b17b9e816d654Pavlin Radoslavov /** 690f5772c6121ee1f5f2aa06711e2762c0f07fb61ccAntony Sargent * Returns whether this device supports optional codecs. 691f5772c6121ee1f5f2aa06711e2762c0f07fb61ccAntony Sargent * 692f5772c6121ee1f5f2aa06711e2762c0f07fb61ccAntony Sargent * @param device The device to check 693f5772c6121ee1f5f2aa06711e2762c0f07fb61ccAntony Sargent * @return one of OPTIONAL_CODECS_SUPPORT_UNKNOWN, OPTIONAL_CODECS_NOT_SUPPORTED, or 694f5772c6121ee1f5f2aa06711e2762c0f07fb61ccAntony Sargent * OPTIONAL_CODECS_SUPPORTED. 695f5772c6121ee1f5f2aa06711e2762c0f07fb61ccAntony Sargent * 696f5772c6121ee1f5f2aa06711e2762c0f07fb61ccAntony Sargent * @hide 697f5772c6121ee1f5f2aa06711e2762c0f07fb61ccAntony Sargent */ 698f5772c6121ee1f5f2aa06711e2762c0f07fb61ccAntony Sargent public int supportsOptionalCodecs(BluetoothDevice device) { 699f5772c6121ee1f5f2aa06711e2762c0f07fb61ccAntony Sargent try { 700f5772c6121ee1f5f2aa06711e2762c0f07fb61ccAntony Sargent mServiceLock.readLock().lock(); 701f5772c6121ee1f5f2aa06711e2762c0f07fb61ccAntony Sargent if (mService != null && isEnabled() && isValidDevice(device)) { 702f5772c6121ee1f5f2aa06711e2762c0f07fb61ccAntony Sargent return mService.supportsOptionalCodecs(device); 703f5772c6121ee1f5f2aa06711e2762c0f07fb61ccAntony Sargent } 704f5772c6121ee1f5f2aa06711e2762c0f07fb61ccAntony Sargent if (mService == null) Log.w(TAG, "Proxy not attached to service"); 705f5772c6121ee1f5f2aa06711e2762c0f07fb61ccAntony Sargent return OPTIONAL_CODECS_SUPPORT_UNKNOWN; 706f5772c6121ee1f5f2aa06711e2762c0f07fb61ccAntony Sargent } catch (RemoteException e) { 707f5772c6121ee1f5f2aa06711e2762c0f07fb61ccAntony Sargent Log.e(TAG, "Error talking to BT service in getSupportsOptionalCodecs()", e); 708f5772c6121ee1f5f2aa06711e2762c0f07fb61ccAntony Sargent return OPTIONAL_CODECS_SUPPORT_UNKNOWN; 709f5772c6121ee1f5f2aa06711e2762c0f07fb61ccAntony Sargent } finally { 710f5772c6121ee1f5f2aa06711e2762c0f07fb61ccAntony Sargent mServiceLock.readLock().unlock(); 711f5772c6121ee1f5f2aa06711e2762c0f07fb61ccAntony Sargent } 712f5772c6121ee1f5f2aa06711e2762c0f07fb61ccAntony Sargent } 713f5772c6121ee1f5f2aa06711e2762c0f07fb61ccAntony Sargent 714f5772c6121ee1f5f2aa06711e2762c0f07fb61ccAntony Sargent /** 715f5772c6121ee1f5f2aa06711e2762c0f07fb61ccAntony Sargent * Returns whether this device should have optional codecs enabled. 716f5772c6121ee1f5f2aa06711e2762c0f07fb61ccAntony Sargent * 717f5772c6121ee1f5f2aa06711e2762c0f07fb61ccAntony Sargent * @param device The device in question. 718f5772c6121ee1f5f2aa06711e2762c0f07fb61ccAntony Sargent * @return one of OPTIONAL_CODECS_PREF_UNKNOWN, OPTIONAL_CODECS_PREF_ENABLED, or 719f5772c6121ee1f5f2aa06711e2762c0f07fb61ccAntony Sargent * OPTIONAL_CODECS_PREF_DISABLED. 720f5772c6121ee1f5f2aa06711e2762c0f07fb61ccAntony Sargent * 721f5772c6121ee1f5f2aa06711e2762c0f07fb61ccAntony Sargent * @hide 722f5772c6121ee1f5f2aa06711e2762c0f07fb61ccAntony Sargent */ 723f5772c6121ee1f5f2aa06711e2762c0f07fb61ccAntony Sargent public int getOptionalCodecsEnabled(BluetoothDevice device) { 724f5772c6121ee1f5f2aa06711e2762c0f07fb61ccAntony Sargent try { 725f5772c6121ee1f5f2aa06711e2762c0f07fb61ccAntony Sargent mServiceLock.readLock().lock(); 726f5772c6121ee1f5f2aa06711e2762c0f07fb61ccAntony Sargent if (mService != null && isEnabled() && isValidDevice(device)) { 727f5772c6121ee1f5f2aa06711e2762c0f07fb61ccAntony Sargent return mService.getOptionalCodecsEnabled(device); 728f5772c6121ee1f5f2aa06711e2762c0f07fb61ccAntony Sargent } 729f5772c6121ee1f5f2aa06711e2762c0f07fb61ccAntony Sargent if (mService == null) Log.w(TAG, "Proxy not attached to service"); 730f5772c6121ee1f5f2aa06711e2762c0f07fb61ccAntony Sargent return OPTIONAL_CODECS_PREF_UNKNOWN; 731f5772c6121ee1f5f2aa06711e2762c0f07fb61ccAntony Sargent } catch (RemoteException e) { 732f5772c6121ee1f5f2aa06711e2762c0f07fb61ccAntony Sargent Log.e(TAG, "Error talking to BT service in getSupportsOptionalCodecs()", e); 733f5772c6121ee1f5f2aa06711e2762c0f07fb61ccAntony Sargent return OPTIONAL_CODECS_PREF_UNKNOWN; 734f5772c6121ee1f5f2aa06711e2762c0f07fb61ccAntony Sargent } finally { 735f5772c6121ee1f5f2aa06711e2762c0f07fb61ccAntony Sargent mServiceLock.readLock().unlock(); 736f5772c6121ee1f5f2aa06711e2762c0f07fb61ccAntony Sargent } 737f5772c6121ee1f5f2aa06711e2762c0f07fb61ccAntony Sargent } 738f5772c6121ee1f5f2aa06711e2762c0f07fb61ccAntony Sargent 739f5772c6121ee1f5f2aa06711e2762c0f07fb61ccAntony Sargent /** 740f5772c6121ee1f5f2aa06711e2762c0f07fb61ccAntony Sargent * Sets a persistent preference for whether a given device should have optional codecs enabled. 741f5772c6121ee1f5f2aa06711e2762c0f07fb61ccAntony Sargent * 742f5772c6121ee1f5f2aa06711e2762c0f07fb61ccAntony Sargent * @param device The device to set this preference for. 743f5772c6121ee1f5f2aa06711e2762c0f07fb61ccAntony Sargent * @param value Whether the optional codecs should be enabled for this device. This should be 744f5772c6121ee1f5f2aa06711e2762c0f07fb61ccAntony Sargent * one of OPTIONAL_CODECS_PREF_UNKNOWN, OPTIONAL_CODECS_PREF_ENABLED, or 745f5772c6121ee1f5f2aa06711e2762c0f07fb61ccAntony Sargent * OPTIONAL_CODECS_PREF_DISABLED. 746f5772c6121ee1f5f2aa06711e2762c0f07fb61ccAntony Sargent * @hide 747f5772c6121ee1f5f2aa06711e2762c0f07fb61ccAntony Sargent */ 748f5772c6121ee1f5f2aa06711e2762c0f07fb61ccAntony Sargent public void setOptionalCodecsEnabled(BluetoothDevice device, int value) { 749f5772c6121ee1f5f2aa06711e2762c0f07fb61ccAntony Sargent try { 750f5772c6121ee1f5f2aa06711e2762c0f07fb61ccAntony Sargent if (value != BluetoothA2dp.OPTIONAL_CODECS_PREF_UNKNOWN && 751f5772c6121ee1f5f2aa06711e2762c0f07fb61ccAntony Sargent value != BluetoothA2dp.OPTIONAL_CODECS_PREF_DISABLED && 752f5772c6121ee1f5f2aa06711e2762c0f07fb61ccAntony Sargent value != BluetoothA2dp.OPTIONAL_CODECS_PREF_ENABLED) { 753f5772c6121ee1f5f2aa06711e2762c0f07fb61ccAntony Sargent Log.e(TAG, "Invalid value passed to setOptionalCodecsEnabled: " + value); 754f5772c6121ee1f5f2aa06711e2762c0f07fb61ccAntony Sargent return; 755f5772c6121ee1f5f2aa06711e2762c0f07fb61ccAntony Sargent } 756f5772c6121ee1f5f2aa06711e2762c0f07fb61ccAntony Sargent mServiceLock.readLock().lock(); 757f5772c6121ee1f5f2aa06711e2762c0f07fb61ccAntony Sargent if (mService != null && isEnabled() 758f5772c6121ee1f5f2aa06711e2762c0f07fb61ccAntony Sargent && isValidDevice(device)) { 759f5772c6121ee1f5f2aa06711e2762c0f07fb61ccAntony Sargent mService.setOptionalCodecsEnabled(device, value); 760f5772c6121ee1f5f2aa06711e2762c0f07fb61ccAntony Sargent } 761f5772c6121ee1f5f2aa06711e2762c0f07fb61ccAntony Sargent if (mService == null) Log.w(TAG, "Proxy not attached to service"); 762f5772c6121ee1f5f2aa06711e2762c0f07fb61ccAntony Sargent return; 763f5772c6121ee1f5f2aa06711e2762c0f07fb61ccAntony Sargent } catch (RemoteException e) { 764f5772c6121ee1f5f2aa06711e2762c0f07fb61ccAntony Sargent Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable())); 765f5772c6121ee1f5f2aa06711e2762c0f07fb61ccAntony Sargent return; 766f5772c6121ee1f5f2aa06711e2762c0f07fb61ccAntony Sargent } finally { 767f5772c6121ee1f5f2aa06711e2762c0f07fb61ccAntony Sargent mServiceLock.readLock().unlock(); 768f5772c6121ee1f5f2aa06711e2762c0f07fb61ccAntony Sargent } 769f5772c6121ee1f5f2aa06711e2762c0f07fb61ccAntony Sargent } 770f5772c6121ee1f5f2aa06711e2762c0f07fb61ccAntony Sargent 771f5772c6121ee1f5f2aa06711e2762c0f07fb61ccAntony Sargent /** 77262c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * Helper for converting a state to a string. 77362c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * 7749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * For debug use only - strings are not internationalized. 7759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @hide 7769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 7779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static String stateToString(int state) { 7789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project switch (state) { 7799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case STATE_DISCONNECTED: 7809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return "disconnected"; 7819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case STATE_CONNECTING: 7829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return "connecting"; 7839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case STATE_CONNECTED: 7849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return "connected"; 7859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case STATE_DISCONNECTING: 7869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return "disconnecting"; 7879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case STATE_PLAYING: 7889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return "playing"; 78962c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh case STATE_NOT_PLAYING: 79062c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh return "not playing"; 7919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project default: 7929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return "<unknown state " + state + ">"; 7939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 795f5b4b98fada53d91c4c2ebeb5a1d33ccc95c94d2The Android Open Source Project 7969b6939939901cb82bc6fca93aad3810a4936dfc6Matthew Xie private final ServiceConnection mConnection = new ServiceConnection() { 7973e8c82edb1feafc796aa52efafedc13f794c4dcdMatthew Xie public void onServiceConnected(ComponentName className, IBinder service) { 7983e8c82edb1feafc796aa52efafedc13f794c4dcdMatthew Xie if (DBG) Log.d(TAG, "Proxy object connected"); 799d7d16b9f372116da1658f589df213aed33c2ded6Calvin On try { 800d7d16b9f372116da1658f589df213aed33c2ded6Calvin On mServiceLock.writeLock().lock(); 8010a17db1cc5942ea000ca87bb72853de57a15ec64Jeff Sharkey mService = IBluetoothA2dp.Stub.asInterface(Binder.allowBlocking(service)); 802d7d16b9f372116da1658f589df213aed33c2ded6Calvin On } finally { 803d7d16b9f372116da1658f589df213aed33c2ded6Calvin On mServiceLock.writeLock().unlock(); 804d7d16b9f372116da1658f589df213aed33c2ded6Calvin On } 8053e8c82edb1feafc796aa52efafedc13f794c4dcdMatthew Xie 8063e8c82edb1feafc796aa52efafedc13f794c4dcdMatthew Xie if (mServiceListener != null) { 8073e8c82edb1feafc796aa52efafedc13f794c4dcdMatthew Xie mServiceListener.onServiceConnected(BluetoothProfile.A2DP, BluetoothA2dp.this); 8083e8c82edb1feafc796aa52efafedc13f794c4dcdMatthew Xie } 8093e8c82edb1feafc796aa52efafedc13f794c4dcdMatthew Xie } 8103e8c82edb1feafc796aa52efafedc13f794c4dcdMatthew Xie public void onServiceDisconnected(ComponentName className) { 8113e8c82edb1feafc796aa52efafedc13f794c4dcdMatthew Xie if (DBG) Log.d(TAG, "Proxy object disconnected"); 812d7d16b9f372116da1658f589df213aed33c2ded6Calvin On try { 813d7d16b9f372116da1658f589df213aed33c2ded6Calvin On mServiceLock.writeLock().lock(); 814d7d16b9f372116da1658f589df213aed33c2ded6Calvin On mService = null; 815d7d16b9f372116da1658f589df213aed33c2ded6Calvin On } finally { 816d7d16b9f372116da1658f589df213aed33c2ded6Calvin On mServiceLock.writeLock().unlock(); 817d7d16b9f372116da1658f589df213aed33c2ded6Calvin On } 8183e8c82edb1feafc796aa52efafedc13f794c4dcdMatthew Xie if (mServiceListener != null) { 8193e8c82edb1feafc796aa52efafedc13f794c4dcdMatthew Xie mServiceListener.onServiceDisconnected(BluetoothProfile.A2DP); 8203e8c82edb1feafc796aa52efafedc13f794c4dcdMatthew Xie } 8213e8c82edb1feafc796aa52efafedc13f794c4dcdMatthew Xie } 8223e8c82edb1feafc796aa52efafedc13f794c4dcdMatthew Xie }; 8233e8c82edb1feafc796aa52efafedc13f794c4dcdMatthew Xie 82462c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh private boolean isEnabled() { 82562c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh if (mAdapter.getState() == BluetoothAdapter.STATE_ON) return true; 82662c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh return false; 82762c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh } 82862c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh 82962c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh private boolean isValidDevice(BluetoothDevice device) { 83062c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh if (device == null) return false; 83162c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh 83262c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh if (BluetoothAdapter.checkBluetoothAddress(device.getAddress())) return true; 83362c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh return false; 83462c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh } 83562c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh 836f5b4b98fada53d91c4c2ebeb5a1d33ccc95c94d2The Android Open Source Project private static void log(String msg) { 83762c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh Log.d(TAG, msg); 838f5b4b98fada53d91c4c2ebeb5a1d33ccc95c94d2The Android Open Source Project } 8399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 840