• 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.BluetoothAdapter;
20 import android.bluetooth.BluetoothClass;
21 import android.bluetooth.BluetoothDevice;
22 import android.bluetooth.BluetoothHearingAid;
23 import android.bluetooth.BluetoothProfile;
24 import android.content.Context;
25 import android.util.Log;
26 
27 import com.android.settingslib.R;
28 
29 import java.util.ArrayList;
30 import java.util.List;
31 
32 public 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 
41     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 
onServiceConnected(int profile, BluetoothProfile proxy)53         public void onServiceConnected(int profile, BluetoothProfile proxy) {
54             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) {
62                     if (V) {
63                         Log.d(TAG, "HearingAidProfile found new device: " + nextDevice);
64                     }
65                     device = mDeviceManager.addDevice(nextDevice);
66                 }
67                 device.onProfileStateChanged(HearingAidProfile.this,
68                         BluetoothProfile.STATE_CONNECTED);
69                 device.refresh();
70             }
71 
72             // Check current list of CachedDevices to see if any are Hearing Aid devices.
73             mDeviceManager.updateHearingAidsDevices();
74             mIsProfileReady=true;
75             mProfileManager.callServiceConnectedListeners();
76         }
77 
onServiceDisconnected(int profile)78         public void onServiceDisconnected(int profile) {
79             mIsProfileReady=false;
80         }
81     }
82 
isProfileReady()83     public boolean isProfileReady() {
84         return mIsProfileReady;
85     }
86 
87     @Override
getProfileId()88     public int getProfileId() {
89         return BluetoothProfile.HEARING_AID;
90     }
91 
HearingAidProfile(Context context, CachedBluetoothDeviceManager deviceManager, LocalBluetoothProfileManager profileManager)92     HearingAidProfile(Context context, CachedBluetoothDeviceManager deviceManager,
93             LocalBluetoothProfileManager profileManager) {
94         mContext = context;
95         mDeviceManager = deviceManager;
96         mProfileManager = profileManager;
97         BluetoothAdapter.getDefaultAdapter().getProfileProxy(context,
98                 new HearingAidServiceListener(), BluetoothProfile.HEARING_AID);
99     }
100 
accessProfileEnabled()101     public boolean accessProfileEnabled() {
102         return false;
103     }
104 
isAutoConnectable()105     public boolean isAutoConnectable() {
106         return true;
107     }
108 
109     /**
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      */
getConnectedDevices()117     public List<BluetoothDevice> getConnectedDevices() {
118         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      */
getConnectableDevices()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 
getDevicesByStates(int[] states)141     private List<BluetoothDevice> getDevicesByStates(int[] states) {
142         if (mService == null) {
143             return new ArrayList<BluetoothDevice>(0);
144         }
145         return mService.getDevicesMatchingConnectionStates(states);
146     }
147 
connect(BluetoothDevice device)148     public boolean connect(BluetoothDevice device) {
149         if (mService == null) return false;
150         return mService.connect(device);
151     }
152 
disconnect(BluetoothDevice device)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 
getConnectionStatus(BluetoothDevice device)162     public int getConnectionStatus(BluetoothDevice device) {
163         if (mService == null) {
164             return BluetoothProfile.STATE_DISCONNECTED;
165         }
166         return mService.getConnectionState(device);
167     }
168 
setActiveDevice(BluetoothDevice device)169     public boolean setActiveDevice(BluetoothDevice device) {
170         if (mService == null) return false;
171         return mService.setActiveDevice(device);
172     }
173 
getActiveDevices()174     public List<BluetoothDevice> getActiveDevices() {
175         if (mService == null) return new ArrayList<>();
176         return mService.getActiveDevices();
177     }
178 
isPreferred(BluetoothDevice device)179     public boolean isPreferred(BluetoothDevice device) {
180         if (mService == null) return false;
181         return mService.getPriority(device) > BluetoothProfile.PRIORITY_OFF;
182     }
183 
getPreferred(BluetoothDevice device)184     public int getPreferred(BluetoothDevice device) {
185         if (mService == null) return BluetoothProfile.PRIORITY_OFF;
186         return mService.getPriority(device);
187     }
188 
setPreferred(BluetoothDevice device, boolean preferred)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 
getVolume()200     public int getVolume() {
201         if (mService == null) {
202             return 0;
203         }
204         return mService.getVolume();
205     }
206 
setVolume(int volume)207     public void setVolume(int volume) {
208         if (mService == null) {
209             return;
210         }
211         mService.setVolume(volume);
212     }
213 
getHiSyncId(BluetoothDevice device)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 
getDeviceSide(BluetoothDevice device)221     public int getDeviceSide(BluetoothDevice device) {
222         if (mService == null) {
223             return BluetoothHearingAid.SIDE_LEFT;
224         }
225         return mService.getDeviceSide(device);
226     }
227 
getDeviceMode(BluetoothDevice device)228     public int getDeviceMode(BluetoothDevice device) {
229         if (mService == null) {
230             return BluetoothHearingAid.MODE_MONAURAL;
231         }
232         return mService.getDeviceMode(device);
233     }
234 
toString()235     public String toString() {
236         return NAME;
237     }
238 
getOrdinal()239     public int getOrdinal() {
240         return ORDINAL;
241     }
242 
getNameResource(BluetoothDevice device)243     public int getNameResource(BluetoothDevice device) {
244         return R.string.bluetooth_profile_hearing_aid;
245     }
246 
getSummaryResourceForDevice(BluetoothDevice device)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:
257                 return BluetoothUtils.getConnectionStateSummary(state);
258         }
259     }
260 
getDrawableResource(BluetoothClass btClass)261     public int getDrawableResource(BluetoothClass btClass) {
262         return com.android.internal.R.drawable.ic_bt_hearing_aid;
263     }
264 
finalize()265     protected void finalize() {
266         Log.d(TAG, "finalize()");
267         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 }
278