BluetoothA2dpSink.java revision 1bec6a5b0d67f120b7013572f6b1a4f1e1b3c584
12263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood/* 22263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood * Copyright (C) 2014 The Android Open Source Project 32263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood * 42263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood * Licensed under the Apache License, Version 2.0 (the "License"); 52263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood * you may not use this file except in compliance with the License. 62263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood * You may obtain a copy of the License at 72263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood * 82263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood * http://www.apache.org/licenses/LICENSE-2.0 92263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood * 102263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood * Unless required by applicable law or agreed to in writing, software 112263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood * distributed under the License is distributed on an "AS IS" BASIS, 122263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 132263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood * See the License for the specific language governing permissions and 142263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood * limitations under the License. 152263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood */ 162263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood 172263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwoodpackage android.bluetooth; 182263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood 192263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwoodimport android.content.ComponentName; 202263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwoodimport android.content.Context; 212263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwoodimport android.content.Intent; 222263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwoodimport android.content.ServiceConnection; 232263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwoodimport android.os.IBinder; 242263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwoodimport android.os.RemoteException; 252263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwoodimport android.util.Log; 262263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood 272263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwoodimport java.util.ArrayList; 282263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwoodimport java.util.List; 292263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood 302263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood/** 312263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood * This class provides the public APIs to control the Bluetooth A2DP Sink 322263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood * profile. 332263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood * 342263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood *<p>BluetoothA2dpSink is a proxy object for controlling the Bluetooth A2DP Sink 352263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood * Service via IPC. Use {@link BluetoothAdapter#getProfileProxy} to get 362263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood * the BluetoothA2dpSink proxy object. 372263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood * 382263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood * @hide 392263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood */ 402263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwoodpublic final class BluetoothA2dpSink implements BluetoothProfile { 412263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood private static final String TAG = "BluetoothA2dpSink"; 422263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood private static final boolean DBG = true; 432263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood private static final boolean VDBG = false; 442263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood 452263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood /** 462263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood * Intent used to broadcast the change in connection state of the A2DP Sink 472263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood * profile. 482263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood * 492263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood * <p>This intent will have 3 extras: 502263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood * <ul> 512263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood * <li> {@link #EXTRA_STATE} - The current state of the profile. </li> 522263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood * <li> {@link #EXTRA_PREVIOUS_STATE}- The previous state of the profile.</li> 532263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood * <li> {@link BluetoothDevice#EXTRA_DEVICE} - The remote device. </li> 542263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood * </ul> 552263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood * 562263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood * <p>{@link #EXTRA_STATE} or {@link #EXTRA_PREVIOUS_STATE} can be any of 572263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood * {@link #STATE_DISCONNECTED}, {@link #STATE_CONNECTING}, 582263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood * {@link #STATE_CONNECTED}, {@link #STATE_DISCONNECTING}. 592263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood * 602263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission to 612263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood * receive. 622263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood */ 632263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood public static final String ACTION_CONNECTION_STATE_CHANGED = 642263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood "android.bluetooth.a2dp-sink.profile.action.CONNECTION_STATE_CHANGED"; 652263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood 662263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood /** 672263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood * Intent used to broadcast the change in the Playing state of the A2DP Sink 682263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood * profile. 692263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood * 702263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood * <p>This intent will have 3 extras: 712263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood * <ul> 722263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood * <li> {@link #EXTRA_STATE} - The current state of the profile. </li> 732263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood * <li> {@link #EXTRA_PREVIOUS_STATE}- The previous state of the profile. </li> 742263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood * <li> {@link BluetoothDevice#EXTRA_DEVICE} - The remote device. </li> 752263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood * </ul> 762263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood * 772263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood * <p>{@link #EXTRA_STATE} or {@link #EXTRA_PREVIOUS_STATE} can be any of 782263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood * {@link #STATE_PLAYING}, {@link #STATE_NOT_PLAYING}, 792263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood * 802263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission to 812263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood * receive. 822263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood */ 832263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood public static final String ACTION_PLAYING_STATE_CHANGED = 842263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood "android.bluetooth.a2dp-sink.profile.action.PLAYING_STATE_CHANGED"; 852263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood 862263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood /** 872263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood * A2DP sink device is streaming music. This state can be one of 882263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood * {@link #EXTRA_STATE} or {@link #EXTRA_PREVIOUS_STATE} of 892263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood * {@link #ACTION_PLAYING_STATE_CHANGED} intent. 902263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood */ 912263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood public static final int STATE_PLAYING = 10; 922263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood 932263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood /** 942263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood * A2DP sink device is NOT streaming music. This state can be one of 952263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood * {@link #EXTRA_STATE} or {@link #EXTRA_PREVIOUS_STATE} of 962263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood * {@link #ACTION_PLAYING_STATE_CHANGED} intent. 972263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood */ 982263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood public static final int STATE_NOT_PLAYING = 11; 992263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood 1002263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood /** 1012263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood * Intent used to broadcast the change in the Playing state of the A2DP Sink 1022263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood * profile. 1032263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood * 1042263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood * <p>This intent will have 3 extras: 1052263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood * <ul> 1062263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood * <li> {@link #EXTRA_AUDIO_CONFIG} - The audio configuration for the remote device. </li> 1072263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood * <li> {@link BluetoothDevice#EXTRA_DEVICE} - The remote device. </li> 1082263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood * </ul> 1092263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood * 1102263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission to 1112263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood * receive. 1122263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood */ 1132263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood public static final String ACTION_AUDIO_CONFIG_CHANGED = 1142263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood "android.bluetooth.a2dp-sink.profile.action.AUDIO_CONFIG_CHANGED"; 1152263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood 1162263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood /** 1172263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood * Extra for the {@link #ACTION_AUDIO_CONFIG_CHANGED} intent. 1182263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood * 1192263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood * This extra represents the current audio configuration of the A2DP source device. 1202263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood * {@see BluetoothAudioConfig} 1212263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood */ 1222263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood public static final String EXTRA_AUDIO_CONFIG 1232263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood = "android.bluetooth.a2dp-sink.profile.extra.AUDIO_CONFIG"; 1242263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood 1252263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood private Context mContext; 1262263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood private ServiceListener mServiceListener; 1272263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood private IBluetoothA2dpSink mService; 1282263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood private BluetoothAdapter mAdapter; 1292263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood 1302263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood final private IBluetoothStateChangeCallback mBluetoothStateChangeCallback = 1312263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood new IBluetoothStateChangeCallback.Stub() { 1322263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood public void onBluetoothStateChange(boolean up) { 1332263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood if (DBG) Log.d(TAG, "onBluetoothStateChange: up=" + up); 1342263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood if (!up) { 1352263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood if (VDBG) Log.d(TAG,"Unbinding service..."); 1362263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood synchronized (mConnection) { 1372263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood try { 1382263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood mService = null; 1392263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood mContext.unbindService(mConnection); 1402263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood } catch (Exception re) { 1412263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood Log.e(TAG,"",re); 1422263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood } 1432263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood } 1442263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood } else { 1452263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood synchronized (mConnection) { 1462263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood try { 1472263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood if (mService == null) { 1482263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood if (VDBG) Log.d(TAG,"Binding service..."); 1492263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood doBind(); 1502263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood } 1512263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood } catch (Exception re) { 1522263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood Log.e(TAG,"",re); 1532263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood } 1542263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood } 1552263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood } 1562263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood } 1572263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood }; 1582263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood /** 1592263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood * Create a BluetoothA2dp proxy object for interacting with the local 1602263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood * Bluetooth A2DP service. 1612263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood * 1622263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood */ 1632263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood /*package*/ BluetoothA2dpSink(Context context, ServiceListener l) { 1642263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood mContext = context; 1652263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood mServiceListener = l; 1662263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood mAdapter = BluetoothAdapter.getDefaultAdapter(); 1672263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood IBluetoothManager mgr = mAdapter.getBluetoothManager(); 1682263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood if (mgr != null) { 1692263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood try { 1702263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood mgr.registerStateChangeCallback(mBluetoothStateChangeCallback); 1712263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood } catch (RemoteException e) { 1722263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood Log.e(TAG,"",e); 1732263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood } 1742263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood } 1752263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood 1762263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood doBind(); 1772263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood } 1782263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood 1792263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood boolean doBind() { 1802263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood Intent intent = new Intent(IBluetoothA2dpSink.class.getName()); 1812263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood ComponentName comp = intent.resolveSystemService(mContext.getPackageManager(), 0); 1822263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood intent.setComponent(comp); 1832263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood if (comp == null || !mContext.bindServiceAsUser(intent, mConnection, 0, 1842263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood android.os.Process.myUserHandle())) { 1852263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood Log.e(TAG, "Could not bind to Bluetooth A2DP Service with " + intent); 1862263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood return false; 1872263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood } 1882263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood return true; 1892263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood } 1902263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood 1912263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood /*package*/ void close() { 1922263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood mServiceListener = null; 1932263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood IBluetoothManager mgr = mAdapter.getBluetoothManager(); 1942263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood if (mgr != null) { 1952263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood try { 1962263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood mgr.unregisterStateChangeCallback(mBluetoothStateChangeCallback); 1972263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood } catch (Exception e) { 1982263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood Log.e(TAG,"",e); 1992263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood } 2002263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood } 2012263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood 2022263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood synchronized (mConnection) { 2032263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood if (mService != null) { 2042263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood try { 2052263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood mService = null; 2062263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood mContext.unbindService(mConnection); 2072263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood } catch (Exception re) { 2082263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood Log.e(TAG,"",re); 2092263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood } 2102263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood } 2112263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood } 2122263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood } 2132263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood 2142263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood public void finalize() { 2152263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood close(); 2162263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood } 2172263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood /** 2182263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood * Initiate connection to a profile of the remote bluetooth device. 2192263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood * 2202263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood * <p> Currently, the system supports only 1 connection to the 2212263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood * A2DP profile. The API will automatically disconnect connected 2222263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood * devices before connecting. 2232263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood * 2242263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood * <p> This API returns false in scenarios like the profile on the 2252263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood * device is already connected or Bluetooth is not turned on. 2262263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood * When this API returns true, it is guaranteed that 2272263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood * connection state intent for the profile will be broadcasted with 2282263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood * the state. Users can get the connection state of the profile 2292263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood * from this intent. 2302263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood * 2312263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN} 2322263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood * permission. 2332263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood * 2342263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood * @param device Remote Bluetooth Device 2352263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood * @return false on immediate error, 2362263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood * true otherwise 2372263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood * @hide 2382263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood */ 2392263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood public boolean connect(BluetoothDevice device) { 2402263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood if (DBG) log("connect(" + device + ")"); 2412263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood if (mService != null && isEnabled() && 2422263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood isValidDevice(device)) { 2432263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood try { 2442263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood return mService.connect(device); 2452263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood } catch (RemoteException e) { 2462263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable())); 2472263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood return false; 2482263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood } 2492263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood } 2502263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood if (mService == null) Log.w(TAG, "Proxy not attached to service"); 2512263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood return false; 2522263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood } 2532263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood 2542263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood /** 2552263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood * Initiate disconnection from a profile 2562263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood * 2572263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood * <p> This API will return false in scenarios like the profile on the 2582263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood * Bluetooth device is not in connected state etc. When this API returns, 2592263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood * true, it is guaranteed that the connection state change 2602263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood * intent will be broadcasted with the state. Users can get the 2612263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood * disconnection state of the profile from this intent. 2622263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood * 2632263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood * <p> If the disconnection is initiated by a remote device, the state 2642263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood * will transition from {@link #STATE_CONNECTED} to 2652263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood * {@link #STATE_DISCONNECTED}. If the disconnect is initiated by the 2662263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood * host (local) device the state will transition from 2672263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood * {@link #STATE_CONNECTED} to state {@link #STATE_DISCONNECTING} to 2682263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood * state {@link #STATE_DISCONNECTED}. The transition to 2692263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood * {@link #STATE_DISCONNECTING} can be used to distinguish between the 2702263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood * two scenarios. 2712263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood * 2722263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN} 2732263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood * permission. 2742263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood * 2752263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood * @param device Remote Bluetooth Device 2762263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood * @return false on immediate error, 2772263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood * true otherwise 2782263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood * @hide 2792263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood */ 2802263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood public boolean disconnect(BluetoothDevice device) { 2812263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood if (DBG) log("disconnect(" + device + ")"); 2822263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood if (mService != null && isEnabled() && 2832263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood isValidDevice(device)) { 2842263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood try { 2852263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood return mService.disconnect(device); 2862263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood } catch (RemoteException e) { 2872263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable())); 2882263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood return false; 2892263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood } 2902263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood } 2912263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood if (mService == null) Log.w(TAG, "Proxy not attached to service"); 2922263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood return false; 2932263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood } 2942263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood 2952263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood /** 2962263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood * {@inheritDoc} 2972263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood */ 2982263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood public List<BluetoothDevice> getConnectedDevices() { 2992263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood if (VDBG) log("getConnectedDevices()"); 3002263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood if (mService != null && isEnabled()) { 3012263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood try { 3022263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood return mService.getConnectedDevices(); 3032263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood } catch (RemoteException e) { 3042263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable())); 3052263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood return new ArrayList<BluetoothDevice>(); 3062263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood } 3072263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood } 3082263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood if (mService == null) Log.w(TAG, "Proxy not attached to service"); 3092263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood return new ArrayList<BluetoothDevice>(); 3102263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood } 3112263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood 3122263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood /** 3132263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood * {@inheritDoc} 3142263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood */ 3152263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood public List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) { 3162263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood if (VDBG) log("getDevicesMatchingStates()"); 3172263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood if (mService != null && isEnabled()) { 3182263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood try { 3192263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood return mService.getDevicesMatchingConnectionStates(states); 3202263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood } catch (RemoteException e) { 3212263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable())); 3222263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood return new ArrayList<BluetoothDevice>(); 3232263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood } 3242263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood } 3252263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood if (mService == null) Log.w(TAG, "Proxy not attached to service"); 3262263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood return new ArrayList<BluetoothDevice>(); 3272263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood } 3282263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood 3292263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood /** 3302263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood * {@inheritDoc} 3312263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood */ 3322263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood public int getConnectionState(BluetoothDevice device) { 3332263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood if (VDBG) log("getState(" + device + ")"); 3342263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood if (mService != null && isEnabled() 3352263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood && isValidDevice(device)) { 3362263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood try { 3372263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood return mService.getConnectionState(device); 3382263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood } catch (RemoteException e) { 3392263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable())); 3402263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood return BluetoothProfile.STATE_DISCONNECTED; 3412263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood } 3422263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood } 3432263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood if (mService == null) Log.w(TAG, "Proxy not attached to service"); 3442263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood return BluetoothProfile.STATE_DISCONNECTED; 3452263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood } 3462263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood 3472263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood /** 3482263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood * Get the current audio configuration for the A2DP source device, 3492263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood * or null if the device has no audio configuration 3502263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood * 3512263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission. 3522263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood * 3532263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood * @param device Remote bluetooth device. 3542263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood * @return audio configuration for the device, or null 3552263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood * 3562263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood * {@see BluetoothAudioConfig} 3572263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood */ 3582263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood public BluetoothAudioConfig getAudioConfig(BluetoothDevice device) { 3592263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood if (VDBG) log("getAudioConfig(" + device + ")"); 3602263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood if (mService != null && isEnabled() 3612263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood && isValidDevice(device)) { 3622263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood try { 3632263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood return mService.getAudioConfig(device); 3642263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood } catch (RemoteException e) { 3652263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable())); 3662263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood return null; 3672263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood } 3682263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood } 3692263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood if (mService == null) Log.w(TAG, "Proxy not attached to service"); 3702263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood return null; 3712263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood } 3722263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood 3732263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood /** 3741bec6a5b0d67f120b7013572f6b1a4f1e1b3c584Sanket Agarwal * Set priority of the profile 3751bec6a5b0d67f120b7013572f6b1a4f1e1b3c584Sanket Agarwal * 3761bec6a5b0d67f120b7013572f6b1a4f1e1b3c584Sanket Agarwal * <p> The device should already be paired. 3771bec6a5b0d67f120b7013572f6b1a4f1e1b3c584Sanket Agarwal * Priority can be one of {@link #PRIORITY_ON} orgetBluetoothManager 3781bec6a5b0d67f120b7013572f6b1a4f1e1b3c584Sanket Agarwal * {@link #PRIORITY_OFF}, 3791bec6a5b0d67f120b7013572f6b1a4f1e1b3c584Sanket Agarwal * 3801bec6a5b0d67f120b7013572f6b1a4f1e1b3c584Sanket Agarwal * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN} 3811bec6a5b0d67f120b7013572f6b1a4f1e1b3c584Sanket Agarwal * permission. 3821bec6a5b0d67f120b7013572f6b1a4f1e1b3c584Sanket Agarwal * 3831bec6a5b0d67f120b7013572f6b1a4f1e1b3c584Sanket Agarwal * @param device Paired bluetooth device 3841bec6a5b0d67f120b7013572f6b1a4f1e1b3c584Sanket Agarwal * @param priority 3851bec6a5b0d67f120b7013572f6b1a4f1e1b3c584Sanket Agarwal * @return true if priority is set, false on error 3861bec6a5b0d67f120b7013572f6b1a4f1e1b3c584Sanket Agarwal * @hide 3871bec6a5b0d67f120b7013572f6b1a4f1e1b3c584Sanket Agarwal */ 3881bec6a5b0d67f120b7013572f6b1a4f1e1b3c584Sanket Agarwal public boolean setPriority(BluetoothDevice device, int priority) { 3891bec6a5b0d67f120b7013572f6b1a4f1e1b3c584Sanket Agarwal if (DBG) log("setPriority(" + device + ", " + priority + ")"); 3901bec6a5b0d67f120b7013572f6b1a4f1e1b3c584Sanket Agarwal if (mService != null && isEnabled() 3911bec6a5b0d67f120b7013572f6b1a4f1e1b3c584Sanket Agarwal && isValidDevice(device)) { 3921bec6a5b0d67f120b7013572f6b1a4f1e1b3c584Sanket Agarwal if (priority != BluetoothProfile.PRIORITY_OFF && 3931bec6a5b0d67f120b7013572f6b1a4f1e1b3c584Sanket Agarwal priority != BluetoothProfile.PRIORITY_ON){ 3941bec6a5b0d67f120b7013572f6b1a4f1e1b3c584Sanket Agarwal return false; 3951bec6a5b0d67f120b7013572f6b1a4f1e1b3c584Sanket Agarwal } 3961bec6a5b0d67f120b7013572f6b1a4f1e1b3c584Sanket Agarwal try { 3971bec6a5b0d67f120b7013572f6b1a4f1e1b3c584Sanket Agarwal return mService.setPriority(device, priority); 3981bec6a5b0d67f120b7013572f6b1a4f1e1b3c584Sanket Agarwal } catch (RemoteException e) { 3991bec6a5b0d67f120b7013572f6b1a4f1e1b3c584Sanket Agarwal Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable())); 4001bec6a5b0d67f120b7013572f6b1a4f1e1b3c584Sanket Agarwal return false; 4011bec6a5b0d67f120b7013572f6b1a4f1e1b3c584Sanket Agarwal } 4021bec6a5b0d67f120b7013572f6b1a4f1e1b3c584Sanket Agarwal } 4031bec6a5b0d67f120b7013572f6b1a4f1e1b3c584Sanket Agarwal if (mService == null) Log.w(TAG, "Proxy not attached to service"); 4041bec6a5b0d67f120b7013572f6b1a4f1e1b3c584Sanket Agarwal return false; 4051bec6a5b0d67f120b7013572f6b1a4f1e1b3c584Sanket Agarwal } 4061bec6a5b0d67f120b7013572f6b1a4f1e1b3c584Sanket Agarwal 4071bec6a5b0d67f120b7013572f6b1a4f1e1b3c584Sanket Agarwal /** 4081bec6a5b0d67f120b7013572f6b1a4f1e1b3c584Sanket Agarwal * Get the priority of the profile. 4091bec6a5b0d67f120b7013572f6b1a4f1e1b3c584Sanket Agarwal * 4101bec6a5b0d67f120b7013572f6b1a4f1e1b3c584Sanket Agarwal * <p> The priority can be any of: 4111bec6a5b0d67f120b7013572f6b1a4f1e1b3c584Sanket Agarwal * {@link #PRIORITY_AUTO_CONNECT}, {@link #PRIORITY_OFF}, 4121bec6a5b0d67f120b7013572f6b1a4f1e1b3c584Sanket Agarwal * {@link #PRIORITY_ON}, {@link #PRIORITY_UNDEFINED} 4131bec6a5b0d67f120b7013572f6b1a4f1e1b3c584Sanket Agarwal * 4141bec6a5b0d67f120b7013572f6b1a4f1e1b3c584Sanket Agarwal * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission. 4151bec6a5b0d67f120b7013572f6b1a4f1e1b3c584Sanket Agarwal * 4161bec6a5b0d67f120b7013572f6b1a4f1e1b3c584Sanket Agarwal * @param device Bluetooth device 4171bec6a5b0d67f120b7013572f6b1a4f1e1b3c584Sanket Agarwal * @return priority of the device 4181bec6a5b0d67f120b7013572f6b1a4f1e1b3c584Sanket Agarwal * @hide 4191bec6a5b0d67f120b7013572f6b1a4f1e1b3c584Sanket Agarwal */ 4201bec6a5b0d67f120b7013572f6b1a4f1e1b3c584Sanket Agarwal public int getPriority(BluetoothDevice device) { 4211bec6a5b0d67f120b7013572f6b1a4f1e1b3c584Sanket Agarwal if (VDBG) log("getPriority(" + device + ")"); 4221bec6a5b0d67f120b7013572f6b1a4f1e1b3c584Sanket Agarwal if (mService != null && isEnabled() 4231bec6a5b0d67f120b7013572f6b1a4f1e1b3c584Sanket Agarwal && isValidDevice(device)) { 4241bec6a5b0d67f120b7013572f6b1a4f1e1b3c584Sanket Agarwal try { 4251bec6a5b0d67f120b7013572f6b1a4f1e1b3c584Sanket Agarwal return mService.getPriority(device); 4261bec6a5b0d67f120b7013572f6b1a4f1e1b3c584Sanket Agarwal } catch (RemoteException e) { 4271bec6a5b0d67f120b7013572f6b1a4f1e1b3c584Sanket Agarwal Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable())); 4281bec6a5b0d67f120b7013572f6b1a4f1e1b3c584Sanket Agarwal return BluetoothProfile.PRIORITY_OFF; 4291bec6a5b0d67f120b7013572f6b1a4f1e1b3c584Sanket Agarwal } 4301bec6a5b0d67f120b7013572f6b1a4f1e1b3c584Sanket Agarwal } 4311bec6a5b0d67f120b7013572f6b1a4f1e1b3c584Sanket Agarwal if (mService == null) Log.w(TAG, "Proxy not attached to service"); 4321bec6a5b0d67f120b7013572f6b1a4f1e1b3c584Sanket Agarwal return BluetoothProfile.PRIORITY_OFF; 4331bec6a5b0d67f120b7013572f6b1a4f1e1b3c584Sanket Agarwal } 4341bec6a5b0d67f120b7013572f6b1a4f1e1b3c584Sanket Agarwal 4351bec6a5b0d67f120b7013572f6b1a4f1e1b3c584Sanket Agarwal /** 4361bec6a5b0d67f120b7013572f6b1a4f1e1b3c584Sanket Agarwal * Check if A2DP profile is streaming music. 4371bec6a5b0d67f120b7013572f6b1a4f1e1b3c584Sanket Agarwal * 4381bec6a5b0d67f120b7013572f6b1a4f1e1b3c584Sanket Agarwal * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission. 4391bec6a5b0d67f120b7013572f6b1a4f1e1b3c584Sanket Agarwal * 4401bec6a5b0d67f120b7013572f6b1a4f1e1b3c584Sanket Agarwal * @param device BluetoothDevice device 4411bec6a5b0d67f120b7013572f6b1a4f1e1b3c584Sanket Agarwal */ 4421bec6a5b0d67f120b7013572f6b1a4f1e1b3c584Sanket Agarwal public boolean isA2dpPlaying(BluetoothDevice device) { 4431bec6a5b0d67f120b7013572f6b1a4f1e1b3c584Sanket Agarwal if (mService != null && isEnabled() 4441bec6a5b0d67f120b7013572f6b1a4f1e1b3c584Sanket Agarwal && isValidDevice(device)) { 4451bec6a5b0d67f120b7013572f6b1a4f1e1b3c584Sanket Agarwal try { 4461bec6a5b0d67f120b7013572f6b1a4f1e1b3c584Sanket Agarwal return mService.isA2dpPlaying(device); 4471bec6a5b0d67f120b7013572f6b1a4f1e1b3c584Sanket Agarwal } catch (RemoteException e) { 4481bec6a5b0d67f120b7013572f6b1a4f1e1b3c584Sanket Agarwal Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable())); 4491bec6a5b0d67f120b7013572f6b1a4f1e1b3c584Sanket Agarwal return false; 4501bec6a5b0d67f120b7013572f6b1a4f1e1b3c584Sanket Agarwal } 4511bec6a5b0d67f120b7013572f6b1a4f1e1b3c584Sanket Agarwal } 4521bec6a5b0d67f120b7013572f6b1a4f1e1b3c584Sanket Agarwal if (mService == null) Log.w(TAG, "Proxy not attached to service"); 4531bec6a5b0d67f120b7013572f6b1a4f1e1b3c584Sanket Agarwal return false; 4541bec6a5b0d67f120b7013572f6b1a4f1e1b3c584Sanket Agarwal } 4551bec6a5b0d67f120b7013572f6b1a4f1e1b3c584Sanket Agarwal 4561bec6a5b0d67f120b7013572f6b1a4f1e1b3c584Sanket Agarwal /** 4572263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood * Helper for converting a state to a string. 4582263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood * 4592263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood * For debug use only - strings are not internationalized. 4602263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood * @hide 4612263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood */ 4622263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood public static String stateToString(int state) { 4632263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood switch (state) { 4642263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood case STATE_DISCONNECTED: 4652263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood return "disconnected"; 4662263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood case STATE_CONNECTING: 4672263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood return "connecting"; 4682263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood case STATE_CONNECTED: 4692263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood return "connected"; 4702263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood case STATE_DISCONNECTING: 4712263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood return "disconnecting"; 4722263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood case STATE_PLAYING: 4732263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood return "playing"; 4742263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood case STATE_NOT_PLAYING: 4752263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood return "not playing"; 4762263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood default: 4772263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood return "<unknown state " + state + ">"; 4782263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood } 4792263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood } 4802263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood 4812263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood private final ServiceConnection mConnection = new ServiceConnection() { 4822263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood public void onServiceConnected(ComponentName className, IBinder service) { 4832263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood if (DBG) Log.d(TAG, "Proxy object connected"); 4842263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood mService = IBluetoothA2dpSink.Stub.asInterface(service); 4852263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood 4862263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood if (mServiceListener != null) { 4872263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood mServiceListener.onServiceConnected(BluetoothProfile.A2DP_SINK, 4882263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood BluetoothA2dpSink.this); 4892263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood } 4902263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood } 4912263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood public void onServiceDisconnected(ComponentName className) { 4922263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood if (DBG) Log.d(TAG, "Proxy object disconnected"); 4932263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood mService = null; 4942263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood if (mServiceListener != null) { 4952263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood mServiceListener.onServiceDisconnected(BluetoothProfile.A2DP_SINK); 4962263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood } 4972263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood } 4982263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood }; 4992263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood 5002263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood private boolean isEnabled() { 5012263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood if (mAdapter.getState() == BluetoothAdapter.STATE_ON) return true; 5022263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood return false; 5032263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood } 5042263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood 5052263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood private boolean isValidDevice(BluetoothDevice device) { 5062263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood if (device == null) return false; 5072263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood 5082263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood if (BluetoothAdapter.checkBluetoothAddress(device.getAddress())) return true; 5092263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood return false; 5102263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood } 5112263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood 5122263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood private static void log(String msg) { 5132263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood Log.d(TAG, msg); 5142263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood } 5152263dd1ddd1a8ac828c25d34000c85165cad21efMike Lockwood} 516