• 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 static android.bluetooth.BluetoothProfile.CONNECTION_POLICY_ALLOWED;
20 import static android.bluetooth.BluetoothProfile.CONNECTION_POLICY_FORBIDDEN;
21 
22 import android.bluetooth.BluetoothAdapter;
23 import android.bluetooth.BluetoothClass;
24 import android.bluetooth.BluetoothDevice;
25 import android.bluetooth.BluetoothMapClient;
26 import android.bluetooth.BluetoothProfile;
27 import android.bluetooth.BluetoothUuid;
28 import android.content.Context;
29 import android.os.ParcelUuid;
30 import android.util.Log;
31 
32 import com.android.settingslib.R;
33 
34 import java.util.ArrayList;
35 import java.util.List;
36 
37 /**
38  * MapClientProfile handles the Bluetooth MAP MCE role.
39  */
40 public final class MapClientProfile implements LocalBluetoothProfile {
41     private static final String TAG = "MapClientProfile";
42 
43     private BluetoothMapClient mService;
44     private boolean mIsProfileReady;
45 
46     private final CachedBluetoothDeviceManager mDeviceManager;
47     private final LocalBluetoothProfileManager mProfileManager;
48 
49     static final ParcelUuid[] UUIDS = {
50         BluetoothUuid.MAS,
51     };
52 
53     static final String NAME = "MAP Client";
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 MapClientServiceListener
60             implements BluetoothProfile.ServiceListener {
61 
onServiceConnected(int profile, BluetoothProfile proxy)62         public void onServiceConnected(int profile, BluetoothProfile proxy) {
63             mService = (BluetoothMapClient) proxy;
64             // We just bound to the service, so refresh the UI for any connected MAP devices.
65             List<BluetoothDevice> deviceList = mService.getConnectedDevices();
66             while (!deviceList.isEmpty()) {
67                 BluetoothDevice nextDevice = deviceList.remove(0);
68                 CachedBluetoothDevice device = mDeviceManager.findDevice(nextDevice);
69                 // we may add a new device here, but generally this should not happen
70                 if (device == null) {
71                     Log.w(TAG, "MapProfile found new device: " + nextDevice);
72                     device = mDeviceManager.addDevice(nextDevice);
73                 }
74                 device.onProfileStateChanged(MapClientProfile.this,
75                         BluetoothProfile.STATE_CONNECTED);
76                 device.refresh();
77             }
78 
79             mProfileManager.callServiceConnectedListeners();
80             mIsProfileReady=true;
81         }
82 
onServiceDisconnected(int profile)83         public void onServiceDisconnected(int profile) {
84             mProfileManager.callServiceDisconnectedListeners();
85             mIsProfileReady=false;
86         }
87     }
88 
isProfileReady()89     public boolean isProfileReady() {
90         Log.d(TAG, "isProfileReady(): "+ mIsProfileReady);
91         return mIsProfileReady;
92     }
93 
94     @Override
getProfileId()95     public int getProfileId() {
96         return BluetoothProfile.MAP_CLIENT;
97     }
98 
MapClientProfile(Context context, CachedBluetoothDeviceManager deviceManager, LocalBluetoothProfileManager profileManager)99     MapClientProfile(Context context, CachedBluetoothDeviceManager deviceManager,
100             LocalBluetoothProfileManager profileManager) {
101         mDeviceManager = deviceManager;
102         mProfileManager = profileManager;
103         BluetoothAdapter.getDefaultAdapter().getProfileProxy(context,
104                 new MapClientServiceListener(), BluetoothProfile.MAP_CLIENT);
105     }
106 
accessProfileEnabled()107     public boolean accessProfileEnabled() {
108         return true;
109     }
110 
isAutoConnectable()111     public boolean isAutoConnectable() {
112         return true;
113     }
114 
getConnectionStatus(BluetoothDevice device)115     public int getConnectionStatus(BluetoothDevice device) {
116         if (mService == null) {
117             return BluetoothProfile.STATE_DISCONNECTED;
118         }
119         return mService.getConnectionState(device);
120     }
121 
122     @Override
isEnabled(BluetoothDevice device)123     public boolean isEnabled(BluetoothDevice device) {
124         if (mService == null) {
125             return false;
126         }
127         return mService.getConnectionPolicy(device) > CONNECTION_POLICY_FORBIDDEN;
128     }
129 
130     @Override
getConnectionPolicy(BluetoothDevice device)131     public int getConnectionPolicy(BluetoothDevice device) {
132         if (mService == null) {
133             return CONNECTION_POLICY_FORBIDDEN;
134         }
135         return mService.getConnectionPolicy(device);
136     }
137 
138     @Override
setEnabled(BluetoothDevice device, boolean enabled)139     public boolean setEnabled(BluetoothDevice device, boolean enabled) {
140         boolean isEnabled = false;
141         if (mService == null) {
142             return false;
143         }
144         if (enabled) {
145             if (mService.getConnectionPolicy(device) < CONNECTION_POLICY_ALLOWED) {
146                 isEnabled = mService.setConnectionPolicy(device, CONNECTION_POLICY_ALLOWED);
147             }
148         } else {
149             isEnabled = mService.setConnectionPolicy(device, CONNECTION_POLICY_FORBIDDEN);
150         }
151 
152         return isEnabled;
153     }
154 
getConnectedDevices()155     public List<BluetoothDevice> getConnectedDevices() {
156         if (mService == null) {
157             return new ArrayList<BluetoothDevice>(0);
158         }
159         return mService.getDevicesMatchingConnectionStates(
160               new int[] {BluetoothProfile.STATE_CONNECTED,
161                          BluetoothProfile.STATE_CONNECTING,
162                          BluetoothProfile.STATE_DISCONNECTING});
163     }
164 
toString()165     public String toString() {
166         return NAME;
167     }
168 
getOrdinal()169     public int getOrdinal() {
170         return ORDINAL;
171     }
172 
getNameResource(BluetoothDevice device)173     public int getNameResource(BluetoothDevice device) {
174         return R.string.bluetooth_profile_map;
175     }
176 
getSummaryResourceForDevice(BluetoothDevice device)177     public int getSummaryResourceForDevice(BluetoothDevice device) {
178         int state = getConnectionStatus(device);
179         switch (state) {
180             case BluetoothProfile.STATE_DISCONNECTED:
181                 return R.string.bluetooth_map_profile_summary_use_for;
182 
183             case BluetoothProfile.STATE_CONNECTED:
184                 return R.string.bluetooth_map_profile_summary_connected;
185 
186             default:
187                 return BluetoothUtils.getConnectionStateSummary(state);
188         }
189     }
190 
getDrawableResource(BluetoothClass btClass)191     public int getDrawableResource(BluetoothClass btClass) {
192         return com.android.internal.R.drawable.ic_phone;
193     }
194 
finalize()195     protected void finalize() {
196         Log.d(TAG, "finalize()");
197         if (mService != null) {
198             try {
199                 BluetoothAdapter.getDefaultAdapter().closeProfileProxy(BluetoothProfile.MAP_CLIENT,
200                         mService);
201                 mService = null;
202             }catch (Throwable t) {
203                 Log.w(TAG, "Error cleaning up MAP Client proxy", t);
204             }
205         }
206     }
207 }
208