• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 com.android.settings.ProgressCategory;
20 import com.android.settings.R;
21 
22 import java.util.List;
23 import java.util.WeakHashMap;
24 
25 import android.bluetooth.BluetoothDevice;
26 import android.bluetooth.BluetoothIntent;
27 import android.content.BroadcastReceiver;
28 import android.content.Context;
29 import android.content.Intent;
30 import android.content.IntentFilter;
31 import android.os.Bundle;
32 import android.preference.CheckBoxPreference;
33 import android.preference.Preference;
34 import android.preference.PreferenceActivity;
35 import android.preference.PreferenceScreen;
36 import android.view.ContextMenu;
37 import android.view.Menu;
38 import android.view.MenuItem;
39 import android.view.View;
40 import android.view.ContextMenu.ContextMenuInfo;
41 import android.widget.AdapterView.AdapterContextMenuInfo;
42 
43 /**
44  * BluetoothSettings is the Settings screen for Bluetooth configuration and
45  * connection management.
46  */
47 public class BluetoothSettings extends PreferenceActivity
48         implements LocalBluetoothManager.Callback {
49 
50     private static final String TAG = "BluetoothSettings";
51 
52     private static final int MENU_SCAN = Menu.FIRST;
53 
54     private static final String KEY_BT_CHECKBOX = "bt_checkbox";
55     private static final String KEY_BT_DISCOVERABLE = "bt_discoverable";
56     private static final String KEY_BT_DEVICE_LIST = "bt_device_list";
57     private static final String KEY_BT_NAME = "bt_name";
58     private static final String KEY_BT_SCAN = "bt_scan";
59 
60     private LocalBluetoothManager mLocalManager;
61 
62     private BluetoothEnabler mEnabler;
63     private BluetoothDiscoverableEnabler mDiscoverableEnabler;
64 
65     private BluetoothNamePreference mNamePreference;
66 
67     private ProgressCategory mDeviceList;
68 
69     private WeakHashMap<LocalBluetoothDevice, BluetoothDevicePreference> mDevicePreferenceMap =
70             new WeakHashMap<LocalBluetoothDevice, BluetoothDevicePreference>();
71 
72     private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
73         @Override
74         public void onReceive(Context context, Intent intent) {
75             // TODO: put this in callback instead of receiving
76             onBluetoothStateChanged(mLocalManager.getBluetoothState());
77         }
78     };
79 
80     @Override
onCreate(Bundle savedInstanceState)81     protected void onCreate(Bundle savedInstanceState) {
82         super.onCreate(savedInstanceState);
83 
84         mLocalManager = LocalBluetoothManager.getInstance(this);
85         if (mLocalManager == null) finish();
86 
87         addPreferencesFromResource(R.xml.bluetooth_settings);
88 
89         mEnabler = new BluetoothEnabler(
90                 this,
91                 (CheckBoxPreference) findPreference(KEY_BT_CHECKBOX));
92 
93         mDiscoverableEnabler = new BluetoothDiscoverableEnabler(
94                 this,
95                 (CheckBoxPreference) findPreference(KEY_BT_DISCOVERABLE));
96 
97         mNamePreference = (BluetoothNamePreference) findPreference(KEY_BT_NAME);
98 
99         mDeviceList = (ProgressCategory) findPreference(KEY_BT_DEVICE_LIST);
100 
101         registerForContextMenu(getListView());
102     }
103 
104     @Override
onResume()105     protected void onResume() {
106         super.onResume();
107 
108         // Repopulate (which isn't too bad since it's cached in the settings
109         // bluetooth manager
110         mDevicePreferenceMap.clear();
111         mDeviceList.removeAll();
112         addDevices();
113 
114         mEnabler.resume();
115         mDiscoverableEnabler.resume();
116         mNamePreference.resume();
117         mLocalManager.registerCallback(this);
118 
119         mLocalManager.startScanning(false);
120 
121         registerReceiver(mReceiver,
122                 new IntentFilter(BluetoothIntent.BLUETOOTH_STATE_CHANGED_ACTION));
123 
124         mLocalManager.setForegroundActivity(this);
125     }
126 
127     @Override
onPause()128     protected void onPause() {
129         super.onPause();
130 
131         mLocalManager.setForegroundActivity(null);
132 
133         unregisterReceiver(mReceiver);
134 
135         mLocalManager.unregisterCallback(this);
136         mNamePreference.pause();
137         mDiscoverableEnabler.pause();
138         mEnabler.pause();
139     }
140 
addDevices()141     private void addDevices() {
142         List<LocalBluetoothDevice> devices = mLocalManager.getLocalDeviceManager().getDevicesCopy();
143         for (LocalBluetoothDevice device : devices) {
144             onDeviceAdded(device);
145         }
146     }
147 
148     @Override
onCreateOptionsMenu(Menu menu)149     public boolean onCreateOptionsMenu(Menu menu) {
150         menu.add(0, MENU_SCAN, 0, R.string.bluetooth_scan_for_devices)
151                 .setIcon(com.android.internal.R.drawable.ic_menu_refresh)
152                 .setAlphabeticShortcut('r');
153         return true;
154     }
155 
156     @Override
onPrepareOptionsMenu(Menu menu)157     public boolean onPrepareOptionsMenu(Menu menu) {
158         menu.findItem(MENU_SCAN).setEnabled(mLocalManager.getBluetoothManager().isEnabled());
159         return true;
160     }
161 
162     @Override
onOptionsItemSelected(MenuItem item)163     public boolean onOptionsItemSelected(MenuItem item) {
164         switch (item.getItemId()) {
165 
166             case MENU_SCAN:
167                 mLocalManager.startScanning(true);
168                 return true;
169 
170             default:
171                 return false;
172         }
173     }
174 
175     @Override
onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference)176     public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen,
177             Preference preference) {
178 
179         if (KEY_BT_SCAN.equals(preference.getKey())) {
180             mLocalManager.startScanning(true);
181             return true;
182         }
183 
184         if (preference instanceof BluetoothDevicePreference) {
185             BluetoothDevicePreference btPreference = (BluetoothDevicePreference) preference;
186             btPreference.getDevice().onClicked();
187             return true;
188         }
189 
190         return super.onPreferenceTreeClick(preferenceScreen, preference);
191     }
192 
193     @Override
onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo)194     public void onCreateContextMenu(ContextMenu menu, View v,
195             ContextMenuInfo menuInfo) {
196         LocalBluetoothDevice device = getDeviceFromMenuInfo(menuInfo);
197         if (device == null) return;
198 
199         device.onCreateContextMenu(menu);
200     }
201 
202     @Override
onContextItemSelected(MenuItem item)203     public boolean onContextItemSelected(MenuItem item) {
204         LocalBluetoothDevice device = getDeviceFromMenuInfo(item.getMenuInfo());
205         if (device == null) return false;
206 
207         device.onContextItemSelected(item);
208         return true;
209     }
210 
getDeviceFromMenuInfo(ContextMenuInfo menuInfo)211     private LocalBluetoothDevice getDeviceFromMenuInfo(ContextMenuInfo menuInfo) {
212         if ((menuInfo == null) || !(menuInfo instanceof AdapterContextMenuInfo)) {
213             return null;
214         }
215 
216         AdapterContextMenuInfo adapterMenuInfo = (AdapterContextMenuInfo) menuInfo;
217         Preference pref = (Preference) getPreferenceScreen().getRootAdapter().getItem(
218                 adapterMenuInfo.position);
219         if (pref == null || !(pref instanceof BluetoothDevicePreference)) {
220             return null;
221         }
222 
223         return ((BluetoothDevicePreference) pref).getDevice();
224     }
225 
onDeviceAdded(LocalBluetoothDevice device)226     public void onDeviceAdded(LocalBluetoothDevice device) {
227 
228         if (mDevicePreferenceMap.get(device) != null) {
229             throw new IllegalStateException("Got onDeviceAdded, but device already exists");
230         }
231 
232         createDevicePreference(device);
233     }
234 
createDevicePreference(LocalBluetoothDevice device)235     private void createDevicePreference(LocalBluetoothDevice device) {
236         BluetoothDevicePreference preference = new BluetoothDevicePreference(this, device);
237         mDeviceList.addPreference(preference);
238         mDevicePreferenceMap.put(device, preference);
239     }
240 
onDeviceDeleted(LocalBluetoothDevice device)241     public void onDeviceDeleted(LocalBluetoothDevice device) {
242         BluetoothDevicePreference preference = mDevicePreferenceMap.remove(device);
243         if (preference != null) {
244             mDeviceList.removePreference(preference);
245         }
246     }
247 
onScanningStateChanged(boolean started)248     public void onScanningStateChanged(boolean started) {
249         mDeviceList.setProgress(started);
250     }
251 
onBluetoothStateChanged(int bluetoothState)252     private void onBluetoothStateChanged(int bluetoothState) {
253         // When bluetooth is enabled (and we are in the activity, which we are),
254         // we should start a scan
255         if (bluetoothState == BluetoothDevice.BLUETOOTH_STATE_ON) {
256             mLocalManager.startScanning(false);
257         } else if (bluetoothState == BluetoothDevice.BLUETOOTH_STATE_OFF) {
258             mDeviceList.setProgress(false);
259         }
260     }
261 }
262