blob: 76683b6a5e6a1eeb91bdccc3e7ad1a098887c271 [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
Jason Monk8111bcc2018-12-21 13:38:56 -050019import android.annotation.Nullable;
Sudheer Shankab6fc9312016-01-27 19:59:03 +000020import android.app.ActivityManager;
John Spurlockaf8d6c42014-05-07 17:49:08 -040021import android.bluetooth.BluetoothAdapter;
Jason Monk9ef03b42017-06-13 12:49:55 -040022import android.bluetooth.BluetoothDevice;
23import android.bluetooth.BluetoothProfile;
John Spurlockaf8d6c42014-05-07 17:49:08 -040024import android.content.Context;
Jason Monk744cf642015-05-19 12:04:41 -040025import android.os.Handler;
Jason Monk4ae97d32014-12-17 10:14:33 -050026import android.os.Looper;
Jason Monk744cf642015-05-19 12:04:41 -040027import android.os.Message;
Sudheer Shankab6fc9312016-01-27 19:59:03 +000028import android.os.UserHandle;
29import android.os.UserManager;
John Spurlock486b78e2014-07-07 08:37:56 -040030import android.util.Log;
John Spurlockaf8d6c42014-05-07 17:49:08 -040031
Jason Monkbe3c5db2015-02-04 13:00:55 -050032import com.android.settingslib.bluetooth.BluetoothCallback;
33import com.android.settingslib.bluetooth.CachedBluetoothDevice;
34import com.android.settingslib.bluetooth.LocalBluetoothManager;
Amin Shaikh45fb7a72018-04-18 14:14:38 -040035import com.android.settingslib.bluetooth.LocalBluetoothProfileManager;
Dave Mankofff4736812019-10-18 17:25:50 -040036import com.android.systemui.dagger.qualifiers.BgLooper;
37import com.android.systemui.dagger.qualifiers.MainLooper;
John Spurlock486b78e2014-07-07 08:37:56 -040038
39import java.io.FileDescriptor;
40import java.io.PrintWriter;
Jason Monk9ef03b42017-06-13 12:49:55 -040041import java.lang.ref.WeakReference;
John Spurlockaf8d6c42014-05-07 17:49:08 -040042import java.util.ArrayList;
Jason Monkbe3c5db2015-02-04 13:00:55 -050043import java.util.Collection;
Amin Shaikh45fb7a72018-04-18 14:14:38 -040044import java.util.List;
Jason Monk9ef03b42017-06-13 12:49:55 -040045import java.util.WeakHashMap;
John Spurlockaf8d6c42014-05-07 17:49:08 -040046
Jason Monk196d6392018-12-20 13:25:34 -050047import javax.inject.Inject;
Jason Monk196d6392018-12-20 13:25:34 -050048import javax.inject.Singleton;
49
50/**
51 */
52@Singleton
Jason Monkbe3c5db2015-02-04 13:00:55 -050053public class BluetoothControllerImpl implements BluetoothController, BluetoothCallback,
Amin Shaikh45fb7a72018-04-18 14:14:38 -040054 CachedBluetoothDevice.Callback, LocalBluetoothProfileManager.ServiceListener {
John Spurlock486b78e2014-07-07 08:37:56 -040055 private static final String TAG = "BluetoothController";
56 private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
Jason Monk4ae97d32014-12-17 10:14:33 -050057
Jason Monkbe3c5db2015-02-04 13:00:55 -050058 private final LocalBluetoothManager mLocalBluetoothManager;
Sudheer Shankab6fc9312016-01-27 19:59:03 +000059 private final UserManager mUserManager;
60 private final int mCurrentUser;
Jason Monk9ef03b42017-06-13 12:49:55 -040061 private final WeakHashMap<CachedBluetoothDevice, ActuallyCachedState> mCachedState =
62 new WeakHashMap<>();
63 private final Handler mBgHandler;
Amin Shaikh45fb7a72018-04-18 14:14:38 -040064 private final List<CachedBluetoothDevice> mConnectedDevices = new ArrayList<>();
Jason Monk4ae97d32014-12-17 10:14:33 -050065
John Spurlockd1c86e22014-06-01 00:04:53 -040066 private boolean mEnabled;
Jason Monka7d92b62015-05-27 10:20:37 -040067 private int mConnectionState = BluetoothAdapter.STATE_DISCONNECTED;
John Spurlockaf8d6c42014-05-07 17:49:08 -040068
Fabian Kozynskifee2e212019-09-17 12:09:21 -040069 private final H mHandler;
Jason Monkfac25382016-07-19 14:13:37 -040070 private int mState;
Jason Monk744cf642015-05-19 12:04:41 -040071
Jason Monk196d6392018-12-20 13:25:34 -050072 /**
73 */
74 @Inject
Dave Mankofff4736812019-10-18 17:25:50 -040075 public BluetoothControllerImpl(Context context, @BgLooper Looper bgLooper,
76 @MainLooper Looper mainLooper, @Nullable LocalBluetoothManager localBluetoothManager) {
Jason Monk8111bcc2018-12-21 13:38:56 -050077 mLocalBluetoothManager = localBluetoothManager;
Jason Monk9ef03b42017-06-13 12:49:55 -040078 mBgHandler = new Handler(bgLooper);
Fabian Kozynskifee2e212019-09-17 12:09:21 -040079 mHandler = new H(mainLooper);
Jason Monkbe3c5db2015-02-04 13:00:55 -050080 if (mLocalBluetoothManager != null) {
81 mLocalBluetoothManager.getEventManager().registerCallback(this);
Amin Shaikh45fb7a72018-04-18 14:14:38 -040082 mLocalBluetoothManager.getProfileManager().addServiceListener(this);
Jason Monkbe3c5db2015-02-04 13:00:55 -050083 onBluetoothStateChanged(
84 mLocalBluetoothManager.getBluetoothAdapter().getBluetoothState());
John Spurlockaf8d6c42014-05-07 17:49:08 -040085 }
Sudheer Shankab6fc9312016-01-27 19:59:03 +000086 mUserManager = (UserManager) context.getSystemService(Context.USER_SERVICE);
87 mCurrentUser = ActivityManager.getCurrentUser();
88 }
89
90 @Override
91 public boolean canConfigBluetooth() {
92 return !mUserManager.hasUserRestriction(UserManager.DISALLOW_CONFIG_BLUETOOTH,
phweissbd8d0332017-06-12 11:38:09 +020093 UserHandle.of(mCurrentUser))
94 && !mUserManager.hasUserRestriction(UserManager.DISALLOW_BLUETOOTH,
Sudheer Shankab6fc9312016-01-27 19:59:03 +000095 UserHandle.of(mCurrentUser));
John Spurlockaf8d6c42014-05-07 17:49:08 -040096 }
97
John Spurlock486b78e2014-07-07 08:37:56 -040098 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
99 pw.println("BluetoothController state:");
Jason Monkbe3c5db2015-02-04 13:00:55 -0500100 pw.print(" mLocalBluetoothManager="); pw.println(mLocalBluetoothManager);
Jason Monk09389a92015-05-19 16:06:52 -0400101 if (mLocalBluetoothManager == null) {
102 return;
103 }
John Spurlock486b78e2014-07-07 08:37:56 -0400104 pw.print(" mEnabled="); pw.println(mEnabled);
Jason Monka7d92b62015-05-27 10:20:37 -0400105 pw.print(" mConnectionState="); pw.println(stateToString(mConnectionState));
Amin Shaikh45fb7a72018-04-18 14:14:38 -0400106 pw.print(" mConnectedDevices="); pw.println(mConnectedDevices);
Adrian Roosa4b54862016-06-17 14:28:27 -0700107 pw.print(" mCallbacks.size="); pw.println(mHandler.mCallbacks.size());
Jason Monkbe3c5db2015-02-04 13:00:55 -0500108 pw.println(" Bluetooth Devices:");
Amin Shaikh45fb7a72018-04-18 14:14:38 -0400109 for (CachedBluetoothDevice device : getDevices()) {
Jason Monkbe3c5db2015-02-04 13:00:55 -0500110 pw.println(" " + getDeviceString(device));
John Spurlock486b78e2014-07-07 08:37:56 -0400111 }
112 }
113
Jason Monka7d92b62015-05-27 10:20:37 -0400114 private static String stateToString(int state) {
115 switch (state) {
116 case BluetoothAdapter.STATE_CONNECTED:
117 return "CONNECTED";
118 case BluetoothAdapter.STATE_CONNECTING:
119 return "CONNECTING";
120 case BluetoothAdapter.STATE_DISCONNECTED:
121 return "DISCONNECTED";
122 case BluetoothAdapter.STATE_DISCONNECTING:
123 return "DISCONNECTING";
124 }
125 return "UNKNOWN(" + state + ")";
126 }
127
Jason Monkbe3c5db2015-02-04 13:00:55 -0500128 private String getDeviceString(CachedBluetoothDevice device) {
129 return device.getName() + " " + device.getBondState() + " " + device.isConnected();
John Spurlock486b78e2014-07-07 08:37:56 -0400130 }
131
Jason Monka7d92b62015-05-27 10:20:37 -0400132 @Override
Jason Monk9ef03b42017-06-13 12:49:55 -0400133 public int getBondState(CachedBluetoothDevice device) {
134 return getCachedState(device).mBondState;
135 }
136
137 @Override
Amin Shaikh45fb7a72018-04-18 14:14:38 -0400138 public List<CachedBluetoothDevice> getConnectedDevices() {
139 return mConnectedDevices;
Jason Monk3fd0b142017-08-30 18:11:21 -0400140 }
141
142 @Override
Jason Monk9ef03b42017-06-13 12:49:55 -0400143 public int getMaxConnectionState(CachedBluetoothDevice device) {
144 return getCachedState(device).mMaxConnectionState;
145 }
146
147 @Override
Jason Monk88529052016-11-04 13:29:58 -0400148 public void addCallback(Callback cb) {
Adrian Roosa4b54862016-06-17 14:28:27 -0700149 mHandler.obtainMessage(H.MSG_ADD_CALLBACK, cb).sendToTarget();
Jason Monk744cf642015-05-19 12:04:41 -0400150 mHandler.sendEmptyMessage(H.MSG_STATE_CHANGED);
John Spurlockaf8d6c42014-05-07 17:49:08 -0400151 }
152
153 @Override
Jason Monk88529052016-11-04 13:29:58 -0400154 public void removeCallback(Callback cb) {
Adrian Roosa4b54862016-06-17 14:28:27 -0700155 mHandler.obtainMessage(H.MSG_REMOVE_CALLBACK, cb).sendToTarget();
John Spurlockaf8d6c42014-05-07 17:49:08 -0400156 }
157
158 @Override
159 public boolean isBluetoothEnabled() {
Jason Monkbe3c5db2015-02-04 13:00:55 -0500160 return mEnabled;
John Spurlockaf8d6c42014-05-07 17:49:08 -0400161 }
162
163 @Override
Jason Monkfac25382016-07-19 14:13:37 -0400164 public int getBluetoothState() {
165 return mState;
166 }
167
168 @Override
John Spurlockaf8d6c42014-05-07 17:49:08 -0400169 public boolean isBluetoothConnected() {
Jason Monka7d92b62015-05-27 10:20:37 -0400170 return mConnectionState == BluetoothAdapter.STATE_CONNECTED;
John Spurlockaf8d6c42014-05-07 17:49:08 -0400171 }
172
173 @Override
John Spurlockd1c86e22014-06-01 00:04:53 -0400174 public boolean isBluetoothConnecting() {
Jason Monka7d92b62015-05-27 10:20:37 -0400175 return mConnectionState == BluetoothAdapter.STATE_CONNECTING;
John Spurlockd1c86e22014-06-01 00:04:53 -0400176 }
177
178 @Override
John Spurlockaf8d6c42014-05-07 17:49:08 -0400179 public void setBluetoothEnabled(boolean enabled) {
Jason Monkbe3c5db2015-02-04 13:00:55 -0500180 if (mLocalBluetoothManager != null) {
181 mLocalBluetoothManager.getBluetoothAdapter().setBluetoothEnabled(enabled);
John Spurlockaf8d6c42014-05-07 17:49:08 -0400182 }
183 }
184
185 @Override
186 public boolean isBluetoothSupported() {
Jason Monkbe3c5db2015-02-04 13:00:55 -0500187 return mLocalBluetoothManager != null;
John Spurlockaf8d6c42014-05-07 17:49:08 -0400188 }
189
John Spurlock486b78e2014-07-07 08:37:56 -0400190 @Override
Jason Monkbe3c5db2015-02-04 13:00:55 -0500191 public void connect(final CachedBluetoothDevice device) {
192 if (mLocalBluetoothManager == null || device == null) return;
193 device.connect(true);
John Spurlock486b78e2014-07-07 08:37:56 -0400194 }
195
196 @Override
Jason Monkbe3c5db2015-02-04 13:00:55 -0500197 public void disconnect(CachedBluetoothDevice device) {
198 if (mLocalBluetoothManager == null || device == null) return;
199 device.disconnect();
John Spurlockaf8d6c42014-05-07 17:49:08 -0400200 }
201
202 @Override
Amin Shaikh45fb7a72018-04-18 14:14:38 -0400203 public String getConnectedDeviceName() {
204 if (mConnectedDevices.size() == 1) {
205 return mConnectedDevices.get(0).getName();
206 }
207 return null;
John Spurlockaf8d6c42014-05-07 17:49:08 -0400208 }
209
Jason Monkbe3c5db2015-02-04 13:00:55 -0500210 @Override
211 public Collection<CachedBluetoothDevice> getDevices() {
212 return mLocalBluetoothManager != null
213 ? mLocalBluetoothManager.getCachedDeviceManager().getCachedDevicesCopy()
214 : null;
Jason Monk4630c892014-12-08 16:36:16 -0500215 }
216
Jason Monkbe3c5db2015-02-04 13:00:55 -0500217 private void updateConnected() {
Jason Monk90970562015-06-19 10:04:49 -0400218 // Make sure our connection state is up to date.
219 int state = mLocalBluetoothManager.getBluetoothAdapter().getConnectionState();
Amin Shaikh45fb7a72018-04-18 14:14:38 -0400220 mConnectedDevices.clear();
Jason Monk6a73e632017-03-17 11:08:30 -0400221 // If any of the devices are in a higher state than the adapter, move the adapter into
222 // that state.
Jason Monkbe3c5db2015-02-04 13:00:55 -0500223 for (CachedBluetoothDevice device : getDevices()) {
Jason Monk6a73e632017-03-17 11:08:30 -0400224 int maxDeviceState = device.getMaxConnectionState();
225 if (maxDeviceState > state) {
226 state = maxDeviceState;
227 }
Amin Shaikh45fb7a72018-04-18 14:14:38 -0400228 if (device.isConnected()) {
229 mConnectedDevices.add(device);
John Spurlock486b78e2014-07-07 08:37:56 -0400230 }
John Spurlock486b78e2014-07-07 08:37:56 -0400231 }
Jason Monk6a73e632017-03-17 11:08:30 -0400232
Amin Shaikh45fb7a72018-04-18 14:14:38 -0400233 if (mConnectedDevices.isEmpty() && state == BluetoothAdapter.STATE_CONNECTED) {
Jason Monkbba73172015-08-12 16:17:34 -0400234 // If somehow we think we are connected, but have no connected devices, we aren't
235 // connected.
Jason Monk6a73e632017-03-17 11:08:30 -0400236 state = BluetoothAdapter.STATE_DISCONNECTED;
237 }
238 if (state != mConnectionState) {
239 mConnectionState = state;
Jason Monkbba73172015-08-12 16:17:34 -0400240 mHandler.sendEmptyMessage(H.MSG_STATE_CHANGED);
241 }
John Spurlock486b78e2014-07-07 08:37:56 -0400242 }
243
Jason Monkbe3c5db2015-02-04 13:00:55 -0500244 @Override
245 public void onBluetoothStateChanged(int bluetoothState) {
Fabian Kozynski7f27b8e2019-05-07 16:18:15 -0400246 if (DEBUG) Log.d(TAG, "BluetoothStateChanged=" + stateToString(bluetoothState));
Jason Monkfac25382016-07-19 14:13:37 -0400247 mEnabled = bluetoothState == BluetoothAdapter.STATE_ON
248 || bluetoothState == BluetoothAdapter.STATE_TURNING_ON;
249 mState = bluetoothState;
Amin Shaikhc5483402018-04-26 13:51:54 -0400250 updateConnected();
Jason Monk744cf642015-05-19 12:04:41 -0400251 mHandler.sendEmptyMessage(H.MSG_STATE_CHANGED);
John Spurlock486b78e2014-07-07 08:37:56 -0400252 }
253
Jason Monkbe3c5db2015-02-04 13:00:55 -0500254 @Override
Jason Monkbe3c5db2015-02-04 13:00:55 -0500255 public void onDeviceAdded(CachedBluetoothDevice cachedDevice) {
Fabian Kozynski7f27b8e2019-05-07 16:18:15 -0400256 if (DEBUG) Log.d(TAG, "DeviceAdded=" + cachedDevice.getAddress());
Jason Monkbe3c5db2015-02-04 13:00:55 -0500257 cachedDevice.registerCallback(this);
258 updateConnected();
Jason Monk744cf642015-05-19 12:04:41 -0400259 mHandler.sendEmptyMessage(H.MSG_PAIRED_DEVICES_CHANGED);
Jason Monkbe3c5db2015-02-04 13:00:55 -0500260 }
Jason Monk4ae97d32014-12-17 10:14:33 -0500261
Jason Monkbe3c5db2015-02-04 13:00:55 -0500262 @Override
263 public void onDeviceDeleted(CachedBluetoothDevice cachedDevice) {
Fabian Kozynski7f27b8e2019-05-07 16:18:15 -0400264 if (DEBUG) Log.d(TAG, "DeviceDeleted=" + cachedDevice.getAddress());
Jason Monk9ef03b42017-06-13 12:49:55 -0400265 mCachedState.remove(cachedDevice);
Jason Monkbe3c5db2015-02-04 13:00:55 -0500266 updateConnected();
Jason Monk744cf642015-05-19 12:04:41 -0400267 mHandler.sendEmptyMessage(H.MSG_PAIRED_DEVICES_CHANGED);
Jason Monkbe3c5db2015-02-04 13:00:55 -0500268 }
269
270 @Override
271 public void onDeviceBondStateChanged(CachedBluetoothDevice cachedDevice, int bondState) {
Fabian Kozynski7f27b8e2019-05-07 16:18:15 -0400272 if (DEBUG) Log.d(TAG, "DeviceBondStateChanged=" + cachedDevice.getAddress());
Jason Monk9ef03b42017-06-13 12:49:55 -0400273 mCachedState.remove(cachedDevice);
Jason Monkbe3c5db2015-02-04 13:00:55 -0500274 updateConnected();
Jason Monk744cf642015-05-19 12:04:41 -0400275 mHandler.sendEmptyMessage(H.MSG_PAIRED_DEVICES_CHANGED);
Jason Monkbe3c5db2015-02-04 13:00:55 -0500276 }
277
278 @Override
279 public void onDeviceAttributesChanged() {
Fabian Kozynski7f27b8e2019-05-07 16:18:15 -0400280 if (DEBUG) Log.d(TAG, "DeviceAttributesChanged");
Jason Monkbe3c5db2015-02-04 13:00:55 -0500281 updateConnected();
Jason Monk744cf642015-05-19 12:04:41 -0400282 mHandler.sendEmptyMessage(H.MSG_PAIRED_DEVICES_CHANGED);
Jason Monkbe3c5db2015-02-04 13:00:55 -0500283 }
284
285 @Override
286 public void onConnectionStateChanged(CachedBluetoothDevice cachedDevice, int state) {
Fabian Kozynski7f27b8e2019-05-07 16:18:15 -0400287 if (DEBUG) {
288 Log.d(TAG, "ConnectionStateChanged=" + cachedDevice.getAddress() + " "
289 + stateToString(state));
290 }
291 mCachedState.remove(cachedDevice);
292 updateConnected();
293 mHandler.sendEmptyMessage(H.MSG_STATE_CHANGED);
294 }
295
296 @Override
Amin Shaikha7e6f392019-07-03 08:33:28 -0400297 public void onProfileConnectionStateChanged(CachedBluetoothDevice cachedDevice,
298 int state, int bluetoothProfile) {
299 if (DEBUG) {
300 Log.d(TAG, "ProfileConnectionStateChanged=" + cachedDevice.getAddress() + " "
301 + stateToString(state) + " profileId=" + bluetoothProfile);
302 }
303 mCachedState.remove(cachedDevice);
304 updateConnected();
305 mHandler.sendEmptyMessage(H.MSG_STATE_CHANGED);
306 }
307
308 @Override
Fabian Kozynski7f27b8e2019-05-07 16:18:15 -0400309 public void onAclConnectionStateChanged(CachedBluetoothDevice cachedDevice, int state) {
310 if (DEBUG) {
311 Log.d(TAG, "ACLConnectionStateChanged=" + cachedDevice.getAddress() + " "
312 + stateToString(state));
313 }
Jason Monk9ef03b42017-06-13 12:49:55 -0400314 mCachedState.remove(cachedDevice);
Jason Monkbe3c5db2015-02-04 13:00:55 -0500315 updateConnected();
Jason Monk744cf642015-05-19 12:04:41 -0400316 mHandler.sendEmptyMessage(H.MSG_STATE_CHANGED);
317 }
318
Jason Monk9ef03b42017-06-13 12:49:55 -0400319 private ActuallyCachedState getCachedState(CachedBluetoothDevice device) {
320 ActuallyCachedState state = mCachedState.get(device);
321 if (state == null) {
322 state = new ActuallyCachedState(device, mHandler);
323 mBgHandler.post(state);
324 mCachedState.put(device, state);
325 return state;
326 }
327 return state;
328 }
329
Amin Shaikh45fb7a72018-04-18 14:14:38 -0400330 @Override
331 public void onServiceConnected() {
332 updateConnected();
333 mHandler.sendEmptyMessage(H.MSG_PAIRED_DEVICES_CHANGED);
334 }
335
336 @Override
337 public void onServiceDisconnected() {}
338
Jason Monk9ef03b42017-06-13 12:49:55 -0400339 private static class ActuallyCachedState implements Runnable {
340
341 private final WeakReference<CachedBluetoothDevice> mDevice;
342 private final Handler mUiHandler;
343 private int mBondState = BluetoothDevice.BOND_NONE;
344 private int mMaxConnectionState = BluetoothProfile.STATE_DISCONNECTED;
345
346 private ActuallyCachedState(CachedBluetoothDevice device, Handler uiHandler) {
347 mDevice = new WeakReference<>(device);
348 mUiHandler = uiHandler;
349 }
350
351 @Override
352 public void run() {
Jason Monk0f5d4022017-08-15 14:29:49 -0400353 CachedBluetoothDevice device = mDevice.get();
354 if (device != null) {
355 mBondState = device.getBondState();
356 mMaxConnectionState = device.getMaxConnectionState();
357 mUiHandler.removeMessages(H.MSG_PAIRED_DEVICES_CHANGED);
358 mUiHandler.sendEmptyMessage(H.MSG_PAIRED_DEVICES_CHANGED);
359 }
Jason Monk9ef03b42017-06-13 12:49:55 -0400360 }
361 }
362
Jason Monk744cf642015-05-19 12:04:41 -0400363 private final class H extends Handler {
Adrian Roosa4b54862016-06-17 14:28:27 -0700364 private final ArrayList<BluetoothController.Callback> mCallbacks = new ArrayList<>();
365
Jason Monk744cf642015-05-19 12:04:41 -0400366 private static final int MSG_PAIRED_DEVICES_CHANGED = 1;
367 private static final int MSG_STATE_CHANGED = 2;
Adrian Roosa4b54862016-06-17 14:28:27 -0700368 private static final int MSG_ADD_CALLBACK = 3;
369 private static final int MSG_REMOVE_CALLBACK = 4;
Jason Monk744cf642015-05-19 12:04:41 -0400370
Jason Monk9ef03b42017-06-13 12:49:55 -0400371 public H(Looper looper) {
372 super(looper);
373 }
374
Jason Monk744cf642015-05-19 12:04:41 -0400375 @Override
376 public void handleMessage(Message msg) {
377 switch (msg.what) {
378 case MSG_PAIRED_DEVICES_CHANGED:
379 firePairedDevicesChanged();
380 break;
381 case MSG_STATE_CHANGED:
382 fireStateChange();
383 break;
Adrian Roosa4b54862016-06-17 14:28:27 -0700384 case MSG_ADD_CALLBACK:
385 mCallbacks.add((BluetoothController.Callback) msg.obj);
386 break;
387 case MSG_REMOVE_CALLBACK:
388 mCallbacks.remove((BluetoothController.Callback) msg.obj);
389 break;
Jason Monk744cf642015-05-19 12:04:41 -0400390 }
391 }
392
393 private void firePairedDevicesChanged() {
394 for (BluetoothController.Callback cb : mCallbacks) {
395 cb.onBluetoothDevicesChanged();
396 }
397 }
398
399 private void fireStateChange() {
400 for (BluetoothController.Callback cb : mCallbacks) {
401 fireStateChange(cb);
402 }
403 }
404
405 private void fireStateChange(BluetoothController.Callback cb) {
Jason Monka7d92b62015-05-27 10:20:37 -0400406 cb.onBluetoothStateChange(mEnabled);
Jason Monk744cf642015-05-19 12:04:41 -0400407 }
John Spurlock486b78e2014-07-07 08:37:56 -0400408 }
John Spurlockaf8d6c42014-05-07 17:49:08 -0400409}