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.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 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 && cachedDevice.getName() != 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