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