blob: 7d334eb31a199e3d835a3a7631c7c52c7385f568 [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
Joseph Pirozzo631768d2016-09-01 14:19:28 -070044 private final CachedBluetoothDeviceManager mDeviceManager;
45 private final LocalBluetoothProfileManager mProfileManager;
46
47 static final ParcelUuid[] UUIDS = {
48 BluetoothUuid.MAP,
49 BluetoothUuid.MNS,
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
62 public void onServiceConnected(int profile, BluetoothProfile proxy) {
63 if (V) Log.d(TAG,"Bluetooth service connected");
64 mService = (BluetoothMapClient) proxy;
65 // We just bound to the service, so refresh the UI for any connected MAP devices.
66 List<BluetoothDevice> deviceList = mService.getConnectedDevices();
67 while (!deviceList.isEmpty()) {
68 BluetoothDevice nextDevice = deviceList.remove(0);
69 CachedBluetoothDevice device = mDeviceManager.findDevice(nextDevice);
70 // we may add a new device here, but generally this should not happen
71 if (device == null) {
72 Log.w(TAG, "MapProfile found new device: " + nextDevice);
timhypengf64f6902018-07-31 15:40:15 +080073 device = mDeviceManager.addDevice(nextDevice);
Joseph Pirozzo631768d2016-09-01 14:19:28 -070074 }
75 device.onProfileStateChanged(MapClientProfile.this,
76 BluetoothProfile.STATE_CONNECTED);
77 device.refresh();
78 }
79
80 mProfileManager.callServiceConnectedListeners();
81 mIsProfileReady=true;
82 }
83
84 public void onServiceDisconnected(int profile) {
85 if (V) Log.d(TAG,"Bluetooth service disconnected");
86 mProfileManager.callServiceDisconnectedListeners();
87 mIsProfileReady=false;
88 }
89 }
90
91 public boolean isProfileReady() {
92 if(V) Log.d(TAG,"isProfileReady(): "+ mIsProfileReady);
93 return mIsProfileReady;
94 }
95
ryanywlin44de3a02018-05-02 15:15:37 +080096 @Override
97 public int getProfileId() {
98 return BluetoothProfile.MAP_CLIENT;
99 }
100
timhypengf64f6902018-07-31 15:40:15 +0800101 MapClientProfile(Context context, CachedBluetoothDeviceManager deviceManager,
Joseph Pirozzo631768d2016-09-01 14:19:28 -0700102 LocalBluetoothProfileManager profileManager) {
Joseph Pirozzo631768d2016-09-01 14:19:28 -0700103 mDeviceManager = deviceManager;
104 mProfileManager = profileManager;
timhypengf64f6902018-07-31 15:40:15 +0800105 BluetoothAdapter.getDefaultAdapter().getProfileProxy(context,
106 new MapClientServiceListener(), BluetoothProfile.MAP_CLIENT);
Joseph Pirozzo631768d2016-09-01 14:19:28 -0700107 }
108
109 public boolean isConnectable() {
110 return true;
111 }
112
113 public boolean isAutoConnectable() {
114 return true;
115 }
116
117 public boolean connect(BluetoothDevice device) {
118 if (mService == null) return false;
119 List<BluetoothDevice> connectedDevices = getConnectedDevices();
Joseph Pirozzo43eba082017-03-30 15:42:01 -0700120 if (connectedDevices != null && connectedDevices.contains(device)) {
121 // Connect to same device, Ignore it
122 Log.d(TAG,"Ignoring Connect");
123 return true;
Joseph Pirozzo631768d2016-09-01 14:19:28 -0700124 }
125 return mService.connect(device);
126 }
127
128 public boolean disconnect(BluetoothDevice device) {
129 if (mService == null) return false;
130 // Downgrade priority as user is disconnecting.
131 if (mService.getPriority(device) > BluetoothProfile.PRIORITY_ON) {
132 mService.setPriority(device, BluetoothProfile.PRIORITY_ON);
133 }
134 return mService.disconnect(device);
135 }
136
137 public int getConnectionStatus(BluetoothDevice device) {
138 if (mService == null) return BluetoothProfile.STATE_DISCONNECTED;
139
140 return mService.getConnectionState(device);
141 }
142
143 public boolean isPreferred(BluetoothDevice device) {
144 if (mService == null) return false;
145 return mService.getPriority(device) > BluetoothProfile.PRIORITY_OFF;
146 }
147
148 public int getPreferred(BluetoothDevice device) {
149 if (mService == null) return BluetoothProfile.PRIORITY_OFF;
150 return mService.getPriority(device);
151 }
152
153 public void setPreferred(BluetoothDevice device, boolean preferred) {
154 if (mService == null) return;
155 if (preferred) {
156 if (mService.getPriority(device) < BluetoothProfile.PRIORITY_ON) {
157 mService.setPriority(device, BluetoothProfile.PRIORITY_ON);
158 }
159 } else {
160 mService.setPriority(device, BluetoothProfile.PRIORITY_OFF);
161 }
162 }
163
164 public List<BluetoothDevice> getConnectedDevices() {
165 if (mService == null) return new ArrayList<BluetoothDevice>(0);
166 return mService.getDevicesMatchingConnectionStates(
167 new int[] {BluetoothProfile.STATE_CONNECTED,
168 BluetoothProfile.STATE_CONNECTING,
169 BluetoothProfile.STATE_DISCONNECTING});
170 }
171
172 public String toString() {
173 return NAME;
174 }
175
176 public int getOrdinal() {
177 return ORDINAL;
178 }
179
180 public int getNameResource(BluetoothDevice device) {
181 return R.string.bluetooth_profile_map;
182 }
183
184 public int getSummaryResourceForDevice(BluetoothDevice device) {
185 int state = getConnectionStatus(device);
186 switch (state) {
187 case BluetoothProfile.STATE_DISCONNECTED:
188 return R.string.bluetooth_map_profile_summary_use_for;
189
190 case BluetoothProfile.STATE_CONNECTED:
191 return R.string.bluetooth_map_profile_summary_connected;
192
193 default:
Kunhung Lie7b7cb82018-05-17 11:04:54 +0800194 return BluetoothUtils.getConnectionStateSummary(state);
Joseph Pirozzo631768d2016-09-01 14:19:28 -0700195 }
196 }
197
198 public int getDrawableResource(BluetoothClass btClass) {
199 return R.drawable.ic_bt_cellphone;
200 }
201
202 protected void finalize() {
203 if (V) Log.d(TAG, "finalize()");
204 if (mService != null) {
205 try {
206 BluetoothAdapter.getDefaultAdapter().closeProfileProxy(BluetoothProfile.MAP_CLIENT,
207 mService);
208 mService = null;
209 }catch (Throwable t) {
210 Log.w(TAG, "Error cleaning up MAP Client proxy", t);
211 }
212 }
213 }
214}