CachedBluetoothDeviceManager.java revision be3c5dbee66758517a8198f98ed2e20c80af326b
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
17package com.android.settingslib.bluetooth;
18
19import android.bluetooth.BluetoothAdapter;
20import android.bluetooth.BluetoothDevice;
21import android.content.Context;
22import android.util.Log;
23
24import java.util.ArrayList;
25import java.util.Collection;
26import java.util.List;
27
28/**
29 * CachedBluetoothDeviceManager manages the set of remote Bluetooth devices.
30 */
31public 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
40    CachedBluetoothDeviceManager(Context context, LocalBluetoothManager localBtManager) {
41        mContext = context;
42        mBtManager = localBtManager;
43    }
44
45    public synchronized Collection<CachedBluetoothDevice> getCachedDevicesCopy() {
46        return new ArrayList<CachedBluetoothDevice>(mCachedDevices);
47    }
48
49    public static boolean onDeviceDisappeared(CachedBluetoothDevice cachedDevice) {
50        cachedDevice.setVisible(false);
51        return cachedDevice.getBondState() == BluetoothDevice.BOND_NONE;
52    }
53
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     */
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     */
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     */
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
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
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
138    public synchronized void onBtClassChanged(BluetoothDevice device) {
139        CachedBluetoothDevice cachedDevice = findDevice(device);
140        if (cachedDevice != null) {
141            cachedDevice.refreshBtClass();
142        }
143    }
144
145    public synchronized void onUuidChanged(BluetoothDevice device) {
146        CachedBluetoothDevice cachedDevice = findDevice(device);
147        if (cachedDevice != null) {
148            cachedDevice.onUuidChanged();
149        }
150    }
151
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    }
170    private void log(String msg) {
171        if (DEBUG) {
172            Log.d(TAG, msg);
173        }
174    }
175}
176