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