• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2012 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.BluetoothHeadset;
23 import android.bluetooth.BluetoothProfile;
24 import android.bluetooth.BluetoothUuid;
25 import android.content.Context;
26 import android.os.ParcelUuid;
27 import android.util.Log;
28 
29 import com.android.settingslib.R;
30 
31 import java.util.ArrayList;
32 import java.util.List;
33 
34 /**
35  * HeadsetProfile handles Bluetooth HFP and Headset profiles.
36  */
37 public class HeadsetProfile implements LocalBluetoothProfile {
38     private static final String TAG = "HeadsetProfile";
39     private static boolean V = true;
40 
41     private BluetoothHeadset mService;
42     private boolean mIsProfileReady;
43 
44     private final LocalBluetoothAdapter mLocalAdapter;
45     private final CachedBluetoothDeviceManager mDeviceManager;
46     private final LocalBluetoothProfileManager mProfileManager;
47 
48     static final ParcelUuid[] UUIDS = {
49         BluetoothUuid.HSP,
50         BluetoothUuid.Handsfree,
51     };
52 
53     static final String NAME = "HEADSET";
54 
55     // Order of this profile in device profiles list
56     private static final int ORDINAL = 0;
57 
58     // These callbacks run on the main thread.
59     private final class HeadsetServiceListener
60             implements BluetoothProfile.ServiceListener {
61 
onServiceConnected(int profile, BluetoothProfile proxy)62         public void onServiceConnected(int profile, BluetoothProfile proxy) {
63             if (V) Log.d(TAG,"Bluetooth service connected");
64             mService = (BluetoothHeadset) proxy;
65             // We just bound to the service, so refresh the UI for any connected HFP devices.
66             List<BluetoothDevice> deviceList = mService.getConnectedDevices();
67             while (!deviceList.isEmpty()) {
68                 BluetoothDevice nextDevice = deviceList.remove(0);
69                 CachedBluetoothDevice device = mDeviceManager.findDevice(nextDevice);
70                 // we may add a new device here, but generally this should not happen
71                 if (device == null) {
72                     Log.w(TAG, "HeadsetProfile found new device: " + nextDevice);
73                     device = mDeviceManager.addDevice(mLocalAdapter, mProfileManager, nextDevice);
74                 }
75                 device.onProfileStateChanged(HeadsetProfile.this,
76                         BluetoothProfile.STATE_CONNECTED);
77                 device.refresh();
78             }
79 
80             mProfileManager.callServiceConnectedListeners();
81             mIsProfileReady=true;
82         }
83 
onServiceDisconnected(int profile)84         public void onServiceDisconnected(int profile) {
85             if (V) Log.d(TAG,"Bluetooth service disconnected");
86             mProfileManager.callServiceDisconnectedListeners();
87             mIsProfileReady=false;
88         }
89     }
90 
isProfileReady()91     public boolean isProfileReady() {
92         return mIsProfileReady;
93     }
94 
95     @Override
getProfileId()96     public int getProfileId() {
97         return BluetoothProfile.HEADSET;
98     }
99 
HeadsetProfile(Context context, LocalBluetoothAdapter adapter, CachedBluetoothDeviceManager deviceManager, LocalBluetoothProfileManager profileManager)100     HeadsetProfile(Context context, LocalBluetoothAdapter adapter,
101             CachedBluetoothDeviceManager deviceManager,
102             LocalBluetoothProfileManager profileManager) {
103         mLocalAdapter = adapter;
104         mDeviceManager = deviceManager;
105         mProfileManager = profileManager;
106         mLocalAdapter.getProfileProxy(context, new HeadsetServiceListener(),
107                 BluetoothProfile.HEADSET);
108     }
109 
isConnectable()110     public boolean isConnectable() {
111         return true;
112     }
113 
isAutoConnectable()114     public boolean isAutoConnectable() {
115         return true;
116     }
117 
connect(BluetoothDevice device)118     public boolean connect(BluetoothDevice device) {
119         if (mService == null) return false;
120         List<BluetoothDevice> sinks = mService.getConnectedDevices();
121         if (sinks != null) {
122             for (BluetoothDevice sink : sinks) {
123                 Log.d(TAG,"Not disconnecting device = " + sink);
124             }
125         }
126         return mService.connect(device);
127     }
128 
disconnect(BluetoothDevice device)129     public boolean disconnect(BluetoothDevice device) {
130         if (mService == null) return false;
131         List<BluetoothDevice> deviceList = mService.getConnectedDevices();
132         if (!deviceList.isEmpty()) {
133             for (BluetoothDevice dev : deviceList) {
134                 if (dev.equals(device)) {
135                     if (V) Log.d(TAG,"Downgrade priority as user" +
136                                         "is disconnecting the headset");
137                     // Downgrade priority as user is disconnecting the headset.
138                     if (mService.getPriority(device) > BluetoothProfile.PRIORITY_ON) {
139                         mService.setPriority(device, BluetoothProfile.PRIORITY_ON);
140                     }
141                     return mService.disconnect(device);
142                 }
143             }
144         }
145         return false;
146     }
147 
getConnectionStatus(BluetoothDevice device)148     public int getConnectionStatus(BluetoothDevice device) {
149         if (mService == null) return BluetoothProfile.STATE_DISCONNECTED;
150         List<BluetoothDevice> deviceList = mService.getConnectedDevices();
151         if (!deviceList.isEmpty()){
152             for (BluetoothDevice dev : deviceList) {
153                 if (dev.equals(device)) {
154                     return mService.getConnectionState(device);
155                 }
156             }
157         }
158         return BluetoothProfile.STATE_DISCONNECTED;
159     }
160 
setActiveDevice(BluetoothDevice device)161     public boolean setActiveDevice(BluetoothDevice device) {
162         if (mService == null) return false;
163         return mService.setActiveDevice(device);
164     }
165 
getActiveDevice()166     public BluetoothDevice getActiveDevice() {
167         if (mService == null) return null;
168         return mService.getActiveDevice();
169     }
170 
isAudioOn()171     public boolean isAudioOn() {
172         if (mService == null) return false;
173         return mService.isAudioOn();
174     }
175 
getAudioState(BluetoothDevice device)176     public int getAudioState(BluetoothDevice device) {
177         if (mService == null) return BluetoothHeadset.STATE_AUDIO_DISCONNECTED;
178         return mService.getAudioState(device);
179     }
180 
isPreferred(BluetoothDevice device)181     public boolean isPreferred(BluetoothDevice device) {
182         if (mService == null) return false;
183         return mService.getPriority(device) > BluetoothProfile.PRIORITY_OFF;
184     }
185 
getPreferred(BluetoothDevice device)186     public int getPreferred(BluetoothDevice device) {
187         if (mService == null) return BluetoothProfile.PRIORITY_OFF;
188         return mService.getPriority(device);
189     }
190 
setPreferred(BluetoothDevice device, boolean preferred)191     public void setPreferred(BluetoothDevice device, boolean preferred) {
192         if (mService == null) return;
193         if (preferred) {
194             if (mService.getPriority(device) < BluetoothProfile.PRIORITY_ON) {
195                 mService.setPriority(device, BluetoothProfile.PRIORITY_ON);
196             }
197         } else {
198             mService.setPriority(device, BluetoothProfile.PRIORITY_OFF);
199         }
200     }
201 
getConnectedDevices()202     public List<BluetoothDevice> getConnectedDevices() {
203         if (mService == null) return new ArrayList<BluetoothDevice>(0);
204         return mService.getDevicesMatchingConnectionStates(
205               new int[] {BluetoothProfile.STATE_CONNECTED,
206                          BluetoothProfile.STATE_CONNECTING,
207                          BluetoothProfile.STATE_DISCONNECTING});
208     }
209 
toString()210     public String toString() {
211         return NAME;
212     }
213 
getOrdinal()214     public int getOrdinal() {
215         return ORDINAL;
216     }
217 
getNameResource(BluetoothDevice device)218     public int getNameResource(BluetoothDevice device) {
219         return R.string.bluetooth_profile_headset;
220     }
221 
getSummaryResourceForDevice(BluetoothDevice device)222     public int getSummaryResourceForDevice(BluetoothDevice device) {
223         int state = getConnectionStatus(device);
224         switch (state) {
225             case BluetoothProfile.STATE_DISCONNECTED:
226                 return R.string.bluetooth_headset_profile_summary_use_for;
227 
228             case BluetoothProfile.STATE_CONNECTED:
229                 return R.string.bluetooth_headset_profile_summary_connected;
230 
231             default:
232                 return Utils.getConnectionStateSummary(state);
233         }
234     }
235 
getDrawableResource(BluetoothClass btClass)236     public int getDrawableResource(BluetoothClass btClass) {
237         return R.drawable.ic_bt_headset_hfp;
238     }
239 
finalize()240     protected void finalize() {
241         if (V) Log.d(TAG, "finalize()");
242         if (mService != null) {
243             try {
244                 BluetoothAdapter.getDefaultAdapter().closeProfileProxy(BluetoothProfile.HEADSET,
245                                                                        mService);
246                 mService = null;
247             }catch (Throwable t) {
248                 Log.w(TAG, "Error cleaning up HID proxy", t);
249             }
250         }
251     }
252 }
253