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