BluetoothA2dp.java revision 44a4ef0aa93ebb2912f36d65af42ffbb1bcdbc0f
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; 289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.IBinder; 2941d5c805d96aef0aaa9a2aaa86ccc4b77ca75e11Jaikumar Ganeshimport android.os.ParcelUuid; 3062c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganeshimport android.os.RemoteException; 319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.Log; 329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 33d7d16b9f372116da1658f589df213aed33c2ded6Calvin Onimport com.android.internal.annotations.GuardedBy; 34d7d16b9f372116da1658f589df213aed33c2ded6Calvin On 3503cd78cf5e51c3adb78d2e3d314838dcf3e36b26Jaikumar Ganeshimport java.util.ArrayList; 3603cd78cf5e51c3adb78d2e3d314838dcf3e36b26Jaikumar Ganeshimport java.util.List; 37d7d16b9f372116da1658f589df213aed33c2ded6Calvin Onimport java.util.concurrent.locks.ReentrantReadWriteLock; 3862c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh 399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/** 4162c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * This class provides the public APIs to control the Bluetooth A2DP 4262c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * profile. 439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 4462c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh *<p>BluetoothA2dp is a proxy object for controlling the Bluetooth A2DP 4562c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * Service via IPC. Use {@link BluetoothAdapter#getProfileProxy} to get 4662c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * the BluetoothA2dp proxy object. 479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 4862c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * <p> Android only supports one connected Bluetooth A2dp device at a time. 4962c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * Each method is protected with its appropriate permission. 509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 5162c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganeshpublic final class BluetoothA2dp implements BluetoothProfile { 529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final String TAG = "BluetoothA2dp"; 533e8c82edb1feafc796aa52efafedc13f794c4dcdMatthew Xie private static final boolean DBG = true; 54563e414784eb81e4ea4051667d5c8855b17f7534Matthew Xie private static final boolean VDBG = false; 559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5662c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh /** 5762c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * Intent used to broadcast the change in connection state of the A2DP 5862c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * profile. 5962c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * 6062c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * <p>This intent will have 3 extras: 61c8fa4ff838a0c3d2c67db65540fa751e5abe27edJaikumar Ganesh * <ul> 62c8fa4ff838a0c3d2c67db65540fa751e5abe27edJaikumar Ganesh * <li> {@link #EXTRA_STATE} - The current state of the profile. </li> 63c8fa4ff838a0c3d2c67db65540fa751e5abe27edJaikumar Ganesh * <li> {@link #EXTRA_PREVIOUS_STATE}- The previous state of the profile.</li> 64c8fa4ff838a0c3d2c67db65540fa751e5abe27edJaikumar Ganesh * <li> {@link BluetoothDevice#EXTRA_DEVICE} - The remote device. </li> 65c8fa4ff838a0c3d2c67db65540fa751e5abe27edJaikumar Ganesh * </ul> 6662c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * 670706fed52075f7f2b25101a40287519ac18d3184Jaikumar Ganesh * <p>{@link #EXTRA_STATE} or {@link #EXTRA_PREVIOUS_STATE} can be any of 6862c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * {@link #STATE_DISCONNECTED}, {@link #STATE_CONNECTING}, 6962c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * {@link #STATE_CONNECTED}, {@link #STATE_DISCONNECTING}. 7062c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * 71c8fa4ff838a0c3d2c67db65540fa751e5abe27edJaikumar Ganesh * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission to 72c8fa4ff838a0c3d2c67db65540fa751e5abe27edJaikumar Ganesh * receive. 7362c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh */ 7462c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) 7562c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh public static final String ACTION_CONNECTION_STATE_CHANGED = 7662c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh "android.bluetooth.a2dp.profile.action.CONNECTION_STATE_CHANGED"; 779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7862c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh /** 7962c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * Intent used to broadcast the change in the Playing state of the A2DP 8062c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * profile. 8162c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * 8262c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * <p>This intent will have 3 extras: 83c8fa4ff838a0c3d2c67db65540fa751e5abe27edJaikumar Ganesh * <ul> 84c8fa4ff838a0c3d2c67db65540fa751e5abe27edJaikumar Ganesh * <li> {@link #EXTRA_STATE} - The current state of the profile. </li> 85c8fa4ff838a0c3d2c67db65540fa751e5abe27edJaikumar Ganesh * <li> {@link #EXTRA_PREVIOUS_STATE}- The previous state of the profile. </li> 860706fed52075f7f2b25101a40287519ac18d3184Jaikumar Ganesh * <li> {@link BluetoothDevice#EXTRA_DEVICE} - The remote device. </li> 87c8fa4ff838a0c3d2c67db65540fa751e5abe27edJaikumar Ganesh * </ul> 8862c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * 890706fed52075f7f2b25101a40287519ac18d3184Jaikumar Ganesh * <p>{@link #EXTRA_STATE} or {@link #EXTRA_PREVIOUS_STATE} can be any of 9062c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * {@link #STATE_PLAYING}, {@link #STATE_NOT_PLAYING}, 9162c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * 92c8fa4ff838a0c3d2c67db65540fa751e5abe27edJaikumar Ganesh * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission to 93c8fa4ff838a0c3d2c67db65540fa751e5abe27edJaikumar Ganesh * receive. 949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) 9662c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh public static final String ACTION_PLAYING_STATE_CHANGED = 9762c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh "android.bluetooth.a2dp.profile.action.PLAYING_STATE_CHANGED"; 989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 993b76a4b2b62e9539e2629dc569d7e9a934e65dfbHemant Gupta /** @hide */ 1003b76a4b2b62e9539e2629dc569d7e9a934e65dfbHemant Gupta @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) 1013b76a4b2b62e9539e2629dc569d7e9a934e65dfbHemant Gupta public static final String ACTION_AVRCP_CONNECTION_STATE_CHANGED = 1023b76a4b2b62e9539e2629dc569d7e9a934e65dfbHemant Gupta "android.bluetooth.a2dp.profile.action.AVRCP_CONNECTION_STATE_CHANGED"; 1033b76a4b2b62e9539e2629dc569d7e9a934e65dfbHemant Gupta 10462c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh /** 10544a4ef0aa93ebb2912f36d65af42ffbb1bcdbc0fPavlin Radoslavov * Intent used to broadcast the change in the Audio Codec state of the 10644a4ef0aa93ebb2912f36d65af42ffbb1bcdbc0fPavlin Radoslavov * A2DP Source profile. 10744a4ef0aa93ebb2912f36d65af42ffbb1bcdbc0fPavlin Radoslavov * 10844a4ef0aa93ebb2912f36d65af42ffbb1bcdbc0fPavlin Radoslavov * <p>This intent will have 3 extras: 10944a4ef0aa93ebb2912f36d65af42ffbb1bcdbc0fPavlin Radoslavov * <ul> 11044a4ef0aa93ebb2912f36d65af42ffbb1bcdbc0fPavlin Radoslavov * <li> {@link #EXTRA_CODEC_CONFIG} - The current codec configuration. </li> 11144a4ef0aa93ebb2912f36d65af42ffbb1bcdbc0fPavlin Radoslavov * <li> {@link #EXTRA_PREVIOUS_CODEC_CONFIG} - The previous codec configuration. </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 1393e8c82edb1feafc796aa52efafedc13f794c4dcdMatthew Xie private Context mContext; 14062c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh private ServiceListener mServiceListener; 141d7d16b9f372116da1658f589df213aed33c2ded6Calvin On private final ReentrantReadWriteLock mServiceLock = new ReentrantReadWriteLock(); 142d7d16b9f372116da1658f589df213aed33c2ded6Calvin On @GuardedBy("mServiceLock") private IBluetoothA2dp mService; 14362c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh private BluetoothAdapter mAdapter; 1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1450f42037eb7b5118015c2caca635538324ccf0ccffredc final private IBluetoothStateChangeCallback mBluetoothStateChangeCallback = 1460f42037eb7b5118015c2caca635538324ccf0ccffredc new IBluetoothStateChangeCallback.Stub() { 1470f42037eb7b5118015c2caca635538324ccf0ccffredc public void onBluetoothStateChange(boolean up) { 1480f42037eb7b5118015c2caca635538324ccf0ccffredc if (DBG) Log.d(TAG, "onBluetoothStateChange: up=" + up); 1490f42037eb7b5118015c2caca635538324ccf0ccffredc if (!up) { 150d7d16b9f372116da1658f589df213aed33c2ded6Calvin On if (VDBG) Log.d(TAG, "Unbinding service..."); 151d7d16b9f372116da1658f589df213aed33c2ded6Calvin On try { 152d7d16b9f372116da1658f589df213aed33c2ded6Calvin On mServiceLock.writeLock().lock(); 153d7d16b9f372116da1658f589df213aed33c2ded6Calvin On mService = null; 154d7d16b9f372116da1658f589df213aed33c2ded6Calvin On mContext.unbindService(mConnection); 155d7d16b9f372116da1658f589df213aed33c2ded6Calvin On } catch (Exception re) { 156d7d16b9f372116da1658f589df213aed33c2ded6Calvin On Log.e(TAG, "", re); 157d7d16b9f372116da1658f589df213aed33c2ded6Calvin On } finally { 158d7d16b9f372116da1658f589df213aed33c2ded6Calvin On mServiceLock.writeLock().unlock(); 1590f42037eb7b5118015c2caca635538324ccf0ccffredc } 1600f42037eb7b5118015c2caca635538324ccf0ccffredc } else { 161d7d16b9f372116da1658f589df213aed33c2ded6Calvin On try { 162d7d16b9f372116da1658f589df213aed33c2ded6Calvin On mServiceLock.readLock().lock(); 163d7d16b9f372116da1658f589df213aed33c2ded6Calvin On if (mService == null) { 164d7d16b9f372116da1658f589df213aed33c2ded6Calvin On if (VDBG) Log.d(TAG,"Binding service..."); 165d7d16b9f372116da1658f589df213aed33c2ded6Calvin On doBind(); 1660f42037eb7b5118015c2caca635538324ccf0ccffredc } 167d7d16b9f372116da1658f589df213aed33c2ded6Calvin On } catch (Exception re) { 168d7d16b9f372116da1658f589df213aed33c2ded6Calvin On Log.e(TAG,"",re); 169d7d16b9f372116da1658f589df213aed33c2ded6Calvin On } finally { 170d7d16b9f372116da1658f589df213aed33c2ded6Calvin On mServiceLock.readLock().unlock(); 1710f42037eb7b5118015c2caca635538324ccf0ccffredc } 1720f42037eb7b5118015c2caca635538324ccf0ccffredc } 1730f42037eb7b5118015c2caca635538324ccf0ccffredc } 1740f42037eb7b5118015c2caca635538324ccf0ccffredc }; 1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Create a BluetoothA2dp proxy object for interacting with the local 1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Bluetooth A2DP service. 17862c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * 1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1803e8c82edb1feafc796aa52efafedc13f794c4dcdMatthew Xie /*package*/ BluetoothA2dp(Context context, ServiceListener l) { 1813e8c82edb1feafc796aa52efafedc13f794c4dcdMatthew Xie mContext = context; 18262c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh mServiceListener = l; 18362c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh mAdapter = BluetoothAdapter.getDefaultAdapter(); 1840f42037eb7b5118015c2caca635538324ccf0ccffredc IBluetoothManager mgr = mAdapter.getBluetoothManager(); 1850f42037eb7b5118015c2caca635538324ccf0ccffredc if (mgr != null) { 1860f42037eb7b5118015c2caca635538324ccf0ccffredc try { 1870f42037eb7b5118015c2caca635538324ccf0ccffredc mgr.registerStateChangeCallback(mBluetoothStateChangeCallback); 1880f42037eb7b5118015c2caca635538324ccf0ccffredc } catch (RemoteException e) { 1890f42037eb7b5118015c2caca635538324ccf0ccffredc Log.e(TAG,"",e); 1900f42037eb7b5118015c2caca635538324ccf0ccffredc } 1910f42037eb7b5118015c2caca635538324ccf0ccffredc } 1920f42037eb7b5118015c2caca635538324ccf0ccffredc 193221ea892dcc661bd07d6f36ff012edca2c48aed4Dianne Hackborn doBind(); 194221ea892dcc661bd07d6f36ff012edca2c48aed4Dianne Hackborn } 195221ea892dcc661bd07d6f36ff012edca2c48aed4Dianne Hackborn 196221ea892dcc661bd07d6f36ff012edca2c48aed4Dianne Hackborn boolean doBind() { 197221ea892dcc661bd07d6f36ff012edca2c48aed4Dianne Hackborn Intent intent = new Intent(IBluetoothA2dp.class.getName()); 198221ea892dcc661bd07d6f36ff012edca2c48aed4Dianne Hackborn ComponentName comp = intent.resolveSystemService(mContext.getPackageManager(), 0); 199221ea892dcc661bd07d6f36ff012edca2c48aed4Dianne Hackborn intent.setComponent(comp); 200466ce96da8ca7ea8c97e716b02a7d55007179aa1Dianne Hackborn if (comp == null || !mContext.bindServiceAsUser(intent, mConnection, 0, 201466ce96da8ca7ea8c97e716b02a7d55007179aa1Dianne Hackborn android.os.Process.myUserHandle())) { 202221ea892dcc661bd07d6f36ff012edca2c48aed4Dianne Hackborn Log.e(TAG, "Could not bind to Bluetooth A2DP Service with " + intent); 203221ea892dcc661bd07d6f36ff012edca2c48aed4Dianne Hackborn return false; 2049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 205221ea892dcc661bd07d6f36ff012edca2c48aed4Dianne Hackborn return true; 2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2089bb275197df8eb999eab4cdd0a2aff83c2bb2ef6Jaikumar Ganesh /*package*/ void close() { 2099bb275197df8eb999eab4cdd0a2aff83c2bb2ef6Jaikumar Ganesh mServiceListener = null; 2100f42037eb7b5118015c2caca635538324ccf0ccffredc IBluetoothManager mgr = mAdapter.getBluetoothManager(); 2110f42037eb7b5118015c2caca635538324ccf0ccffredc if (mgr != null) { 2120f42037eb7b5118015c2caca635538324ccf0ccffredc try { 2130f42037eb7b5118015c2caca635538324ccf0ccffredc mgr.unregisterStateChangeCallback(mBluetoothStateChangeCallback); 2140f42037eb7b5118015c2caca635538324ccf0ccffredc } catch (Exception e) { 2150f42037eb7b5118015c2caca635538324ccf0ccffredc Log.e(TAG,"",e); 2160f42037eb7b5118015c2caca635538324ccf0ccffredc } 2170f42037eb7b5118015c2caca635538324ccf0ccffredc } 2180f42037eb7b5118015c2caca635538324ccf0ccffredc 219d7d16b9f372116da1658f589df213aed33c2ded6Calvin On try { 220d7d16b9f372116da1658f589df213aed33c2ded6Calvin On mServiceLock.writeLock().lock(); 2210f42037eb7b5118015c2caca635538324ccf0ccffredc if (mService != null) { 222d7d16b9f372116da1658f589df213aed33c2ded6Calvin On mService = null; 223d7d16b9f372116da1658f589df213aed33c2ded6Calvin On mContext.unbindService(mConnection); 2240f42037eb7b5118015c2caca635538324ccf0ccffredc } 225d7d16b9f372116da1658f589df213aed33c2ded6Calvin On } catch (Exception re) { 226d7d16b9f372116da1658f589df213aed33c2ded6Calvin On Log.e(TAG, "", re); 227d7d16b9f372116da1658f589df213aed33c2ded6Calvin On } finally { 228d7d16b9f372116da1658f589df213aed33c2ded6Calvin On mServiceLock.writeLock().unlock(); 2290f42037eb7b5118015c2caca635538324ccf0ccffredc } 2309bb275197df8eb999eab4cdd0a2aff83c2bb2ef6Jaikumar Ganesh } 2319bb275197df8eb999eab4cdd0a2aff83c2bb2ef6Jaikumar Ganesh 2320f42037eb7b5118015c2caca635538324ccf0ccffredc public void finalize() { 2332d2d8c28545c687dbb105006ef4554eac8480313Mathias Jeppsson // The empty finalize needs to be kept or the 2342d2d8c28545c687dbb105006ef4554eac8480313Mathias Jeppsson // cts signature tests would fail. 2350f42037eb7b5118015c2caca635538324ccf0ccffredc } 23662c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh /** 237f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * Initiate connection to a profile of the remote bluetooth device. 238f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * 239f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * <p> Currently, the system supports only 1 connection to the 240f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * A2DP profile. The API will automatically disconnect connected 241f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * devices before connecting. 242f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * 243f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * <p> This API returns false in scenarios like the profile on the 244f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * device is already connected or Bluetooth is not turned on. 245f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * When this API returns true, it is guaranteed that 246f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * connection state intent for the profile will be broadcasted with 247f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * the state. Users can get the connection state of the profile 248f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * from this intent. 249f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * 250f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN} 251f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * permission. 252f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * 253f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * @param device Remote Bluetooth Device 254f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * @return false on immediate error, 255f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * true otherwise 25662c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * @hide 2579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 25862c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh public boolean connect(BluetoothDevice device) { 25962c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh if (DBG) log("connect(" + device + ")"); 260d7d16b9f372116da1658f589df213aed33c2ded6Calvin On try { 261d7d16b9f372116da1658f589df213aed33c2ded6Calvin On mServiceLock.readLock().lock(); 262d7d16b9f372116da1658f589df213aed33c2ded6Calvin On if (mService != null && isEnabled() && 263d7d16b9f372116da1658f589df213aed33c2ded6Calvin On isValidDevice(device)) { 26462c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh return mService.connect(device); 26562c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh } 266d7d16b9f372116da1658f589df213aed33c2ded6Calvin On if (mService == null) Log.w(TAG, "Proxy not attached to service"); 267d7d16b9f372116da1658f589df213aed33c2ded6Calvin On return false; 268d7d16b9f372116da1658f589df213aed33c2ded6Calvin On } catch (RemoteException e) { 269d7d16b9f372116da1658f589df213aed33c2ded6Calvin On Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable())); 270d7d16b9f372116da1658f589df213aed33c2ded6Calvin On return false; 271d7d16b9f372116da1658f589df213aed33c2ded6Calvin On } finally { 272d7d16b9f372116da1658f589df213aed33c2ded6Calvin On mServiceLock.readLock().unlock(); 2739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 27662c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh /** 277f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * Initiate disconnection from a profile 278f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * 279f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * <p> This API will return false in scenarios like the profile on the 280f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * Bluetooth device is not in connected state etc. When this API returns, 281f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * true, it is guaranteed that the connection state change 282f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * intent will be broadcasted with the state. Users can get the 283f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * disconnection state of the profile from this intent. 284f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * 285f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * <p> If the disconnection is initiated by a remote device, the state 286f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * will transition from {@link #STATE_CONNECTED} to 287f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * {@link #STATE_DISCONNECTED}. If the disconnect is initiated by the 288f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * host (local) device the state will transition from 289f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * {@link #STATE_CONNECTED} to state {@link #STATE_DISCONNECTING} to 290f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * state {@link #STATE_DISCONNECTED}. The transition to 291f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * {@link #STATE_DISCONNECTING} can be used to distinguish between the 292f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * two scenarios. 293f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * 294f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN} 295f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * permission. 296f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * 297f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * @param device Remote Bluetooth Device 298f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * @return false on immediate error, 299f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * true otherwise 30062c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * @hide 3019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 30262c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh public boolean disconnect(BluetoothDevice device) { 30362c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh if (DBG) log("disconnect(" + device + ")"); 304d7d16b9f372116da1658f589df213aed33c2ded6Calvin On try { 305d7d16b9f372116da1658f589df213aed33c2ded6Calvin On mServiceLock.readLock().lock(); 306d7d16b9f372116da1658f589df213aed33c2ded6Calvin On if (mService != null && isEnabled() && 307d7d16b9f372116da1658f589df213aed33c2ded6Calvin On isValidDevice(device)) { 30862c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh return mService.disconnect(device); 30962c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh } 310d7d16b9f372116da1658f589df213aed33c2ded6Calvin On if (mService == null) Log.w(TAG, "Proxy not attached to service"); 311d7d16b9f372116da1658f589df213aed33c2ded6Calvin On return false; 312d7d16b9f372116da1658f589df213aed33c2ded6Calvin On } catch (RemoteException e) { 313d7d16b9f372116da1658f589df213aed33c2ded6Calvin On Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable())); 314d7d16b9f372116da1658f589df213aed33c2ded6Calvin On return false; 315d7d16b9f372116da1658f589df213aed33c2ded6Calvin On } finally { 316d7d16b9f372116da1658f589df213aed33c2ded6Calvin On mServiceLock.readLock().unlock(); 3179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 32062c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh /** 32162c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * {@inheritDoc} 322f9bbe1e71a502fe7bd1f4a23ba5bbe4dde0d9d57Zhu Lan */ 32303cd78cf5e51c3adb78d2e3d314838dcf3e36b26Jaikumar Ganesh public List<BluetoothDevice> getConnectedDevices() { 324563e414784eb81e4ea4051667d5c8855b17f7534Matthew Xie if (VDBG) log("getConnectedDevices()"); 325d7d16b9f372116da1658f589df213aed33c2ded6Calvin On try { 326d7d16b9f372116da1658f589df213aed33c2ded6Calvin On mServiceLock.readLock().lock(); 327d7d16b9f372116da1658f589df213aed33c2ded6Calvin On if (mService != null && isEnabled()) { 32803cd78cf5e51c3adb78d2e3d314838dcf3e36b26Jaikumar Ganesh return mService.getConnectedDevices(); 32962c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh } 330d7d16b9f372116da1658f589df213aed33c2ded6Calvin On if (mService == null) Log.w(TAG, "Proxy not attached to service"); 331d7d16b9f372116da1658f589df213aed33c2ded6Calvin On return new ArrayList<BluetoothDevice>(); 332d7d16b9f372116da1658f589df213aed33c2ded6Calvin On } catch (RemoteException e) { 333d7d16b9f372116da1658f589df213aed33c2ded6Calvin On Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable())); 334d7d16b9f372116da1658f589df213aed33c2ded6Calvin On return new ArrayList<BluetoothDevice>(); 335d7d16b9f372116da1658f589df213aed33c2ded6Calvin On } finally { 336d7d16b9f372116da1658f589df213aed33c2ded6Calvin On mServiceLock.readLock().unlock(); 337f9bbe1e71a502fe7bd1f4a23ba5bbe4dde0d9d57Zhu Lan } 338f9bbe1e71a502fe7bd1f4a23ba5bbe4dde0d9d57Zhu Lan } 339f9bbe1e71a502fe7bd1f4a23ba5bbe4dde0d9d57Zhu Lan 34062c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh /** 34162c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * {@inheritDoc} 342f9bbe1e71a502fe7bd1f4a23ba5bbe4dde0d9d57Zhu Lan */ 34303cd78cf5e51c3adb78d2e3d314838dcf3e36b26Jaikumar Ganesh public List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) { 344563e414784eb81e4ea4051667d5c8855b17f7534Matthew Xie if (VDBG) log("getDevicesMatchingStates()"); 345d7d16b9f372116da1658f589df213aed33c2ded6Calvin On try { 346d7d16b9f372116da1658f589df213aed33c2ded6Calvin On mServiceLock.readLock().lock(); 347d7d16b9f372116da1658f589df213aed33c2ded6Calvin On if (mService != null && isEnabled()) { 34803cd78cf5e51c3adb78d2e3d314838dcf3e36b26Jaikumar Ganesh return mService.getDevicesMatchingConnectionStates(states); 34962c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh } 350d7d16b9f372116da1658f589df213aed33c2ded6Calvin On if (mService == null) Log.w(TAG, "Proxy not attached to service"); 351d7d16b9f372116da1658f589df213aed33c2ded6Calvin On return new ArrayList<BluetoothDevice>(); 352d7d16b9f372116da1658f589df213aed33c2ded6Calvin On } catch (RemoteException e) { 353d7d16b9f372116da1658f589df213aed33c2ded6Calvin On Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable())); 354d7d16b9f372116da1658f589df213aed33c2ded6Calvin On return new ArrayList<BluetoothDevice>(); 355d7d16b9f372116da1658f589df213aed33c2ded6Calvin On } finally { 356d7d16b9f372116da1658f589df213aed33c2ded6Calvin On mServiceLock.readLock().unlock(); 357f9bbe1e71a502fe7bd1f4a23ba5bbe4dde0d9d57Zhu Lan } 358f9bbe1e71a502fe7bd1f4a23ba5bbe4dde0d9d57Zhu Lan } 359f9bbe1e71a502fe7bd1f4a23ba5bbe4dde0d9d57Zhu Lan 36062c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh /** 36162c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * {@inheritDoc} 3629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 36362c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh public int getConnectionState(BluetoothDevice device) { 364563e414784eb81e4ea4051667d5c8855b17f7534Matthew Xie if (VDBG) log("getState(" + device + ")"); 365d7d16b9f372116da1658f589df213aed33c2ded6Calvin On try { 366d7d16b9f372116da1658f589df213aed33c2ded6Calvin On mServiceLock.readLock().lock(); 367d7d16b9f372116da1658f589df213aed33c2ded6Calvin On if (mService != null && isEnabled() 368d7d16b9f372116da1658f589df213aed33c2ded6Calvin On && isValidDevice(device)) { 36962c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh return mService.getConnectionState(device); 37062c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh } 371d7d16b9f372116da1658f589df213aed33c2ded6Calvin On if (mService == null) Log.w(TAG, "Proxy not attached to service"); 372d7d16b9f372116da1658f589df213aed33c2ded6Calvin On return BluetoothProfile.STATE_DISCONNECTED; 373d7d16b9f372116da1658f589df213aed33c2ded6Calvin On } catch (RemoteException e) { 374d7d16b9f372116da1658f589df213aed33c2ded6Calvin On Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable())); 375d7d16b9f372116da1658f589df213aed33c2ded6Calvin On return BluetoothProfile.STATE_DISCONNECTED; 376d7d16b9f372116da1658f589df213aed33c2ded6Calvin On } finally { 377d7d16b9f372116da1658f589df213aed33c2ded6Calvin On mServiceLock.readLock().unlock(); 37862c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh } 3799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 38162c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh /** 382f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * Set priority of the profile 383f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * 384f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * <p> The device should already be paired. 3850f42037eb7b5118015c2caca635538324ccf0ccffredc * Priority can be one of {@link #PRIORITY_ON} orgetBluetoothManager 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 3949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @hide 3959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 39662c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh public boolean setPriority(BluetoothDevice device, int priority) { 39762c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh if (DBG) log("setPriority(" + device + ", " + priority + ")"); 398d7d16b9f372116da1658f589df213aed33c2ded6Calvin On try { 399d7d16b9f372116da1658f589df213aed33c2ded6Calvin On mServiceLock.readLock().lock(); 400d7d16b9f372116da1658f589df213aed33c2ded6Calvin On if (mService != null && isEnabled() 401d7d16b9f372116da1658f589df213aed33c2ded6Calvin On && isValidDevice(device)) { 402d7d16b9f372116da1658f589df213aed33c2ded6Calvin On if (priority != BluetoothProfile.PRIORITY_OFF && 403d7d16b9f372116da1658f589df213aed33c2ded6Calvin On priority != BluetoothProfile.PRIORITY_ON) { 404d7d16b9f372116da1658f589df213aed33c2ded6Calvin On return false; 405d7d16b9f372116da1658f589df213aed33c2ded6Calvin On } 40662c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh return mService.setPriority(device, priority); 40762c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh } 408d7d16b9f372116da1658f589df213aed33c2ded6Calvin On if (mService == null) Log.w(TAG, "Proxy not attached to service"); 409d7d16b9f372116da1658f589df213aed33c2ded6Calvin On return false; 410d7d16b9f372116da1658f589df213aed33c2ded6Calvin On } catch (RemoteException e) { 411d7d16b9f372116da1658f589df213aed33c2ded6Calvin On Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable())); 412d7d16b9f372116da1658f589df213aed33c2ded6Calvin On return false; 413d7d16b9f372116da1658f589df213aed33c2ded6Calvin On } finally { 414d7d16b9f372116da1658f589df213aed33c2ded6Calvin On mServiceLock.readLock().unlock(); 4159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 41862c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh /** 419f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * Get the priority of the profile. 420f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * 421f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * <p> The priority can be any of: 422f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * {@link #PRIORITY_AUTO_CONNECT}, {@link #PRIORITY_OFF}, 423f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * {@link #PRIORITY_ON}, {@link #PRIORITY_UNDEFINED} 424f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * 425f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission. 426f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * 427f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * @param device Bluetooth device 428f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * @return priority of the device 429b16c4f7dd92dabf0cc27438a5d3d9ebd203a38b3Jaikumar Ganesh * @hide 430b16c4f7dd92dabf0cc27438a5d3d9ebd203a38b3Jaikumar Ganesh */ 4312d49752ee050ab7f1cd848933f6c62a73707e2d9Tor Norbye @RequiresPermission(Manifest.permission.BLUETOOTH) 43262c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh public int getPriority(BluetoothDevice device) { 433563e414784eb81e4ea4051667d5c8855b17f7534Matthew Xie if (VDBG) log("getPriority(" + device + ")"); 434d7d16b9f372116da1658f589df213aed33c2ded6Calvin On try { 435d7d16b9f372116da1658f589df213aed33c2ded6Calvin On mServiceLock.readLock().lock(); 436d7d16b9f372116da1658f589df213aed33c2ded6Calvin On if (mService != null && isEnabled() 437d7d16b9f372116da1658f589df213aed33c2ded6Calvin On && isValidDevice(device)) { 43862c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh return mService.getPriority(device); 43962c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh } 440d7d16b9f372116da1658f589df213aed33c2ded6Calvin On if (mService == null) Log.w(TAG, "Proxy not attached to service"); 441d7d16b9f372116da1658f589df213aed33c2ded6Calvin On return BluetoothProfile.PRIORITY_OFF; 442d7d16b9f372116da1658f589df213aed33c2ded6Calvin On } catch (RemoteException e) { 443d7d16b9f372116da1658f589df213aed33c2ded6Calvin On Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable())); 444d7d16b9f372116da1658f589df213aed33c2ded6Calvin On return BluetoothProfile.PRIORITY_OFF; 445d7d16b9f372116da1658f589df213aed33c2ded6Calvin On } finally { 446d7d16b9f372116da1658f589df213aed33c2ded6Calvin On mServiceLock.readLock().unlock(); 447b16c4f7dd92dabf0cc27438a5d3d9ebd203a38b3Jaikumar Ganesh } 448b16c4f7dd92dabf0cc27438a5d3d9ebd203a38b3Jaikumar Ganesh } 449b16c4f7dd92dabf0cc27438a5d3d9ebd203a38b3Jaikumar Ganesh 45062c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh /** 4515a0cf7a27f3953a1266af48543ccd9024f4cd89fJohn Du * Checks if Avrcp device supports the absolute volume feature. 4525a0cf7a27f3953a1266af48543ccd9024f4cd89fJohn Du * 4535a0cf7a27f3953a1266af48543ccd9024f4cd89fJohn Du * @return true if device supports absolute volume 4545a0cf7a27f3953a1266af48543ccd9024f4cd89fJohn Du * @hide 4555a0cf7a27f3953a1266af48543ccd9024f4cd89fJohn Du */ 4565a0cf7a27f3953a1266af48543ccd9024f4cd89fJohn Du public boolean isAvrcpAbsoluteVolumeSupported() { 4575a0cf7a27f3953a1266af48543ccd9024f4cd89fJohn Du if (DBG) Log.d(TAG, "isAvrcpAbsoluteVolumeSupported"); 458d7d16b9f372116da1658f589df213aed33c2ded6Calvin On try { 459d7d16b9f372116da1658f589df213aed33c2ded6Calvin On mServiceLock.readLock().lock(); 460d7d16b9f372116da1658f589df213aed33c2ded6Calvin On if (mService != null && isEnabled()) { 4615a0cf7a27f3953a1266af48543ccd9024f4cd89fJohn Du return mService.isAvrcpAbsoluteVolumeSupported(); 4625a0cf7a27f3953a1266af48543ccd9024f4cd89fJohn Du } 463d7d16b9f372116da1658f589df213aed33c2ded6Calvin On if (mService == null) Log.w(TAG, "Proxy not attached to service"); 464d7d16b9f372116da1658f589df213aed33c2ded6Calvin On return false; 465d7d16b9f372116da1658f589df213aed33c2ded6Calvin On } catch (RemoteException e) { 466d7d16b9f372116da1658f589df213aed33c2ded6Calvin On Log.e(TAG, "Error talking to BT service in isAvrcpAbsoluteVolumeSupported()", e); 467d7d16b9f372116da1658f589df213aed33c2ded6Calvin On return false; 468d7d16b9f372116da1658f589df213aed33c2ded6Calvin On } finally { 469d7d16b9f372116da1658f589df213aed33c2ded6Calvin On mServiceLock.readLock().unlock(); 4705a0cf7a27f3953a1266af48543ccd9024f4cd89fJohn Du } 4715a0cf7a27f3953a1266af48543ccd9024f4cd89fJohn Du } 4725a0cf7a27f3953a1266af48543ccd9024f4cd89fJohn Du 4735a0cf7a27f3953a1266af48543ccd9024f4cd89fJohn Du /** 4744197cb60bc74629fe4c04ab10cb3b1c9a7427d24RoboErik * Tells remote device to adjust volume. Only if absolute volume is 4754197cb60bc74629fe4c04ab10cb3b1c9a7427d24RoboErik * supported. Uses the following values: 4764197cb60bc74629fe4c04ab10cb3b1c9a7427d24RoboErik * <ul> 4774197cb60bc74629fe4c04ab10cb3b1c9a7427d24RoboErik * <li>{@link AudioManager#ADJUST_LOWER}</li> 4784197cb60bc74629fe4c04ab10cb3b1c9a7427d24RoboErik * <li>{@link AudioManager#ADJUST_RAISE}</li> 4794197cb60bc74629fe4c04ab10cb3b1c9a7427d24RoboErik * <li>{@link AudioManager#ADJUST_MUTE}</li> 4804197cb60bc74629fe4c04ab10cb3b1c9a7427d24RoboErik * <li>{@link AudioManager#ADJUST_UNMUTE}</li> 4814197cb60bc74629fe4c04ab10cb3b1c9a7427d24RoboErik * </ul> 4825a0cf7a27f3953a1266af48543ccd9024f4cd89fJohn Du * 4834197cb60bc74629fe4c04ab10cb3b1c9a7427d24RoboErik * @param direction One of the supported adjust values. 4845a0cf7a27f3953a1266af48543ccd9024f4cd89fJohn Du * @hide 4855a0cf7a27f3953a1266af48543ccd9024f4cd89fJohn Du */ 4865a0cf7a27f3953a1266af48543ccd9024f4cd89fJohn Du public void adjustAvrcpAbsoluteVolume(int direction) { 4875a0cf7a27f3953a1266af48543ccd9024f4cd89fJohn Du if (DBG) Log.d(TAG, "adjustAvrcpAbsoluteVolume"); 488d7d16b9f372116da1658f589df213aed33c2ded6Calvin On try { 489d7d16b9f372116da1658f589df213aed33c2ded6Calvin On mServiceLock.readLock().lock(); 490d7d16b9f372116da1658f589df213aed33c2ded6Calvin On if (mService != null && isEnabled()) { 4915a0cf7a27f3953a1266af48543ccd9024f4cd89fJohn Du mService.adjustAvrcpAbsoluteVolume(direction); 4925a0cf7a27f3953a1266af48543ccd9024f4cd89fJohn Du } 493d7d16b9f372116da1658f589df213aed33c2ded6Calvin On if (mService == null) Log.w(TAG, "Proxy not attached to service"); 494d7d16b9f372116da1658f589df213aed33c2ded6Calvin On } catch (RemoteException e) { 495d7d16b9f372116da1658f589df213aed33c2ded6Calvin On Log.e(TAG, "Error talking to BT service in adjustAvrcpAbsoluteVolume()", e); 496d7d16b9f372116da1658f589df213aed33c2ded6Calvin On } finally { 497d7d16b9f372116da1658f589df213aed33c2ded6Calvin On mServiceLock.readLock().unlock(); 4985a0cf7a27f3953a1266af48543ccd9024f4cd89fJohn Du } 4995a0cf7a27f3953a1266af48543ccd9024f4cd89fJohn Du } 5005a0cf7a27f3953a1266af48543ccd9024f4cd89fJohn Du 5015a0cf7a27f3953a1266af48543ccd9024f4cd89fJohn Du /** 5025a0cf7a27f3953a1266af48543ccd9024f4cd89fJohn Du * Tells remote device to set an absolute volume. Only if absolute volume is supported 5035a0cf7a27f3953a1266af48543ccd9024f4cd89fJohn Du * 5045a0cf7a27f3953a1266af48543ccd9024f4cd89fJohn Du * @param volume Absolute volume to be set on AVRCP side 5055a0cf7a27f3953a1266af48543ccd9024f4cd89fJohn Du * @hide 5065a0cf7a27f3953a1266af48543ccd9024f4cd89fJohn Du */ 5075a0cf7a27f3953a1266af48543ccd9024f4cd89fJohn Du public void setAvrcpAbsoluteVolume(int volume) { 5085a0cf7a27f3953a1266af48543ccd9024f4cd89fJohn Du if (DBG) Log.d(TAG, "setAvrcpAbsoluteVolume"); 509d7d16b9f372116da1658f589df213aed33c2ded6Calvin On try { 510d7d16b9f372116da1658f589df213aed33c2ded6Calvin On mServiceLock.readLock().lock(); 511d7d16b9f372116da1658f589df213aed33c2ded6Calvin On if (mService != null && isEnabled()) { 5125a0cf7a27f3953a1266af48543ccd9024f4cd89fJohn Du mService.setAvrcpAbsoluteVolume(volume); 5135a0cf7a27f3953a1266af48543ccd9024f4cd89fJohn Du } 514d7d16b9f372116da1658f589df213aed33c2ded6Calvin On if (mService == null) Log.w(TAG, "Proxy not attached to service"); 515d7d16b9f372116da1658f589df213aed33c2ded6Calvin On } catch (RemoteException e) { 516d7d16b9f372116da1658f589df213aed33c2ded6Calvin On Log.e(TAG, "Error talking to BT service in setAvrcpAbsoluteVolume()", e); 517d7d16b9f372116da1658f589df213aed33c2ded6Calvin On } finally { 518d7d16b9f372116da1658f589df213aed33c2ded6Calvin On mServiceLock.readLock().unlock(); 5195a0cf7a27f3953a1266af48543ccd9024f4cd89fJohn Du } 5205a0cf7a27f3953a1266af48543ccd9024f4cd89fJohn Du } 5215a0cf7a27f3953a1266af48543ccd9024f4cd89fJohn Du 5225a0cf7a27f3953a1266af48543ccd9024f4cd89fJohn Du /** 52362c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * Check if A2DP profile is streaming music. 52462c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * 525c8fa4ff838a0c3d2c67db65540fa751e5abe27edJaikumar Ganesh * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission. 52662c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * 52762c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * @param device BluetoothDevice device 5289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 52962c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh public boolean isA2dpPlaying(BluetoothDevice device) { 530d7d16b9f372116da1658f589df213aed33c2ded6Calvin On try { 531d7d16b9f372116da1658f589df213aed33c2ded6Calvin On mServiceLock.readLock().lock(); 532d7d16b9f372116da1658f589df213aed33c2ded6Calvin On if (mService != null && isEnabled() 533d7d16b9f372116da1658f589df213aed33c2ded6Calvin On && isValidDevice(device)) { 53462c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh return mService.isA2dpPlaying(device); 53562c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh } 536d7d16b9f372116da1658f589df213aed33c2ded6Calvin On if (mService == null) Log.w(TAG, "Proxy not attached to service"); 537d7d16b9f372116da1658f589df213aed33c2ded6Calvin On return false; 538d7d16b9f372116da1658f589df213aed33c2ded6Calvin On } catch (RemoteException e) { 539d7d16b9f372116da1658f589df213aed33c2ded6Calvin On Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable())); 540d7d16b9f372116da1658f589df213aed33c2ded6Calvin On return false; 541d7d16b9f372116da1658f589df213aed33c2ded6Calvin On } finally { 542d7d16b9f372116da1658f589df213aed33c2ded6Calvin On mServiceLock.readLock().unlock(); 5439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 54741d5c805d96aef0aaa9a2aaa86ccc4b77ca75e11Jaikumar Ganesh * This function checks if the remote device is an AVCRP 54841d5c805d96aef0aaa9a2aaa86ccc4b77ca75e11Jaikumar Ganesh * target and thus whether we should send volume keys 54941d5c805d96aef0aaa9a2aaa86ccc4b77ca75e11Jaikumar Ganesh * changes or not. 55041d5c805d96aef0aaa9a2aaa86ccc4b77ca75e11Jaikumar Ganesh * @hide 55141d5c805d96aef0aaa9a2aaa86ccc4b77ca75e11Jaikumar Ganesh */ 55241d5c805d96aef0aaa9a2aaa86ccc4b77ca75e11Jaikumar Ganesh public boolean shouldSendVolumeKeys(BluetoothDevice device) { 55341d5c805d96aef0aaa9a2aaa86ccc4b77ca75e11Jaikumar Ganesh if (isEnabled() && isValidDevice(device)) { 55441d5c805d96aef0aaa9a2aaa86ccc4b77ca75e11Jaikumar Ganesh ParcelUuid[] uuids = device.getUuids(); 55541d5c805d96aef0aaa9a2aaa86ccc4b77ca75e11Jaikumar Ganesh if (uuids == null) return false; 55641d5c805d96aef0aaa9a2aaa86ccc4b77ca75e11Jaikumar Ganesh 55741d5c805d96aef0aaa9a2aaa86ccc4b77ca75e11Jaikumar Ganesh for (ParcelUuid uuid: uuids) { 55841d5c805d96aef0aaa9a2aaa86ccc4b77ca75e11Jaikumar Ganesh if (BluetoothUuid.isAvrcpTarget(uuid)) { 55941d5c805d96aef0aaa9a2aaa86ccc4b77ca75e11Jaikumar Ganesh return true; 56041d5c805d96aef0aaa9a2aaa86ccc4b77ca75e11Jaikumar Ganesh } 56141d5c805d96aef0aaa9a2aaa86ccc4b77ca75e11Jaikumar Ganesh } 56241d5c805d96aef0aaa9a2aaa86ccc4b77ca75e11Jaikumar Ganesh } 56341d5c805d96aef0aaa9a2aaa86ccc4b77ca75e11Jaikumar Ganesh return false; 56441d5c805d96aef0aaa9a2aaa86ccc4b77ca75e11Jaikumar Ganesh } 56541d5c805d96aef0aaa9a2aaa86ccc4b77ca75e11Jaikumar Ganesh 566a0c680393f2dd03a937c598b2cb9abf98a58152cMatthew Xie /** 56744a4ef0aa93ebb2912f36d65af42ffbb1bcdbc0fPavlin Radoslavov * Gets the current codec configuration. 56844a4ef0aa93ebb2912f36d65af42ffbb1bcdbc0fPavlin Radoslavov * 56944a4ef0aa93ebb2912f36d65af42ffbb1bcdbc0fPavlin Radoslavov * @return the current codec configuration 57044a4ef0aa93ebb2912f36d65af42ffbb1bcdbc0fPavlin Radoslavov * @hide 57144a4ef0aa93ebb2912f36d65af42ffbb1bcdbc0fPavlin Radoslavov */ 57244a4ef0aa93ebb2912f36d65af42ffbb1bcdbc0fPavlin Radoslavov public BluetoothCodecConfig getCodecConfig() { 57344a4ef0aa93ebb2912f36d65af42ffbb1bcdbc0fPavlin Radoslavov if (DBG) Log.d(TAG, "getCodecConfig"); 57444a4ef0aa93ebb2912f36d65af42ffbb1bcdbc0fPavlin Radoslavov try { 57544a4ef0aa93ebb2912f36d65af42ffbb1bcdbc0fPavlin Radoslavov mServiceLock.readLock().lock(); 57644a4ef0aa93ebb2912f36d65af42ffbb1bcdbc0fPavlin Radoslavov if (mService != null && isEnabled()) { 57744a4ef0aa93ebb2912f36d65af42ffbb1bcdbc0fPavlin Radoslavov return mService.getCodecConfig(); 57844a4ef0aa93ebb2912f36d65af42ffbb1bcdbc0fPavlin Radoslavov } 57944a4ef0aa93ebb2912f36d65af42ffbb1bcdbc0fPavlin Radoslavov if (mService == null) { 58044a4ef0aa93ebb2912f36d65af42ffbb1bcdbc0fPavlin Radoslavov Log.w(TAG, "Proxy not attached to service"); 58144a4ef0aa93ebb2912f36d65af42ffbb1bcdbc0fPavlin Radoslavov } 58244a4ef0aa93ebb2912f36d65af42ffbb1bcdbc0fPavlin Radoslavov return null; 58344a4ef0aa93ebb2912f36d65af42ffbb1bcdbc0fPavlin Radoslavov } catch (RemoteException e) { 58444a4ef0aa93ebb2912f36d65af42ffbb1bcdbc0fPavlin Radoslavov Log.e(TAG, "Error talking to BT service in getCodecConfig()", e); 58544a4ef0aa93ebb2912f36d65af42ffbb1bcdbc0fPavlin Radoslavov return null; 58644a4ef0aa93ebb2912f36d65af42ffbb1bcdbc0fPavlin Radoslavov } finally { 58744a4ef0aa93ebb2912f36d65af42ffbb1bcdbc0fPavlin Radoslavov mServiceLock.readLock().unlock(); 58844a4ef0aa93ebb2912f36d65af42ffbb1bcdbc0fPavlin Radoslavov } 58944a4ef0aa93ebb2912f36d65af42ffbb1bcdbc0fPavlin Radoslavov } 59044a4ef0aa93ebb2912f36d65af42ffbb1bcdbc0fPavlin Radoslavov 59144a4ef0aa93ebb2912f36d65af42ffbb1bcdbc0fPavlin Radoslavov /** 59244a4ef0aa93ebb2912f36d65af42ffbb1bcdbc0fPavlin Radoslavov * Sets the codec configuration preference. 59344a4ef0aa93ebb2912f36d65af42ffbb1bcdbc0fPavlin Radoslavov * 59444a4ef0aa93ebb2912f36d65af42ffbb1bcdbc0fPavlin Radoslavov * @param codecConfig the codec configuration preference 59544a4ef0aa93ebb2912f36d65af42ffbb1bcdbc0fPavlin Radoslavov * @hide 59644a4ef0aa93ebb2912f36d65af42ffbb1bcdbc0fPavlin Radoslavov */ 59744a4ef0aa93ebb2912f36d65af42ffbb1bcdbc0fPavlin Radoslavov public void setCodecConfigPreference(BluetoothCodecConfig codecConfig) { 59844a4ef0aa93ebb2912f36d65af42ffbb1bcdbc0fPavlin Radoslavov if (DBG) Log.d(TAG, "setCodecConfigPreference"); 59944a4ef0aa93ebb2912f36d65af42ffbb1bcdbc0fPavlin Radoslavov try { 60044a4ef0aa93ebb2912f36d65af42ffbb1bcdbc0fPavlin Radoslavov mServiceLock.readLock().lock(); 60144a4ef0aa93ebb2912f36d65af42ffbb1bcdbc0fPavlin Radoslavov if (mService != null && isEnabled()) { 60244a4ef0aa93ebb2912f36d65af42ffbb1bcdbc0fPavlin Radoslavov mService.setCodecConfigPreference(codecConfig); 60344a4ef0aa93ebb2912f36d65af42ffbb1bcdbc0fPavlin Radoslavov } 60444a4ef0aa93ebb2912f36d65af42ffbb1bcdbc0fPavlin Radoslavov if (mService == null) Log.w(TAG, "Proxy not attached to service"); 60544a4ef0aa93ebb2912f36d65af42ffbb1bcdbc0fPavlin Radoslavov return; 60644a4ef0aa93ebb2912f36d65af42ffbb1bcdbc0fPavlin Radoslavov } catch (RemoteException e) { 60744a4ef0aa93ebb2912f36d65af42ffbb1bcdbc0fPavlin Radoslavov Log.e(TAG, "Error talking to BT service in setCodecConfigPreference()", e); 60844a4ef0aa93ebb2912f36d65af42ffbb1bcdbc0fPavlin Radoslavov return; 60944a4ef0aa93ebb2912f36d65af42ffbb1bcdbc0fPavlin Radoslavov } finally { 61044a4ef0aa93ebb2912f36d65af42ffbb1bcdbc0fPavlin Radoslavov mServiceLock.readLock().unlock(); 61144a4ef0aa93ebb2912f36d65af42ffbb1bcdbc0fPavlin Radoslavov } 61244a4ef0aa93ebb2912f36d65af42ffbb1bcdbc0fPavlin Radoslavov } 61344a4ef0aa93ebb2912f36d65af42ffbb1bcdbc0fPavlin Radoslavov 61444a4ef0aa93ebb2912f36d65af42ffbb1bcdbc0fPavlin Radoslavov /** 61562c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * Helper for converting a state to a string. 61662c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh * 6179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * For debug use only - strings are not internationalized. 6189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @hide 6199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 6209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static String stateToString(int state) { 6219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project switch (state) { 6229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case STATE_DISCONNECTED: 6239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return "disconnected"; 6249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case STATE_CONNECTING: 6259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return "connecting"; 6269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case STATE_CONNECTED: 6279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return "connected"; 6289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case STATE_DISCONNECTING: 6299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return "disconnecting"; 6309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case STATE_PLAYING: 6319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return "playing"; 63262c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh case STATE_NOT_PLAYING: 63362c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh return "not playing"; 6349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project default: 6359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return "<unknown state " + state + ">"; 6369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 638f5b4b98fada53d91c4c2ebeb5a1d33ccc95c94d2The Android Open Source Project 6399b6939939901cb82bc6fca93aad3810a4936dfc6Matthew Xie private final ServiceConnection mConnection = new ServiceConnection() { 6403e8c82edb1feafc796aa52efafedc13f794c4dcdMatthew Xie public void onServiceConnected(ComponentName className, IBinder service) { 6413e8c82edb1feafc796aa52efafedc13f794c4dcdMatthew Xie if (DBG) Log.d(TAG, "Proxy object connected"); 642d7d16b9f372116da1658f589df213aed33c2ded6Calvin On try { 643d7d16b9f372116da1658f589df213aed33c2ded6Calvin On mServiceLock.writeLock().lock(); 644d7d16b9f372116da1658f589df213aed33c2ded6Calvin On mService = IBluetoothA2dp.Stub.asInterface(service); 645d7d16b9f372116da1658f589df213aed33c2ded6Calvin On } finally { 646d7d16b9f372116da1658f589df213aed33c2ded6Calvin On mServiceLock.writeLock().unlock(); 647d7d16b9f372116da1658f589df213aed33c2ded6Calvin On } 6483e8c82edb1feafc796aa52efafedc13f794c4dcdMatthew Xie 6493e8c82edb1feafc796aa52efafedc13f794c4dcdMatthew Xie if (mServiceListener != null) { 6503e8c82edb1feafc796aa52efafedc13f794c4dcdMatthew Xie mServiceListener.onServiceConnected(BluetoothProfile.A2DP, BluetoothA2dp.this); 6513e8c82edb1feafc796aa52efafedc13f794c4dcdMatthew Xie } 6523e8c82edb1feafc796aa52efafedc13f794c4dcdMatthew Xie } 6533e8c82edb1feafc796aa52efafedc13f794c4dcdMatthew Xie public void onServiceDisconnected(ComponentName className) { 6543e8c82edb1feafc796aa52efafedc13f794c4dcdMatthew Xie if (DBG) Log.d(TAG, "Proxy object disconnected"); 655d7d16b9f372116da1658f589df213aed33c2ded6Calvin On try { 656d7d16b9f372116da1658f589df213aed33c2ded6Calvin On mServiceLock.writeLock().lock(); 657d7d16b9f372116da1658f589df213aed33c2ded6Calvin On mService = null; 658d7d16b9f372116da1658f589df213aed33c2ded6Calvin On } finally { 659d7d16b9f372116da1658f589df213aed33c2ded6Calvin On mServiceLock.writeLock().unlock(); 660d7d16b9f372116da1658f589df213aed33c2ded6Calvin On } 6613e8c82edb1feafc796aa52efafedc13f794c4dcdMatthew Xie if (mServiceListener != null) { 6623e8c82edb1feafc796aa52efafedc13f794c4dcdMatthew Xie mServiceListener.onServiceDisconnected(BluetoothProfile.A2DP); 6633e8c82edb1feafc796aa52efafedc13f794c4dcdMatthew Xie } 6643e8c82edb1feafc796aa52efafedc13f794c4dcdMatthew Xie } 6653e8c82edb1feafc796aa52efafedc13f794c4dcdMatthew Xie }; 6663e8c82edb1feafc796aa52efafedc13f794c4dcdMatthew Xie 66762c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh private boolean isEnabled() { 66862c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh if (mAdapter.getState() == BluetoothAdapter.STATE_ON) return true; 66962c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh return false; 67062c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh } 67162c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh 67262c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh private boolean isValidDevice(BluetoothDevice device) { 67362c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh if (device == null) return false; 67462c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh 67562c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh if (BluetoothAdapter.checkBluetoothAddress(device.getAddress())) return true; 67662c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh return false; 67762c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh } 67862c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh 679f5b4b98fada53d91c4c2ebeb5a1d33ccc95c94d2The Android Open Source Project private static void log(String msg) { 68062c37efc9e894809b29a004c142a8e0a6b374db7Jaikumar Ganesh Log.d(TAG, msg); 681f5b4b98fada53d91c4c2ebeb5a1d33ccc95c94d2The Android Open Source Project } 6829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 683