BluetoothEnabler.java revision 1c4e96864f054f0d3d754d21eb4803fe0df6d89f
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 17package com.android.settings.bluetooth; 18 19import com.android.settings.AirplaneModeEnabler; 20import com.android.settings.R; 21 22import android.bluetooth.BluetoothAdapter; 23import android.content.BroadcastReceiver; 24import android.content.Context; 25import android.content.Intent; 26import android.content.IntentFilter; 27import android.preference.Preference; 28import android.preference.CheckBoxPreference; 29import android.provider.Settings; 30import android.text.TextUtils; 31import android.util.Config; 32 33/** 34 * BluetoothEnabler is a helper to manage the Bluetooth on/off checkbox 35 * preference. It is turns on/off Bluetooth and ensures the summary of the 36 * preference reflects the current state. 37 */ 38public class BluetoothEnabler implements Preference.OnPreferenceChangeListener { 39 40 private static final boolean LOCAL_LOGD = Config.LOGD || false; 41 private static final String TAG = "BluetoothEnabler"; 42 43 private final Context mContext; 44 private final CheckBoxPreference mCheckBoxPreference; 45 private final CharSequence mOriginalSummary; 46 47 private final LocalBluetoothManager mLocalManager; 48 49 private final BroadcastReceiver mReceiver = new BroadcastReceiver() { 50 @Override 51 public void onReceive(Context context, Intent intent) { 52 int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.ERROR); 53 handleStateChanged(state); 54 } 55 }; 56 57 public BluetoothEnabler(Context context, CheckBoxPreference checkBoxPreference) { 58 mContext = context; 59 mCheckBoxPreference = checkBoxPreference; 60 61 mOriginalSummary = checkBoxPreference.getSummary(); 62 checkBoxPreference.setPersistent(false); 63 64 mLocalManager = LocalBluetoothManager.getInstance(context); 65 if (mLocalManager == null) { 66 // Bluetooth not supported 67 checkBoxPreference.setEnabled(false); 68 } 69 } 70 71 public void resume() { 72 if (mLocalManager == null) { 73 return; 74 } 75 76 int state = mLocalManager.getBluetoothState(); 77 // This is the widget enabled state, not the preference toggled state 78 mCheckBoxPreference.setEnabled(state == BluetoothAdapter.STATE_ON || 79 state == BluetoothAdapter.STATE_OFF); 80 // BT state is not a sticky broadcast, so set it manually 81 handleStateChanged(state); 82 83 mContext.registerReceiver(mReceiver, 84 new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED)); 85 mCheckBoxPreference.setOnPreferenceChangeListener(this); 86 } 87 88 public void pause() { 89 if (mLocalManager == null) { 90 return; 91 } 92 93 mContext.unregisterReceiver(mReceiver); 94 mCheckBoxPreference.setOnPreferenceChangeListener(null); 95 } 96 97 public boolean onPreferenceChange(Preference preference, Object value) { 98 // Turn on/off BT 99 setEnabled((Boolean) value); 100 101 // Don't update UI to opposite state until we're sure 102 return false; 103 } 104 105 private void setEnabled(final boolean enable) { 106 // Disable preference 107 mCheckBoxPreference.setEnabled(false); 108 109 mLocalManager.setBluetoothEnabled(enable); 110 } 111 112 private void handleStateChanged(int state) { 113 114 if (state == BluetoothAdapter.STATE_OFF || 115 state == BluetoothAdapter.STATE_ON) { 116 mCheckBoxPreference.setChecked(state == BluetoothAdapter.STATE_ON); 117 mCheckBoxPreference.setSummary(state == BluetoothAdapter.STATE_OFF ? 118 mOriginalSummary : 119 null); 120 121 final boolean hasDependency = !TextUtils.isEmpty(mCheckBoxPreference.getDependency()); 122 final boolean bluetoothAllowed = isBluetoothAllowed(mContext); 123 124 // Avoid disabling when dependencies have been manually set, 125 // workaround for framework bug http://b/2053751 126 if (bluetoothAllowed) { 127 mCheckBoxPreference.setEnabled(true); 128 } else if (!hasDependency) { 129 mCheckBoxPreference.setEnabled(false); 130 } 131 132 } else if (state == BluetoothAdapter.STATE_TURNING_ON || 133 state == BluetoothAdapter.STATE_TURNING_OFF) { 134 mCheckBoxPreference.setSummary(state == BluetoothAdapter.STATE_TURNING_ON 135 ? R.string.wifi_starting 136 : R.string.wifi_stopping); 137 138 } else { 139 mCheckBoxPreference.setChecked(false); 140 mCheckBoxPreference.setSummary(R.string.wifi_error); 141 mCheckBoxPreference.setEnabled(true); 142 } 143 } 144 145 private static boolean isBluetoothAllowed(Context context) { 146 // allowed if we are not in airplane mode 147 if (!AirplaneModeEnabler.isAirplaneModeOn(context)) { 148 return true; 149 } 150 // allowed if bluetooth is not in AIRPLANE_MODE_RADIOS 151 String radios = Settings.System.getString(context.getContentResolver(), 152 Settings.System.AIRPLANE_MODE_RADIOS); 153 if (radios == null || !radios.contains(Settings.System.RADIO_BLUETOOTH)) { 154 return true; 155 } 156 // allowed if bluetooth is in AIRPLANE_MODE_TOGGLEABLE_RADIOS 157 radios = Settings.System.getString(context.getContentResolver(), 158 Settings.System.AIRPLANE_MODE_TOGGLEABLE_RADIOS); 159 return (radios != null && radios.contains(Settings.System.RADIO_BLUETOOTH)); 160 } 161 162} 163