blob: a7621fcf02fb1a915551a5394abc6dbe8d5a4478 [file] [log] [blame]
Joseph Pirozzo631768d2016-09-01 14:19:28 -07001/*
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
17package com.android.settingslib.bluetooth;
18
19import android.bluetooth.BluetoothAdapter;
20import android.bluetooth.BluetoothClass;
21import android.bluetooth.BluetoothDevice;
22import android.bluetooth.BluetoothMapClient;
23import android.bluetooth.BluetoothProfile;
24import android.bluetooth.BluetoothUuid;
25import android.content.Context;
26import android.os.ParcelUuid;
27import android.util.Log;
28
29import com.android.settingslib.R;
30
31import java.util.ArrayList;
32import java.util.List;
33
34/**
35 * MapClientProfile handles Bluetooth MAP profile.
36 */
37public 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
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
85 public void onServiceDisconnected(int profile) {
86 if (V) Log.d(TAG,"Bluetooth service disconnected");
87 mProfileManager.callServiceDisconnectedListeners();
88 mIsProfileReady=false;
89 }
90 }
91
92 public boolean isProfileReady() {
93 if(V) Log.d(TAG,"isProfileReady(): "+ mIsProfileReady);
94 return mIsProfileReady;
95 }
96
97 MapClientProfile(Context context, LocalBluetoothAdapter adapter,
98 CachedBluetoothDeviceManager deviceManager,
99 LocalBluetoothProfileManager profileManager) {
100 mLocalAdapter = adapter;
101 mDeviceManager = deviceManager;
102 mProfileManager = profileManager;
103 mLocalAdapter.getProfileProxy(context, new MapClientServiceListener(),
104 BluetoothProfile.MAP_CLIENT);
105 }
106
107 public boolean isConnectable() {
108 return true;
109 }
110
111 public boolean isAutoConnectable() {
112 return true;
113 }
114
115 public boolean connect(BluetoothDevice device) {
116 if (mService == null) return false;
117 List<BluetoothDevice> connectedDevices = getConnectedDevices();
118 if (connectedDevices != null) {
119 for (BluetoothDevice connectedDevice : connectedDevices) {
120 mService.disconnect(connectedDevice);
121 }
122 }
123 return mService.connect(device);
124 }
125
126 public boolean disconnect(BluetoothDevice device) {
127 if (mService == null) return false;
128 // Downgrade priority as user is disconnecting.
129 if (mService.getPriority(device) > BluetoothProfile.PRIORITY_ON) {
130 mService.setPriority(device, BluetoothProfile.PRIORITY_ON);
131 }
132 return mService.disconnect(device);
133 }
134
135 public int getConnectionStatus(BluetoothDevice device) {
136 if (mService == null) return BluetoothProfile.STATE_DISCONNECTED;
137
138 return mService.getConnectionState(device);
139 }
140
141 public boolean isPreferred(BluetoothDevice device) {
142 if (mService == null) return false;
143 return mService.getPriority(device) > BluetoothProfile.PRIORITY_OFF;
144 }
145
146 public int getPreferred(BluetoothDevice device) {
147 if (mService == null) return BluetoothProfile.PRIORITY_OFF;
148 return mService.getPriority(device);
149 }
150
151 public void setPreferred(BluetoothDevice device, boolean preferred) {
152 if (mService == null) return;
153 if (preferred) {
154 if (mService.getPriority(device) < BluetoothProfile.PRIORITY_ON) {
155 mService.setPriority(device, BluetoothProfile.PRIORITY_ON);
156 }
157 } else {
158 mService.setPriority(device, BluetoothProfile.PRIORITY_OFF);
159 }
160 }
161
162 public List<BluetoothDevice> getConnectedDevices() {
163 if (mService == null) return new ArrayList<BluetoothDevice>(0);
164 return mService.getDevicesMatchingConnectionStates(
165 new int[] {BluetoothProfile.STATE_CONNECTED,
166 BluetoothProfile.STATE_CONNECTING,
167 BluetoothProfile.STATE_DISCONNECTING});
168 }
169
170 public String toString() {
171 return NAME;
172 }
173
174 public int getOrdinal() {
175 return ORDINAL;
176 }
177
178 public int getNameResource(BluetoothDevice device) {
179 return R.string.bluetooth_profile_map;
180 }
181
182 public int getSummaryResourceForDevice(BluetoothDevice device) {
183 int state = getConnectionStatus(device);
184 switch (state) {
185 case BluetoothProfile.STATE_DISCONNECTED:
186 return R.string.bluetooth_map_profile_summary_use_for;
187
188 case BluetoothProfile.STATE_CONNECTED:
189 return R.string.bluetooth_map_profile_summary_connected;
190
191 default:
192 return Utils.getConnectionStateSummary(state);
193 }
194 }
195
196 public int getDrawableResource(BluetoothClass btClass) {
197 return R.drawable.ic_bt_cellphone;
198 }
199
200 protected void finalize() {
201 if (V) Log.d(TAG, "finalize()");
202 if (mService != null) {
203 try {
204 BluetoothAdapter.getDefaultAdapter().closeProfileProxy(BluetoothProfile.MAP_CLIENT,
205 mService);
206 mService = null;
207 }catch (Throwable t) {
208 Log.w(TAG, "Error cleaning up MAP Client proxy", t);
209 }
210 }
211 }
212}