• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2012 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.bluetooth.a2dp;
18 
19 import android.bluetooth.BluetoothDevice;
20 import android.bluetooth.BluetoothProfile;
21 import android.bluetooth.IBluetoothA2dp;
22 import android.content.Context;
23 import android.content.Intent;
24 import android.provider.Settings;
25 import android.util.Log;
26 import com.android.bluetooth.btservice.ProfileService;
27 import com.android.bluetooth.Utils;
28 import java.util.ArrayList;
29 import java.util.Iterator;
30 import java.util.List;
31 import java.util.Map;
32 
33 /**
34  * Provides Bluetooth A2DP profile, as a service in the Bluetooth application.
35  * @hide
36  */
37 public class A2dpService extends ProfileService {
38     private static final boolean DBG = false;
39     private static final String TAG="A2dpService";
40 
41     private A2dpStateMachine mStateMachine;
42     private static A2dpService sAd2dpService;
43 
getName()44     protected String getName() {
45         return TAG;
46     }
47 
initBinder()48     protected IProfileServiceBinder initBinder() {
49         return new BluetoothA2dpBinder(this);
50     }
51 
start()52     protected boolean start() {
53         mStateMachine = A2dpStateMachine.make(this, this);
54         setA2dpService(this);
55         return true;
56     }
57 
stop()58     protected boolean stop() {
59         mStateMachine.doQuit();
60         return true;
61     }
62 
cleanup()63     protected boolean cleanup() {
64         if (mStateMachine!= null) {
65             mStateMachine.cleanup();
66         }
67         clearA2dpService();
68         return true;
69     }
70 
71     //API Methods
72 
getA2dpService()73     public static synchronized A2dpService getA2dpService(){
74         if (sAd2dpService != null && sAd2dpService.isAvailable()) {
75             if (DBG) Log.d(TAG, "getA2DPService(): returning " + sAd2dpService);
76             return sAd2dpService;
77         }
78         if (DBG)  {
79             if (sAd2dpService == null) {
80                 Log.d(TAG, "getA2dpService(): service is NULL");
81             } else if (!(sAd2dpService.isAvailable())) {
82                 Log.d(TAG,"getA2dpService(): service is not available");
83             }
84         }
85         return null;
86     }
87 
setA2dpService(A2dpService instance)88     private static synchronized void setA2dpService(A2dpService instance) {
89         if (instance != null && instance.isAvailable()) {
90             if (DBG) Log.d(TAG, "setA2dpService(): set to: " + sAd2dpService);
91             sAd2dpService = instance;
92         } else {
93             if (DBG)  {
94                 if (sAd2dpService == null) {
95                     Log.d(TAG, "setA2dpService(): service not available");
96                 } else if (!sAd2dpService.isAvailable()) {
97                     Log.d(TAG,"setA2dpService(): service is cleaning up");
98                 }
99             }
100         }
101     }
102 
clearA2dpService()103     private static synchronized void clearA2dpService() {
104         sAd2dpService = null;
105     }
106 
connect(BluetoothDevice device)107     public boolean connect(BluetoothDevice device) {
108         enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM,
109                                        "Need BLUETOOTH ADMIN permission");
110 
111         if (getPriority(device) == BluetoothProfile.PRIORITY_OFF) {
112             return false;
113         }
114 
115         int connectionState = mStateMachine.getConnectionState(device);
116         if (connectionState == BluetoothProfile.STATE_CONNECTED ||
117             connectionState == BluetoothProfile.STATE_CONNECTING) {
118             return false;
119         }
120 
121         mStateMachine.sendMessage(A2dpStateMachine.CONNECT, device);
122         return true;
123     }
124 
disconnect(BluetoothDevice device)125     boolean disconnect(BluetoothDevice device) {
126         enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM,
127                                        "Need BLUETOOTH ADMIN permission");
128         int connectionState = mStateMachine.getConnectionState(device);
129         if (connectionState != BluetoothProfile.STATE_CONNECTED &&
130             connectionState != BluetoothProfile.STATE_CONNECTING) {
131             return false;
132         }
133 
134         mStateMachine.sendMessage(A2dpStateMachine.DISCONNECT, device);
135         return true;
136     }
137 
getConnectedDevices()138     public List<BluetoothDevice> getConnectedDevices() {
139         enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
140         return mStateMachine.getConnectedDevices();
141     }
142 
getDevicesMatchingConnectionStates(int[] states)143     List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) {
144         enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
145         return mStateMachine.getDevicesMatchingConnectionStates(states);
146     }
147 
getConnectionState(BluetoothDevice device)148     int getConnectionState(BluetoothDevice device) {
149         enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
150         return mStateMachine.getConnectionState(device);
151     }
152 
setPriority(BluetoothDevice device, int priority)153     public boolean setPriority(BluetoothDevice device, int priority) {
154         enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM,
155                                        "Need BLUETOOTH_ADMIN permission");
156         Settings.Global.putInt(getContentResolver(),
157             Settings.Global.getBluetoothA2dpSinkPriorityKey(device.getAddress()),
158             priority);
159         if (DBG) Log.d(TAG,"Saved priority " + device + " = " + priority);
160         return true;
161     }
162 
getPriority(BluetoothDevice device)163     public int getPriority(BluetoothDevice device) {
164         enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM,
165                                        "Need BLUETOOTH_ADMIN permission");
166         int priority = Settings.Global.getInt(getContentResolver(),
167             Settings.Global.getBluetoothA2dpSinkPriorityKey(device.getAddress()),
168             BluetoothProfile.PRIORITY_UNDEFINED);
169         return priority;
170     }
171 
isA2dpPlaying(BluetoothDevice device)172     synchronized boolean isA2dpPlaying(BluetoothDevice device) {
173         enforceCallingOrSelfPermission(BLUETOOTH_PERM,
174                                        "Need BLUETOOTH permission");
175         if (DBG) Log.d(TAG, "isA2dpPlaying(" + device + ")");
176         return mStateMachine.isPlaying(device);
177     }
178 
179     //Binder object: Must be static class or memory leak may occur
180     private static class BluetoothA2dpBinder extends IBluetoothA2dp.Stub
181         implements IProfileServiceBinder {
182         private A2dpService mService;
183 
getService()184         private A2dpService getService() {
185             if (!Utils.checkCaller()) {
186                 Log.w(TAG,"A2dp call not allowed for non-active user");
187                 return null;
188             }
189 
190             if (mService != null && mService.isAvailable()) {
191                 return mService;
192             }
193             return null;
194         }
195 
BluetoothA2dpBinder(A2dpService svc)196         BluetoothA2dpBinder(A2dpService svc) {
197             mService = svc;
198         }
199 
cleanup()200         public boolean cleanup()  {
201             mService = null;
202             return true;
203         }
204 
connect(BluetoothDevice device)205         public boolean connect(BluetoothDevice device) {
206             A2dpService service = getService();
207             if (service == null) return false;
208             return service.connect(device);
209         }
210 
disconnect(BluetoothDevice device)211         public boolean disconnect(BluetoothDevice device) {
212             A2dpService service = getService();
213             if (service == null) return false;
214             return service.disconnect(device);
215         }
216 
getConnectedDevices()217         public List<BluetoothDevice> getConnectedDevices() {
218             A2dpService service = getService();
219             if (service == null) return new ArrayList<BluetoothDevice>(0);
220             return service.getConnectedDevices();
221         }
222 
getDevicesMatchingConnectionStates(int[] states)223         public List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) {
224             A2dpService service = getService();
225             if (service == null) return new ArrayList<BluetoothDevice>(0);
226             return service.getDevicesMatchingConnectionStates(states);
227         }
228 
getConnectionState(BluetoothDevice device)229         public int getConnectionState(BluetoothDevice device) {
230             A2dpService service = getService();
231             if (service == null) return BluetoothProfile.STATE_DISCONNECTED;
232             return service.getConnectionState(device);
233         }
234 
setPriority(BluetoothDevice device, int priority)235         public boolean setPriority(BluetoothDevice device, int priority) {
236             A2dpService service = getService();
237             if (service == null) return false;
238             return service.setPriority(device, priority);
239         }
240 
getPriority(BluetoothDevice device)241         public int getPriority(BluetoothDevice device) {
242             A2dpService service = getService();
243             if (service == null) return BluetoothProfile.PRIORITY_UNDEFINED;
244             return service.getPriority(device);
245         }
246 
isA2dpPlaying(BluetoothDevice device)247         public boolean isA2dpPlaying(BluetoothDevice device) {
248             A2dpService service = getService();
249             if (service == null) return false;
250             return service.isA2dpPlaying(device);
251         }
252     };
253 }
254