blob: ebaeb742b1984441f2baf1eadfd553c7bfaac239 [file] [log] [blame]
Jakub Pawlowskiea580fa2017-11-22 11:02:34 -08001/*
2 * Copyright (C) 2018 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
17package com.android.settingslib.bluetooth;
18
Jakub Pawlowskiea580fa2017-11-22 11:02:34 -080019import android.bluetooth.BluetoothAdapter;
20import android.bluetooth.BluetoothClass;
Jakub Pawlowskiea580fa2017-11-22 11:02:34 -080021import android.bluetooth.BluetoothDevice;
Fan Zhangf7802ea2018-08-28 15:15:19 -070022import android.bluetooth.BluetoothHearingAid;
Jakub Pawlowskiea580fa2017-11-22 11:02:34 -080023import android.bluetooth.BluetoothProfile;
Jakub Pawlowskiea580fa2017-11-22 11:02:34 -080024import android.content.Context;
Jakub Pawlowskiea580fa2017-11-22 11:02:34 -080025import android.util.Log;
26
Jakub Pawlowskiea580fa2017-11-22 11:02:34 -080027import com.android.settingslib.R;
28
29import java.util.ArrayList;
Jakub Pawlowskiea580fa2017-11-22 11:02:34 -080030import java.util.List;
31
32public class HearingAidProfile implements LocalBluetoothProfile {
33 private static final String TAG = "HearingAidProfile";
34 private static boolean V = true;
35
36 private Context mContext;
37
38 private BluetoothHearingAid mService;
39 private boolean mIsProfileReady;
40
Jakub Pawlowskiea580fa2017-11-22 11:02:34 -080041 private final CachedBluetoothDeviceManager mDeviceManager;
42
43 static final String NAME = "HearingAid";
44 private final LocalBluetoothProfileManager mProfileManager;
45
46 // Order of this profile in device profiles list
47 private static final int ORDINAL = 1;
48
49 // These callbacks run on the main thread.
50 private final class HearingAidServiceListener
51 implements BluetoothProfile.ServiceListener {
52
53 public void onServiceConnected(int profile, BluetoothProfile proxy) {
Jakub Pawlowskiea580fa2017-11-22 11:02:34 -080054 mService = (BluetoothHearingAid) proxy;
55 // We just bound to the service, so refresh the UI for any connected HearingAid devices.
56 List<BluetoothDevice> deviceList = mService.getConnectedDevices();
57 while (!deviceList.isEmpty()) {
58 BluetoothDevice nextDevice = deviceList.remove(0);
59 CachedBluetoothDevice device = mDeviceManager.findDevice(nextDevice);
60 // we may add a new device here, but generally this should not happen
61 if (device == null) {
Isha Bobrac3d94132018-02-08 16:04:36 -080062 if (V) {
63 Log.d(TAG, "HearingAidProfile found new device: " + nextDevice);
64 }
timhypengf64f6902018-07-31 15:40:15 +080065 device = mDeviceManager.addDevice(nextDevice);
Jakub Pawlowskiea580fa2017-11-22 11:02:34 -080066 }
Isha Bobrac3d94132018-02-08 16:04:36 -080067 device.onProfileStateChanged(HearingAidProfile.this,
68 BluetoothProfile.STATE_CONNECTED);
Jakub Pawlowskiea580fa2017-11-22 11:02:34 -080069 device.refresh();
70 }
Isha Bobrac3d94132018-02-08 16:04:36 -080071
72 // Check current list of CachedDevices to see if any are Hearing Aid devices.
timhypeng5c62ebb2018-08-28 09:59:03 +080073 mDeviceManager.updateHearingAidsDevices();
Jakub Pawlowskiea580fa2017-11-22 11:02:34 -080074 mIsProfileReady=true;
hughchenbd0dd492019-01-08 14:34:10 +080075 mProfileManager.callServiceConnectedListeners();
Jakub Pawlowskiea580fa2017-11-22 11:02:34 -080076 }
77
78 public void onServiceDisconnected(int profile) {
Jakub Pawlowskiea580fa2017-11-22 11:02:34 -080079 mIsProfileReady=false;
80 }
81 }
82
83 public boolean isProfileReady() {
84 return mIsProfileReady;
85 }
86
ryanywlin44de3a02018-05-02 15:15:37 +080087 @Override
88 public int getProfileId() {
89 return BluetoothProfile.HEARING_AID;
90 }
91
timhypengf64f6902018-07-31 15:40:15 +080092 HearingAidProfile(Context context, CachedBluetoothDeviceManager deviceManager,
Jakub Pawlowskiea580fa2017-11-22 11:02:34 -080093 LocalBluetoothProfileManager profileManager) {
94 mContext = context;
Jakub Pawlowskiea580fa2017-11-22 11:02:34 -080095 mDeviceManager = deviceManager;
96 mProfileManager = profileManager;
timhypengf64f6902018-07-31 15:40:15 +080097 BluetoothAdapter.getDefaultAdapter().getProfileProxy(context,
98 new HearingAidServiceListener(), BluetoothProfile.HEARING_AID);
Jakub Pawlowskiea580fa2017-11-22 11:02:34 -080099 }
100
Leon Liao3b5e6bd2018-09-18 12:45:45 +0800101 public boolean accessProfileEnabled() {
Stanley Tng854714d2018-05-17 08:34:32 -0700102 return false;
Jakub Pawlowskiea580fa2017-11-22 11:02:34 -0800103 }
104
105 public boolean isAutoConnectable() {
106 return true;
107 }
108
timhypenge54887b2019-02-27 15:01:31 +0800109 /**
110 * Get Hearing Aid devices matching connection states{
111 * @code BluetoothProfile.STATE_CONNECTED,
112 * @code BluetoothProfile.STATE_CONNECTING,
113 * @code BluetoothProfile.STATE_DISCONNECTING}
114 *
115 * @return Matching device list
116 */
Jakub Pawlowskiea580fa2017-11-22 11:02:34 -0800117 public List<BluetoothDevice> getConnectedDevices() {
timhypenge54887b2019-02-27 15:01:31 +0800118 return getDevicesByStates(new int[] {
119 BluetoothProfile.STATE_CONNECTED,
120 BluetoothProfile.STATE_CONNECTING,
121 BluetoothProfile.STATE_DISCONNECTING});
122 }
123
124 /**
125 * Get Hearing Aid devices matching connection states{
126 * @code BluetoothProfile.STATE_DISCONNECTED,
127 * @code BluetoothProfile.STATE_CONNECTED,
128 * @code BluetoothProfile.STATE_CONNECTING,
129 * @code BluetoothProfile.STATE_DISCONNECTING}
130 *
131 * @return Matching device list
132 */
133 public List<BluetoothDevice> getConnectableDevices() {
134 return getDevicesByStates(new int[] {
135 BluetoothProfile.STATE_DISCONNECTED,
136 BluetoothProfile.STATE_CONNECTED,
137 BluetoothProfile.STATE_CONNECTING,
138 BluetoothProfile.STATE_DISCONNECTING});
139 }
140
141 private List<BluetoothDevice> getDevicesByStates(int[] states) {
142 if (mService == null) {
143 return new ArrayList<BluetoothDevice>(0);
144 }
145 return mService.getDevicesMatchingConnectionStates(states);
Jakub Pawlowskiea580fa2017-11-22 11:02:34 -0800146 }
147
148 public boolean connect(BluetoothDevice device) {
149 if (mService == null) return false;
150 return mService.connect(device);
151 }
152
153 public boolean disconnect(BluetoothDevice device) {
154 if (mService == null) return false;
155 // Downgrade priority as user is disconnecting the hearing aid.
156 if (mService.getPriority(device) > BluetoothProfile.PRIORITY_ON){
157 mService.setPriority(device, BluetoothProfile.PRIORITY_ON);
158 }
159 return mService.disconnect(device);
160 }
161
162 public int getConnectionStatus(BluetoothDevice device) {
163 if (mService == null) {
164 return BluetoothProfile.STATE_DISCONNECTED;
165 }
166 return mService.getConnectionState(device);
167 }
168
Hansong Zhangd7b35912018-03-16 09:15:48 -0700169 public boolean setActiveDevice(BluetoothDevice device) {
170 if (mService == null) return false;
Hansong Zhang3b8f09b2018-03-28 16:53:10 -0700171 return mService.setActiveDevice(device);
Hansong Zhangd7b35912018-03-16 09:15:48 -0700172 }
173
Hansong Zhang3b8f09b2018-03-28 16:53:10 -0700174 public List<BluetoothDevice> getActiveDevices() {
175 if (mService == null) return new ArrayList<>();
176 return mService.getActiveDevices();
Hansong Zhangd7b35912018-03-16 09:15:48 -0700177 }
178
Jakub Pawlowskiea580fa2017-11-22 11:02:34 -0800179 public boolean isPreferred(BluetoothDevice device) {
180 if (mService == null) return false;
181 return mService.getPriority(device) > BluetoothProfile.PRIORITY_OFF;
182 }
183
184 public int getPreferred(BluetoothDevice device) {
185 if (mService == null) return BluetoothProfile.PRIORITY_OFF;
186 return mService.getPriority(device);
187 }
188
189 public void setPreferred(BluetoothDevice device, boolean preferred) {
190 if (mService == null) return;
191 if (preferred) {
192 if (mService.getPriority(device) < BluetoothProfile.PRIORITY_ON) {
193 mService.setPriority(device, BluetoothProfile.PRIORITY_ON);
194 }
195 } else {
196 mService.setPriority(device, BluetoothProfile.PRIORITY_OFF);
197 }
198 }
199
200 public int getVolume() {
201 if (mService == null) {
202 return 0;
203 }
204 return mService.getVolume();
205 }
206
207 public void setVolume(int volume) {
208 if (mService == null) {
209 return;
210 }
211 mService.setVolume(volume);
212 }
213
214 public long getHiSyncId(BluetoothDevice device) {
215 if (mService == null) {
216 return BluetoothHearingAid.HI_SYNC_ID_INVALID;
217 }
218 return mService.getHiSyncId(device);
219 }
220
221 public int getDeviceSide(BluetoothDevice device) {
222 if (mService == null) {
223 return BluetoothHearingAid.SIDE_LEFT;
224 }
225 return mService.getDeviceSide(device);
226 }
227
228 public int getDeviceMode(BluetoothDevice device) {
229 if (mService == null) {
230 return BluetoothHearingAid.MODE_MONAURAL;
231 }
232 return mService.getDeviceMode(device);
233 }
234
235 public String toString() {
236 return NAME;
237 }
238
239 public int getOrdinal() {
240 return ORDINAL;
241 }
242
243 public int getNameResource(BluetoothDevice device) {
244 return R.string.bluetooth_profile_hearing_aid;
245 }
246
247 public int getSummaryResourceForDevice(BluetoothDevice device) {
248 int state = getConnectionStatus(device);
249 switch (state) {
250 case BluetoothProfile.STATE_DISCONNECTED:
251 return R.string.bluetooth_hearing_aid_profile_summary_use_for;
252
253 case BluetoothProfile.STATE_CONNECTED:
254 return R.string.bluetooth_hearing_aid_profile_summary_connected;
255
256 default:
Kunhung Lie7b7cb82018-05-17 11:04:54 +0800257 return BluetoothUtils.getConnectionStateSummary(state);
Jakub Pawlowskiea580fa2017-11-22 11:02:34 -0800258 }
259 }
260
261 public int getDrawableResource(BluetoothClass btClass) {
Amin Shaikh10f363b2019-01-24 17:59:49 -0500262 return com.android.internal.R.drawable.ic_bt_hearing_aid;
Jakub Pawlowskiea580fa2017-11-22 11:02:34 -0800263 }
264
265 protected void finalize() {
Chienyuan97e4b202019-01-03 20:02:27 +0800266 Log.d(TAG, "finalize()");
Jakub Pawlowskiea580fa2017-11-22 11:02:34 -0800267 if (mService != null) {
268 try {
269 BluetoothAdapter.getDefaultAdapter().closeProfileProxy(BluetoothProfile.HEARING_AID,
270 mService);
271 mService = null;
272 }catch (Throwable t) {
273 Log.w(TAG, "Error cleaning up Hearing Aid proxy", t);
274 }
275 }
276 }
277}