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 196c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xieimport android.bluetooth.BluetoothDevice; 206c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xieimport android.bluetooth.BluetoothProfile; 216c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xieimport android.bluetooth.IBluetoothA2dp; 226c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xieimport android.content.Context; 236c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xieimport android.content.Intent; 246c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xieimport android.provider.Settings; 256c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xieimport android.util.Log; 2637510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xuimport com.android.bluetooth.btservice.ProfileService; 2737510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xuimport com.android.bluetooth.Utils; 2874ae04c73312403e89db0f8e9bd9601d403b4783fredcimport java.util.ArrayList; 296654f5c903de510a70f9e72cd5ad7837b615d93ffredcimport java.util.Iterator; 3037510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xuimport java.util.List; 316654f5c903de510a70f9e72cd5ad7837b615d93ffredcimport java.util.Map; 326c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie 336c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie/** 346c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie * Provides Bluetooth A2DP profile, as a service in the Bluetooth application. 356c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie * @hide 366c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie */ 37b5cc776c9353a203cdde97e62b25f05d9633d14cfredcpublic class A2dpService extends ProfileService { 38fd1da115cbf09b7dd9bca3c7d3a4fb816a835dc5Matthew Xie private static final boolean DBG = false; 39b5cc776c9353a203cdde97e62b25f05d9633d14cfredc private static final String TAG="A2dpService"; 406c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie 416c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie private A2dpStateMachine mStateMachine; 42c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu private Avrcp mAvrcp; 434f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta private static A2dpService sAd2dpService; 446c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie 4574ae04c73312403e89db0f8e9bd9601d403b4783fredc protected String getName() { 4674ae04c73312403e89db0f8e9bd9601d403b4783fredc return TAG; 4774ae04c73312403e89db0f8e9bd9601d403b4783fredc } 4874ae04c73312403e89db0f8e9bd9601d403b4783fredc 4974ae04c73312403e89db0f8e9bd9601d403b4783fredc protected IProfileServiceBinder initBinder() { 5074ae04c73312403e89db0f8e9bd9601d403b4783fredc return new BluetoothA2dpBinder(this); 5174ae04c73312403e89db0f8e9bd9601d403b4783fredc } 526c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie 53b5cc776c9353a203cdde97e62b25f05d9633d14cfredc protected boolean start() { 54c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu mAvrcp = Avrcp.make(this); 55d3195daf68329036df6a01331b466844b5cb29deZhihai Xu mStateMachine = A2dpStateMachine.make(this, this); 564f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta setA2dpService(this); 57b5cc776c9353a203cdde97e62b25f05d9633d14cfredc return true; 586654f5c903de510a70f9e72cd5ad7837b615d93ffredc } 596654f5c903de510a70f9e72cd5ad7837b615d93ffredc 60b5cc776c9353a203cdde97e62b25f05d9633d14cfredc protected boolean stop() { 6115d36984a79d6e35c659edb0efdf929f0b526bd5Fred mStateMachine.doQuit(); 62c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu mAvrcp.doQuit(); 6374ae04c73312403e89db0f8e9bd9601d403b4783fredc return true; 6474ae04c73312403e89db0f8e9bd9601d403b4783fredc } 6574ae04c73312403e89db0f8e9bd9601d403b4783fredc 6674ae04c73312403e89db0f8e9bd9601d403b4783fredc protected boolean cleanup() { 676654f5c903de510a70f9e72cd5ad7837b615d93ffredc if (mStateMachine!= null) { 686654f5c903de510a70f9e72cd5ad7837b615d93ffredc mStateMachine.cleanup(); 696654f5c903de510a70f9e72cd5ad7837b615d93ffredc } 70c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu if (mAvrcp != null) { 71c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu mAvrcp.cleanup(); 72c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu mAvrcp = null; 73c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu } 744f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta clearA2dpService(); 75b5cc776c9353a203cdde97e62b25f05d9633d14cfredc return true; 76b5cc776c9353a203cdde97e62b25f05d9633d14cfredc } 776654f5c903de510a70f9e72cd5ad7837b615d93ffredc 7874ae04c73312403e89db0f8e9bd9601d403b4783fredc //API Methods 794f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta 804f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta public static synchronized A2dpService getA2dpService(){ 814f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta if (sAd2dpService != null && sAd2dpService.isAvailable()) { 824f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta if (DBG) Log.d(TAG, "getA2DPService(): returning " + sAd2dpService); 834f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta return sAd2dpService; 844f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta } 854f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta if (DBG) { 864f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta if (sAd2dpService == null) { 874f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta Log.d(TAG, "getA2dpService(): service is NULL"); 884f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta } else if (!(sAd2dpService.isAvailable())) { 894f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta Log.d(TAG,"getA2dpService(): service is not available"); 904f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta } 914f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta } 924f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta return null; 934f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta } 944f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta 954f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta private static synchronized void setA2dpService(A2dpService instance) { 964f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta if (instance != null && instance.isAvailable()) { 974f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta if (DBG) Log.d(TAG, "setA2dpService(): set to: " + sAd2dpService); 984f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta sAd2dpService = instance; 994f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta } else { 1004f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta if (DBG) { 1014f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta if (sAd2dpService == null) { 1024f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta Log.d(TAG, "setA2dpService(): service not available"); 1034f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta } else if (!sAd2dpService.isAvailable()) { 1044f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta Log.d(TAG,"setA2dpService(): service is cleaning up"); 1054f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta } 1064f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta } 1074f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta } 1084f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta } 1094f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta 1104f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta private static synchronized void clearA2dpService() { 1114f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta sAd2dpService = null; 1124f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta } 1134f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta 1144f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta public boolean connect(BluetoothDevice device) { 11574ae04c73312403e89db0f8e9bd9601d403b4783fredc enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM, 11674ae04c73312403e89db0f8e9bd9601d403b4783fredc "Need BLUETOOTH ADMIN permission"); 11774ae04c73312403e89db0f8e9bd9601d403b4783fredc 11874ae04c73312403e89db0f8e9bd9601d403b4783fredc if (getPriority(device) == BluetoothProfile.PRIORITY_OFF) { 11974ae04c73312403e89db0f8e9bd9601d403b4783fredc return false; 12074ae04c73312403e89db0f8e9bd9601d403b4783fredc } 12174ae04c73312403e89db0f8e9bd9601d403b4783fredc 12274ae04c73312403e89db0f8e9bd9601d403b4783fredc int connectionState = mStateMachine.getConnectionState(device); 12374ae04c73312403e89db0f8e9bd9601d403b4783fredc if (connectionState == BluetoothProfile.STATE_CONNECTED || 12474ae04c73312403e89db0f8e9bd9601d403b4783fredc connectionState == BluetoothProfile.STATE_CONNECTING) { 12574ae04c73312403e89db0f8e9bd9601d403b4783fredc return false; 12674ae04c73312403e89db0f8e9bd9601d403b4783fredc } 12774ae04c73312403e89db0f8e9bd9601d403b4783fredc 12874ae04c73312403e89db0f8e9bd9601d403b4783fredc mStateMachine.sendMessage(A2dpStateMachine.CONNECT, device); 12974ae04c73312403e89db0f8e9bd9601d403b4783fredc return true; 130b5cc776c9353a203cdde97e62b25f05d9633d14cfredc } 131b5cc776c9353a203cdde97e62b25f05d9633d14cfredc 13274ae04c73312403e89db0f8e9bd9601d403b4783fredc boolean disconnect(BluetoothDevice device) { 13374ae04c73312403e89db0f8e9bd9601d403b4783fredc enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM, 13474ae04c73312403e89db0f8e9bd9601d403b4783fredc "Need BLUETOOTH ADMIN permission"); 13574ae04c73312403e89db0f8e9bd9601d403b4783fredc int connectionState = mStateMachine.getConnectionState(device); 13674ae04c73312403e89db0f8e9bd9601d403b4783fredc if (connectionState != BluetoothProfile.STATE_CONNECTED && 13774ae04c73312403e89db0f8e9bd9601d403b4783fredc connectionState != BluetoothProfile.STATE_CONNECTING) { 13874ae04c73312403e89db0f8e9bd9601d403b4783fredc return false; 13974ae04c73312403e89db0f8e9bd9601d403b4783fredc } 14074ae04c73312403e89db0f8e9bd9601d403b4783fredc 14174ae04c73312403e89db0f8e9bd9601d403b4783fredc mStateMachine.sendMessage(A2dpStateMachine.DISCONNECT, device); 14274ae04c73312403e89db0f8e9bd9601d403b4783fredc return true; 1436c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie } 1446c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie 1454f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta public List<BluetoothDevice> getConnectedDevices() { 14674ae04c73312403e89db0f8e9bd9601d403b4783fredc enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 14774ae04c73312403e89db0f8e9bd9601d403b4783fredc return mStateMachine.getConnectedDevices(); 14874ae04c73312403e89db0f8e9bd9601d403b4783fredc } 1496c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie 15074ae04c73312403e89db0f8e9bd9601d403b4783fredc List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) { 15174ae04c73312403e89db0f8e9bd9601d403b4783fredc enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 15274ae04c73312403e89db0f8e9bd9601d403b4783fredc return mStateMachine.getDevicesMatchingConnectionStates(states); 15374ae04c73312403e89db0f8e9bd9601d403b4783fredc } 1546c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie 15574ae04c73312403e89db0f8e9bd9601d403b4783fredc int getConnectionState(BluetoothDevice device) { 15674ae04c73312403e89db0f8e9bd9601d403b4783fredc enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 15774ae04c73312403e89db0f8e9bd9601d403b4783fredc return mStateMachine.getConnectionState(device); 15874ae04c73312403e89db0f8e9bd9601d403b4783fredc } 15974ae04c73312403e89db0f8e9bd9601d403b4783fredc 1604f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta public boolean setPriority(BluetoothDevice device, int priority) { 16174ae04c73312403e89db0f8e9bd9601d403b4783fredc enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM, 16274ae04c73312403e89db0f8e9bd9601d403b4783fredc "Need BLUETOOTH_ADMIN permission"); 163c7ead6d5827f3832b9210e92fab7597142059852Jeff Sharkey Settings.Global.putInt(getContentResolver(), 164c7ead6d5827f3832b9210e92fab7597142059852Jeff Sharkey Settings.Global.getBluetoothA2dpSinkPriorityKey(device.getAddress()), 16574ae04c73312403e89db0f8e9bd9601d403b4783fredc priority); 16674ae04c73312403e89db0f8e9bd9601d403b4783fredc if (DBG) Log.d(TAG,"Saved priority " + device + " = " + priority); 16774ae04c73312403e89db0f8e9bd9601d403b4783fredc return true; 16874ae04c73312403e89db0f8e9bd9601d403b4783fredc } 1696c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie 1704f5430babbc5a8f870e5a578a4ea3452f41dd97aGanesh Ganapathi Batta public int getPriority(BluetoothDevice device) { 17174ae04c73312403e89db0f8e9bd9601d403b4783fredc enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM, 17274ae04c73312403e89db0f8e9bd9601d403b4783fredc "Need BLUETOOTH_ADMIN permission"); 173c7ead6d5827f3832b9210e92fab7597142059852Jeff Sharkey int priority = Settings.Global.getInt(getContentResolver(), 174c7ead6d5827f3832b9210e92fab7597142059852Jeff Sharkey Settings.Global.getBluetoothA2dpSinkPriorityKey(device.getAddress()), 17574ae04c73312403e89db0f8e9bd9601d403b4783fredc BluetoothProfile.PRIORITY_UNDEFINED); 17674ae04c73312403e89db0f8e9bd9601d403b4783fredc return priority; 17774ae04c73312403e89db0f8e9bd9601d403b4783fredc } 17874ae04c73312403e89db0f8e9bd9601d403b4783fredc 17917675906064bb72fdcca75baa56cdf8bb8968d01John Du /* Absolute volume implementation */ 18017675906064bb72fdcca75baa56cdf8bb8968d01John Du public boolean isAvrcpAbsoluteVolumeSupported() { 18117675906064bb72fdcca75baa56cdf8bb8968d01John Du return mAvrcp.isAbsoluteVolumeSupported(); 18217675906064bb72fdcca75baa56cdf8bb8968d01John Du } 18317675906064bb72fdcca75baa56cdf8bb8968d01John Du 18417675906064bb72fdcca75baa56cdf8bb8968d01John Du public void adjustAvrcpAbsoluteVolume(int direction) { 18517675906064bb72fdcca75baa56cdf8bb8968d01John Du mAvrcp.adjustVolume(direction); 18617675906064bb72fdcca75baa56cdf8bb8968d01John Du } 18717675906064bb72fdcca75baa56cdf8bb8968d01John Du 18817675906064bb72fdcca75baa56cdf8bb8968d01John Du public void setAvrcpAbsoluteVolume(int volume) { 18917675906064bb72fdcca75baa56cdf8bb8968d01John Du mAvrcp.setAbsoluteVolume(volume); 19017675906064bb72fdcca75baa56cdf8bb8968d01John Du } 19117675906064bb72fdcca75baa56cdf8bb8968d01John Du 192d3195daf68329036df6a01331b466844b5cb29deZhihai Xu public void setAvrcpAudioState(int state) { 193d3195daf68329036df6a01331b466844b5cb29deZhihai Xu mAvrcp.setA2dpAudioState(state); 194d3195daf68329036df6a01331b466844b5cb29deZhihai Xu } 195d3195daf68329036df6a01331b466844b5cb29deZhihai Xu 19674ae04c73312403e89db0f8e9bd9601d403b4783fredc synchronized boolean isA2dpPlaying(BluetoothDevice device) { 19774ae04c73312403e89db0f8e9bd9601d403b4783fredc enforceCallingOrSelfPermission(BLUETOOTH_PERM, 19874ae04c73312403e89db0f8e9bd9601d403b4783fredc "Need BLUETOOTH permission"); 19974ae04c73312403e89db0f8e9bd9601d403b4783fredc if (DBG) Log.d(TAG, "isA2dpPlaying(" + device + ")"); 20074ae04c73312403e89db0f8e9bd9601d403b4783fredc return mStateMachine.isPlaying(device); 20174ae04c73312403e89db0f8e9bd9601d403b4783fredc } 20274ae04c73312403e89db0f8e9bd9601d403b4783fredc 20374ae04c73312403e89db0f8e9bd9601d403b4783fredc //Binder object: Must be static class or memory leak may occur 20474ae04c73312403e89db0f8e9bd9601d403b4783fredc private static class BluetoothA2dpBinder extends IBluetoothA2dp.Stub 20574ae04c73312403e89db0f8e9bd9601d403b4783fredc implements IProfileServiceBinder { 20674ae04c73312403e89db0f8e9bd9601d403b4783fredc private A2dpService mService; 20774ae04c73312403e89db0f8e9bd9601d403b4783fredc 20874ae04c73312403e89db0f8e9bd9601d403b4783fredc private A2dpService getService() { 20937510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu if (!Utils.checkCaller()) { 21037510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu Log.w(TAG,"A2dp call not allowed for non-active user"); 21137510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu return null; 21237510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu } 21337510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu 21437510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu if (mService != null && mService.isAvailable()) { 21574ae04c73312403e89db0f8e9bd9601d403b4783fredc return mService; 2166c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie } 21774ae04c73312403e89db0f8e9bd9601d403b4783fredc return null; 21874ae04c73312403e89db0f8e9bd9601d403b4783fredc } 2196c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie 22074ae04c73312403e89db0f8e9bd9601d403b4783fredc BluetoothA2dpBinder(A2dpService svc) { 22174ae04c73312403e89db0f8e9bd9601d403b4783fredc mService = svc; 22274ae04c73312403e89db0f8e9bd9601d403b4783fredc } 22374ae04c73312403e89db0f8e9bd9601d403b4783fredc 22474ae04c73312403e89db0f8e9bd9601d403b4783fredc public boolean cleanup() { 22574ae04c73312403e89db0f8e9bd9601d403b4783fredc mService = null; 2266c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie return true; 2276c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie } 2286c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie 22974ae04c73312403e89db0f8e9bd9601d403b4783fredc public boolean connect(BluetoothDevice device) { 23074ae04c73312403e89db0f8e9bd9601d403b4783fredc A2dpService service = getService(); 23174ae04c73312403e89db0f8e9bd9601d403b4783fredc if (service == null) return false; 23274ae04c73312403e89db0f8e9bd9601d403b4783fredc return service.connect(device); 23374ae04c73312403e89db0f8e9bd9601d403b4783fredc } 2346c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie 23574ae04c73312403e89db0f8e9bd9601d403b4783fredc public boolean disconnect(BluetoothDevice device) { 23674ae04c73312403e89db0f8e9bd9601d403b4783fredc A2dpService service = getService(); 23774ae04c73312403e89db0f8e9bd9601d403b4783fredc if (service == null) return false; 23874ae04c73312403e89db0f8e9bd9601d403b4783fredc return service.disconnect(device); 2396c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie } 2406c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie 2416c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie public List<BluetoothDevice> getConnectedDevices() { 24274ae04c73312403e89db0f8e9bd9601d403b4783fredc A2dpService service = getService(); 24374ae04c73312403e89db0f8e9bd9601d403b4783fredc if (service == null) return new ArrayList<BluetoothDevice>(0); 24474ae04c73312403e89db0f8e9bd9601d403b4783fredc return service.getConnectedDevices(); 2456c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie } 2466c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie 2476c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie public List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) { 24874ae04c73312403e89db0f8e9bd9601d403b4783fredc A2dpService service = getService(); 24974ae04c73312403e89db0f8e9bd9601d403b4783fredc if (service == null) return new ArrayList<BluetoothDevice>(0); 25074ae04c73312403e89db0f8e9bd9601d403b4783fredc return service.getDevicesMatchingConnectionStates(states); 2516c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie } 2526c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie 2536c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie public int getConnectionState(BluetoothDevice device) { 25474ae04c73312403e89db0f8e9bd9601d403b4783fredc A2dpService service = getService(); 25574ae04c73312403e89db0f8e9bd9601d403b4783fredc if (service == null) return BluetoothProfile.STATE_DISCONNECTED; 25674ae04c73312403e89db0f8e9bd9601d403b4783fredc return service.getConnectionState(device); 2576c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie } 2586c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie 2596c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie public boolean setPriority(BluetoothDevice device, int priority) { 26074ae04c73312403e89db0f8e9bd9601d403b4783fredc A2dpService service = getService(); 26174ae04c73312403e89db0f8e9bd9601d403b4783fredc if (service == null) return false; 26274ae04c73312403e89db0f8e9bd9601d403b4783fredc return service.setPriority(device, priority); 2636c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie } 2646c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie 2656c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie public int getPriority(BluetoothDevice device) { 26674ae04c73312403e89db0f8e9bd9601d403b4783fredc A2dpService service = getService(); 26774ae04c73312403e89db0f8e9bd9601d403b4783fredc if (service == null) return BluetoothProfile.PRIORITY_UNDEFINED; 26874ae04c73312403e89db0f8e9bd9601d403b4783fredc return service.getPriority(device); 2696c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie } 2706c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie 27117675906064bb72fdcca75baa56cdf8bb8968d01John Du public boolean isAvrcpAbsoluteVolumeSupported() { 27217675906064bb72fdcca75baa56cdf8bb8968d01John Du A2dpService service = getService(); 27317675906064bb72fdcca75baa56cdf8bb8968d01John Du if (service == null) return false; 27417675906064bb72fdcca75baa56cdf8bb8968d01John Du return service.isAvrcpAbsoluteVolumeSupported(); 27517675906064bb72fdcca75baa56cdf8bb8968d01John Du } 27617675906064bb72fdcca75baa56cdf8bb8968d01John Du 27717675906064bb72fdcca75baa56cdf8bb8968d01John Du public void adjustAvrcpAbsoluteVolume(int direction) { 27817675906064bb72fdcca75baa56cdf8bb8968d01John Du A2dpService service = getService(); 27917675906064bb72fdcca75baa56cdf8bb8968d01John Du if (service == null) return; 28017675906064bb72fdcca75baa56cdf8bb8968d01John Du service.adjustAvrcpAbsoluteVolume(direction); 28117675906064bb72fdcca75baa56cdf8bb8968d01John Du } 28217675906064bb72fdcca75baa56cdf8bb8968d01John Du 28317675906064bb72fdcca75baa56cdf8bb8968d01John Du public void setAvrcpAbsoluteVolume(int volume) { 28417675906064bb72fdcca75baa56cdf8bb8968d01John Du A2dpService service = getService(); 28517675906064bb72fdcca75baa56cdf8bb8968d01John Du if (service == null) return; 28617675906064bb72fdcca75baa56cdf8bb8968d01John Du service.setAvrcpAbsoluteVolume(volume); 28717675906064bb72fdcca75baa56cdf8bb8968d01John Du } 28817675906064bb72fdcca75baa56cdf8bb8968d01John Du 28974ae04c73312403e89db0f8e9bd9601d403b4783fredc public boolean isA2dpPlaying(BluetoothDevice device) { 29074ae04c73312403e89db0f8e9bd9601d403b4783fredc A2dpService service = getService(); 29174ae04c73312403e89db0f8e9bd9601d403b4783fredc if (service == null) return false; 29274ae04c73312403e89db0f8e9bd9601d403b4783fredc return service.isA2dpPlaying(device); 2936c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie } 2946c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie }; 2956c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie} 296