• 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.BluetoothMapClient;
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  * MapClientProfile handles Bluetooth MAP profile.
36  */
37 public final class MapClientProfile implements LocalBluetoothProfile {
38     private static final String TAG = "MapClientProfile";
39     private static boolean V = false;
40 
41     private BluetoothMapClient 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.MAP,
50         BluetoothUuid.MNS,
51         BluetoothUuid.MAS,
52     };
53 
54     static final String NAME = "MAP Client";
55 
56     // Order of this profile in device profiles list
57     private static final int ORDINAL = 0;
58 
59     // These callbacks run on the main thread.
60     private final class MapClientServiceListener
61             implements BluetoothProfile.ServiceListener {
62 
onServiceConnected(int profile, BluetoothProfile proxy)63         public void onServiceConnected(int profile, BluetoothProfile proxy) {
64             if (V) Log.d(TAG,"Bluetooth service connected");
65             mService = (BluetoothMapClient) proxy;
66             // We just bound to the service, so refresh the UI for any connected MAP devices.
67             List<BluetoothDevice> deviceList = mService.getConnectedDevices();
68             while (!deviceList.isEmpty()) {
69                 BluetoothDevice nextDevice = deviceList.remove(0);
70                 CachedBluetoothDevice device = mDeviceManager.findDevice(nextDevice);
71                 // we may add a new device here, but generally this should not happen
72                 if (device == null) {
73                     Log.w(TAG, "MapProfile found new device: " + nextDevice);
74                     device = mDeviceManager.addDevice(mLocalAdapter, mProfileManager, nextDevice);
75                 }
76                 device.onProfileStateChanged(MapClientProfile.this,
77                         BluetoothProfile.STATE_CONNECTED);
78                 device.refresh();
79             }
80 
81             mProfileManager.callServiceConnectedListeners();
82             mIsProfileReady=true;
83         }
84 
onServiceDisconnected(int profile)85         public void onServiceDisconnected(int profile) {
86             if (V) Log.d(TAG,"Bluetooth service disconnected");
87             mProfileManager.callServiceDisconnectedListeners();
88             mIsProfileReady=false;
89         }
90     }
91 
isProfileReady()92     public boolean isProfileReady() {
93         if(V) Log.d(TAG,"isProfileReady(): "+ mIsProfileReady);
94         return mIsProfileReady;
95     }
96 
97     @Override
getProfileId()98     public int getProfileId() {
99         return BluetoothProfile.MAP_CLIENT;
100     }
101 
MapClientProfile(Context context, LocalBluetoothAdapter adapter, CachedBluetoothDeviceManager deviceManager, LocalBluetoothProfileManager profileManager)102     MapClientProfile(Context context, LocalBluetoothAdapter adapter,
103             CachedBluetoothDeviceManager deviceManager,
104             LocalBluetoothProfileManager profileManager) {
105         mLocalAdapter = adapter;
106         mDeviceManager = deviceManager;
107         mProfileManager = profileManager;
108         mLocalAdapter.getProfileProxy(context, new MapClientServiceListener(),
109                 BluetoothProfile.MAP_CLIENT);
110     }
111 
isConnectable()112     public boolean isConnectable() {
113         return true;
114     }
115 
isAutoConnectable()116     public boolean isAutoConnectable() {
117         return true;
118     }
119 
connect(BluetoothDevice device)120     public boolean connect(BluetoothDevice device) {
121         if (mService == null) return false;
122         List<BluetoothDevice> connectedDevices = getConnectedDevices();
123         if (connectedDevices != null && connectedDevices.contains(device)) {
124             // Connect to same device, Ignore it
125             Log.d(TAG,"Ignoring Connect");
126             return true;
127         }
128         return mService.connect(device);
129     }
130 
disconnect(BluetoothDevice device)131     public boolean disconnect(BluetoothDevice device) {
132         if (mService == null) return false;
133         // Downgrade priority as user is disconnecting.
134         if (mService.getPriority(device) > BluetoothProfile.PRIORITY_ON) {
135             mService.setPriority(device, BluetoothProfile.PRIORITY_ON);
136         }
137         return mService.disconnect(device);
138     }
139 
getConnectionStatus(BluetoothDevice device)140     public int getConnectionStatus(BluetoothDevice device) {
141         if (mService == null) return BluetoothProfile.STATE_DISCONNECTED;
142 
143         return mService.getConnectionState(device);
144     }
145 
isPreferred(BluetoothDevice device)146     public boolean isPreferred(BluetoothDevice device) {
147         if (mService == null) return false;
148         return mService.getPriority(device) > BluetoothProfile.PRIORITY_OFF;
149     }
150 
getPreferred(BluetoothDevice device)151     public int getPreferred(BluetoothDevice device) {
152         if (mService == null) return BluetoothProfile.PRIORITY_OFF;
153         return mService.getPriority(device);
154     }
155 
setPreferred(BluetoothDevice device, boolean preferred)156     public void setPreferred(BluetoothDevice device, boolean preferred) {
157         if (mService == null) return;
158         if (preferred) {
159             if (mService.getPriority(device) < BluetoothProfile.PRIORITY_ON) {
160                 mService.setPriority(device, BluetoothProfile.PRIORITY_ON);
161             }
162         } else {
163             mService.setPriority(device, BluetoothProfile.PRIORITY_OFF);
164         }
165     }
166 
getConnectedDevices()167     public List<BluetoothDevice> getConnectedDevices() {
168         if (mService == null) return new ArrayList<BluetoothDevice>(0);
169         return mService.getDevicesMatchingConnectionStates(
170               new int[] {BluetoothProfile.STATE_CONNECTED,
171                          BluetoothProfile.STATE_CONNECTING,
172                          BluetoothProfile.STATE_DISCONNECTING});
173     }
174 
toString()175     public String toString() {
176         return NAME;
177     }
178 
getOrdinal()179     public int getOrdinal() {
180         return ORDINAL;
181     }
182 
getNameResource(BluetoothDevice device)183     public int getNameResource(BluetoothDevice device) {
184         return R.string.bluetooth_profile_map;
185     }
186 
getSummaryResourceForDevice(BluetoothDevice device)187     public int getSummaryResourceForDevice(BluetoothDevice device) {
188         int state = getConnectionStatus(device);
189         switch (state) {
190             case BluetoothProfile.STATE_DISCONNECTED:
191                 return R.string.bluetooth_map_profile_summary_use_for;
192 
193             case BluetoothProfile.STATE_CONNECTED:
194                 return R.string.bluetooth_map_profile_summary_connected;
195 
196             default:
197                 return Utils.getConnectionStateSummary(state);
198         }
199     }
200 
getDrawableResource(BluetoothClass btClass)201     public int getDrawableResource(BluetoothClass btClass) {
202         return R.drawable.ic_bt_cellphone;
203     }
204 
finalize()205     protected void finalize() {
206         if (V) Log.d(TAG, "finalize()");
207         if (mService != null) {
208             try {
209                 BluetoothAdapter.getDefaultAdapter().closeProfileProxy(BluetoothProfile.MAP_CLIENT,
210                                                                        mService);
211                 mService = null;
212             }catch (Throwable t) {
213                 Log.w(TAG, "Error cleaning up MAP Client proxy", t);
214             }
215         }
216     }
217 }
218