• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.app.Activity;
20 import android.bluetooth.BluetoothAdapter;
21 import android.bluetooth.BluetoothDevice;
22 import android.content.BroadcastReceiver;
23 import android.content.ContentResolver;
24 import android.content.Context;
25 import android.content.Intent;
26 import android.content.IntentFilter;
27 import android.content.res.Resources;
28 import android.os.Bundle;
29 import android.provider.Settings;
30 import android.support.annotation.VisibleForTesting;
31 import android.support.v7.preference.PreferenceCategory;
32 import android.support.v7.preference.PreferenceGroup;
33 import android.support.v7.preference.PreferenceScreen;
34 import android.text.BidiFormatter;
35 import android.text.Spannable;
36 import android.text.style.TextAppearanceSpan;
37 import android.util.Log;
38 import android.view.Menu;
39 import android.view.MenuInflater;
40 import android.view.MenuItem;
41 import android.view.View;
42 import android.widget.TextView;
43 
44 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
45 import com.android.settings.LinkifyUtils;
46 import com.android.settings.R;
47 import com.android.settings.SettingsActivity;
48 import com.android.settings.dashboard.SummaryLoader;
49 import com.android.settings.location.ScanningSettings;
50 import com.android.settings.search.BaseSearchIndexProvider;
51 import com.android.settings.search.Indexable;
52 import com.android.settings.search.SearchIndexableRaw;
53 import com.android.settings.widget.FooterPreference;
54 import com.android.settings.widget.GearPreference;
55 import com.android.settings.widget.SummaryUpdater.OnSummaryChangeListener;
56 import com.android.settings.widget.SwitchBar;
57 import com.android.settings.widget.SwitchBarController;
58 import com.android.settingslib.bluetooth.BluetoothDeviceFilter;
59 import com.android.settingslib.bluetooth.CachedBluetoothDevice;
60 import com.android.settingslib.bluetooth.LocalBluetoothManager;
61 
62 import java.util.ArrayList;
63 import java.util.List;
64 import java.util.Locale;
65 import java.util.Set;
66 
67 import static android.os.UserManager.DISALLOW_CONFIG_BLUETOOTH;
68 
69 /**
70  * BluetoothSettings is the Settings screen for Bluetooth configuration and
71  * connection management.
72  */
73 public final class BluetoothSettings extends DeviceListPreferenceFragment implements Indexable {
74     private static final String TAG = "BluetoothSettings";
75 
76     private static final int MENU_ID_SCAN = Menu.FIRST;
77     private static final int MENU_ID_RENAME_DEVICE = Menu.FIRST + 1;
78     private static final int MENU_ID_SHOW_RECEIVED = Menu.FIRST + 2;
79 
80     /* Private intent to show the list of received files */
81     private static final String BTOPP_ACTION_OPEN_RECEIVED_FILES =
82             "android.btopp.intent.action.OPEN_RECEIVED_FILES";
83     private static final String BTOPP_PACKAGE =
84             "com.android.bluetooth";
85 
86     private static final String KEY_PAIRED_DEVICES = "paired_devices";
87 
88     private static View mSettingsDialogView = null;
89 
90     private BluetoothEnabler mBluetoothEnabler;
91 
92     private PreferenceGroup mPairedDevicesCategory;
93     private PreferenceGroup mAvailableDevicesCategory;
94     private boolean mAvailableDevicesCategoryIsPresent;
95 
96     private boolean mInitialScanStarted;
97     private boolean mInitiateDiscoverable;
98 
99     private SwitchBar mSwitchBar;
100 
101     private final IntentFilter mIntentFilter;
102 
103     // For Search
104     private static final String DATA_KEY_REFERENCE = "main_toggle_bluetooth";
105 
106     // accessed from inner class (not private to avoid thunks)
107     FooterPreference mMyDevicePreference;
108 
109     private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
110         @Override
111         public void onReceive(Context context, Intent intent) {
112             final String action = intent.getAction();
113             final int state =
114                     intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.ERROR);
115 
116             if (action.equals(BluetoothAdapter.ACTION_LOCAL_NAME_CHANGED)) {
117                 updateDeviceName(context);
118             }
119 
120             if (state == BluetoothAdapter.STATE_ON) {
121                 mInitiateDiscoverable = true;
122             }
123         }
124 
125         private void updateDeviceName(Context context) {
126             if (mLocalAdapter.isEnabled() && mMyDevicePreference != null) {
127                 final Resources res = context.getResources();
128                 final Locale locale = res.getConfiguration().getLocales().get(0);
129                 final BidiFormatter bidiFormatter = BidiFormatter.getInstance(locale);
130                 mMyDevicePreference.setTitle(res.getString(
131                         R.string.bluetooth_is_visible_message,
132                         bidiFormatter.unicodeWrap(mLocalAdapter.getName())));
133             }
134         }
135     };
136 
BluetoothSettings()137     public BluetoothSettings() {
138         super(DISALLOW_CONFIG_BLUETOOTH);
139         mIntentFilter = new IntentFilter(BluetoothAdapter.ACTION_LOCAL_NAME_CHANGED);
140     }
141 
142     @Override
getMetricsCategory()143     public int getMetricsCategory() {
144         return MetricsEvent.BLUETOOTH;
145     }
146 
147     @Override
onActivityCreated(Bundle savedInstanceState)148     public void onActivityCreated(Bundle savedInstanceState) {
149         super.onActivityCreated(savedInstanceState);
150         mInitialScanStarted = false;
151         mInitiateDiscoverable = true;
152 
153         final SettingsActivity activity = (SettingsActivity) getActivity();
154         mSwitchBar = activity.getSwitchBar();
155 
156         mBluetoothEnabler = new BluetoothEnabler(activity, new SwitchBarController(mSwitchBar),
157             mMetricsFeatureProvider, Utils.getLocalBtManager(activity),
158             MetricsEvent.ACTION_BLUETOOTH_TOGGLE);
159         mBluetoothEnabler.setupSwitchController();
160     }
161 
162     @Override
onDestroyView()163     public void onDestroyView() {
164         super.onDestroyView();
165 
166         mBluetoothEnabler.teardownSwitchController();
167     }
168 
169     @Override
addPreferencesForActivity()170     void addPreferencesForActivity() {
171         addPreferencesFromResource(R.xml.bluetooth_settings);
172         final Context prefContext = getPrefContext();
173         mPairedDevicesCategory = new PreferenceCategory(prefContext);
174         mPairedDevicesCategory.setKey(KEY_PAIRED_DEVICES);
175         mPairedDevicesCategory.setOrder(1);
176         getPreferenceScreen().addPreference(mPairedDevicesCategory);
177 
178         mAvailableDevicesCategory = new BluetoothProgressCategory(prefContext);
179         mAvailableDevicesCategory.setSelectable(false);
180         mAvailableDevicesCategory.setOrder(2);
181         getPreferenceScreen().addPreference(mAvailableDevicesCategory);
182 
183         mMyDevicePreference = mFooterPreferenceMixin.createFooterPreference();
184         mMyDevicePreference.setSelectable(false);
185 
186         setHasOptionsMenu(true);
187     }
188 
189     @Override
onStart()190     public void onStart() {
191         // resume BluetoothEnabler before calling super.onStart() so we don't get
192         // any onDeviceAdded() callbacks before setting up view in updateContent()
193         if (mBluetoothEnabler != null) {
194             mBluetoothEnabler.resume(getActivity());
195         }
196         super.onStart();
197 
198         mInitiateDiscoverable = true;
199 
200         if (isUiRestricted()) {
201             setDeviceListGroup(getPreferenceScreen());
202             if (!isUiRestrictedByOnlyAdmin()) {
203                 getEmptyTextView().setText(R.string.bluetooth_empty_list_user_restricted);
204             }
205             removeAllDevices();
206             return;
207         }
208 
209         getActivity().registerReceiver(mReceiver, mIntentFilter);
210         if (mLocalAdapter != null) {
211             updateContent(mLocalAdapter.getBluetoothState());
212         }
213     }
214 
215     @Override
onStop()216     public void onStop() {
217         super.onStop();
218         if (mBluetoothEnabler != null) {
219             mBluetoothEnabler.pause();
220         }
221 
222         // Make the device only visible to connected devices.
223         mLocalAdapter.setScanMode(BluetoothAdapter.SCAN_MODE_CONNECTABLE);
224 
225         if (isUiRestricted()) {
226             return;
227         }
228 
229         getActivity().unregisterReceiver(mReceiver);
230     }
231 
232     @Override
onCreateOptionsMenu(Menu menu, MenuInflater inflater)233     public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
234         if (mLocalAdapter == null) return;
235         // If the user is not allowed to configure bluetooth, do not show the menu.
236         if (isUiRestricted()) return;
237 
238         boolean bluetoothIsEnabled = mLocalAdapter.getBluetoothState() == BluetoothAdapter.STATE_ON;
239         boolean isDiscovering = mLocalAdapter.isDiscovering();
240         int textId = isDiscovering ? R.string.bluetooth_searching_for_devices :
241                 R.string.bluetooth_search_for_devices;
242         menu.add(Menu.NONE, MENU_ID_SCAN, 0, textId)
243                 .setEnabled(bluetoothIsEnabled && !isDiscovering)
244                 .setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER);
245         menu.add(Menu.NONE, MENU_ID_RENAME_DEVICE, 0, R.string.bluetooth_rename_device)
246                 .setEnabled(bluetoothIsEnabled)
247                 .setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER);
248         menu.add(Menu.NONE, MENU_ID_SHOW_RECEIVED, 0, R.string.bluetooth_show_received_files)
249                 .setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER);
250         super.onCreateOptionsMenu(menu, inflater);
251     }
252 
253     @Override
onOptionsItemSelected(MenuItem item)254     public boolean onOptionsItemSelected(MenuItem item) {
255         switch (item.getItemId()) {
256             case MENU_ID_SCAN:
257                 if (mLocalAdapter.getBluetoothState() == BluetoothAdapter.STATE_ON) {
258                     mMetricsFeatureProvider.action(getActivity(),
259                             MetricsEvent.ACTION_BLUETOOTH_SCAN);
260                     startScanning();
261                 }
262                 return true;
263 
264             case MENU_ID_RENAME_DEVICE:
265                 mMetricsFeatureProvider.action(getActivity(),
266                         MetricsEvent.ACTION_BLUETOOTH_RENAME);
267                 new BluetoothNameDialogFragment().show(
268                         getFragmentManager(), "rename device");
269                 return true;
270 
271             case MENU_ID_SHOW_RECEIVED:
272                 mMetricsFeatureProvider.action(getActivity(),
273                         MetricsEvent.ACTION_BLUETOOTH_FILES);
274                 Intent intent = new Intent(BTOPP_ACTION_OPEN_RECEIVED_FILES);
275                 intent.setPackage(BTOPP_PACKAGE);
276                 getActivity().sendBroadcast(intent);
277                 return true;
278         }
279         return super.onOptionsItemSelected(item);
280     }
281 
startScanning()282     private void startScanning() {
283         if (isUiRestricted()) {
284             return;
285         }
286 
287         if (!mAvailableDevicesCategoryIsPresent) {
288             getPreferenceScreen().addPreference(mAvailableDevicesCategory);
289             mAvailableDevicesCategoryIsPresent = true;
290         }
291 
292         if (mAvailableDevicesCategory != null) {
293             setDeviceListGroup(mAvailableDevicesCategory);
294             removeAllDevices();
295         }
296 
297         mLocalManager.getCachedDeviceManager().clearNonBondedDevices();
298         mAvailableDevicesCategory.removeAll();
299         mInitialScanStarted = true;
300         mLocalAdapter.startScanning(true);
301     }
302 
303     @Override
onDevicePreferenceClick(BluetoothDevicePreference btPreference)304     void onDevicePreferenceClick(BluetoothDevicePreference btPreference) {
305         mLocalAdapter.stopScanning();
306         super.onDevicePreferenceClick(btPreference);
307     }
308 
addDeviceCategory(PreferenceGroup preferenceGroup, int titleId, BluetoothDeviceFilter.Filter filter, boolean addCachedDevices)309     private void addDeviceCategory(PreferenceGroup preferenceGroup, int titleId,
310             BluetoothDeviceFilter.Filter filter, boolean addCachedDevices) {
311         cacheRemoveAllPrefs(preferenceGroup);
312         preferenceGroup.setTitle(titleId);
313         setFilter(filter);
314         setDeviceListGroup(preferenceGroup);
315         if (addCachedDevices) {
316             addCachedDevices();
317         }
318         preferenceGroup.setEnabled(true);
319         removeCachedPrefs(preferenceGroup);
320     }
321 
updateContent(int bluetoothState)322     private void updateContent(int bluetoothState) {
323         final PreferenceScreen preferenceScreen = getPreferenceScreen();
324         int messageId = 0;
325 
326         switch (bluetoothState) {
327             case BluetoothAdapter.STATE_ON:
328                 mDevicePreferenceMap.clear();
329 
330                 if (isUiRestricted()) {
331                     messageId = R.string.bluetooth_empty_list_user_restricted;
332                     break;
333                 }
334                 getPreferenceScreen().removeAll();
335                 getPreferenceScreen().addPreference(mPairedDevicesCategory);
336                 getPreferenceScreen().addPreference(mAvailableDevicesCategory);
337                 getPreferenceScreen().addPreference(mMyDevicePreference);
338 
339                 // Paired devices category
340                 addDeviceCategory(mPairedDevicesCategory,
341                         R.string.bluetooth_preference_paired_devices,
342                         BluetoothDeviceFilter.BONDED_DEVICE_FILTER, true);
343                 int numberOfPairedDevices = mPairedDevicesCategory.getPreferenceCount();
344 
345                 if (isUiRestricted() || numberOfPairedDevices <= 0) {
346                     if (preferenceScreen.findPreference(KEY_PAIRED_DEVICES) != null) {
347                         preferenceScreen.removePreference(mPairedDevicesCategory);
348                     }
349                 } else {
350                     if (preferenceScreen.findPreference(KEY_PAIRED_DEVICES) == null) {
351                         preferenceScreen.addPreference(mPairedDevicesCategory);
352                     }
353                 }
354 
355                 // Available devices category
356                 addDeviceCategory(mAvailableDevicesCategory,
357                         R.string.bluetooth_preference_found_devices,
358                         BluetoothDeviceFilter.UNBONDED_DEVICE_FILTER, mInitialScanStarted);
359 
360                 if (!mInitialScanStarted) {
361                     startScanning();
362                 }
363 
364                 final Resources res = getResources();
365                 final Locale locale = res.getConfiguration().getLocales().get(0);
366                 final BidiFormatter bidiFormatter = BidiFormatter.getInstance(locale);
367                 mMyDevicePreference.setTitle(res.getString(
368                         R.string.bluetooth_is_visible_message,
369                         bidiFormatter.unicodeWrap(mLocalAdapter.getName())));
370 
371                 getActivity().invalidateOptionsMenu();
372 
373                 // mLocalAdapter.setScanMode is internally synchronized so it is okay for multiple
374                 // threads to execute.
375                 if (mInitiateDiscoverable) {
376                     // Make the device visible to other devices.
377                     mLocalAdapter.setScanMode(BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE);
378                     mInitiateDiscoverable = false;
379                 }
380                 return; // not break
381 
382             case BluetoothAdapter.STATE_TURNING_OFF:
383                 messageId = R.string.bluetooth_turning_off;
384                 break;
385 
386             case BluetoothAdapter.STATE_OFF:
387                 setOffMessage();
388                 if (isUiRestricted()) {
389                     messageId = R.string.bluetooth_empty_list_user_restricted;
390                 }
391                 break;
392 
393             case BluetoothAdapter.STATE_TURNING_ON:
394                 messageId = R.string.bluetooth_turning_on;
395                 mInitialScanStarted = false;
396                 break;
397         }
398 
399         setDeviceListGroup(preferenceScreen);
400         removeAllDevices();
401         if (messageId != 0) {
402             getEmptyTextView().setText(messageId);
403         }
404         if (!isUiRestricted()) {
405             getActivity().invalidateOptionsMenu();
406         }
407     }
408 
setOffMessage()409     private void setOffMessage() {
410         final TextView emptyView = getEmptyTextView();
411         if (emptyView == null) {
412             return;
413         }
414         final CharSequence briefText = getText(R.string.bluetooth_empty_list_bluetooth_off);
415 
416         final ContentResolver resolver = getActivity().getContentResolver();
417         final boolean bleScanningMode = Settings.Global.getInt(
418                 resolver, Settings.Global.BLE_SCAN_ALWAYS_AVAILABLE, 0) == 1;
419 
420         if (!bleScanningMode) {
421             // Show only the brief text if the scanning mode has been turned off.
422             emptyView.setText(briefText, TextView.BufferType.SPANNABLE);
423         } else {
424             final StringBuilder contentBuilder = new StringBuilder();
425             contentBuilder.append(briefText);
426             contentBuilder.append("\n\n");
427             contentBuilder.append(getText(R.string.ble_scan_notify_text));
428             LinkifyUtils.linkify(emptyView, contentBuilder, new LinkifyUtils.OnClickListener() {
429                 @Override
430                 public void onClick() {
431                     final SettingsActivity activity =
432                             (SettingsActivity) BluetoothSettings.this.getActivity();
433                     activity.startPreferencePanel(BluetoothSettings.this,
434                             ScanningSettings.class.getName(), null,
435                             R.string.location_scanning_screen_title, null, null, 0);
436                 }
437             });
438         }
439         getPreferenceScreen().removeAll();
440         setTextSpan(emptyView.getText(), briefText);
441     }
442 
443     @Override
onBluetoothStateChanged(int bluetoothState)444     public void onBluetoothStateChanged(int bluetoothState) {
445         super.onBluetoothStateChanged(bluetoothState);
446         // If BT is turned off/on staying in the same BT Settings screen
447         // discoverability to be set again
448         if (BluetoothAdapter.STATE_ON == bluetoothState) {
449             mInitiateDiscoverable = true;
450         }
451         updateContent(bluetoothState);
452     }
453 
454     @Override
onScanningStateChanged(boolean started)455     public void onScanningStateChanged(boolean started) {
456         super.onScanningStateChanged(started);
457         // Update options' enabled state
458         if (getActivity() != null) {
459             getActivity().invalidateOptionsMenu();
460         }
461     }
462 
463     @Override
onDeviceBondStateChanged(CachedBluetoothDevice cachedDevice, int bondState)464     public void onDeviceBondStateChanged(CachedBluetoothDevice cachedDevice, int bondState) {
465         setDeviceListGroup(getPreferenceScreen());
466         removeAllDevices();
467         updateContent(mLocalAdapter.getBluetoothState());
468     }
469 
470     @VisibleForTesting
setTextSpan(CharSequence text, CharSequence briefText)471     void setTextSpan(CharSequence text, CharSequence briefText) {
472         if (text instanceof Spannable) {
473             Spannable boldSpan = (Spannable) text;
474             boldSpan.setSpan(
475                 new TextAppearanceSpan(getActivity(), android.R.style.TextAppearance_Medium), 0,
476                 briefText.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
477         }
478     }
479 
480     private final GearPreference.OnGearClickListener mDeviceProfilesListener = pref -> {
481         // User clicked on advanced options icon for a device in the list
482         if (!(pref instanceof BluetoothDevicePreference)) {
483             Log.w(TAG, "onClick() called for other View: " + pref);
484             return;
485         }
486         final CachedBluetoothDevice device =
487                 ((BluetoothDevicePreference) pref).getBluetoothDevice();
488         if (device == null) {
489             Log.w(TAG, "No BT device attached with this pref: " + pref);
490             return;
491         }
492         final Bundle args = new Bundle();
493         args.putString(DeviceProfilesSettings.ARG_DEVICE_ADDRESS,
494                 device.getDevice().getAddress());
495         final DeviceProfilesSettings profileSettings = new DeviceProfilesSettings();
496         profileSettings.setArguments(args);
497         profileSettings.show(getFragmentManager(),
498                 DeviceProfilesSettings.class.getSimpleName());
499     };
500 
501     /**
502      * Add a listener, which enables the advanced settings icon.
503      *
504      * @param preference the newly added preference
505      */
506     @Override
initDevicePreference(BluetoothDevicePreference preference)507     void initDevicePreference(BluetoothDevicePreference preference) {
508         CachedBluetoothDevice cachedDevice = preference.getCachedDevice();
509         if (cachedDevice.getBondState() == BluetoothDevice.BOND_BONDED) {
510             // Only paired device have an associated advanced settings screen
511             preference.setOnGearClickListener(mDeviceProfilesListener);
512         }
513     }
514 
515     @Override
getHelpResource()516     protected int getHelpResource() {
517         return R.string.help_url_bluetooth;
518     }
519 
520     @VisibleForTesting
521     static class SummaryProvider implements SummaryLoader.SummaryProvider, OnSummaryChangeListener {
522 
523         private final LocalBluetoothManager mBluetoothManager;
524         private final Context mContext;
525         private final SummaryLoader mSummaryLoader;
526 
527         @VisibleForTesting
528         BluetoothSummaryUpdater mSummaryUpdater;
529 
SummaryProvider(Context context, SummaryLoader summaryLoader, LocalBluetoothManager bluetoothManager)530         public SummaryProvider(Context context, SummaryLoader summaryLoader,
531                 LocalBluetoothManager bluetoothManager) {
532             mBluetoothManager = bluetoothManager;
533             mContext = context;
534             mSummaryLoader = summaryLoader;
535             mSummaryUpdater = new BluetoothSummaryUpdater(mContext, this, mBluetoothManager);
536         }
537 
538         @Override
setListening(boolean listening)539         public void setListening(boolean listening) {
540             mSummaryUpdater.register(listening);
541         }
542 
543         @Override
onSummaryChanged(String summary)544         public void onSummaryChanged(String summary) {
545             if (mSummaryLoader != null) {
546                 mSummaryLoader.setSummary(this, summary);
547             }
548         }
549     }
550 
551     public static final SummaryLoader.SummaryProviderFactory SUMMARY_PROVIDER_FACTORY
552             = new SummaryLoader.SummaryProviderFactory() {
553         @Override
554         public SummaryLoader.SummaryProvider createSummaryProvider(Activity activity,
555                 SummaryLoader summaryLoader) {
556 
557             return new SummaryProvider(activity, summaryLoader, Utils.getLocalBtManager(activity));
558         }
559     };
560 
561     public static final SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
562             new BaseSearchIndexProvider() {
563                 @Override
564                 public List<SearchIndexableRaw> getRawDataToIndex(Context context,
565                         boolean enabled) {
566 
567                     final List<SearchIndexableRaw> result = new ArrayList<SearchIndexableRaw>();
568 
569                     final Resources res = context.getResources();
570 
571                     // Add fragment title
572                     SearchIndexableRaw data = new SearchIndexableRaw(context);
573                     data.title = res.getString(R.string.bluetooth_settings);
574                     data.screenTitle = res.getString(R.string.bluetooth_settings);
575                     data.key = DATA_KEY_REFERENCE;
576                     result.add(data);
577 
578                     // Add cached paired BT devices
579                     LocalBluetoothManager lbtm = Utils.getLocalBtManager(context);
580                     // LocalBluetoothManager.getInstance can return null if the device does not
581                     // support bluetooth (e.g. the emulator).
582                     if (lbtm != null) {
583                         Set<BluetoothDevice> bondedDevices =
584                                 lbtm.getBluetoothAdapter().getBondedDevices();
585 
586                         for (BluetoothDevice device : bondedDevices) {
587                             data = new SearchIndexableRaw(context);
588                             data.title = device.getName();
589                             data.screenTitle = res.getString(R.string.bluetooth_settings);
590                             data.enabled = enabled;
591                             result.add(data);
592                         }
593                     }
594                     return result;
595                 }
596             };
597 }
598