Home | History | Annotate | Download | only in bluetooth
      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         synchronized (mCachedDevices) {
     90             mCachedDevices.add(newDevice);
     91         }
     92         return newDevice;
     93     }
     94 
     95     /**
     96      * Attempts to get the name of a remote device, otherwise returns the address.
     97      *
     98      * @param device The remote device.
     99      * @return The name, or if unavailable, the address.
    100      */
    101     public String getName(BluetoothDevice device) {
    102         CachedBluetoothDevice cachedDevice = findDevice(device);
    103         if (cachedDevice != null) {
    104             return cachedDevice.getName();
    105         }
    106 
    107         String name = device.getAliasName();
    108         if (name != null) {
    109             return name;
    110         }
    111 
    112         return device.getAddress();
    113     }
    114 
    115     public synchronized void clearNonBondedDevices() {
    116         for (int i = mCachedDevices.size() - 1; i >= 0; i--) {
    117             CachedBluetoothDevice cachedDevice = mCachedDevices.get(i);
    118             if (cachedDevice.getBondState() != BluetoothDevice.BOND_BONDED) {
    119                 mCachedDevices.remove(i);
    120             }
    121         }
    122     }
    123 
    124     public synchronized void onScanningStateChanged(boolean started) {
    125         if (!started) return;
    126 
    127         // If starting a new scan, clear old visibility
    128         // Iterate in reverse order since devices may be removed.
    129         for (int i = mCachedDevices.size() - 1; i >= 0; i--) {
    130             CachedBluetoothDevice cachedDevice = mCachedDevices.get(i);
    131             cachedDevice.setVisible(false);
    132         }
    133     }
    134 
    135     public synchronized void onBtClassChanged(BluetoothDevice device) {
    136         CachedBluetoothDevice cachedDevice = findDevice(device);
    137         if (cachedDevice != null) {
    138             cachedDevice.refreshBtClass();
    139         }
    140     }
    141 
    142     public synchronized void onUuidChanged(BluetoothDevice device) {
    143         CachedBluetoothDevice cachedDevice = findDevice(device);
    144         if (cachedDevice != null) {
    145             cachedDevice.onUuidChanged();
    146         }
    147     }
    148 
    149     public synchronized void onBluetoothStateChanged(int bluetoothState) {
    150         // When Bluetooth is turning off, we need to clear the non-bonded devices
    151         // Otherwise, they end up showing up on the next BT enable
    152         if (bluetoothState == BluetoothAdapter.STATE_TURNING_OFF) {
    153             for (int i = mCachedDevices.size() - 1; i >= 0; i--) {
    154                 CachedBluetoothDevice cachedDevice = mCachedDevices.get(i);
    155                 if (cachedDevice.getBondState() != BluetoothDevice.BOND_BONDED) {
    156                     cachedDevice.setVisible(false);
    157                     mCachedDevices.remove(i);
    158                 } else {
    159                     // For bonded devices, we need to clear the connection status so that
    160                     // when BT is enabled next time, device connection status shall be retrieved
    161                     // by making a binder call.
    162                     cachedDevice.clearProfileConnectionState();
    163                 }
    164             }
    165         }
    166     }
    167     private void log(String msg) {
    168         if (DEBUG) {
    169             Log.d(TAG, msg);
    170         }
    171     }
    172 }
    173