BluetoothEnabler.java revision 9d1bfd1e8de6e46137a9571507c03526880d6a46
1/* 2 * Copyright (C) 2010 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 android.bluetooth.BluetoothAdapter; 20import android.content.BroadcastReceiver; 21import android.content.Context; 22import android.content.Intent; 23import android.content.IntentFilter; 24import android.os.Handler; 25import android.os.Message; 26import android.provider.Settings; 27import android.widget.Switch; 28import android.widget.Toast; 29 30import com.android.internal.logging.MetricsLogger; 31import com.android.internal.logging.MetricsProto.MetricsEvent; 32import com.android.settings.R; 33import com.android.settings.search.Index; 34import com.android.settings.widget.SwitchBar; 35import com.android.settingslib.WirelessUtils; 36import com.android.settingslib.bluetooth.LocalBluetoothAdapter; 37import com.android.settingslib.bluetooth.LocalBluetoothManager; 38 39/** 40 * BluetoothEnabler is a helper to manage the Bluetooth on/off checkbox 41 * preference. It turns on/off Bluetooth and ensures the summary of the 42 * preference reflects the current state. 43 */ 44public final class BluetoothEnabler implements SwitchBar.OnSwitchChangeListener { 45 private Context mContext; 46 private Switch mSwitch; 47 private SwitchBar mSwitchBar; 48 private boolean mValidListener; 49 private final LocalBluetoothAdapter mLocalAdapter; 50 private final IntentFilter mIntentFilter; 51 52 private static final String EVENT_DATA_IS_BT_ON = "is_bluetooth_on"; 53 private static final int EVENT_UPDATE_INDEX = 0; 54 55 private Handler mHandler = new Handler() { 56 @Override 57 public void handleMessage(Message msg) { 58 switch (msg.what) { 59 case EVENT_UPDATE_INDEX: 60 final boolean isBluetoothOn = msg.getData().getBoolean(EVENT_DATA_IS_BT_ON); 61 Index.getInstance(mContext).updateFromClassNameResource( 62 BluetoothSettings.class.getName(), true, isBluetoothOn); 63 break; 64 } 65 } 66 }; 67 68 private final BroadcastReceiver mReceiver = new BroadcastReceiver() { 69 @Override 70 public void onReceive(Context context, Intent intent) { 71 // Broadcast receiver is always running on the UI thread here, 72 // so we don't need consider thread synchronization. 73 int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.ERROR); 74 handleStateChanged(state); 75 } 76 }; 77 78 public BluetoothEnabler(Context context, SwitchBar switchBar) { 79 mContext = context; 80 mSwitchBar = switchBar; 81 mSwitch = switchBar.getSwitch(); 82 mValidListener = false; 83 84 LocalBluetoothManager manager = Utils.getLocalBtManager(context); 85 if (manager == null) { 86 // Bluetooth is not supported 87 mLocalAdapter = null; 88 mSwitch.setEnabled(false); 89 } else { 90 mLocalAdapter = manager.getBluetoothAdapter(); 91 } 92 mIntentFilter = new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED); 93 } 94 95 public void setupSwitchBar() { 96 mSwitchBar.show(); 97 } 98 99 public void teardownSwitchBar() { 100 mSwitchBar.hide(); 101 } 102 103 public void resume(Context context) { 104 if (mLocalAdapter == null) { 105 mSwitch.setEnabled(false); 106 return; 107 } 108 109 if (mContext != context) { 110 mContext = context; 111 } 112 113 // Bluetooth state is not sticky, so set it manually 114 handleStateChanged(mLocalAdapter.getBluetoothState()); 115 116 mSwitchBar.addOnSwitchChangeListener(this); 117 mContext.registerReceiver(mReceiver, mIntentFilter); 118 mValidListener = true; 119 } 120 121 public void pause() { 122 if (mLocalAdapter == null) { 123 return; 124 } 125 126 mSwitchBar.removeOnSwitchChangeListener(this); 127 mContext.unregisterReceiver(mReceiver); 128 mValidListener = false; 129 } 130 131 void handleStateChanged(int state) { 132 switch (state) { 133 case BluetoothAdapter.STATE_TURNING_ON: 134 mSwitch.setEnabled(false); 135 break; 136 case BluetoothAdapter.STATE_ON: 137 setChecked(true); 138 mSwitch.setEnabled(true); 139 updateSearchIndex(true); 140 break; 141 case BluetoothAdapter.STATE_TURNING_OFF: 142 mSwitch.setEnabled(false); 143 break; 144 case BluetoothAdapter.STATE_OFF: 145 setChecked(false); 146 mSwitch.setEnabled(true); 147 updateSearchIndex(false); 148 break; 149 default: 150 setChecked(false); 151 mSwitch.setEnabled(true); 152 updateSearchIndex(false); 153 } 154 } 155 156 private void setChecked(boolean isChecked) { 157 if (isChecked != mSwitch.isChecked()) { 158 // set listener to null, so onCheckedChanged won't be called 159 // if the checked status on Switch isn't changed by user click 160 if (mValidListener) { 161 mSwitchBar.removeOnSwitchChangeListener(this); 162 } 163 mSwitch.setChecked(isChecked); 164 if (mValidListener) { 165 mSwitchBar.addOnSwitchChangeListener(this); 166 } 167 } 168 } 169 170 private void updateSearchIndex(boolean isBluetoothOn) { 171 mHandler.removeMessages(EVENT_UPDATE_INDEX); 172 173 Message msg = new Message(); 174 msg.what = EVENT_UPDATE_INDEX; 175 msg.getData().putBoolean(EVENT_DATA_IS_BT_ON, isBluetoothOn); 176 mHandler.sendMessage(msg); 177 } 178 179 @Override 180 public void onSwitchChanged(Switch switchView, boolean isChecked) { 181 // Show toast message if Bluetooth is not allowed in airplane mode 182 if (isChecked && 183 !WirelessUtils.isRadioAllowed(mContext, Settings.Global.RADIO_BLUETOOTH)) { 184 Toast.makeText(mContext, R.string.wifi_in_airplane_mode, Toast.LENGTH_SHORT).show(); 185 // Reset switch to off 186 switchView.setChecked(false); 187 } 188 189 MetricsLogger.action(mContext, MetricsEvent.ACTION_BLUETOOTH_TOGGLE, isChecked); 190 191 if (mLocalAdapter != null) { 192 mLocalAdapter.setBluetoothEnabled(isChecked); 193 } 194 mSwitch.setEnabled(false); 195 } 196} 197