• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
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 
17 package com.android.settingslib.bluetooth;
18 
19 import android.bluetooth.BluetoothHearingAid;
20 import android.bluetooth.BluetoothAdapter;
21 import android.bluetooth.BluetoothClass;
22 import android.bluetooth.BluetoothCodecConfig;
23 import android.bluetooth.BluetoothCodecStatus;
24 import android.bluetooth.BluetoothDevice;
25 import android.bluetooth.BluetoothProfile;
26 import android.bluetooth.BluetoothUuid;
27 import android.content.Context;
28 import android.os.ParcelUuid;
29 import android.util.Log;
30 
31 import com.android.internal.annotations.VisibleForTesting;
32 import com.android.settingslib.R;
33 
34 import java.util.ArrayList;
35 import java.util.Arrays;
36 import java.util.List;
37 
38 public 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 
onServiceConnected(int profile, BluetoothProfile proxy)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                     if (V) {
71                         Log.d(TAG, "HearingAidProfile found new device: " + nextDevice);
72                     }
73                     device = mDeviceManager.addDevice(mLocalAdapter, mProfileManager, nextDevice);
74                 }
75                 device.onProfileStateChanged(HearingAidProfile.this,
76                         BluetoothProfile.STATE_CONNECTED);
77                 device.refresh();
78             }
79 
80             // Check current list of CachedDevices to see if any are Hearing Aid devices.
81             mDeviceManager.updateHearingAidsDevices(mProfileManager);
82 
83             mIsProfileReady=true;
84         }
85 
onServiceDisconnected(int profile)86         public void onServiceDisconnected(int profile) {
87             if (V) Log.d(TAG,"Bluetooth service disconnected");
88             mIsProfileReady=false;
89         }
90     }
91 
isProfileReady()92     public boolean isProfileReady() {
93         return mIsProfileReady;
94     }
95 
96     @Override
getProfileId()97     public int getProfileId() {
98         return BluetoothProfile.HEARING_AID;
99     }
100 
HearingAidProfile(Context context, LocalBluetoothAdapter adapter, CachedBluetoothDeviceManager deviceManager, LocalBluetoothProfileManager profileManager)101     HearingAidProfile(Context context, LocalBluetoothAdapter adapter,
102             CachedBluetoothDeviceManager deviceManager,
103             LocalBluetoothProfileManager profileManager) {
104         mContext = context;
105         mLocalAdapter = adapter;
106         mDeviceManager = deviceManager;
107         mProfileManager = profileManager;
108         mLocalAdapter.getProfileProxy(context, new HearingAidServiceListener(),
109                 BluetoothProfile.HEARING_AID);
110     }
111 
isConnectable()112     public boolean isConnectable() {
113         return false;
114     }
115 
isAutoConnectable()116     public boolean isAutoConnectable() {
117         return true;
118     }
119 
getConnectedDevices()120     public List<BluetoothDevice> getConnectedDevices() {
121         if (mService == null) return new ArrayList<BluetoothDevice>(0);
122         return mService.getDevicesMatchingConnectionStates(
123               new int[] {BluetoothProfile.STATE_CONNECTED,
124                          BluetoothProfile.STATE_CONNECTING,
125                          BluetoothProfile.STATE_DISCONNECTING});
126     }
127 
connect(BluetoothDevice device)128     public boolean connect(BluetoothDevice device) {
129         if (mService == null) return false;
130         return mService.connect(device);
131     }
132 
disconnect(BluetoothDevice device)133     public boolean disconnect(BluetoothDevice device) {
134         if (mService == null) return false;
135         // Downgrade priority as user is disconnecting the hearing aid.
136         if (mService.getPriority(device) > BluetoothProfile.PRIORITY_ON){
137             mService.setPriority(device, BluetoothProfile.PRIORITY_ON);
138         }
139         return mService.disconnect(device);
140     }
141 
getConnectionStatus(BluetoothDevice device)142     public int getConnectionStatus(BluetoothDevice device) {
143         if (mService == null) {
144             return BluetoothProfile.STATE_DISCONNECTED;
145         }
146         return mService.getConnectionState(device);
147     }
148 
setActiveDevice(BluetoothDevice device)149     public boolean setActiveDevice(BluetoothDevice device) {
150         if (mService == null) return false;
151         return mService.setActiveDevice(device);
152     }
153 
getActiveDevices()154     public List<BluetoothDevice> getActiveDevices() {
155         if (mService == null) return new ArrayList<>();
156         return mService.getActiveDevices();
157     }
158 
isPreferred(BluetoothDevice device)159     public boolean isPreferred(BluetoothDevice device) {
160         if (mService == null) return false;
161         return mService.getPriority(device) > BluetoothProfile.PRIORITY_OFF;
162     }
163 
getPreferred(BluetoothDevice device)164     public int getPreferred(BluetoothDevice device) {
165         if (mService == null) return BluetoothProfile.PRIORITY_OFF;
166         return mService.getPriority(device);
167     }
168 
setPreferred(BluetoothDevice device, boolean preferred)169     public void setPreferred(BluetoothDevice device, boolean preferred) {
170         if (mService == null) return;
171         if (preferred) {
172             if (mService.getPriority(device) < BluetoothProfile.PRIORITY_ON) {
173                 mService.setPriority(device, BluetoothProfile.PRIORITY_ON);
174             }
175         } else {
176             mService.setPriority(device, BluetoothProfile.PRIORITY_OFF);
177         }
178     }
179 
getVolume()180     public int getVolume() {
181         if (mService == null) {
182             return 0;
183         }
184         return mService.getVolume();
185     }
186 
setVolume(int volume)187     public void setVolume(int volume) {
188         if (mService == null) {
189             return;
190         }
191         mService.setVolume(volume);
192     }
193 
getHiSyncId(BluetoothDevice device)194     public long getHiSyncId(BluetoothDevice device) {
195         if (mService == null) {
196             return BluetoothHearingAid.HI_SYNC_ID_INVALID;
197         }
198         return mService.getHiSyncId(device);
199     }
200 
getDeviceSide(BluetoothDevice device)201     public int getDeviceSide(BluetoothDevice device) {
202         if (mService == null) {
203             return BluetoothHearingAid.SIDE_LEFT;
204         }
205         return mService.getDeviceSide(device);
206     }
207 
getDeviceMode(BluetoothDevice device)208     public int getDeviceMode(BluetoothDevice device) {
209         if (mService == null) {
210             return BluetoothHearingAid.MODE_MONAURAL;
211         }
212         return mService.getDeviceMode(device);
213     }
214 
toString()215     public String toString() {
216         return NAME;
217     }
218 
getOrdinal()219     public int getOrdinal() {
220         return ORDINAL;
221     }
222 
getNameResource(BluetoothDevice device)223     public int getNameResource(BluetoothDevice device) {
224         return R.string.bluetooth_profile_hearing_aid;
225     }
226 
getSummaryResourceForDevice(BluetoothDevice device)227     public int getSummaryResourceForDevice(BluetoothDevice device) {
228         int state = getConnectionStatus(device);
229         switch (state) {
230             case BluetoothProfile.STATE_DISCONNECTED:
231                 return R.string.bluetooth_hearing_aid_profile_summary_use_for;
232 
233             case BluetoothProfile.STATE_CONNECTED:
234                 return R.string.bluetooth_hearing_aid_profile_summary_connected;
235 
236             default:
237                 return Utils.getConnectionStateSummary(state);
238         }
239     }
240 
getDrawableResource(BluetoothClass btClass)241     public int getDrawableResource(BluetoothClass btClass) {
242         return R.drawable.ic_bt_hearing_aid;
243     }
244 
finalize()245     protected void finalize() {
246         if (V) Log.d(TAG, "finalize()");
247         if (mService != null) {
248             try {
249                 BluetoothAdapter.getDefaultAdapter().closeProfileProxy(BluetoothProfile.HEARING_AID,
250                                                                        mService);
251                 mService = null;
252             }catch (Throwable t) {
253                 Log.w(TAG, "Error cleaning up Hearing Aid proxy", t);
254             }
255         }
256     }
257 }
258