• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2017 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 static android.os.UserManager.DISALLOW_CONFIG_BLUETOOTH;
20 
21 import android.bluetooth.BluetoothAdapter;
22 import android.bluetooth.BluetoothDevice;
23 import android.content.Context;
24 import android.os.Bundle;
25 import android.support.annotation.VisibleForTesting;
26 import android.util.Log;
27 
28 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
29 import com.android.settings.R;
30 import com.android.settings.search.Indexable;
31 import com.android.settingslib.bluetooth.BluetoothDeviceFilter;
32 import com.android.settingslib.bluetooth.CachedBluetoothDevice;
33 import com.android.settingslib.widget.FooterPreference;
34 
35 /**
36  * BluetoothPairingDetail is a page to scan bluetooth devices and pair them.
37  */
38 public class BluetoothPairingDetail extends DeviceListPreferenceFragment implements
39         Indexable {
40     private static final String TAG = "BluetoothPairingDetail";
41 
42     @VisibleForTesting
43     static final String KEY_AVAIL_DEVICES = "available_devices";
44     @VisibleForTesting
45     static final String KEY_FOOTER_PREF = "footer_preference";
46 
47     @VisibleForTesting
48     BluetoothProgressCategory mAvailableDevicesCategory;
49     @VisibleForTesting
50     FooterPreference mFooterPreference;
51     @VisibleForTesting
52     AlwaysDiscoverable mAlwaysDiscoverable;
53 
54     private boolean mInitialScanStarted;
55 
BluetoothPairingDetail()56     public BluetoothPairingDetail() {
57         super(DISALLOW_CONFIG_BLUETOOTH);
58     }
59 
60     @Override
onActivityCreated(Bundle savedInstanceState)61     public void onActivityCreated(Bundle savedInstanceState) {
62         super.onActivityCreated(savedInstanceState);
63         mInitialScanStarted = false;
64         mAlwaysDiscoverable = new AlwaysDiscoverable(getContext(), mLocalAdapter);
65     }
66 
67     @Override
onStart()68     public void onStart() {
69         super.onStart();
70         if (mLocalManager == null){
71             Log.e(TAG, "Bluetooth is not supported on this device");
72             return;
73         }
74         updateBluetooth();
75         mAvailableDevicesCategory.setProgress(mLocalAdapter.isDiscovering());
76     }
77 
78     @Override
onAttach(Context context)79     public void onAttach(Context context) {
80         super.onAttach(context);
81         use(BluetoothDeviceRenamePreferenceController.class).setFragment(this);
82     }
83 
84     @VisibleForTesting
updateBluetooth()85     void updateBluetooth() {
86         if (mLocalAdapter.isEnabled()) {
87             updateContent(mLocalAdapter.getBluetoothState());
88         } else {
89             // Turn on bluetooth if it is disabled
90             mLocalAdapter.enable();
91         }
92     }
93 
94     @Override
onStop()95     public void onStop() {
96         super.onStop();
97         if (mLocalManager == null){
98             Log.e(TAG, "Bluetooth is not supported on this device");
99             return;
100         }
101         // Make the device only visible to connected devices.
102         mAlwaysDiscoverable.stop();
103         disableScanning();
104     }
105 
106     @Override
initPreferencesFromPreferenceScreen()107     void initPreferencesFromPreferenceScreen() {
108         mAvailableDevicesCategory = (BluetoothProgressCategory) findPreference(KEY_AVAIL_DEVICES);
109         mFooterPreference = (FooterPreference) findPreference(KEY_FOOTER_PREF);
110         mFooterPreference.setSelectable(false);
111     }
112 
113     @Override
getMetricsCategory()114     public int getMetricsCategory() {
115         return MetricsEvent.BLUETOOTH_PAIRING;
116     }
117 
118     @Override
enableScanning()119     void enableScanning() {
120         // Clear all device states before first scan
121         if (!mInitialScanStarted) {
122             if (mAvailableDevicesCategory != null) {
123                 removeAllDevices();
124             }
125             mLocalManager.getCachedDeviceManager().clearNonBondedDevices();
126             mInitialScanStarted = true;
127         }
128         super.enableScanning();
129     }
130 
131     @Override
onDevicePreferenceClick(BluetoothDevicePreference btPreference)132     void onDevicePreferenceClick(BluetoothDevicePreference btPreference) {
133         disableScanning();
134         super.onDevicePreferenceClick(btPreference);
135     }
136 
137     @Override
onScanningStateChanged(boolean started)138     public void onScanningStateChanged(boolean started) {
139         super.onScanningStateChanged(started);
140         started |= mScanEnabled;
141         mAvailableDevicesCategory.setProgress(started);
142     }
143 
144     @VisibleForTesting
updateContent(int bluetoothState)145     void updateContent(int bluetoothState) {
146         switch (bluetoothState) {
147             case BluetoothAdapter.STATE_ON:
148                 mDevicePreferenceMap.clear();
149                 mLocalAdapter.setBluetoothEnabled(true);
150 
151                 addDeviceCategory(mAvailableDevicesCategory,
152                         R.string.bluetooth_preference_found_media_devices,
153                         BluetoothDeviceFilter.UNBONDED_DEVICE_FILTER, mInitialScanStarted);
154                 updateFooterPreference(mFooterPreference);
155                 mAlwaysDiscoverable.start();
156                 enableScanning();
157                 break;
158 
159             case BluetoothAdapter.STATE_OFF:
160                 finish();
161                 break;
162         }
163     }
164 
165     @Override
onBluetoothStateChanged(int bluetoothState)166     public void onBluetoothStateChanged(int bluetoothState) {
167         super.onBluetoothStateChanged(bluetoothState);
168         updateContent(bluetoothState);
169     }
170 
171     @Override
onDeviceBondStateChanged(CachedBluetoothDevice cachedDevice, int bondState)172     public void onDeviceBondStateChanged(CachedBluetoothDevice cachedDevice, int bondState) {
173         if (bondState == BluetoothDevice.BOND_BONDED) {
174             // If one device is connected(bonded), then close this fragment.
175             finish();
176             return;
177         }
178         if (mSelectedDevice != null && cachedDevice != null) {
179             BluetoothDevice device = cachedDevice.getDevice();
180             if (device != null && mSelectedDevice.equals(device)
181                     && bondState == BluetoothDevice.BOND_NONE) {
182                 // If currently selected device failed to bond, restart scanning
183                 enableScanning();
184             }
185         }
186     }
187 
188     @Override
getHelpResource()189     public int getHelpResource() {
190         return R.string.help_url_bluetooth;
191     }
192 
193     @Override
getLogTag()194     protected String getLogTag() {
195         return TAG;
196     }
197 
198     @Override
getPreferenceScreenResId()199     protected int getPreferenceScreenResId() {
200         return R.xml.bluetooth_pairing_detail;
201     }
202 
203     @Override
getDeviceListKey()204     public String getDeviceListKey() {
205         return KEY_AVAIL_DEVICES;
206     }
207 
208 }
209