A2dpService.java revision 4f5430babbc5a8f870e5a578a4ea3452f41dd97a
1/* 2 * Copyright (C) 2012 Google Inc. 3 */ 4package com.android.bluetooth.a2dp; 5 6import android.bluetooth.BluetoothDevice; 7import android.bluetooth.BluetoothProfile; 8import android.bluetooth.IBluetoothA2dp; 9import android.content.Context; 10import android.content.Intent; 11import android.provider.Settings; 12import android.util.Log; 13import java.util.ArrayList; 14import java.util.List; 15import java.util.Iterator; 16import java.util.Map; 17import com.android.bluetooth.btservice.ProfileService; 18 19/** 20 * Provides Bluetooth A2DP profile, as a service in the Bluetooth application. 21 * @hide 22 */ 23public class A2dpService extends ProfileService { 24 private static final boolean DBG = true; 25 private static final String TAG="A2dpService"; 26 27 private A2dpStateMachine mStateMachine; 28 private static A2dpService sAd2dpService; 29 30 protected String getName() { 31 return TAG; 32 } 33 34 protected IProfileServiceBinder initBinder() { 35 return new BluetoothA2dpBinder(this); 36 } 37 38 protected boolean start() { 39 mStateMachine = new A2dpStateMachine(this,this); 40 mStateMachine.start(); 41 setA2dpService(this); 42 return true; 43 } 44 45 protected boolean stop() { 46 // TODO(BT) mStateMachine.quit(); 47 return true; 48 } 49 50 protected boolean cleanup() { 51 if (mStateMachine!= null) { 52 mStateMachine.cleanup(); 53 mStateMachine=null; 54 } 55 clearA2dpService(); 56 return true; 57 } 58 59 //API Methods 60 61 public static synchronized A2dpService getA2dpService(){ 62 if (sAd2dpService != null && sAd2dpService.isAvailable()) { 63 if (DBG) Log.d(TAG, "getA2DPService(): returning " + sAd2dpService); 64 return sAd2dpService; 65 } 66 if (DBG) { 67 if (sAd2dpService == null) { 68 Log.d(TAG, "getA2dpService(): service is NULL"); 69 } else if (!(sAd2dpService.isAvailable())) { 70 Log.d(TAG,"getA2dpService(): service is not available"); 71 } 72 } 73 return null; 74 } 75 76 private static synchronized void setA2dpService(A2dpService instance) { 77 if (instance != null && instance.isAvailable()) { 78 if (DBG) Log.d(TAG, "setA2dpService(): set to: " + sAd2dpService); 79 sAd2dpService = instance; 80 } else { 81 if (DBG) { 82 if (sAd2dpService == null) { 83 Log.d(TAG, "setA2dpService(): service not available"); 84 } else if (!sAd2dpService.isAvailable()) { 85 Log.d(TAG,"setA2dpService(): service is cleaning up"); 86 } 87 } 88 } 89 } 90 91 private static synchronized void clearA2dpService() { 92 sAd2dpService = null; 93 } 94 95 public boolean connect(BluetoothDevice device) { 96 enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM, 97 "Need BLUETOOTH ADMIN permission"); 98 99 if (getPriority(device) == BluetoothProfile.PRIORITY_OFF) { 100 return false; 101 } 102 103 int connectionState = mStateMachine.getConnectionState(device); 104 if (connectionState == BluetoothProfile.STATE_CONNECTED || 105 connectionState == BluetoothProfile.STATE_CONNECTING) { 106 return false; 107 } 108 109 mStateMachine.sendMessage(A2dpStateMachine.CONNECT, device); 110 return true; 111 } 112 113 boolean disconnect(BluetoothDevice device) { 114 enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM, 115 "Need BLUETOOTH ADMIN permission"); 116 int connectionState = mStateMachine.getConnectionState(device); 117 if (connectionState != BluetoothProfile.STATE_CONNECTED && 118 connectionState != BluetoothProfile.STATE_CONNECTING) { 119 return false; 120 } 121 122 mStateMachine.sendMessage(A2dpStateMachine.DISCONNECT, device); 123 return true; 124 } 125 126 public List<BluetoothDevice> getConnectedDevices() { 127 enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 128 return mStateMachine.getConnectedDevices(); 129 } 130 131 List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) { 132 enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 133 return mStateMachine.getDevicesMatchingConnectionStates(states); 134 } 135 136 int getConnectionState(BluetoothDevice device) { 137 enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 138 return mStateMachine.getConnectionState(device); 139 } 140 141 public boolean setPriority(BluetoothDevice device, int priority) { 142 enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM, 143 "Need BLUETOOTH_ADMIN permission"); 144 Settings.Secure.putInt(getContentResolver(), 145 Settings.Secure.getBluetoothA2dpSinkPriorityKey(device.getAddress()), 146 priority); 147 if (DBG) Log.d(TAG,"Saved priority " + device + " = " + priority); 148 return true; 149 } 150 151 public int getPriority(BluetoothDevice device) { 152 enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM, 153 "Need BLUETOOTH_ADMIN permission"); 154 int priority = Settings.Secure.getInt(getContentResolver(), 155 Settings.Secure.getBluetoothA2dpSinkPriorityKey(device.getAddress()), 156 BluetoothProfile.PRIORITY_UNDEFINED); 157 return priority; 158 } 159 160 synchronized boolean isA2dpPlaying(BluetoothDevice device) { 161 enforceCallingOrSelfPermission(BLUETOOTH_PERM, 162 "Need BLUETOOTH permission"); 163 if (DBG) Log.d(TAG, "isA2dpPlaying(" + device + ")"); 164 return mStateMachine.isPlaying(device); 165 } 166 167 //Binder object: Must be static class or memory leak may occur 168 private static class BluetoothA2dpBinder extends IBluetoothA2dp.Stub 169 implements IProfileServiceBinder { 170 private A2dpService mService; 171 172 private A2dpService getService() { 173 if (mService != null && mService.isAvailable()) { 174 return mService; 175 } 176 return null; 177 } 178 179 BluetoothA2dpBinder(A2dpService svc) { 180 mService = svc; 181 } 182 183 public boolean cleanup() { 184 mService = null; 185 return true; 186 } 187 188 public boolean connect(BluetoothDevice device) { 189 A2dpService service = getService(); 190 if (service == null) return false; 191 return service.connect(device); 192 } 193 194 public boolean disconnect(BluetoothDevice device) { 195 A2dpService service = getService(); 196 if (service == null) return false; 197 return service.disconnect(device); 198 } 199 200 public List<BluetoothDevice> getConnectedDevices() { 201 A2dpService service = getService(); 202 if (service == null) return new ArrayList<BluetoothDevice>(0); 203 return service.getConnectedDevices(); 204 } 205 206 public List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) { 207 A2dpService service = getService(); 208 if (service == null) return new ArrayList<BluetoothDevice>(0); 209 return service.getDevicesMatchingConnectionStates(states); 210 } 211 212 public int getConnectionState(BluetoothDevice device) { 213 A2dpService service = getService(); 214 if (service == null) return BluetoothProfile.STATE_DISCONNECTED; 215 return service.getConnectionState(device); 216 } 217 218 public boolean setPriority(BluetoothDevice device, int priority) { 219 A2dpService service = getService(); 220 if (service == null) return false; 221 return service.setPriority(device, priority); 222 } 223 224 public int getPriority(BluetoothDevice device) { 225 A2dpService service = getService(); 226 if (service == null) return BluetoothProfile.PRIORITY_UNDEFINED; 227 return service.getPriority(device); 228 } 229 230 public boolean isA2dpPlaying(BluetoothDevice device) { 231 A2dpService service = getService(); 232 if (service == null) return false; 233 return service.isA2dpPlaying(device); 234 } 235 }; 236} 237