blob: 41c1d60ca551ed5e48c2cef86732139fa116b14d [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
109 public List<BluetoothDevice> getConnectedDevices() {
110 if (mService == null) return new ArrayList<BluetoothDevice>(0);
111 return mService.getDevicesMatchingConnectionStates(
112 new int[] {BluetoothProfile.STATE_CONNECTED,
113 BluetoothProfile.STATE_CONNECTING,
114 BluetoothProfile.STATE_DISCONNECTING});
115 }
116
117 public boolean connect(BluetoothDevice device) {
118 if (mService == null) return false;
119 return mService.connect(device);
120 }
121
122 public boolean disconnect(BluetoothDevice device) {
123 if (mService == null) return false;
124 // Downgrade priority as user is disconnecting the hearing aid.
125 if (mService.getPriority(device) > BluetoothProfile.PRIORITY_ON){
126 mService.setPriority(device, BluetoothProfile.PRIORITY_ON);
127 }
128 return mService.disconnect(device);
129 }
130
131 public int getConnectionStatus(BluetoothDevice device) {
132 if (mService == null) {
133 return BluetoothProfile.STATE_DISCONNECTED;
134 }
135 return mService.getConnectionState(device);
136 }
137
Hansong Zhangd7b35912018-03-16 09:15:48 -0700138 public boolean setActiveDevice(BluetoothDevice device) {
139 if (mService == null) return false;
Hansong Zhang3b8f09b2018-03-28 16:53:10 -0700140 return mService.setActiveDevice(device);
Hansong Zhangd7b35912018-03-16 09:15:48 -0700141 }
142
Hansong Zhang3b8f09b2018-03-28 16:53:10 -0700143 public List<BluetoothDevice> getActiveDevices() {
144 if (mService == null) return new ArrayList<>();
145 return mService.getActiveDevices();
Hansong Zhangd7b35912018-03-16 09:15:48 -0700146 }
147
Jakub Pawlowskiea580fa2017-11-22 11:02:34 -0800148 public boolean isPreferred(BluetoothDevice device) {
149 if (mService == null) return false;
150 return mService.getPriority(device) > BluetoothProfile.PRIORITY_OFF;
151 }
152
153 public int getPreferred(BluetoothDevice device) {
154 if (mService == null) return BluetoothProfile.PRIORITY_OFF;
155 return mService.getPriority(device);
156 }
157
158 public void setPreferred(BluetoothDevice device, boolean preferred) {
159 if (mService == null) return;
160 if (preferred) {
161 if (mService.getPriority(device) < BluetoothProfile.PRIORITY_ON) {
162 mService.setPriority(device, BluetoothProfile.PRIORITY_ON);
163 }
164 } else {
165 mService.setPriority(device, BluetoothProfile.PRIORITY_OFF);
166 }
167 }
168
169 public int getVolume() {
170 if (mService == null) {
171 return 0;
172 }
173 return mService.getVolume();
174 }
175
176 public void setVolume(int volume) {
177 if (mService == null) {
178 return;
179 }
180 mService.setVolume(volume);
181 }
182
183 public long getHiSyncId(BluetoothDevice device) {
184 if (mService == null) {
185 return BluetoothHearingAid.HI_SYNC_ID_INVALID;
186 }
187 return mService.getHiSyncId(device);
188 }
189
190 public int getDeviceSide(BluetoothDevice device) {
191 if (mService == null) {
192 return BluetoothHearingAid.SIDE_LEFT;
193 }
194 return mService.getDeviceSide(device);
195 }
196
197 public int getDeviceMode(BluetoothDevice device) {
198 if (mService == null) {
199 return BluetoothHearingAid.MODE_MONAURAL;
200 }
201 return mService.getDeviceMode(device);
202 }
203
204 public String toString() {
205 return NAME;
206 }
207
208 public int getOrdinal() {
209 return ORDINAL;
210 }
211
212 public int getNameResource(BluetoothDevice device) {
213 return R.string.bluetooth_profile_hearing_aid;
214 }
215
216 public int getSummaryResourceForDevice(BluetoothDevice device) {
217 int state = getConnectionStatus(device);
218 switch (state) {
219 case BluetoothProfile.STATE_DISCONNECTED:
220 return R.string.bluetooth_hearing_aid_profile_summary_use_for;
221
222 case BluetoothProfile.STATE_CONNECTED:
223 return R.string.bluetooth_hearing_aid_profile_summary_connected;
224
225 default:
Kunhung Lie7b7cb82018-05-17 11:04:54 +0800226 return BluetoothUtils.getConnectionStateSummary(state);
Jakub Pawlowskiea580fa2017-11-22 11:02:34 -0800227 }
228 }
229
230 public int getDrawableResource(BluetoothClass btClass) {
Amin Shaikh10f363b2019-01-24 17:59:49 -0500231 return com.android.internal.R.drawable.ic_bt_hearing_aid;
Jakub Pawlowskiea580fa2017-11-22 11:02:34 -0800232 }
233
234 protected void finalize() {
Chienyuan97e4b202019-01-03 20:02:27 +0800235 Log.d(TAG, "finalize()");
Jakub Pawlowskiea580fa2017-11-22 11:02:34 -0800236 if (mService != null) {
237 try {
238 BluetoothAdapter.getDefaultAdapter().closeProfileProxy(BluetoothProfile.HEARING_AID,
239 mService);
240 mService = null;
241 }catch (Throwable t) {
242 Log.w(TAG, "Error cleaning up Hearing Aid proxy", t);
243 }
244 }
245 }
246}