blob: 63af24c30f4a2b053da4930400b8982c75046a98 [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);
Chienyuan804e7c12018-07-30 19:46:33 +080074 device = mDeviceManager.addDevice(mLocalAdapter, nextDevice);
Joseph Pirozzo631768d2016-09-01 14:19:28 -070075 }
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
ryanywlin44de3a02018-05-02 15:15:37 +080097 @Override
98 public int getProfileId() {
99 return BluetoothProfile.MAP_CLIENT;
100 }
101
Joseph Pirozzo631768d2016-09-01 14:19:28 -0700102 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
112 public boolean isConnectable() {
113 return true;
114 }
115
116 public boolean isAutoConnectable() {
117 return true;
118 }
119
120 public boolean connect(BluetoothDevice device) {
121 if (mService == null) return false;
122 List<BluetoothDevice> connectedDevices = getConnectedDevices();
Joseph Pirozzo43eba082017-03-30 15:42:01 -0700123 if (connectedDevices != null && connectedDevices.contains(device)) {
124 // Connect to same device, Ignore it
125 Log.d(TAG,"Ignoring Connect");
126 return true;
Joseph Pirozzo631768d2016-09-01 14:19:28 -0700127 }
128 return mService.connect(device);
129 }
130
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
140 public int getConnectionStatus(BluetoothDevice device) {
141 if (mService == null) return BluetoothProfile.STATE_DISCONNECTED;
142
143 return mService.getConnectionState(device);
144 }
145
146 public boolean isPreferred(BluetoothDevice device) {
147 if (mService == null) return false;
148 return mService.getPriority(device) > BluetoothProfile.PRIORITY_OFF;
149 }
150
151 public int getPreferred(BluetoothDevice device) {
152 if (mService == null) return BluetoothProfile.PRIORITY_OFF;
153 return mService.getPriority(device);
154 }
155
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
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
175 public String toString() {
176 return NAME;
177 }
178
179 public int getOrdinal() {
180 return ORDINAL;
181 }
182
183 public int getNameResource(BluetoothDevice device) {
184 return R.string.bluetooth_profile_map;
185 }
186
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:
Kunhung Lie7b7cb82018-05-17 11:04:54 +0800197 return BluetoothUtils.getConnectionStateSummary(state);
Joseph Pirozzo631768d2016-09-01 14:19:28 -0700198 }
199 }
200
201 public int getDrawableResource(BluetoothClass btClass) {
202 return R.drawable.ic_bt_cellphone;
203 }
204
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}