• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2016 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 
17 package com.android.server.telecom.bluetooth;
18 
19 import android.bluetooth.BluetoothDevice;
20 import android.bluetooth.BluetoothHeadset;
21 import android.bluetooth.BluetoothManager;
22 import android.bluetooth.BluetoothProfile;
23 import android.content.BroadcastReceiver;
24 import android.content.Context;
25 import android.content.Intent;
26 import android.content.IntentFilter;
27 import android.telecom.Log;
28 
29 import com.android.server.telecom.BluetoothAdapterProxy;
30 import com.android.server.telecom.BluetoothHeadsetProxy;
31 import com.android.server.telecom.TelecomSystem;
32 
33 import java.util.Collection;
34 import java.util.LinkedHashMap;
35 import java.util.LinkedList;
36 import java.util.List;
37 import java.util.Map;
38 import java.util.Objects;
39 import java.util.stream.Collectors;
40 
41 public class BluetoothDeviceManager {
42     private final BluetoothProfile.ServiceListener mBluetoothProfileServiceListener =
43             new BluetoothProfile.ServiceListener() {
44                 @Override
45                 public void onServiceConnected(int profile, BluetoothProfile proxy) {
46                     Log.startSession("BMSL.oSC");
47                     try {
48                         synchronized (mLock) {
49                             if (profile == BluetoothProfile.HEADSET) {
50                                 mBluetoothHeadsetService =
51                                         new BluetoothHeadsetProxy((BluetoothHeadset) proxy);
52                                 Log.i(this, "- Got BluetoothHeadset: " + mBluetoothHeadsetService);
53                             } else {
54                                 Log.w(this, "Connected to non-headset bluetooth service." +
55                                         " Not changing bluetooth headset.");
56                             }
57                         }
58                     } finally {
59                         Log.endSession();
60                     }
61                 }
62 
63                 @Override
64                 public void onServiceDisconnected(int profile) {
65                     Log.startSession("BMSL.oSD");
66                     try {
67                         synchronized (mLock) {
68                             mBluetoothHeadsetService = null;
69                             Log.i(BluetoothDeviceManager.this, "Lost BluetoothHeadset service. " +
70                                     "Removing all tracked devices.");
71                             List<BluetoothDevice> devicesToRemove = new LinkedList<>(
72                                     mConnectedDevicesByAddress.values());
73                             mConnectedDevicesByAddress.clear();
74                             for (BluetoothDevice device : devicesToRemove) {
75                                 mBluetoothRouteManager.onDeviceLost(device.getAddress());
76                             }
77                         }
78                     } finally {
79                         Log.endSession();
80                     }
81                 }
82            };
83 
84     private final LinkedHashMap<String, BluetoothDevice> mConnectedDevicesByAddress =
85             new LinkedHashMap<>();
86     private final TelecomSystem.SyncRoot mLock;
87 
88     private BluetoothRouteManager mBluetoothRouteManager;
89     private BluetoothHeadsetProxy mBluetoothHeadsetService;
90 
BluetoothDeviceManager(Context context, BluetoothAdapterProxy bluetoothAdapter, TelecomSystem.SyncRoot lock)91     public BluetoothDeviceManager(Context context, BluetoothAdapterProxy bluetoothAdapter,
92             TelecomSystem.SyncRoot lock) {
93         mLock = lock;
94 
95         if (bluetoothAdapter != null) {
96             bluetoothAdapter.getProfileProxy(context, mBluetoothProfileServiceListener,
97                     BluetoothProfile.HEADSET);
98         }
99     }
100 
setBluetoothRouteManager(BluetoothRouteManager brm)101     public void setBluetoothRouteManager(BluetoothRouteManager brm) {
102         mBluetoothRouteManager = brm;
103     }
104 
getNumConnectedDevices()105     public int getNumConnectedDevices() {
106         return mConnectedDevicesByAddress.size();
107     }
108 
getConnectedDevices()109     public Collection<BluetoothDevice> getConnectedDevices() {
110         return mConnectedDevicesByAddress.values();
111     }
112 
getMostRecentlyConnectedDevice(String excludeAddress)113     public String getMostRecentlyConnectedDevice(String excludeAddress) {
114         String result = null;
115         synchronized (mLock) {
116             for (String addr : mConnectedDevicesByAddress.keySet()) {
117                 if (!Objects.equals(addr, excludeAddress)) {
118                     result = addr;
119                 }
120             }
121         }
122         return result;
123     }
124 
getHeadsetService()125     public BluetoothHeadsetProxy getHeadsetService() {
126         return mBluetoothHeadsetService;
127     }
128 
setHeadsetServiceForTesting(BluetoothHeadsetProxy bluetoothHeadset)129     public void setHeadsetServiceForTesting(BluetoothHeadsetProxy bluetoothHeadset) {
130         mBluetoothHeadsetService = bluetoothHeadset;
131     }
132 
getDeviceFromAddress(String address)133     public BluetoothDevice getDeviceFromAddress(String address) {
134         return mConnectedDevicesByAddress.get(address);
135     }
136 
onDeviceConnected(BluetoothDevice device)137     void onDeviceConnected(BluetoothDevice device) {
138         synchronized (mLock) {
139             if (!mConnectedDevicesByAddress.containsKey(device.getAddress())) {
140                 mConnectedDevicesByAddress.put(device.getAddress(), device);
141                 mBluetoothRouteManager.onDeviceAdded(device.getAddress());
142             }
143         }
144     }
145 
onDeviceDisconnected(BluetoothDevice device)146     void onDeviceDisconnected(BluetoothDevice device) {
147         synchronized (mLock) {
148             if (mConnectedDevicesByAddress.containsKey(device.getAddress())) {
149                 mConnectedDevicesByAddress.remove(device.getAddress());
150                 mBluetoothRouteManager.onDeviceLost(device.getAddress());
151             }
152         }
153     }
154 }
155