blob: 114427c1b94f3b7c688f6aba0567494873c9d98b [file] [log] [blame]
John Spurlockaf8d6c42014-05-07 17:49:08 -04001/*
2 * Copyright (C) 2008 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.systemui.statusbar.policy;
18
19import android.bluetooth.BluetoothAdapter;
John Spurlockaf8d6c42014-05-07 17:49:08 -040020import android.content.Context;
Jason Monk744cf642015-05-19 12:04:41 -040021import android.os.Handler;
Jason Monk4ae97d32014-12-17 10:14:33 -050022import android.os.Looper;
Jason Monk744cf642015-05-19 12:04:41 -040023import android.os.Message;
John Spurlock486b78e2014-07-07 08:37:56 -040024import android.util.Log;
John Spurlockaf8d6c42014-05-07 17:49:08 -040025
Jason Monkbe3c5db2015-02-04 13:00:55 -050026import com.android.settingslib.bluetooth.BluetoothCallback;
27import com.android.settingslib.bluetooth.CachedBluetoothDevice;
28import com.android.settingslib.bluetooth.LocalBluetoothManager;
John Spurlock486b78e2014-07-07 08:37:56 -040029
30import java.io.FileDescriptor;
31import java.io.PrintWriter;
John Spurlockaf8d6c42014-05-07 17:49:08 -040032import java.util.ArrayList;
Jason Monkbe3c5db2015-02-04 13:00:55 -050033import java.util.Collection;
John Spurlockaf8d6c42014-05-07 17:49:08 -040034
Jason Monkbe3c5db2015-02-04 13:00:55 -050035public class BluetoothControllerImpl implements BluetoothController, BluetoothCallback,
36 CachedBluetoothDevice.Callback {
John Spurlock486b78e2014-07-07 08:37:56 -040037 private static final String TAG = "BluetoothController";
38 private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
Jason Monk4ae97d32014-12-17 10:14:33 -050039
John Spurlockd1c86e22014-06-01 00:04:53 -040040 private final ArrayList<Callback> mCallbacks = new ArrayList<Callback>();
Jason Monkbe3c5db2015-02-04 13:00:55 -050041 private final LocalBluetoothManager mLocalBluetoothManager;
Jason Monk4ae97d32014-12-17 10:14:33 -050042
John Spurlockd1c86e22014-06-01 00:04:53 -040043 private boolean mEnabled;
44 private boolean mConnecting;
Jason Monkbe3c5db2015-02-04 13:00:55 -050045 private CachedBluetoothDevice mLastDevice;
John Spurlockaf8d6c42014-05-07 17:49:08 -040046
Jason Monk744cf642015-05-19 12:04:41 -040047 private final H mHandler = new H();
48
Jason Monk4ae97d32014-12-17 10:14:33 -050049 public BluetoothControllerImpl(Context context, Looper bgLooper) {
Jason Monkbe3c5db2015-02-04 13:00:55 -050050 mLocalBluetoothManager = LocalBluetoothManager.getInstance(context, null);
51 if (mLocalBluetoothManager != null) {
Jason Monk744cf642015-05-19 12:04:41 -040052 mLocalBluetoothManager.getEventManager().setReceiverHandler(new Handler(bgLooper));
Jason Monkbe3c5db2015-02-04 13:00:55 -050053 mLocalBluetoothManager.getEventManager().registerCallback(this);
54 onBluetoothStateChanged(
55 mLocalBluetoothManager.getBluetoothAdapter().getBluetoothState());
John Spurlockaf8d6c42014-05-07 17:49:08 -040056 }
John Spurlockaf8d6c42014-05-07 17:49:08 -040057 }
58
John Spurlock486b78e2014-07-07 08:37:56 -040059 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
60 pw.println("BluetoothController state:");
Jason Monkbe3c5db2015-02-04 13:00:55 -050061 pw.print(" mLocalBluetoothManager="); pw.println(mLocalBluetoothManager);
John Spurlock486b78e2014-07-07 08:37:56 -040062 pw.print(" mEnabled="); pw.println(mEnabled);
63 pw.print(" mConnecting="); pw.println(mConnecting);
64 pw.print(" mLastDevice="); pw.println(mLastDevice);
65 pw.print(" mCallbacks.size="); pw.println(mCallbacks.size());
Jason Monkbe3c5db2015-02-04 13:00:55 -050066 pw.println(" Bluetooth Devices:");
67 for (CachedBluetoothDevice device :
68 mLocalBluetoothManager.getCachedDeviceManager().getCachedDevicesCopy()) {
69 pw.println(" " + getDeviceString(device));
John Spurlock486b78e2014-07-07 08:37:56 -040070 }
71 }
72
Jason Monkbe3c5db2015-02-04 13:00:55 -050073 private String getDeviceString(CachedBluetoothDevice device) {
74 return device.getName() + " " + device.getBondState() + " " + device.isConnected();
John Spurlock486b78e2014-07-07 08:37:56 -040075 }
76
John Spurlockd1c86e22014-06-01 00:04:53 -040077 public void addStateChangedCallback(Callback cb) {
78 mCallbacks.add(cb);
Jason Monk744cf642015-05-19 12:04:41 -040079 mHandler.sendEmptyMessage(H.MSG_STATE_CHANGED);
John Spurlockaf8d6c42014-05-07 17:49:08 -040080 }
81
82 @Override
John Spurlockd1c86e22014-06-01 00:04:53 -040083 public void removeStateChangedCallback(Callback cb) {
84 mCallbacks.remove(cb);
John Spurlockaf8d6c42014-05-07 17:49:08 -040085 }
86
87 @Override
88 public boolean isBluetoothEnabled() {
Jason Monkbe3c5db2015-02-04 13:00:55 -050089 return mEnabled;
John Spurlockaf8d6c42014-05-07 17:49:08 -040090 }
91
92 @Override
93 public boolean isBluetoothConnected() {
Jason Monkbe3c5db2015-02-04 13:00:55 -050094 return mLocalBluetoothManager != null
95 && mLocalBluetoothManager.getBluetoothAdapter().getConnectionState()
96 == BluetoothAdapter.STATE_CONNECTED;
John Spurlockaf8d6c42014-05-07 17:49:08 -040097 }
98
99 @Override
John Spurlockd1c86e22014-06-01 00:04:53 -0400100 public boolean isBluetoothConnecting() {
Jason Monkbe3c5db2015-02-04 13:00:55 -0500101 return mConnecting;
John Spurlockd1c86e22014-06-01 00:04:53 -0400102 }
103
104 @Override
John Spurlockaf8d6c42014-05-07 17:49:08 -0400105 public void setBluetoothEnabled(boolean enabled) {
Jason Monkbe3c5db2015-02-04 13:00:55 -0500106 if (mLocalBluetoothManager != null) {
107 mLocalBluetoothManager.getBluetoothAdapter().setBluetoothEnabled(enabled);
John Spurlockaf8d6c42014-05-07 17:49:08 -0400108 }
109 }
110
111 @Override
112 public boolean isBluetoothSupported() {
Jason Monkbe3c5db2015-02-04 13:00:55 -0500113 return mLocalBluetoothManager != null;
John Spurlockaf8d6c42014-05-07 17:49:08 -0400114 }
115
John Spurlock486b78e2014-07-07 08:37:56 -0400116 @Override
Jason Monkbe3c5db2015-02-04 13:00:55 -0500117 public void connect(final CachedBluetoothDevice device) {
118 if (mLocalBluetoothManager == null || device == null) return;
119 device.connect(true);
John Spurlock486b78e2014-07-07 08:37:56 -0400120 }
121
122 @Override
Jason Monkbe3c5db2015-02-04 13:00:55 -0500123 public void disconnect(CachedBluetoothDevice device) {
124 if (mLocalBluetoothManager == null || device == null) return;
125 device.disconnect();
John Spurlockaf8d6c42014-05-07 17:49:08 -0400126 }
127
128 @Override
John Spurlockd1c86e22014-06-01 00:04:53 -0400129 public String getLastDeviceName() {
Jason Monkbe3c5db2015-02-04 13:00:55 -0500130 return mLastDevice != null ? mLastDevice.getName() : null;
John Spurlockaf8d6c42014-05-07 17:49:08 -0400131 }
132
Jason Monkbe3c5db2015-02-04 13:00:55 -0500133 @Override
134 public Collection<CachedBluetoothDevice> getDevices() {
135 return mLocalBluetoothManager != null
136 ? mLocalBluetoothManager.getCachedDeviceManager().getCachedDevicesCopy()
137 : null;
Jason Monk4630c892014-12-08 16:36:16 -0500138 }
139
Jason Monkbe3c5db2015-02-04 13:00:55 -0500140 private void updateConnected() {
141 if (mLastDevice != null && mLastDevice.isConnected()) {
142 // Our current device is still valid.
143 return;
Jason Monk4ae97d32014-12-17 10:14:33 -0500144 }
Jason Monkbe3c5db2015-02-04 13:00:55 -0500145 for (CachedBluetoothDevice device : getDevices()) {
146 if (device.isConnected()) {
John Spurlock486b78e2014-07-07 08:37:56 -0400147 mLastDevice = device;
John Spurlock486b78e2014-07-07 08:37:56 -0400148 }
John Spurlock486b78e2014-07-07 08:37:56 -0400149 }
150 }
151
Jason Monkbe3c5db2015-02-04 13:00:55 -0500152 @Override
153 public void onBluetoothStateChanged(int bluetoothState) {
154 mEnabled = bluetoothState == BluetoothAdapter.STATE_ON;
Jason Monk744cf642015-05-19 12:04:41 -0400155 mHandler.sendEmptyMessage(H.MSG_STATE_CHANGED);
John Spurlock486b78e2014-07-07 08:37:56 -0400156 }
157
Jason Monkbe3c5db2015-02-04 13:00:55 -0500158 @Override
159 public void onScanningStateChanged(boolean started) {
160 // Don't care.
161 }
Jason Monk4ae97d32014-12-17 10:14:33 -0500162
Jason Monkbe3c5db2015-02-04 13:00:55 -0500163 @Override
164 public void onDeviceAdded(CachedBluetoothDevice cachedDevice) {
165 cachedDevice.registerCallback(this);
166 updateConnected();
Jason Monk744cf642015-05-19 12:04:41 -0400167 mHandler.sendEmptyMessage(H.MSG_PAIRED_DEVICES_CHANGED);
Jason Monkbe3c5db2015-02-04 13:00:55 -0500168 }
Jason Monk4ae97d32014-12-17 10:14:33 -0500169
Jason Monkbe3c5db2015-02-04 13:00:55 -0500170 @Override
171 public void onDeviceDeleted(CachedBluetoothDevice cachedDevice) {
172 updateConnected();
Jason Monk744cf642015-05-19 12:04:41 -0400173 mHandler.sendEmptyMessage(H.MSG_PAIRED_DEVICES_CHANGED);
Jason Monkbe3c5db2015-02-04 13:00:55 -0500174 }
175
176 @Override
177 public void onDeviceBondStateChanged(CachedBluetoothDevice cachedDevice, int bondState) {
178 updateConnected();
Jason Monk744cf642015-05-19 12:04:41 -0400179 mHandler.sendEmptyMessage(H.MSG_PAIRED_DEVICES_CHANGED);
Jason Monkbe3c5db2015-02-04 13:00:55 -0500180 }
181
182 @Override
183 public void onDeviceAttributesChanged() {
184 updateConnected();
Jason Monk744cf642015-05-19 12:04:41 -0400185 mHandler.sendEmptyMessage(H.MSG_PAIRED_DEVICES_CHANGED);
Jason Monkbe3c5db2015-02-04 13:00:55 -0500186 }
187
188 @Override
189 public void onConnectionStateChanged(CachedBluetoothDevice cachedDevice, int state) {
190 mConnecting = state == BluetoothAdapter.STATE_CONNECTING;
191 mLastDevice = cachedDevice;
192 updateConnected();
Jason Monk744cf642015-05-19 12:04:41 -0400193 mHandler.sendEmptyMessage(H.MSG_STATE_CHANGED);
194 }
195
196 private final class H extends Handler {
197 private static final int MSG_PAIRED_DEVICES_CHANGED = 1;
198 private static final int MSG_STATE_CHANGED = 2;
199
200 @Override
201 public void handleMessage(Message msg) {
202 switch (msg.what) {
203 case MSG_PAIRED_DEVICES_CHANGED:
204 firePairedDevicesChanged();
205 break;
206 case MSG_STATE_CHANGED:
207 fireStateChange();
208 break;
209 }
210 }
211
212 private void firePairedDevicesChanged() {
213 for (BluetoothController.Callback cb : mCallbacks) {
214 cb.onBluetoothDevicesChanged();
215 }
216 }
217
218 private void fireStateChange() {
219 for (BluetoothController.Callback cb : mCallbacks) {
220 fireStateChange(cb);
221 }
222 }
223
224 private void fireStateChange(BluetoothController.Callback cb) {
225 cb.onBluetoothStateChange(mEnabled, mConnecting);
226 }
John Spurlock486b78e2014-07-07 08:37:56 -0400227 }
John Spurlockaf8d6c42014-05-07 17:49:08 -0400228}