• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2017 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 package com.android.car;
17 
18 
19 import android.bluetooth.BluetoothProfile;
20 import android.bluetooth.BluetoothA2dpSink;
21 import android.bluetooth.BluetoothAdapter;
22 import android.bluetooth.BluetoothDevice;
23 import android.bluetooth.BluetoothHeadsetClient;
24 import android.bluetooth.BluetoothMapClient;
25 import android.bluetooth.BluetoothPbapClient;
26 import android.bluetooth.BluetoothPan;
27 import android.car.ICarBluetoothUserService;
28 import android.util.Log;
29 
30 import java.util.Arrays;
31 import java.util.List;
32 
33 
34 public class CarBluetoothUserService extends ICarBluetoothUserService.Stub {
35     private static final boolean DBG = true;
36     private static final String TAG = "CarBluetoothUsrSvc";
37     private BluetoothAdapter mBluetoothAdapter = null;
38     private final PerUserCarService mService;
39     // Profile Proxies.
40     private BluetoothA2dpSink mBluetoothA2dpSink = null;
41     private BluetoothHeadsetClient mBluetoothHeadsetClient = null;
42     private BluetoothPbapClient mBluetoothPbapClient = null;
43     private BluetoothMapClient mBluetoothMapClient = null;
44     private BluetoothPan mBluetoothPan = null;
45     private List<Integer> mProfilesToConnect;
46 
CarBluetoothUserService(PerUserCarService service)47     public CarBluetoothUserService(PerUserCarService service) {
48         mService = service;
49         mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
50         mProfilesToConnect = Arrays.asList(
51                 BluetoothProfile.HEADSET_CLIENT,
52                 BluetoothProfile.PBAP_CLIENT,
53                 BluetoothProfile.A2DP_SINK,
54                 BluetoothProfile.MAP_CLIENT,
55                 BluetoothProfile.PAN);
56     }
57 
58     /**
59      * Setup connections to the profile proxy object to talk to the Bluetooth profile services
60      */
61     @Override
setupBluetoothConnectionProxy()62     public void setupBluetoothConnectionProxy() {
63         if (DBG) {
64             Log.d(TAG, "setupProfileProxy()");
65         }
66         if (mBluetoothAdapter == null) {
67             Log.d(TAG, "Null BT Adapter");
68             return;
69         }
70         for (Integer profile : mProfilesToConnect) {
71             mBluetoothAdapter.getProfileProxy(mService.getApplicationContext(), mProfileListener,
72                     profile);
73         }
74     }
75 
76     /**
77      * Close connections to the profile proxy object
78      */
79     @Override
closeBluetoothConnectionProxy()80     public void closeBluetoothConnectionProxy() {
81         if (mBluetoothAdapter == null) {
82             return;
83         }
84         if (DBG) {
85             Log.d(TAG, "closeProfileProxy()");
86         }
87         // Close those profile proxy objects for profiles that have not yet disconnected
88         if (mBluetoothA2dpSink != null) {
89             mBluetoothAdapter.closeProfileProxy(BluetoothProfile.A2DP_SINK, mBluetoothA2dpSink);
90         }
91         if (mBluetoothHeadsetClient != null) {
92             mBluetoothAdapter.closeProfileProxy(BluetoothProfile.HEADSET_CLIENT,
93                     mBluetoothHeadsetClient);
94         }
95         if (mBluetoothPbapClient != null) {
96             mBluetoothAdapter.closeProfileProxy(BluetoothProfile.PBAP_CLIENT, mBluetoothPbapClient);
97         }
98         if (mBluetoothMapClient != null) {
99             mBluetoothAdapter.closeProfileProxy(BluetoothProfile.MAP_CLIENT, mBluetoothMapClient);
100         }
101         if (mBluetoothPan != null) {
102             mBluetoothAdapter.closeProfileProxy(BluetoothProfile.PAN, mBluetoothPan);
103         }
104     }
105 
106     /**
107      * Check if a proxy is available for the given profile to talk to the Profile's bluetooth
108      * service.
109      * @param profile - Bluetooth profile to check for
110      * @return - true if proxy available, false if not.
111      */
112     @Override
isBluetoothConnectionProxyAvailable(int profile)113     public boolean isBluetoothConnectionProxyAvailable(int profile) {
114         switch (profile) {
115             case BluetoothProfile.A2DP_SINK:
116                 if (mBluetoothA2dpSink != null) {
117                     return true;
118                 }
119                 break;
120             case BluetoothProfile.HEADSET_CLIENT:
121                 if (mBluetoothHeadsetClient != null) {
122                     return true;
123                 }
124                 break;
125             case BluetoothProfile.PBAP_CLIENT:
126                 if (mBluetoothPbapClient != null) {
127                     return true;
128                 }
129                 break;
130             case BluetoothProfile.MAP_CLIENT:
131                 if (mBluetoothMapClient != null) {
132                     return true;
133                 }
134                 break;
135             case BluetoothProfile.PAN:
136                 if (mBluetoothPan != null) {
137                     return true;
138                 }
139                 break;
140         }
141         return false;
142     }
143 
144     @Override
bluetoothConnectToProfile(int profile, BluetoothDevice device)145     public void bluetoothConnectToProfile(int profile, BluetoothDevice device) {
146         if (!isBluetoothConnectionProxyAvailable(profile)) {
147             Log.e(TAG, "Cannot connect to Profile. Proxy Unavailable");
148             return;
149         }
150         if (DBG) {
151             Log.d(TAG, "Trying to connect to " + device.getName() + " Profile: " + profile);
152         }
153         switch (profile) {
154             case BluetoothProfile.A2DP_SINK:
155                 mBluetoothA2dpSink.connect(device);
156                 break;
157 
158             case BluetoothProfile.HEADSET_CLIENT:
159                 mBluetoothHeadsetClient.connect(device);
160                 break;
161 
162             case BluetoothProfile.MAP_CLIENT:
163                 mBluetoothMapClient.connect(device);
164                 break;
165 
166             case BluetoothProfile.PBAP_CLIENT:
167                 mBluetoothPbapClient.connect(device);
168                 break;
169 
170             case BluetoothProfile.PAN:
171                 mBluetoothPan.connect(device);
172 
173             default:
174                 Log.d(TAG, "Unknown profile");
175                 break;
176         }
177         return;
178     }
179 
180     /**
181      * Set the priority of the given Bluetooth profile for the given remote device
182      * @param profile - Bluetooth profile
183      * @param device - remote Bluetooth device
184      * @param priority - priority to set
185      */
186     @Override
setProfilePriority(int profile, BluetoothDevice device, int priority)187     public void setProfilePriority(int profile, BluetoothDevice device, int priority) {
188         if (!isBluetoothConnectionProxyAvailable(profile)) {
189             Log.e(TAG, "Cannot connect to Profile. Proxy Unavailable");
190             return;
191         }
192         switch (profile) {
193             case BluetoothProfile.A2DP_SINK:
194                 mBluetoothA2dpSink.setPriority(device, priority);
195                 break;
196             case BluetoothProfile.HEADSET_CLIENT:
197                 mBluetoothHeadsetClient.setPriority(device, priority);
198                 break;
199             case BluetoothProfile.MAP_CLIENT:
200                 mBluetoothMapClient.setPriority(device, priority);
201                 break;
202             case BluetoothProfile.PBAP_CLIENT:
203                 mBluetoothPbapClient.setPriority(device, priority);
204                 break;
205             default:
206                 Log.d(TAG, "Unknown Profile");
207                 break;
208         }
209     }
210     /**
211      * All the BluetoothProfile.ServiceListeners to get the Profile Proxy objects
212      */
213     private BluetoothProfile.ServiceListener mProfileListener =
214             new BluetoothProfile.ServiceListener() {
215                 public void onServiceConnected(int profile, BluetoothProfile proxy) {
216                     if (DBG) {
217                         Log.d(TAG, "OnServiceConnected profile: " + profile);
218                     }
219                     switch (profile) {
220                         case BluetoothProfile.A2DP_SINK:
221                             mBluetoothA2dpSink = (BluetoothA2dpSink) proxy;
222                             break;
223 
224                         case BluetoothProfile.HEADSET_CLIENT:
225                             mBluetoothHeadsetClient = (BluetoothHeadsetClient) proxy;
226                             break;
227 
228                         case BluetoothProfile.PBAP_CLIENT:
229                             mBluetoothPbapClient = (BluetoothPbapClient) proxy;
230                             break;
231 
232                         case BluetoothProfile.MAP_CLIENT:
233                             mBluetoothMapClient = (BluetoothMapClient) proxy;
234                             break;
235 
236                         case BluetoothProfile.PAN:
237                             mBluetoothPan = (BluetoothPan) proxy;
238                             break;
239 
240                         default:
241                             if (DBG) {
242                                 Log.d(TAG, "Unhandled profile");
243                             }
244                             break;
245                     }
246                 }
247 
248                 public void onServiceDisconnected(int profile) {
249                     if (DBG) {
250                         Log.d(TAG, "onServiceDisconnected profile: " + profile);
251                     }
252                     switch (profile) {
253                         case BluetoothProfile.A2DP_SINK:
254                             mBluetoothA2dpSink = null;
255                             break;
256 
257                         case BluetoothProfile.HEADSET_CLIENT:
258                             mBluetoothHeadsetClient = null;
259                             break;
260 
261                         case BluetoothProfile.PBAP_CLIENT:
262                             mBluetoothPbapClient = null;
263                             break;
264 
265                         case BluetoothProfile.MAP_CLIENT:
266                             mBluetoothMapClient = null;
267                             break;
268 
269                         case BluetoothProfile.PAN:
270                             mBluetoothPan = null;
271                             break;
272 
273                         default:
274                             if (DBG) {
275                                 Log.d(TAG, "Unhandled profile");
276                             }
277                             break;
278                     }
279                 }
280             };
281 }
282