blob: 920500f97223c0649d684adae7451a9a65df4f68 [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
19import android.bluetooth.BluetoothHearingAid;
20import android.bluetooth.BluetoothAdapter;
21import android.bluetooth.BluetoothClass;
22import android.bluetooth.BluetoothCodecConfig;
23import android.bluetooth.BluetoothCodecStatus;
24import android.bluetooth.BluetoothDevice;
25import android.bluetooth.BluetoothProfile;
26import android.bluetooth.BluetoothUuid;
27import android.content.Context;
28import android.os.ParcelUuid;
29import android.util.Log;
30
31import com.android.internal.annotations.VisibleForTesting;
32import com.android.settingslib.R;
33
34import java.util.ArrayList;
35import java.util.Arrays;
36import java.util.List;
37
38public class HearingAidProfile implements LocalBluetoothProfile {
39 private static final String TAG = "HearingAidProfile";
40 private static boolean V = true;
41
42 private Context mContext;
43
44 private BluetoothHearingAid mService;
45 private boolean mIsProfileReady;
46
47 private final LocalBluetoothAdapter mLocalAdapter;
48 private final CachedBluetoothDeviceManager mDeviceManager;
49
50 static final String NAME = "HearingAid";
51 private final LocalBluetoothProfileManager mProfileManager;
52
53 // Order of this profile in device profiles list
54 private static final int ORDINAL = 1;
55
56 // These callbacks run on the main thread.
57 private final class HearingAidServiceListener
58 implements BluetoothProfile.ServiceListener {
59
60 public void onServiceConnected(int profile, BluetoothProfile proxy) {
61 if (V) Log.d(TAG,"Bluetooth service connected");
62 mService = (BluetoothHearingAid) proxy;
63 // We just bound to the service, so refresh the UI for any connected HearingAid devices.
64 List<BluetoothDevice> deviceList = mService.getConnectedDevices();
65 while (!deviceList.isEmpty()) {
66 BluetoothDevice nextDevice = deviceList.remove(0);
67 CachedBluetoothDevice device = mDeviceManager.findDevice(nextDevice);
68 // we may add a new device here, but generally this should not happen
69 if (device == null) {
70 Log.w(TAG, "HearingAidProfile found new device: " + nextDevice);
71 device = mDeviceManager.addDevice(mLocalAdapter, mProfileManager, nextDevice);
72 }
73 device.onProfileStateChanged(HearingAidProfile.this, BluetoothProfile.STATE_CONNECTED);
74 device.refresh();
75 }
76 mIsProfileReady=true;
77 }
78
79 public void onServiceDisconnected(int profile) {
80 if (V) Log.d(TAG,"Bluetooth service disconnected");
81 mIsProfileReady=false;
82 }
83 }
84
85 public boolean isProfileReady() {
86 return mIsProfileReady;
87 }
88
89 HearingAidProfile(Context context, LocalBluetoothAdapter adapter,
90 CachedBluetoothDeviceManager deviceManager,
91 LocalBluetoothProfileManager profileManager) {
92 mContext = context;
93 mLocalAdapter = adapter;
94 mDeviceManager = deviceManager;
95 mProfileManager = profileManager;
96 mLocalAdapter.getProfileProxy(context, new HearingAidServiceListener(),
97 BluetoothProfile.HEARING_AID);
98 }
99
100 public boolean isConnectable() {
101 return true;
102 }
103
104 public boolean isAutoConnectable() {
105 return true;
106 }
107
108 public List<BluetoothDevice> getConnectedDevices() {
109 if (mService == null) return new ArrayList<BluetoothDevice>(0);
110 return mService.getDevicesMatchingConnectionStates(
111 new int[] {BluetoothProfile.STATE_CONNECTED,
112 BluetoothProfile.STATE_CONNECTING,
113 BluetoothProfile.STATE_DISCONNECTING});
114 }
115
116 public boolean connect(BluetoothDevice device) {
117 if (mService == null) return false;
118 return mService.connect(device);
119 }
120
121 public boolean disconnect(BluetoothDevice device) {
122 if (mService == null) return false;
123 // Downgrade priority as user is disconnecting the hearing aid.
124 if (mService.getPriority(device) > BluetoothProfile.PRIORITY_ON){
125 mService.setPriority(device, BluetoothProfile.PRIORITY_ON);
126 }
127 return mService.disconnect(device);
128 }
129
130 public int getConnectionStatus(BluetoothDevice device) {
131 if (mService == null) {
132 return BluetoothProfile.STATE_DISCONNECTED;
133 }
134 return mService.getConnectionState(device);
135 }
136
Hansong Zhangd7b35912018-03-16 09:15:48 -0700137 public boolean setActiveDevice(BluetoothDevice device) {
138 if (mService == null) return false;
139 mService.setActiveDevice(device);
140 return true;
141 }
142
143 public boolean isActiveDevice(BluetoothDevice device) {
144 if (mService == null) return false;
145 return mService.isActiveDevice(device);
146 }
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:
226 return Utils.getConnectionStateSummary(state);
227 }
228 }
229
230 public int getDrawableResource(BluetoothClass btClass) {
231 return R.drawable.ic_bt_hearing_aid;
232 }
233
234 protected void finalize() {
235 if (V) Log.d(TAG, "finalize()");
236 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}