16c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie/* 2ede67c26e7b2564ea35db6d9b3027a269c150e13Zhihai Xu * Copyright (C) 2012 The Android Open Source Project 3ede67c26e7b2564ea35db6d9b3027a269c150e13Zhihai Xu * 4ede67c26e7b2564ea35db6d9b3027a269c150e13Zhihai Xu * Licensed under the Apache License, Version 2.0 (the "License"); 5ede67c26e7b2564ea35db6d9b3027a269c150e13Zhihai Xu * you may not use this file except in compliance with the License. 6ede67c26e7b2564ea35db6d9b3027a269c150e13Zhihai Xu * You may obtain a copy of the License at 7ede67c26e7b2564ea35db6d9b3027a269c150e13Zhihai Xu * 8ede67c26e7b2564ea35db6d9b3027a269c150e13Zhihai Xu * http://www.apache.org/licenses/LICENSE-2.0 9ede67c26e7b2564ea35db6d9b3027a269c150e13Zhihai Xu * 10ede67c26e7b2564ea35db6d9b3027a269c150e13Zhihai Xu * Unless required by applicable law or agreed to in writing, software 11ede67c26e7b2564ea35db6d9b3027a269c150e13Zhihai Xu * distributed under the License is distributed on an "AS IS" BASIS, 12ede67c26e7b2564ea35db6d9b3027a269c150e13Zhihai Xu * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13ede67c26e7b2564ea35db6d9b3027a269c150e13Zhihai Xu * See the License for the specific language governing permissions and 14ede67c26e7b2564ea35db6d9b3027a269c150e13Zhihai Xu * limitations under the License. 156c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie */ 16ede67c26e7b2564ea35db6d9b3027a269c150e13Zhihai Xu 176c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xiepackage com.android.bluetooth.a2dp; 186c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie 1920155af8008337cb70ea0556472854abf46ca1ebAntony Sargentimport android.bluetooth.BluetoothA2dp; 2033b6b7d2b08dcd7ced1809e2ac653c5e8c2514afPavlin Radoslavovimport android.bluetooth.BluetoothCodecConfig; 2108d3925d3d72837e6f86c9e0beaed5f7b813ea37Pavlin Radoslavovimport android.bluetooth.BluetoothCodecStatus; 226c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xieimport android.bluetooth.BluetoothDevice; 236c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xieimport android.bluetooth.BluetoothProfile; 24e316dfc9b3f648ad3d7b2691927758ea885043c0Anubhav Guptaimport android.bluetooth.BluetoothUuid; 256c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xieimport android.bluetooth.IBluetoothA2dp; 2620155af8008337cb70ea0556472854abf46ca1ebAntony Sargentimport android.content.BroadcastReceiver; 2720155af8008337cb70ea0556472854abf46ca1ebAntony Sargentimport android.content.Context; 2820155af8008337cb70ea0556472854abf46ca1ebAntony Sargentimport android.content.Intent; 2920155af8008337cb70ea0556472854abf46ca1ebAntony Sargentimport android.content.IntentFilter; 30e316dfc9b3f648ad3d7b2691927758ea885043c0Anubhav Guptaimport android.os.ParcelUuid; 316c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xieimport android.provider.Settings; 326c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xieimport android.util.Log; 33066ad9e16a548218b139424f758b92db7af34af2Mike Lockwoodimport com.android.bluetooth.avrcp.Avrcp; 3437510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xuimport com.android.bluetooth.btservice.ProfileService; 3537510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xuimport com.android.bluetooth.Utils; 3674ae04c73312403e89db0f8e9bd9601d403b4783fredcimport java.util.ArrayList; 3737510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xuimport java.util.List; 3833b6b7d2b08dcd7ced1809e2ac653c5e8c2514afPavlin Radoslavovimport java.util.Objects; 396c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie 406c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie/** 416c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie * Provides Bluetooth A2DP profile, as a service in the Bluetooth application. 426c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie * @hide 436c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie */ 44b5cc776c9353a203cdde97e62b25f05d9633d14cfredcpublic class A2dpService extends ProfileService { 45fd1da115cbf09b7dd9bca3c7d3a4fb816a835dc5Matthew Xie private static final boolean DBG = false; 46b5cc776c9353a203cdde97e62b25f05d9633d14cfredc private static final String TAG="A2dpService"; 476c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie 486c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie private A2dpStateMachine mStateMachine; 49c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu private Avrcp mAvrcp; 5020155af8008337cb70ea0556472854abf46ca1ebAntony Sargent 5120155af8008337cb70ea0556472854abf46ca1ebAntony Sargent private BroadcastReceiver mConnectionStateChangedReceiver = new BroadcastReceiver() { 5220155af8008337cb70ea0556472854abf46ca1ebAntony Sargent @Override 5320155af8008337cb70ea0556472854abf46ca1ebAntony Sargent public void onReceive(Context context, Intent intent) { 5420155af8008337cb70ea0556472854abf46ca1ebAntony Sargent if (!BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED.equals(intent.getAction())) { 5520155af8008337cb70ea0556472854abf46ca1ebAntony Sargent return; 5620155af8008337cb70ea0556472854abf46ca1ebAntony Sargent } 5720155af8008337cb70ea0556472854abf46ca1ebAntony Sargent int state = intent.getIntExtra(BluetoothProfile.EXTRA_STATE, -1); 5820155af8008337cb70ea0556472854abf46ca1ebAntony Sargent BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); 5920155af8008337cb70ea0556472854abf46ca1ebAntony Sargent if (state != BluetoothProfile.STATE_CONNECTED || device == null) { 6020155af8008337cb70ea0556472854abf46ca1ebAntony Sargent return; 6120155af8008337cb70ea0556472854abf46ca1ebAntony Sargent } 6220155af8008337cb70ea0556472854abf46ca1ebAntony Sargent // Each time a device connects, we want to re-check if it supports optional 6320155af8008337cb70ea0556472854abf46ca1ebAntony Sargent // codecs (perhaps it's had a firmware update, etc.) and save that state if 6420155af8008337cb70ea0556472854abf46ca1ebAntony Sargent // it differs from what we had saved before. 6520155af8008337cb70ea0556472854abf46ca1ebAntony Sargent int previousSupport = getSupportsOptionalCodecs(device); 6620155af8008337cb70ea0556472854abf46ca1ebAntony Sargent boolean supportsOptional = false; 6720155af8008337cb70ea0556472854abf46ca1ebAntony Sargent for (BluetoothCodecConfig config : 6820155af8008337cb70ea0556472854abf46ca1ebAntony Sargent mStateMachine.getCodecStatus().getCodecsSelectableCapabilities()) { 6920155af8008337cb70ea0556472854abf46ca1ebAntony Sargent if (!config.isMandatoryCodec()) { 7020155af8008337cb70ea0556472854abf46ca1ebAntony Sargent supportsOptional = true; 7120155af8008337cb70ea0556472854abf46ca1ebAntony Sargent break; 7220155af8008337cb70ea0556472854abf46ca1ebAntony Sargent } 7320155af8008337cb70ea0556472854abf46ca1ebAntony Sargent } 7420155af8008337cb70ea0556472854abf46ca1ebAntony Sargent if (previousSupport == BluetoothA2dp.OPTIONAL_CODECS_SUPPORT_UNKNOWN 7520155af8008337cb70ea0556472854abf46ca1ebAntony Sargent || supportsOptional 7620155af8008337cb70ea0556472854abf46ca1ebAntony Sargent != (previousSupport == BluetoothA2dp.OPTIONAL_CODECS_SUPPORTED)) { 7720155af8008337cb70ea0556472854abf46ca1ebAntony Sargent setSupportsOptionalCodecs(device, supportsOptional); 7820155af8008337cb70ea0556472854abf46ca1ebAntony Sargent } 7920155af8008337cb70ea0556472854abf46ca1ebAntony Sargent if (supportsOptional) { 8020155af8008337cb70ea0556472854abf46ca1ebAntony Sargent int enabled = getOptionalCodecsEnabled(device); 8120155af8008337cb70ea0556472854abf46ca1ebAntony Sargent if (enabled == BluetoothA2dp.OPTIONAL_CODECS_PREF_ENABLED) { 8220155af8008337cb70ea0556472854abf46ca1ebAntony Sargent enableOptionalCodecs(); 8320155af8008337cb70ea0556472854abf46ca1ebAntony Sargent } else if (enabled == BluetoothA2dp.OPTIONAL_CODECS_PREF_DISABLED) { 8420155af8008337cb70ea0556472854abf46ca1ebAntony Sargent disableOptionalCodecs(); 8520155af8008337cb70ea0556472854abf46ca1ebAntony Sargent } 8620155af8008337cb70ea0556472854abf46ca1ebAntony Sargent } 8720155af8008337cb70ea0556472854abf46ca1ebAntony Sargent } 8820155af8008337cb70ea0556472854abf46ca1ebAntony Sargent }; 8920155af8008337cb70ea0556472854abf46ca1ebAntony Sargent 904f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta private static A2dpService sAd2dpService; 91e316dfc9b3f648ad3d7b2691927758ea885043c0Anubhav Gupta static final ParcelUuid[] A2DP_SOURCE_UUID = { 92e316dfc9b3f648ad3d7b2691927758ea885043c0Anubhav Gupta BluetoothUuid.AudioSource 93e316dfc9b3f648ad3d7b2691927758ea885043c0Anubhav Gupta }; 94e316dfc9b3f648ad3d7b2691927758ea885043c0Anubhav Gupta static final ParcelUuid[] A2DP_SOURCE_SINK_UUIDS = { 95e316dfc9b3f648ad3d7b2691927758ea885043c0Anubhav Gupta BluetoothUuid.AudioSource, 96e316dfc9b3f648ad3d7b2691927758ea885043c0Anubhav Gupta BluetoothUuid.AudioSink 97e316dfc9b3f648ad3d7b2691927758ea885043c0Anubhav Gupta }; 986c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie 9974ae04c73312403e89db0f8e9bd9601d403b4783fredc protected String getName() { 10074ae04c73312403e89db0f8e9bd9601d403b4783fredc return TAG; 10174ae04c73312403e89db0f8e9bd9601d403b4783fredc } 10274ae04c73312403e89db0f8e9bd9601d403b4783fredc 10374ae04c73312403e89db0f8e9bd9601d403b4783fredc protected IProfileServiceBinder initBinder() { 10474ae04c73312403e89db0f8e9bd9601d403b4783fredc return new BluetoothA2dpBinder(this); 10574ae04c73312403e89db0f8e9bd9601d403b4783fredc } 1066c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie 107b5cc776c9353a203cdde97e62b25f05d9633d14cfredc protected boolean start() { 108c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu mAvrcp = Avrcp.make(this); 109188f205b5f093850d4cc627917a21204be36c56aZhihai Xu mStateMachine = A2dpStateMachine.make(this, this); 1104f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta setA2dpService(this); 11120155af8008337cb70ea0556472854abf46ca1ebAntony Sargent IntentFilter filter = new IntentFilter(); 11220155af8008337cb70ea0556472854abf46ca1ebAntony Sargent filter.addAction(BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED); 11320155af8008337cb70ea0556472854abf46ca1ebAntony Sargent registerReceiver(mConnectionStateChangedReceiver, filter); 114b5cc776c9353a203cdde97e62b25f05d9633d14cfredc return true; 1156654f5c903de510a70f9e72cd5ad7837b615d93ffredc } 1166654f5c903de510a70f9e72cd5ad7837b615d93ffredc 117b5cc776c9353a203cdde97e62b25f05d9633d14cfredc protected boolean stop() { 118ff833ce646e50c3593a313cd6a0be53577e41112Thomas Lehaux if (mStateMachine != null) { 119ff833ce646e50c3593a313cd6a0be53577e41112Thomas Lehaux mStateMachine.doQuit(); 120ff833ce646e50c3593a313cd6a0be53577e41112Thomas Lehaux } 1212609a11670563837625f7dde2192deaba7417e46Andre Eisenbach if (mAvrcp != null) { 1222609a11670563837625f7dde2192deaba7417e46Andre Eisenbach mAvrcp.doQuit(); 1232609a11670563837625f7dde2192deaba7417e46Andre Eisenbach } 12474ae04c73312403e89db0f8e9bd9601d403b4783fredc return true; 12574ae04c73312403e89db0f8e9bd9601d403b4783fredc } 12674ae04c73312403e89db0f8e9bd9601d403b4783fredc 12774ae04c73312403e89db0f8e9bd9601d403b4783fredc protected boolean cleanup() { 12820155af8008337cb70ea0556472854abf46ca1ebAntony Sargent unregisterReceiver(mConnectionStateChangedReceiver); 1296654f5c903de510a70f9e72cd5ad7837b615d93ffredc if (mStateMachine!= null) { 1306654f5c903de510a70f9e72cd5ad7837b615d93ffredc mStateMachine.cleanup(); 1316654f5c903de510a70f9e72cd5ad7837b615d93ffredc } 132c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu if (mAvrcp != null) { 133c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu mAvrcp.cleanup(); 134c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu mAvrcp = null; 135c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu } 1364f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta clearA2dpService(); 137b5cc776c9353a203cdde97e62b25f05d9633d14cfredc return true; 138b5cc776c9353a203cdde97e62b25f05d9633d14cfredc } 1396654f5c903de510a70f9e72cd5ad7837b615d93ffredc 14074ae04c73312403e89db0f8e9bd9601d403b4783fredc //API Methods 1414f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta 1424f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta public static synchronized A2dpService getA2dpService(){ 1434f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta if (sAd2dpService != null && sAd2dpService.isAvailable()) { 1444f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta if (DBG) Log.d(TAG, "getA2DPService(): returning " + sAd2dpService); 1454f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta return sAd2dpService; 1464f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta } 1474f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta if (DBG) { 1484f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta if (sAd2dpService == null) { 1494f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta Log.d(TAG, "getA2dpService(): service is NULL"); 1504f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta } else if (!(sAd2dpService.isAvailable())) { 1514f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta Log.d(TAG,"getA2dpService(): service is not available"); 1524f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta } 1534f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta } 1544f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta return null; 1554f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta } 1564f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta 1574f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta private static synchronized void setA2dpService(A2dpService instance) { 1584f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta if (instance != null && instance.isAvailable()) { 1594f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta if (DBG) Log.d(TAG, "setA2dpService(): set to: " + sAd2dpService); 1604f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta sAd2dpService = instance; 1614f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta } else { 1624f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta if (DBG) { 1634f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta if (sAd2dpService == null) { 1644f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta Log.d(TAG, "setA2dpService(): service not available"); 1654f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta } else if (!sAd2dpService.isAvailable()) { 1664f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta Log.d(TAG,"setA2dpService(): service is cleaning up"); 1674f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta } 1684f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta } 1694f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta } 1704f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta } 1714f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta 1724f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta private static synchronized void clearA2dpService() { 1734f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta sAd2dpService = null; 1744f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta } 1754f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta 1764f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta public boolean connect(BluetoothDevice device) { 17774ae04c73312403e89db0f8e9bd9601d403b4783fredc enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM, 17874ae04c73312403e89db0f8e9bd9601d403b4783fredc "Need BLUETOOTH ADMIN permission"); 17974ae04c73312403e89db0f8e9bd9601d403b4783fredc 18074ae04c73312403e89db0f8e9bd9601d403b4783fredc if (getPriority(device) == BluetoothProfile.PRIORITY_OFF) { 18174ae04c73312403e89db0f8e9bd9601d403b4783fredc return false; 18274ae04c73312403e89db0f8e9bd9601d403b4783fredc } 183e316dfc9b3f648ad3d7b2691927758ea885043c0Anubhav Gupta ParcelUuid[] featureUuids = device.getUuids(); 184e316dfc9b3f648ad3d7b2691927758ea885043c0Anubhav Gupta if ((BluetoothUuid.containsAnyUuid(featureUuids, A2DP_SOURCE_UUID)) && 185e316dfc9b3f648ad3d7b2691927758ea885043c0Anubhav Gupta !(BluetoothUuid.containsAllUuids(featureUuids ,A2DP_SOURCE_SINK_UUIDS))) { 186e316dfc9b3f648ad3d7b2691927758ea885043c0Anubhav Gupta Log.e(TAG,"Remote does not have A2dp Sink UUID"); 187e316dfc9b3f648ad3d7b2691927758ea885043c0Anubhav Gupta return false; 188e316dfc9b3f648ad3d7b2691927758ea885043c0Anubhav Gupta } 18974ae04c73312403e89db0f8e9bd9601d403b4783fredc 19074ae04c73312403e89db0f8e9bd9601d403b4783fredc int connectionState = mStateMachine.getConnectionState(device); 19174ae04c73312403e89db0f8e9bd9601d403b4783fredc if (connectionState == BluetoothProfile.STATE_CONNECTED || 19274ae04c73312403e89db0f8e9bd9601d403b4783fredc connectionState == BluetoothProfile.STATE_CONNECTING) { 19374ae04c73312403e89db0f8e9bd9601d403b4783fredc return false; 19474ae04c73312403e89db0f8e9bd9601d403b4783fredc } 19574ae04c73312403e89db0f8e9bd9601d403b4783fredc 19674ae04c73312403e89db0f8e9bd9601d403b4783fredc mStateMachine.sendMessage(A2dpStateMachine.CONNECT, device); 19774ae04c73312403e89db0f8e9bd9601d403b4783fredc return true; 198b5cc776c9353a203cdde97e62b25f05d9633d14cfredc } 199b5cc776c9353a203cdde97e62b25f05d9633d14cfredc 20074ae04c73312403e89db0f8e9bd9601d403b4783fredc boolean disconnect(BluetoothDevice device) { 20174ae04c73312403e89db0f8e9bd9601d403b4783fredc enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM, 20274ae04c73312403e89db0f8e9bd9601d403b4783fredc "Need BLUETOOTH ADMIN permission"); 20374ae04c73312403e89db0f8e9bd9601d403b4783fredc int connectionState = mStateMachine.getConnectionState(device); 20474ae04c73312403e89db0f8e9bd9601d403b4783fredc if (connectionState != BluetoothProfile.STATE_CONNECTED && 20574ae04c73312403e89db0f8e9bd9601d403b4783fredc connectionState != BluetoothProfile.STATE_CONNECTING) { 20674ae04c73312403e89db0f8e9bd9601d403b4783fredc return false; 20774ae04c73312403e89db0f8e9bd9601d403b4783fredc } 20874ae04c73312403e89db0f8e9bd9601d403b4783fredc 20974ae04c73312403e89db0f8e9bd9601d403b4783fredc mStateMachine.sendMessage(A2dpStateMachine.DISCONNECT, device); 21074ae04c73312403e89db0f8e9bd9601d403b4783fredc return true; 2116c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie } 2126c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie 2134f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta public List<BluetoothDevice> getConnectedDevices() { 21474ae04c73312403e89db0f8e9bd9601d403b4783fredc enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 21574ae04c73312403e89db0f8e9bd9601d403b4783fredc return mStateMachine.getConnectedDevices(); 21674ae04c73312403e89db0f8e9bd9601d403b4783fredc } 2176c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie 21874ae04c73312403e89db0f8e9bd9601d403b4783fredc List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) { 21974ae04c73312403e89db0f8e9bd9601d403b4783fredc enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 22074ae04c73312403e89db0f8e9bd9601d403b4783fredc return mStateMachine.getDevicesMatchingConnectionStates(states); 22174ae04c73312403e89db0f8e9bd9601d403b4783fredc } 2226c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie 22386c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal public int getConnectionState(BluetoothDevice device) { 22474ae04c73312403e89db0f8e9bd9601d403b4783fredc enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 22574ae04c73312403e89db0f8e9bd9601d403b4783fredc return mStateMachine.getConnectionState(device); 22674ae04c73312403e89db0f8e9bd9601d403b4783fredc } 22774ae04c73312403e89db0f8e9bd9601d403b4783fredc 2284f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta public boolean setPriority(BluetoothDevice device, int priority) { 22974ae04c73312403e89db0f8e9bd9601d403b4783fredc enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM, 23074ae04c73312403e89db0f8e9bd9601d403b4783fredc "Need BLUETOOTH_ADMIN permission"); 231c7ead6d5827f3832b9210e92fab7597142059852Jeff Sharkey Settings.Global.putInt(getContentResolver(), 232c7ead6d5827f3832b9210e92fab7597142059852Jeff Sharkey Settings.Global.getBluetoothA2dpSinkPriorityKey(device.getAddress()), 23374ae04c73312403e89db0f8e9bd9601d403b4783fredc priority); 23474ae04c73312403e89db0f8e9bd9601d403b4783fredc if (DBG) Log.d(TAG,"Saved priority " + device + " = " + priority); 23574ae04c73312403e89db0f8e9bd9601d403b4783fredc return true; 23674ae04c73312403e89db0f8e9bd9601d403b4783fredc } 2376c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie 2384f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta public int getPriority(BluetoothDevice device) { 23974ae04c73312403e89db0f8e9bd9601d403b4783fredc enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM, 24074ae04c73312403e89db0f8e9bd9601d403b4783fredc "Need BLUETOOTH_ADMIN permission"); 241c7ead6d5827f3832b9210e92fab7597142059852Jeff Sharkey int priority = Settings.Global.getInt(getContentResolver(), 242c7ead6d5827f3832b9210e92fab7597142059852Jeff Sharkey Settings.Global.getBluetoothA2dpSinkPriorityKey(device.getAddress()), 24374ae04c73312403e89db0f8e9bd9601d403b4783fredc BluetoothProfile.PRIORITY_UNDEFINED); 24474ae04c73312403e89db0f8e9bd9601d403b4783fredc return priority; 24574ae04c73312403e89db0f8e9bd9601d403b4783fredc } 24674ae04c73312403e89db0f8e9bd9601d403b4783fredc 24717675906064bb72fdcca75baa56cdf8bb8968d01John Du /* Absolute volume implementation */ 24817675906064bb72fdcca75baa56cdf8bb8968d01John Du public boolean isAvrcpAbsoluteVolumeSupported() { 24917675906064bb72fdcca75baa56cdf8bb8968d01John Du return mAvrcp.isAbsoluteVolumeSupported(); 25017675906064bb72fdcca75baa56cdf8bb8968d01John Du } 25117675906064bb72fdcca75baa56cdf8bb8968d01John Du 25217675906064bb72fdcca75baa56cdf8bb8968d01John Du public void adjustAvrcpAbsoluteVolume(int direction) { 25317675906064bb72fdcca75baa56cdf8bb8968d01John Du mAvrcp.adjustVolume(direction); 25417675906064bb72fdcca75baa56cdf8bb8968d01John Du } 25517675906064bb72fdcca75baa56cdf8bb8968d01John Du 25617675906064bb72fdcca75baa56cdf8bb8968d01John Du public void setAvrcpAbsoluteVolume(int volume) { 25717675906064bb72fdcca75baa56cdf8bb8968d01John Du mAvrcp.setAbsoluteVolume(volume); 25817675906064bb72fdcca75baa56cdf8bb8968d01John Du } 25917675906064bb72fdcca75baa56cdf8bb8968d01John Du 260188f205b5f093850d4cc627917a21204be36c56aZhihai Xu public void setAvrcpAudioState(int state) { 261188f205b5f093850d4cc627917a21204be36c56aZhihai Xu mAvrcp.setA2dpAudioState(state); 262188f205b5f093850d4cc627917a21204be36c56aZhihai Xu } 263188f205b5f093850d4cc627917a21204be36c56aZhihai Xu 26411798b011c962b602217b479130d413f3b30f19aLiejun Tao public void resetAvrcpBlacklist(BluetoothDevice device) { 265ff495eca3027c9b3aa7d8ef4e9cfd2cde3bbb664Pavlin Radoslavov if (mAvrcp != null) { 266ff495eca3027c9b3aa7d8ef4e9cfd2cde3bbb664Pavlin Radoslavov mAvrcp.resetBlackList(device.getAddress()); 267ff495eca3027c9b3aa7d8ef4e9cfd2cde3bbb664Pavlin Radoslavov } 26811798b011c962b602217b479130d413f3b30f19aLiejun Tao } 26911798b011c962b602217b479130d413f3b30f19aLiejun Tao 27074ae04c73312403e89db0f8e9bd9601d403b4783fredc synchronized boolean isA2dpPlaying(BluetoothDevice device) { 27174ae04c73312403e89db0f8e9bd9601d403b4783fredc enforceCallingOrSelfPermission(BLUETOOTH_PERM, 27274ae04c73312403e89db0f8e9bd9601d403b4783fredc "Need BLUETOOTH permission"); 27374ae04c73312403e89db0f8e9bd9601d403b4783fredc if (DBG) Log.d(TAG, "isA2dpPlaying(" + device + ")"); 27474ae04c73312403e89db0f8e9bd9601d403b4783fredc return mStateMachine.isPlaying(device); 27574ae04c73312403e89db0f8e9bd9601d403b4783fredc } 27674ae04c73312403e89db0f8e9bd9601d403b4783fredc 27708d3925d3d72837e6f86c9e0beaed5f7b813ea37Pavlin Radoslavov public BluetoothCodecStatus getCodecStatus() { 27833b6b7d2b08dcd7ced1809e2ac653c5e8c2514afPavlin Radoslavov enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 27908d3925d3d72837e6f86c9e0beaed5f7b813ea37Pavlin Radoslavov if (DBG) Log.d(TAG, "getCodecStatus()"); 28008d3925d3d72837e6f86c9e0beaed5f7b813ea37Pavlin Radoslavov return mStateMachine.getCodecStatus(); 28133b6b7d2b08dcd7ced1809e2ac653c5e8c2514afPavlin Radoslavov } 28233b6b7d2b08dcd7ced1809e2ac653c5e8c2514afPavlin Radoslavov 28333b6b7d2b08dcd7ced1809e2ac653c5e8c2514afPavlin Radoslavov public void setCodecConfigPreference(BluetoothCodecConfig codecConfig) { 28433b6b7d2b08dcd7ced1809e2ac653c5e8c2514afPavlin Radoslavov enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 28533b6b7d2b08dcd7ced1809e2ac653c5e8c2514afPavlin Radoslavov if (DBG) Log.d(TAG, "setCodecConfigPreference(): " + Objects.toString(codecConfig)); 28633b6b7d2b08dcd7ced1809e2ac653c5e8c2514afPavlin Radoslavov mStateMachine.setCodecConfigPreference(codecConfig); 28733b6b7d2b08dcd7ced1809e2ac653c5e8c2514afPavlin Radoslavov } 28833b6b7d2b08dcd7ced1809e2ac653c5e8c2514afPavlin Radoslavov 2890e1abf2276c4bc7e940624da89113b23e526be7aPavlin Radoslavov public void enableOptionalCodecs() { 2900e1abf2276c4bc7e940624da89113b23e526be7aPavlin Radoslavov enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 2910e1abf2276c4bc7e940624da89113b23e526be7aPavlin Radoslavov if (DBG) Log.d(TAG, "enableOptionalCodecs()"); 2920e1abf2276c4bc7e940624da89113b23e526be7aPavlin Radoslavov mStateMachine.enableOptionalCodecs(); 2930e1abf2276c4bc7e940624da89113b23e526be7aPavlin Radoslavov } 2940e1abf2276c4bc7e940624da89113b23e526be7aPavlin Radoslavov 2950e1abf2276c4bc7e940624da89113b23e526be7aPavlin Radoslavov public void disableOptionalCodecs() { 2960e1abf2276c4bc7e940624da89113b23e526be7aPavlin Radoslavov enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 2970e1abf2276c4bc7e940624da89113b23e526be7aPavlin Radoslavov if (DBG) Log.d(TAG, "disableOptionalCodecs()"); 2980e1abf2276c4bc7e940624da89113b23e526be7aPavlin Radoslavov mStateMachine.disableOptionalCodecs(); 2990e1abf2276c4bc7e940624da89113b23e526be7aPavlin Radoslavov } 3000e1abf2276c4bc7e940624da89113b23e526be7aPavlin Radoslavov 30120155af8008337cb70ea0556472854abf46ca1ebAntony Sargent public int getSupportsOptionalCodecs(BluetoothDevice device) { 30220155af8008337cb70ea0556472854abf46ca1ebAntony Sargent enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM, "Need BLUETOOTH_ADMIN permission"); 30320155af8008337cb70ea0556472854abf46ca1ebAntony Sargent int support = Settings.Global.getInt(getContentResolver(), 30420155af8008337cb70ea0556472854abf46ca1ebAntony Sargent Settings.Global.getBluetoothA2dpSupportsOptionalCodecsKey(device.getAddress()), 30520155af8008337cb70ea0556472854abf46ca1ebAntony Sargent BluetoothA2dp.OPTIONAL_CODECS_SUPPORT_UNKNOWN); 30620155af8008337cb70ea0556472854abf46ca1ebAntony Sargent return support; 30720155af8008337cb70ea0556472854abf46ca1ebAntony Sargent } 30820155af8008337cb70ea0556472854abf46ca1ebAntony Sargent 30920155af8008337cb70ea0556472854abf46ca1ebAntony Sargent public void setSupportsOptionalCodecs(BluetoothDevice device, boolean doesSupport) { 31020155af8008337cb70ea0556472854abf46ca1ebAntony Sargent enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM, "Need BLUETOOTH_ADMIN permission"); 31120155af8008337cb70ea0556472854abf46ca1ebAntony Sargent int value = doesSupport ? BluetoothA2dp.OPTIONAL_CODECS_SUPPORTED 31220155af8008337cb70ea0556472854abf46ca1ebAntony Sargent : BluetoothA2dp.OPTIONAL_CODECS_NOT_SUPPORTED; 31320155af8008337cb70ea0556472854abf46ca1ebAntony Sargent Settings.Global.putInt(getContentResolver(), 31420155af8008337cb70ea0556472854abf46ca1ebAntony Sargent Settings.Global.getBluetoothA2dpSupportsOptionalCodecsKey(device.getAddress()), 31520155af8008337cb70ea0556472854abf46ca1ebAntony Sargent value); 31620155af8008337cb70ea0556472854abf46ca1ebAntony Sargent } 31720155af8008337cb70ea0556472854abf46ca1ebAntony Sargent 31820155af8008337cb70ea0556472854abf46ca1ebAntony Sargent public int getOptionalCodecsEnabled(BluetoothDevice device) { 31920155af8008337cb70ea0556472854abf46ca1ebAntony Sargent enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM, "Need BLUETOOTH_ADMIN permission"); 32020155af8008337cb70ea0556472854abf46ca1ebAntony Sargent return Settings.Global.getInt(getContentResolver(), 32120155af8008337cb70ea0556472854abf46ca1ebAntony Sargent Settings.Global.getBluetoothA2dpOptionalCodecsEnabledKey(device.getAddress()), 32220155af8008337cb70ea0556472854abf46ca1ebAntony Sargent BluetoothA2dp.OPTIONAL_CODECS_PREF_UNKNOWN); 32320155af8008337cb70ea0556472854abf46ca1ebAntony Sargent } 32420155af8008337cb70ea0556472854abf46ca1ebAntony Sargent 32520155af8008337cb70ea0556472854abf46ca1ebAntony Sargent public void setOptionalCodecsEnabled(BluetoothDevice device, int value) { 32620155af8008337cb70ea0556472854abf46ca1ebAntony Sargent enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM, "Need BLUETOOTH_ADMIN permission"); 32720155af8008337cb70ea0556472854abf46ca1ebAntony Sargent if (value != BluetoothA2dp.OPTIONAL_CODECS_PREF_UNKNOWN 32820155af8008337cb70ea0556472854abf46ca1ebAntony Sargent && value != BluetoothA2dp.OPTIONAL_CODECS_PREF_DISABLED 32920155af8008337cb70ea0556472854abf46ca1ebAntony Sargent && value != BluetoothA2dp.OPTIONAL_CODECS_PREF_ENABLED) { 33020155af8008337cb70ea0556472854abf46ca1ebAntony Sargent Log.w(TAG, "Unexpected value passed to setOptionalCodecsEnabled:" + value); 33120155af8008337cb70ea0556472854abf46ca1ebAntony Sargent return; 33220155af8008337cb70ea0556472854abf46ca1ebAntony Sargent } 33320155af8008337cb70ea0556472854abf46ca1ebAntony Sargent Settings.Global.putInt(getContentResolver(), 33420155af8008337cb70ea0556472854abf46ca1ebAntony Sargent Settings.Global.getBluetoothA2dpOptionalCodecsEnabledKey(device.getAddress()), 33520155af8008337cb70ea0556472854abf46ca1ebAntony Sargent value); 33620155af8008337cb70ea0556472854abf46ca1ebAntony Sargent } 33720155af8008337cb70ea0556472854abf46ca1ebAntony Sargent 33874ae04c73312403e89db0f8e9bd9601d403b4783fredc //Binder object: Must be static class or memory leak may occur 33974ae04c73312403e89db0f8e9bd9601d403b4783fredc private static class BluetoothA2dpBinder extends IBluetoothA2dp.Stub 34074ae04c73312403e89db0f8e9bd9601d403b4783fredc implements IProfileServiceBinder { 34174ae04c73312403e89db0f8e9bd9601d403b4783fredc private A2dpService mService; 34274ae04c73312403e89db0f8e9bd9601d403b4783fredc 34374ae04c73312403e89db0f8e9bd9601d403b4783fredc private A2dpService getService() { 34437510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu if (!Utils.checkCaller()) { 34537510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu Log.w(TAG,"A2dp call not allowed for non-active user"); 34637510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu return null; 34737510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu } 34837510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu 34937510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu if (mService != null && mService.isAvailable()) { 35074ae04c73312403e89db0f8e9bd9601d403b4783fredc return mService; 3516c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie } 35274ae04c73312403e89db0f8e9bd9601d403b4783fredc return null; 35374ae04c73312403e89db0f8e9bd9601d403b4783fredc } 3546c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie 35574ae04c73312403e89db0f8e9bd9601d403b4783fredc BluetoothA2dpBinder(A2dpService svc) { 35674ae04c73312403e89db0f8e9bd9601d403b4783fredc mService = svc; 35774ae04c73312403e89db0f8e9bd9601d403b4783fredc } 35874ae04c73312403e89db0f8e9bd9601d403b4783fredc 35974ae04c73312403e89db0f8e9bd9601d403b4783fredc public boolean cleanup() { 36074ae04c73312403e89db0f8e9bd9601d403b4783fredc mService = null; 3616c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie return true; 3626c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie } 3636c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie 36474ae04c73312403e89db0f8e9bd9601d403b4783fredc public boolean connect(BluetoothDevice device) { 36574ae04c73312403e89db0f8e9bd9601d403b4783fredc A2dpService service = getService(); 36674ae04c73312403e89db0f8e9bd9601d403b4783fredc if (service == null) return false; 36774ae04c73312403e89db0f8e9bd9601d403b4783fredc return service.connect(device); 36874ae04c73312403e89db0f8e9bd9601d403b4783fredc } 3696c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie 37074ae04c73312403e89db0f8e9bd9601d403b4783fredc public boolean disconnect(BluetoothDevice device) { 37174ae04c73312403e89db0f8e9bd9601d403b4783fredc A2dpService service = getService(); 37274ae04c73312403e89db0f8e9bd9601d403b4783fredc if (service == null) return false; 37374ae04c73312403e89db0f8e9bd9601d403b4783fredc return service.disconnect(device); 3746c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie } 3756c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie 3766c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie public List<BluetoothDevice> getConnectedDevices() { 37774ae04c73312403e89db0f8e9bd9601d403b4783fredc A2dpService service = getService(); 37874ae04c73312403e89db0f8e9bd9601d403b4783fredc if (service == null) return new ArrayList<BluetoothDevice>(0); 37974ae04c73312403e89db0f8e9bd9601d403b4783fredc return service.getConnectedDevices(); 3806c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie } 3816c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie 3826c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie public List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) { 38374ae04c73312403e89db0f8e9bd9601d403b4783fredc A2dpService service = getService(); 38474ae04c73312403e89db0f8e9bd9601d403b4783fredc if (service == null) return new ArrayList<BluetoothDevice>(0); 38574ae04c73312403e89db0f8e9bd9601d403b4783fredc return service.getDevicesMatchingConnectionStates(states); 3866c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie } 3876c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie 3886c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie public int getConnectionState(BluetoothDevice device) { 38974ae04c73312403e89db0f8e9bd9601d403b4783fredc A2dpService service = getService(); 39074ae04c73312403e89db0f8e9bd9601d403b4783fredc if (service == null) return BluetoothProfile.STATE_DISCONNECTED; 39174ae04c73312403e89db0f8e9bd9601d403b4783fredc return service.getConnectionState(device); 3926c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie } 3936c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie 3946c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie public boolean setPriority(BluetoothDevice device, int priority) { 39574ae04c73312403e89db0f8e9bd9601d403b4783fredc A2dpService service = getService(); 39674ae04c73312403e89db0f8e9bd9601d403b4783fredc if (service == null) return false; 39774ae04c73312403e89db0f8e9bd9601d403b4783fredc return service.setPriority(device, priority); 3986c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie } 3996c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie 4006c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie public int getPriority(BluetoothDevice device) { 40174ae04c73312403e89db0f8e9bd9601d403b4783fredc A2dpService service = getService(); 40274ae04c73312403e89db0f8e9bd9601d403b4783fredc if (service == null) return BluetoothProfile.PRIORITY_UNDEFINED; 40374ae04c73312403e89db0f8e9bd9601d403b4783fredc return service.getPriority(device); 4046c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie } 4056c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie 40617675906064bb72fdcca75baa56cdf8bb8968d01John Du public boolean isAvrcpAbsoluteVolumeSupported() { 40717675906064bb72fdcca75baa56cdf8bb8968d01John Du A2dpService service = getService(); 40817675906064bb72fdcca75baa56cdf8bb8968d01John Du if (service == null) return false; 40917675906064bb72fdcca75baa56cdf8bb8968d01John Du return service.isAvrcpAbsoluteVolumeSupported(); 41017675906064bb72fdcca75baa56cdf8bb8968d01John Du } 41117675906064bb72fdcca75baa56cdf8bb8968d01John Du 41217675906064bb72fdcca75baa56cdf8bb8968d01John Du public void adjustAvrcpAbsoluteVolume(int direction) { 41317675906064bb72fdcca75baa56cdf8bb8968d01John Du A2dpService service = getService(); 41417675906064bb72fdcca75baa56cdf8bb8968d01John Du if (service == null) return; 41517675906064bb72fdcca75baa56cdf8bb8968d01John Du service.adjustAvrcpAbsoluteVolume(direction); 41617675906064bb72fdcca75baa56cdf8bb8968d01John Du } 41717675906064bb72fdcca75baa56cdf8bb8968d01John Du 41817675906064bb72fdcca75baa56cdf8bb8968d01John Du public void setAvrcpAbsoluteVolume(int volume) { 41917675906064bb72fdcca75baa56cdf8bb8968d01John Du A2dpService service = getService(); 42017675906064bb72fdcca75baa56cdf8bb8968d01John Du if (service == null) return; 42117675906064bb72fdcca75baa56cdf8bb8968d01John Du service.setAvrcpAbsoluteVolume(volume); 42217675906064bb72fdcca75baa56cdf8bb8968d01John Du } 42317675906064bb72fdcca75baa56cdf8bb8968d01John Du 42474ae04c73312403e89db0f8e9bd9601d403b4783fredc public boolean isA2dpPlaying(BluetoothDevice device) { 42574ae04c73312403e89db0f8e9bd9601d403b4783fredc A2dpService service = getService(); 42674ae04c73312403e89db0f8e9bd9601d403b4783fredc if (service == null) return false; 42774ae04c73312403e89db0f8e9bd9601d403b4783fredc return service.isA2dpPlaying(device); 4286c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie } 42933b6b7d2b08dcd7ced1809e2ac653c5e8c2514afPavlin Radoslavov 43008d3925d3d72837e6f86c9e0beaed5f7b813ea37Pavlin Radoslavov public BluetoothCodecStatus getCodecStatus() { 43133b6b7d2b08dcd7ced1809e2ac653c5e8c2514afPavlin Radoslavov A2dpService service = getService(); 43233b6b7d2b08dcd7ced1809e2ac653c5e8c2514afPavlin Radoslavov if (service == null) return null; 43308d3925d3d72837e6f86c9e0beaed5f7b813ea37Pavlin Radoslavov return service.getCodecStatus(); 43433b6b7d2b08dcd7ced1809e2ac653c5e8c2514afPavlin Radoslavov } 43533b6b7d2b08dcd7ced1809e2ac653c5e8c2514afPavlin Radoslavov 43633b6b7d2b08dcd7ced1809e2ac653c5e8c2514afPavlin Radoslavov public void setCodecConfigPreference(BluetoothCodecConfig codecConfig) { 43733b6b7d2b08dcd7ced1809e2ac653c5e8c2514afPavlin Radoslavov A2dpService service = getService(); 43833b6b7d2b08dcd7ced1809e2ac653c5e8c2514afPavlin Radoslavov if (service == null) return; 43933b6b7d2b08dcd7ced1809e2ac653c5e8c2514afPavlin Radoslavov service.setCodecConfigPreference(codecConfig); 44033b6b7d2b08dcd7ced1809e2ac653c5e8c2514afPavlin Radoslavov } 4410e1abf2276c4bc7e940624da89113b23e526be7aPavlin Radoslavov 4420e1abf2276c4bc7e940624da89113b23e526be7aPavlin Radoslavov public void enableOptionalCodecs() { 4430e1abf2276c4bc7e940624da89113b23e526be7aPavlin Radoslavov A2dpService service = getService(); 4440e1abf2276c4bc7e940624da89113b23e526be7aPavlin Radoslavov if (service == null) return; 4450e1abf2276c4bc7e940624da89113b23e526be7aPavlin Radoslavov service.enableOptionalCodecs(); 4460e1abf2276c4bc7e940624da89113b23e526be7aPavlin Radoslavov } 4470e1abf2276c4bc7e940624da89113b23e526be7aPavlin Radoslavov 4480e1abf2276c4bc7e940624da89113b23e526be7aPavlin Radoslavov public void disableOptionalCodecs() { 4490e1abf2276c4bc7e940624da89113b23e526be7aPavlin Radoslavov A2dpService service = getService(); 4500e1abf2276c4bc7e940624da89113b23e526be7aPavlin Radoslavov if (service == null) return; 4510e1abf2276c4bc7e940624da89113b23e526be7aPavlin Radoslavov service.disableOptionalCodecs(); 4520e1abf2276c4bc7e940624da89113b23e526be7aPavlin Radoslavov } 45320155af8008337cb70ea0556472854abf46ca1ebAntony Sargent 45420155af8008337cb70ea0556472854abf46ca1ebAntony Sargent public int supportsOptionalCodecs(BluetoothDevice device) { 45520155af8008337cb70ea0556472854abf46ca1ebAntony Sargent A2dpService service = getService(); 45620155af8008337cb70ea0556472854abf46ca1ebAntony Sargent if (service == null) return BluetoothA2dp.OPTIONAL_CODECS_SUPPORT_UNKNOWN; 45720155af8008337cb70ea0556472854abf46ca1ebAntony Sargent return service.getSupportsOptionalCodecs(device); 45820155af8008337cb70ea0556472854abf46ca1ebAntony Sargent } 45920155af8008337cb70ea0556472854abf46ca1ebAntony Sargent 46020155af8008337cb70ea0556472854abf46ca1ebAntony Sargent public int getOptionalCodecsEnabled(BluetoothDevice device) { 46120155af8008337cb70ea0556472854abf46ca1ebAntony Sargent A2dpService service = getService(); 46220155af8008337cb70ea0556472854abf46ca1ebAntony Sargent if (service == null) return BluetoothA2dp.OPTIONAL_CODECS_PREF_UNKNOWN; 46320155af8008337cb70ea0556472854abf46ca1ebAntony Sargent return service.getOptionalCodecsEnabled(device); 46420155af8008337cb70ea0556472854abf46ca1ebAntony Sargent } 46520155af8008337cb70ea0556472854abf46ca1ebAntony Sargent 46620155af8008337cb70ea0556472854abf46ca1ebAntony Sargent public void setOptionalCodecsEnabled(BluetoothDevice device, int value) { 46720155af8008337cb70ea0556472854abf46ca1ebAntony Sargent A2dpService service = getService(); 46820155af8008337cb70ea0556472854abf46ca1ebAntony Sargent if (service == null) return; 46920155af8008337cb70ea0556472854abf46ca1ebAntony Sargent service.setOptionalCodecsEnabled(device, value); 47020155af8008337cb70ea0556472854abf46ca1ebAntony Sargent } 4716c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie }; 472838949d46a4cc054985a8cfd682004f8dd6d3bbbMike Lockwood 473838949d46a4cc054985a8cfd682004f8dd6d3bbbMike Lockwood @Override 474838949d46a4cc054985a8cfd682004f8dd6d3bbbMike Lockwood public void dump(StringBuilder sb) { 475838949d46a4cc054985a8cfd682004f8dd6d3bbbMike Lockwood super.dump(sb); 476838949d46a4cc054985a8cfd682004f8dd6d3bbbMike Lockwood if (mStateMachine != null) { 477838949d46a4cc054985a8cfd682004f8dd6d3bbbMike Lockwood mStateMachine.dump(sb); 478838949d46a4cc054985a8cfd682004f8dd6d3bbbMike Lockwood } 479838949d46a4cc054985a8cfd682004f8dd6d3bbbMike Lockwood if (mAvrcp != null) { 480838949d46a4cc054985a8cfd682004f8dd6d3bbbMike Lockwood mAvrcp.dump(sb); 481838949d46a4cc054985a8cfd682004f8dd6d3bbbMike Lockwood } 482838949d46a4cc054985a8cfd682004f8dd6d3bbbMike Lockwood } 4836c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie} 484