1d63c0112251ab4e4e977545368dd703d875012a4Nick Pelly/*
2d63c0112251ab4e4e977545368dd703d875012a4Nick Pelly * Copyright (C) 2008 The Android Open Source Project
3d63c0112251ab4e4e977545368dd703d875012a4Nick Pelly *
4d63c0112251ab4e4e977545368dd703d875012a4Nick Pelly * Licensed under the Apache License, Version 2.0 (the "License");
5d63c0112251ab4e4e977545368dd703d875012a4Nick Pelly * you may not use this file except in compliance with the License.
6d63c0112251ab4e4e977545368dd703d875012a4Nick Pelly * You may obtain a copy of the License at
7d63c0112251ab4e4e977545368dd703d875012a4Nick Pelly *
8d63c0112251ab4e4e977545368dd703d875012a4Nick Pelly *      http://www.apache.org/licenses/LICENSE-2.0
9d63c0112251ab4e4e977545368dd703d875012a4Nick Pelly *
10d63c0112251ab4e4e977545368dd703d875012a4Nick Pelly * Unless required by applicable law or agreed to in writing, software
11d63c0112251ab4e4e977545368dd703d875012a4Nick Pelly * distributed under the License is distributed on an "AS IS" BASIS,
12d63c0112251ab4e4e977545368dd703d875012a4Nick Pelly * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13d63c0112251ab4e4e977545368dd703d875012a4Nick Pelly * See the License for the specific language governing permissions and
14d63c0112251ab4e4e977545368dd703d875012a4Nick Pelly * limitations under the License.
15d63c0112251ab4e4e977545368dd703d875012a4Nick Pelly */
16d63c0112251ab4e4e977545368dd703d875012a4Nick Pelly
17d63c0112251ab4e4e977545368dd703d875012a4Nick Pellypackage com.android.settings.bluetooth;
18d63c0112251ab4e4e977545368dd703d875012a4Nick Pelly
19d63c0112251ab4e4e977545368dd703d875012a4Nick Pellyimport android.bluetooth.BluetoothDevice;
20b707255a440e53ec2865c4b34c7ea07d16d471bdMatthew Xieimport android.content.Context;
21b707255a440e53ec2865c4b34c7ea07d16d471bdMatthew Xieimport android.util.Log;
22d63c0112251ab4e4e977545368dd703d875012a4Nick Pelly
23d63c0112251ab4e4e977545368dd703d875012a4Nick Pellyimport java.util.ArrayList;
24436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hambyimport java.util.Collection;
25d63c0112251ab4e4e977545368dd703d875012a4Nick Pellyimport java.util.List;
26d63c0112251ab4e4e977545368dd703d875012a4Nick Pelly
27d63c0112251ab4e4e977545368dd703d875012a4Nick Pelly/**
28d63c0112251ab4e4e977545368dd703d875012a4Nick Pelly * CachedBluetoothDeviceManager manages the set of remote Bluetooth devices.
29d63c0112251ab4e4e977545368dd703d875012a4Nick Pelly */
30436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hambyfinal class CachedBluetoothDeviceManager {
31b707255a440e53ec2865c4b34c7ea07d16d471bdMatthew Xie    private static final String TAG = "CachedBluetoothDeviceManager";
32b707255a440e53ec2865c4b34c7ea07d16d471bdMatthew Xie    private static final boolean DEBUG = Utils.D;
33d63c0112251ab4e4e977545368dd703d875012a4Nick Pelly
34b707255a440e53ec2865c4b34c7ea07d16d471bdMatthew Xie    private Context mContext;
35436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby    private final List<CachedBluetoothDevice> mCachedDevices =
36436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby            new ArrayList<CachedBluetoothDevice>();
37d63c0112251ab4e4e977545368dd703d875012a4Nick Pelly
38b707255a440e53ec2865c4b34c7ea07d16d471bdMatthew Xie    CachedBluetoothDeviceManager(Context context) {
39b707255a440e53ec2865c4b34c7ea07d16d471bdMatthew Xie        mContext = context;
40b707255a440e53ec2865c4b34c7ea07d16d471bdMatthew Xie    }
41b707255a440e53ec2865c4b34c7ea07d16d471bdMatthew Xie
42436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby    public synchronized Collection<CachedBluetoothDevice> getCachedDevicesCopy() {
43d63c0112251ab4e4e977545368dd703d875012a4Nick Pelly        return new ArrayList<CachedBluetoothDevice>(mCachedDevices);
44d63c0112251ab4e4e977545368dd703d875012a4Nick Pelly    }
45d63c0112251ab4e4e977545368dd703d875012a4Nick Pelly
4679be0b3e6b5639c4cbe2bbcd9adb0ec4c28716edJake Hamby    public static boolean onDeviceDisappeared(CachedBluetoothDevice cachedDevice) {
47d63c0112251ab4e4e977545368dd703d875012a4Nick Pelly        cachedDevice.setVisible(false);
4879be0b3e6b5639c4cbe2bbcd9adb0ec4c28716edJake Hamby        return cachedDevice.getBondState() == BluetoothDevice.BOND_NONE;
49d63c0112251ab4e4e977545368dd703d875012a4Nick Pelly    }
50d63c0112251ab4e4e977545368dd703d875012a4Nick Pelly
51436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby    public void onDeviceNameUpdated(BluetoothDevice device) {
52d63c0112251ab4e4e977545368dd703d875012a4Nick Pelly        CachedBluetoothDevice cachedDevice = findDevice(device);
53d63c0112251ab4e4e977545368dd703d875012a4Nick Pelly        if (cachedDevice != null) {
54d63c0112251ab4e4e977545368dd703d875012a4Nick Pelly            cachedDevice.refreshName();
55d63c0112251ab4e4e977545368dd703d875012a4Nick Pelly        }
56d63c0112251ab4e4e977545368dd703d875012a4Nick Pelly    }
57d63c0112251ab4e4e977545368dd703d875012a4Nick Pelly
58436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby    /**
59436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby     * Search for existing {@link CachedBluetoothDevice} or return null
60436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby     * if this device isn't in the cache. Use {@link #addDevice}
61436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby     * to create and return a new {@link CachedBluetoothDevice} for
62436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby     * a newly discovered {@link BluetoothDevice}.
63436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby     *
64436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby     * @param device the address of the Bluetooth device
65436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby     * @return the cached device object for this device, or null if it has
66436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby     *   not been previously seen
67436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby     */
68436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby    CachedBluetoothDevice findDevice(BluetoothDevice device) {
69436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby        for (CachedBluetoothDevice cachedDevice : mCachedDevices) {
70d63c0112251ab4e4e977545368dd703d875012a4Nick Pelly            if (cachedDevice.getDevice().equals(device)) {
71d63c0112251ab4e4e977545368dd703d875012a4Nick Pelly                return cachedDevice;
72d63c0112251ab4e4e977545368dd703d875012a4Nick Pelly            }
73d63c0112251ab4e4e977545368dd703d875012a4Nick Pelly        }
74d63c0112251ab4e4e977545368dd703d875012a4Nick Pelly        return null;
75d63c0112251ab4e4e977545368dd703d875012a4Nick Pelly    }
76d63c0112251ab4e4e977545368dd703d875012a4Nick Pelly
77d63c0112251ab4e4e977545368dd703d875012a4Nick Pelly    /**
78436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby     * Create and return a new {@link CachedBluetoothDevice}. This assumes
79436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby     * that {@link #findDevice} has already been called and returned null.
80436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby     * @param device the address of the new Bluetooth device
81436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby     * @return the newly created CachedBluetoothDevice object
82436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby     */
83436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby    CachedBluetoothDevice addDevice(LocalBluetoothAdapter adapter,
84436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby            LocalBluetoothProfileManager profileManager,
85436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby            BluetoothDevice device) {
86b707255a440e53ec2865c4b34c7ea07d16d471bdMatthew Xie        CachedBluetoothDevice newDevice = new CachedBluetoothDevice(mContext, adapter,
87b707255a440e53ec2865c4b34c7ea07d16d471bdMatthew Xie            profileManager, device);
88436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby        mCachedDevices.add(newDevice);
89436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby        return newDevice;
90436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby    }
91436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby
92436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby    /**
93d63c0112251ab4e4e977545368dd703d875012a4Nick Pelly     * Attempts to get the name of a remote device, otherwise returns the address.
94d63c0112251ab4e4e977545368dd703d875012a4Nick Pelly     *
95d63c0112251ab4e4e977545368dd703d875012a4Nick Pelly     * @param device The remote device.
96d63c0112251ab4e4e977545368dd703d875012a4Nick Pelly     * @return The name, or if unavailable, the address.
97d63c0112251ab4e4e977545368dd703d875012a4Nick Pelly     */
98d63c0112251ab4e4e977545368dd703d875012a4Nick Pelly    public String getName(BluetoothDevice device) {
99d63c0112251ab4e4e977545368dd703d875012a4Nick Pelly        CachedBluetoothDevice cachedDevice = findDevice(device);
100436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby        if (cachedDevice != null) {
101436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby            return cachedDevice.getName();
102d63c0112251ab4e4e977545368dd703d875012a4Nick Pelly        }
103d63c0112251ab4e4e977545368dd703d875012a4Nick Pelly
1042036ebd8896bbabbbe04db34c9e7d8a1be6fe32aMatthew Xie        String name = device.getAliasName();
105436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby        if (name != null) {
106436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby            return name;
107d63c0112251ab4e4e977545368dd703d875012a4Nick Pelly        }
108d63c0112251ab4e4e977545368dd703d875012a4Nick Pelly
109436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby        return device.getAddress();
110d63c0112251ab4e4e977545368dd703d875012a4Nick Pelly    }
111d63c0112251ab4e4e977545368dd703d875012a4Nick Pelly
112d63c0112251ab4e4e977545368dd703d875012a4Nick Pelly    public synchronized void onScanningStateChanged(boolean started) {
113d63c0112251ab4e4e977545368dd703d875012a4Nick Pelly        if (!started) return;
114d63c0112251ab4e4e977545368dd703d875012a4Nick Pelly
115d63c0112251ab4e4e977545368dd703d875012a4Nick Pelly        // If starting a new scan, clear old visibility
116436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby        // Iterate in reverse order since devices may be removed.
117d63c0112251ab4e4e977545368dd703d875012a4Nick Pelly        for (int i = mCachedDevices.size() - 1; i >= 0; i--) {
118d63c0112251ab4e4e977545368dd703d875012a4Nick Pelly            CachedBluetoothDevice cachedDevice = mCachedDevices.get(i);
119d63c0112251ab4e4e977545368dd703d875012a4Nick Pelly            cachedDevice.setVisible(false);
120d63c0112251ab4e4e977545368dd703d875012a4Nick Pelly        }
121d63c0112251ab4e4e977545368dd703d875012a4Nick Pelly    }
122d63c0112251ab4e4e977545368dd703d875012a4Nick Pelly
123d63c0112251ab4e4e977545368dd703d875012a4Nick Pelly    public synchronized void onBtClassChanged(BluetoothDevice device) {
124d63c0112251ab4e4e977545368dd703d875012a4Nick Pelly        CachedBluetoothDevice cachedDevice = findDevice(device);
125d63c0112251ab4e4e977545368dd703d875012a4Nick Pelly        if (cachedDevice != null) {
126d63c0112251ab4e4e977545368dd703d875012a4Nick Pelly            cachedDevice.refreshBtClass();
127d63c0112251ab4e4e977545368dd703d875012a4Nick Pelly        }
128d63c0112251ab4e4e977545368dd703d875012a4Nick Pelly    }
1292aef1f3c814b1f8aa00aeefff35caf293c738702Michael Chan
1302aef1f3c814b1f8aa00aeefff35caf293c738702Michael Chan    public synchronized void onUuidChanged(BluetoothDevice device) {
1312aef1f3c814b1f8aa00aeefff35caf293c738702Michael Chan        CachedBluetoothDevice cachedDevice = findDevice(device);
1322aef1f3c814b1f8aa00aeefff35caf293c738702Michael Chan        if (cachedDevice != null) {
1332aef1f3c814b1f8aa00aeefff35caf293c738702Michael Chan            cachedDevice.onUuidChanged();
1342aef1f3c814b1f8aa00aeefff35caf293c738702Michael Chan        }
1352aef1f3c814b1f8aa00aeefff35caf293c738702Michael Chan    }
136b707255a440e53ec2865c4b34c7ea07d16d471bdMatthew Xie
137b707255a440e53ec2865c4b34c7ea07d16d471bdMatthew Xie    private void log(String msg) {
138b707255a440e53ec2865c4b34c7ea07d16d471bdMatthew Xie        if (DEBUG) {
139b707255a440e53ec2865c4b34c7ea07d16d471bdMatthew Xie            Log.d(TAG, msg);
140b707255a440e53ec2865c4b34c7ea07d16d471bdMatthew Xie        }
141b707255a440e53ec2865c4b34c7ea07d16d471bdMatthew Xie    }
142d63c0112251ab4e4e977545368dd703d875012a4Nick Pelly}
143