BluetoothTile.java revision 06d3bca095aecbb7542ebf4bdaa56b368261dd9d
1/* 2 * Copyright (C) 2014 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.systemui.qs.tiles; 18 19import android.content.Context; 20import android.content.Intent; 21import android.provider.Settings; 22import android.text.TextUtils; 23import android.view.View; 24import android.view.ViewGroup; 25 26import com.android.systemui.R; 27import com.android.systemui.qs.QSDetailItems; 28import com.android.systemui.qs.QSDetailItems.Item; 29import com.android.systemui.qs.QSTile; 30import com.android.systemui.statusbar.policy.BluetoothController; 31import com.android.systemui.statusbar.policy.BluetoothController.PairedDevice; 32 33import java.util.Set; 34 35/** Quick settings tile: Bluetooth **/ 36public class BluetoothTile extends QSTile<QSTile.BooleanState> { 37 private static final Intent BLUETOOTH_SETTINGS = new Intent(Settings.ACTION_BLUETOOTH_SETTINGS); 38 39 private final BluetoothController mController; 40 private final BluetoothDetailAdapter mDetailAdapter; 41 42 public BluetoothTile(Host host) { 43 super(host); 44 mController = host.getBluetoothController(); 45 mDetailAdapter = new BluetoothDetailAdapter(); 46 } 47 48 @Override 49 public boolean supportsDualTargets() { 50 return true; 51 } 52 53 @Override 54 public DetailAdapter getDetailAdapter() { 55 return mDetailAdapter; 56 } 57 58 @Override 59 protected BooleanState newTileState() { 60 return new BooleanState(); 61 } 62 63 @Override 64 public void setListening(boolean listening) { 65 if (listening) { 66 mController.addStateChangedCallback(mCallback); 67 } else { 68 mController.removeStateChangedCallback(mCallback); 69 } 70 } 71 72 @Override 73 protected void handleClick() { 74 final boolean isEnabled = (Boolean)mState.value; 75 mController.setBluetoothEnabled(!isEnabled); 76 } 77 78 @Override 79 protected void handleSecondaryClick() { 80 mHost.startSettingsActivity(BLUETOOTH_SETTINGS); 81 } 82 83 @Override 84 protected void handleUpdateState(BooleanState state, Object arg) { 85 final boolean supported = mController.isBluetoothSupported(); 86 final boolean enabled = mController.isBluetoothEnabled(); 87 final boolean connected = mController.isBluetoothConnected(); 88 final boolean connecting = mController.isBluetoothConnecting(); 89 state.visible = supported; 90 state.value = enabled; 91 state.autoMirrorDrawable = false; 92 if (enabled) { 93 state.label = null; 94 if (connected) { 95 state.iconId = R.drawable.ic_qs_bluetooth_connected; 96 state.contentDescription = mContext.getString( 97 R.string.accessibility_quick_settings_bluetooth_connected); 98 state.label = mController.getLastDeviceName(); 99 } else if (connecting) { 100 state.iconId = R.drawable.ic_qs_bluetooth_connecting; 101 state.contentDescription = mContext.getString( 102 R.string.accessibility_quick_settings_bluetooth_connecting); 103 state.label = mContext.getString(R.string.quick_settings_bluetooth_label); 104 } else { 105 state.iconId = R.drawable.ic_qs_bluetooth_on; 106 state.contentDescription = mContext.getString( 107 R.string.accessibility_quick_settings_bluetooth_on); 108 } 109 if (TextUtils.isEmpty(state.label)) { 110 state.label = mContext.getString(R.string.quick_settings_bluetooth_label); 111 } 112 } else { 113 state.iconId = R.drawable.ic_qs_bluetooth_off; 114 state.label = mContext.getString(R.string.quick_settings_bluetooth_label); 115 state.contentDescription = mContext.getString( 116 R.string.accessibility_quick_settings_bluetooth_off); 117 } 118 119 String bluetoothName = state.label; 120 if (connected) { 121 bluetoothName = state.dualLabelContentDescription = mContext.getString( 122 R.string.accessibility_bluetooth_name, state.label); 123 } 124 state.dualLabelContentDescription = bluetoothName; 125 } 126 127 @Override 128 protected String composeChangeAnnouncement() { 129 if (mState.value) { 130 return mContext.getString(R.string.accessibility_quick_settings_bluetooth_changed_on); 131 } else { 132 return mContext.getString(R.string.accessibility_quick_settings_bluetooth_changed_off); 133 } 134 } 135 136 private final BluetoothController.Callback mCallback = new BluetoothController.Callback() { 137 @Override 138 public void onBluetoothStateChange(boolean enabled, boolean connecting) { 139 refreshState(); 140 } 141 @Override 142 public void onBluetoothPairedDevicesChanged() { 143 mUiHandler.post(new Runnable() { 144 @Override 145 public void run() { 146 mDetailAdapter.updateItems(); 147 } 148 }); 149 } 150 }; 151 152 private final class BluetoothDetailAdapter implements DetailAdapter, QSDetailItems.Callback { 153 private QSDetailItems mItems; 154 155 @Override 156 public int getTitle() { 157 return R.string.quick_settings_bluetooth_label; 158 } 159 160 @Override 161 public Boolean getToggleState() { 162 return mState.value; 163 } 164 165 @Override 166 public Intent getSettingsIntent() { 167 return BLUETOOTH_SETTINGS; 168 } 169 170 @Override 171 public void setToggleState(boolean state) { 172 mController.setBluetoothEnabled(state); 173 showDetail(false); 174 } 175 176 @Override 177 public View createDetailView(Context context, View convertView, ViewGroup parent) { 178 mItems = QSDetailItems.convertOrInflate(context, convertView, parent); 179 mItems.setTagSuffix("Bluetooth"); 180 mItems.setEmptyState(R.drawable.ic_qs_bluetooth_detail_empty, 181 R.string.quick_settings_bluetooth_detail_empty_text); 182 mItems.setCallback(this); 183 updateItems(); 184 setItemsVisible(mState.value); 185 return mItems; 186 } 187 188 public void setItemsVisible(boolean visible) { 189 if (mItems == null) return; 190 mItems.setItemsVisible(visible); 191 } 192 193 private void updateItems() { 194 if (mItems == null) return; 195 Item[] items = null; 196 final Set<PairedDevice> devices = mController.getPairedDevices(); 197 if (devices != null) { 198 items = new Item[devices.size()]; 199 int i = 0; 200 for (PairedDevice device : devices) { 201 final Item item = new Item(); 202 item.icon = R.drawable.ic_qs_bluetooth_on; 203 item.line1 = device.name; 204 if (device.state == PairedDevice.STATE_CONNECTED) { 205 item.icon = R.drawable.ic_qs_bluetooth_connected; 206 item.line2 = mContext.getString(R.string.quick_settings_connected); 207 item.canDisconnect = true; 208 } else if (device.state == PairedDevice.STATE_CONNECTING) { 209 item.icon = R.drawable.ic_qs_bluetooth_connecting; 210 item.line2 = mContext.getString(R.string.quick_settings_connecting); 211 } 212 item.tag = device; 213 items[i++] = item; 214 } 215 } 216 mItems.setItems(items); 217 } 218 219 @Override 220 public void onDetailItemClick(Item item) { 221 if (item == null || item.tag == null) return; 222 final PairedDevice device = (PairedDevice) item.tag; 223 if (device != null && device.state == PairedDevice.STATE_DISCONNECTED) { 224 mController.connect(device); 225 } 226 } 227 228 @Override 229 public void onDetailItemDisconnect(Item item) { 230 if (item == null || item.tag == null) return; 231 final PairedDevice device = (PairedDevice) item.tag; 232 if (device != null) { 233 mController.disconnect(device); 234 } 235 } 236 } 237} 238