1 /* 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 17 package com.android.settingslib.bluetooth; 18 19 import android.bluetooth.BluetoothAdapter; 20 import android.bluetooth.BluetoothDevice; 21 import android.content.Context; 22 import android.util.Log; 23 24 import java.util.ArrayList; 25 import java.util.Collection; 26 import java.util.List; 27 28 /** 29 * CachedBluetoothDeviceManager manages the set of remote Bluetooth devices. 30 */ 31 public final class CachedBluetoothDeviceManager { 32 private static final String TAG = "CachedBluetoothDeviceManager"; 33 private static final boolean DEBUG = Utils.D; 34 35 private Context mContext; 36 private final List<CachedBluetoothDevice> mCachedDevices = 37 new ArrayList<CachedBluetoothDevice>(); 38 private final LocalBluetoothManager mBtManager; 39 CachedBluetoothDeviceManager(Context context, LocalBluetoothManager localBtManager)40 CachedBluetoothDeviceManager(Context context, LocalBluetoothManager localBtManager) { 41 mContext = context; 42 mBtManager = localBtManager; 43 } 44 getCachedDevicesCopy()45 public synchronized Collection<CachedBluetoothDevice> getCachedDevicesCopy() { 46 return new ArrayList<CachedBluetoothDevice>(mCachedDevices); 47 } 48 onDeviceDisappeared(CachedBluetoothDevice cachedDevice)49 public static boolean onDeviceDisappeared(CachedBluetoothDevice cachedDevice) { 50 cachedDevice.setVisible(false); 51 return cachedDevice.getBondState() == BluetoothDevice.BOND_NONE; 52 } 53 onDeviceNameUpdated(BluetoothDevice device)54 public void onDeviceNameUpdated(BluetoothDevice device) { 55 CachedBluetoothDevice cachedDevice = findDevice(device); 56 if (cachedDevice != null) { 57 cachedDevice.refreshName(); 58 } 59 } 60 61 /** 62 * Search for existing {@link CachedBluetoothDevice} or return null 63 * if this device isn't in the cache. Use {@link #addDevice} 64 * to create and return a new {@link CachedBluetoothDevice} for 65 * a newly discovered {@link BluetoothDevice}. 66 * 67 * @param device the address of the Bluetooth device 68 * @return the cached device object for this device, or null if it has 69 * not been previously seen 70 */ findDevice(BluetoothDevice device)71 public CachedBluetoothDevice findDevice(BluetoothDevice device) { 72 for (CachedBluetoothDevice cachedDevice : mCachedDevices) { 73 if (cachedDevice.getDevice().equals(device)) { 74 return cachedDevice; 75 } 76 } 77 return null; 78 } 79 80 /** 81 * Create and return a new {@link CachedBluetoothDevice}. This assumes 82 * that {@link #findDevice} has already been called and returned null. 83 * @param device the address of the new Bluetooth device 84 * @return the newly created CachedBluetoothDevice object 85 */ addDevice(LocalBluetoothAdapter adapter, LocalBluetoothProfileManager profileManager, BluetoothDevice device)86 public CachedBluetoothDevice addDevice(LocalBluetoothAdapter adapter, 87 LocalBluetoothProfileManager profileManager, 88 BluetoothDevice device) { 89 CachedBluetoothDevice newDevice = new CachedBluetoothDevice(mContext, adapter, 90 profileManager, device); 91 synchronized (mCachedDevices) { 92 mCachedDevices.add(newDevice); 93 mBtManager.getEventManager().dispatchDeviceAdded(newDevice); 94 } 95 return newDevice; 96 } 97 98 /** 99 * Attempts to get the name of a remote device, otherwise returns the address. 100 * 101 * @param device The remote device. 102 * @return The name, or if unavailable, the address. 103 */ getName(BluetoothDevice device)104 public String getName(BluetoothDevice device) { 105 CachedBluetoothDevice cachedDevice = findDevice(device); 106 if (cachedDevice != null) { 107 return cachedDevice.getName(); 108 } 109 110 String name = device.getAliasName(); 111 if (name != null) { 112 return name; 113 } 114 115 return device.getAddress(); 116 } 117 clearNonBondedDevices()118 public synchronized void clearNonBondedDevices() { 119 for (int i = mCachedDevices.size() - 1; i >= 0; i--) { 120 CachedBluetoothDevice cachedDevice = mCachedDevices.get(i); 121 if (cachedDevice.getBondState() != BluetoothDevice.BOND_BONDED) { 122 mCachedDevices.remove(i); 123 } 124 } 125 } 126 onScanningStateChanged(boolean started)127 public synchronized void onScanningStateChanged(boolean started) { 128 if (!started) return; 129 130 // If starting a new scan, clear old visibility 131 // Iterate in reverse order since devices may be removed. 132 for (int i = mCachedDevices.size() - 1; i >= 0; i--) { 133 CachedBluetoothDevice cachedDevice = mCachedDevices.get(i); 134 cachedDevice.setVisible(false); 135 } 136 } 137 onBtClassChanged(BluetoothDevice device)138 public synchronized void onBtClassChanged(BluetoothDevice device) { 139 CachedBluetoothDevice cachedDevice = findDevice(device); 140 if (cachedDevice != null) { 141 cachedDevice.refreshBtClass(); 142 } 143 } 144 onUuidChanged(BluetoothDevice device)145 public synchronized void onUuidChanged(BluetoothDevice device) { 146 CachedBluetoothDevice cachedDevice = findDevice(device); 147 if (cachedDevice != null) { 148 cachedDevice.onUuidChanged(); 149 } 150 } 151 onBluetoothStateChanged(int bluetoothState)152 public synchronized void onBluetoothStateChanged(int bluetoothState) { 153 // When Bluetooth is turning off, we need to clear the non-bonded devices 154 // Otherwise, they end up showing up on the next BT enable 155 if (bluetoothState == BluetoothAdapter.STATE_TURNING_OFF) { 156 for (int i = mCachedDevices.size() - 1; i >= 0; i--) { 157 CachedBluetoothDevice cachedDevice = mCachedDevices.get(i); 158 if (cachedDevice.getBondState() != BluetoothDevice.BOND_BONDED) { 159 cachedDevice.setVisible(false); 160 mCachedDevices.remove(i); 161 } else { 162 // For bonded devices, we need to clear the connection status so that 163 // when BT is enabled next time, device connection status shall be retrieved 164 // by making a binder call. 165 cachedDevice.clearProfileConnectionState(); 166 } 167 } 168 } 169 } log(String msg)170 private void log(String msg) { 171 if (DEBUG) { 172 Log.d(TAG, msg); 173 } 174 } 175 } 176