Home | History | Annotate | Download | only in bluetooth
      1 /*
      2  * Copyright (C) 2011 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.os.Bundle;
     22 import android.support.v7.preference.Preference;
     23 import android.support.v7.preference.PreferenceCategory;
     24 import android.support.v7.preference.PreferenceGroup;
     25 import android.util.Log;
     26 
     27 import com.android.settings.RestrictedSettingsFragment;
     28 import com.android.settingslib.bluetooth.BluetoothCallback;
     29 import com.android.settingslib.bluetooth.BluetoothDeviceFilter;
     30 import com.android.settingslib.bluetooth.CachedBluetoothDevice;
     31 import com.android.settingslib.bluetooth.LocalBluetoothAdapter;
     32 import com.android.settingslib.bluetooth.LocalBluetoothManager;
     33 
     34 import java.util.Collection;
     35 import java.util.WeakHashMap;
     36 
     37 /**
     38  * Parent class for settings fragments that contain a list of Bluetooth
     39  * devices.
     40  *
     41  * @see BluetoothSettings
     42  * @see DevicePickerFragment
     43  */
     44 public abstract class DeviceListPreferenceFragment extends
     45         RestrictedSettingsFragment implements BluetoothCallback {
     46 
     47     private static final String TAG = "DeviceListPreferenceFragment";
     48 
     49     private static final String KEY_BT_DEVICE_LIST = "bt_device_list";
     50     private static final String KEY_BT_SCAN = "bt_scan";
     51 
     52     private BluetoothDeviceFilter.Filter mFilter;
     53 
     54     BluetoothDevice mSelectedDevice;
     55 
     56     LocalBluetoothAdapter mLocalAdapter;
     57     LocalBluetoothManager mLocalManager;
     58 
     59     private PreferenceGroup mDeviceListGroup;
     60 
     61     final WeakHashMap<CachedBluetoothDevice, BluetoothDevicePreference> mDevicePreferenceMap =
     62             new WeakHashMap<CachedBluetoothDevice, BluetoothDevicePreference>();
     63 
     64     DeviceListPreferenceFragment(String restrictedKey) {
     65         super(restrictedKey);
     66         mFilter = BluetoothDeviceFilter.ALL_FILTER;
     67     }
     68 
     69     final void setFilter(BluetoothDeviceFilter.Filter filter) {
     70         mFilter = filter;
     71     }
     72 
     73     final void setFilter(int filterType) {
     74         mFilter = BluetoothDeviceFilter.getFilter(filterType);
     75     }
     76 
     77     @Override
     78     public void onCreate(Bundle savedInstanceState) {
     79         super.onCreate(savedInstanceState);
     80 
     81         mLocalManager = Utils.getLocalBtManager(getActivity());
     82         if (mLocalManager == null) {
     83             Log.e(TAG, "Bluetooth is not supported on this device");
     84             return;
     85         }
     86         mLocalAdapter = mLocalManager.getBluetoothAdapter();
     87 
     88         addPreferencesForActivity();
     89 
     90         mDeviceListGroup = (PreferenceCategory) findPreference(KEY_BT_DEVICE_LIST);
     91     }
     92 
     93     void setDeviceListGroup(PreferenceGroup preferenceGroup) {
     94         mDeviceListGroup = preferenceGroup;
     95     }
     96 
     97     /** Add preferences from the subclass. */
     98     abstract void addPreferencesForActivity();
     99 
    100     @Override
    101     public void onResume() {
    102         super.onResume();
    103         if (mLocalManager == null || isUiRestricted()) return;
    104 
    105         mLocalManager.setForegroundActivity(getActivity());
    106         mLocalManager.getEventManager().registerCallback(this);
    107 
    108         updateProgressUi(mLocalAdapter.isDiscovering());
    109     }
    110 
    111     @Override
    112     public void onPause() {
    113         super.onPause();
    114         if (mLocalManager == null || isUiRestricted()) {
    115             return;
    116         }
    117 
    118         removeAllDevices();
    119         mLocalManager.setForegroundActivity(null);
    120         mLocalManager.getEventManager().unregisterCallback(this);
    121     }
    122 
    123     void removeAllDevices() {
    124         mLocalAdapter.stopScanning();
    125         mDevicePreferenceMap.clear();
    126         mDeviceListGroup.removeAll();
    127     }
    128 
    129     void addCachedDevices() {
    130         Collection<CachedBluetoothDevice> cachedDevices =
    131                 mLocalManager.getCachedDeviceManager().getCachedDevicesCopy();
    132         for (CachedBluetoothDevice cachedDevice : cachedDevices) {
    133             onDeviceAdded(cachedDevice);
    134         }
    135     }
    136 
    137     @Override
    138     public boolean onPreferenceTreeClick(Preference preference) {
    139         if (KEY_BT_SCAN.equals(preference.getKey())) {
    140             mLocalAdapter.startScanning(true);
    141             return true;
    142         }
    143 
    144         if (preference instanceof BluetoothDevicePreference) {
    145             BluetoothDevicePreference btPreference = (BluetoothDevicePreference) preference;
    146             CachedBluetoothDevice device = btPreference.getCachedDevice();
    147             mSelectedDevice = device.getDevice();
    148             onDevicePreferenceClick(btPreference);
    149             return true;
    150         }
    151 
    152         return super.onPreferenceTreeClick(preference);
    153     }
    154 
    155     void onDevicePreferenceClick(BluetoothDevicePreference btPreference) {
    156         btPreference.onClicked();
    157     }
    158 
    159     public void onDeviceAdded(CachedBluetoothDevice cachedDevice) {
    160         if (mDevicePreferenceMap.get(cachedDevice) != null) {
    161             return;
    162         }
    163 
    164         // Prevent updates while the list shows one of the state messages
    165         if (mLocalAdapter.getBluetoothState() != BluetoothAdapter.STATE_ON) return;
    166 
    167         if (mFilter.matches(cachedDevice.getDevice())) {
    168             createDevicePreference(cachedDevice);
    169         }
    170     }
    171 
    172     void createDevicePreference(CachedBluetoothDevice cachedDevice) {
    173         if (mDeviceListGroup == null) {
    174             Log.w(TAG, "Trying to create a device preference before the list group/category "
    175                     + "exists!");
    176             return;
    177         }
    178 
    179         String key = cachedDevice.getDevice().getAddress();
    180         BluetoothDevicePreference preference = (BluetoothDevicePreference) getCachedPreference(key);
    181 
    182         if (preference == null) {
    183             preference = new BluetoothDevicePreference(getPrefContext(), cachedDevice);
    184             preference.setKey(key);
    185             mDeviceListGroup.addPreference(preference);
    186         } else {
    187             // Tell the preference it is being re-used in case there is new info in the
    188             // cached device.
    189             preference.rebind();
    190         }
    191 
    192         initDevicePreference(preference);
    193         mDevicePreferenceMap.put(cachedDevice, preference);
    194     }
    195 
    196     /**
    197      * Overridden in {@link BluetoothSettings} to add a listener.
    198      * @param preference the newly added preference
    199      */
    200     void initDevicePreference(BluetoothDevicePreference preference) {
    201         // Does nothing by default
    202     }
    203 
    204     public void onDeviceDeleted(CachedBluetoothDevice cachedDevice) {
    205         BluetoothDevicePreference preference = mDevicePreferenceMap.remove(cachedDevice);
    206         if (preference != null) {
    207             mDeviceListGroup.removePreference(preference);
    208         }
    209     }
    210 
    211     public void onScanningStateChanged(boolean started) {
    212         updateProgressUi(started);
    213     }
    214 
    215     private void updateProgressUi(boolean start) {
    216         if (mDeviceListGroup instanceof BluetoothProgressCategory) {
    217             ((BluetoothProgressCategory) mDeviceListGroup).setProgress(start);
    218         }
    219     }
    220 
    221     public void onBluetoothStateChanged(int bluetoothState) {
    222         if (bluetoothState == BluetoothAdapter.STATE_OFF) {
    223             updateProgressUi(false);
    224         }
    225     }
    226 
    227     public void onConnectionStateChanged(CachedBluetoothDevice cachedDevice, int state) { }
    228 }
    229