WifiTile.java revision d2263cd9db36d5f74a124c5ffaf8594ef702408f
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.content.res.Resources; 22import android.provider.Settings; 23import android.util.Log; 24import android.view.View; 25import android.view.ViewGroup; 26 27import com.android.systemui.R; 28import com.android.systemui.qs.QSDetailItems; 29import com.android.systemui.qs.QSDetailItems.Item; 30import com.android.systemui.qs.QSTile; 31import com.android.systemui.qs.QSTileView; 32import com.android.systemui.qs.SignalTileView; 33import com.android.systemui.statusbar.policy.NetworkController; 34import com.android.systemui.statusbar.policy.NetworkController.AccessPointController; 35import com.android.systemui.statusbar.policy.NetworkController.AccessPointController.AccessPoint; 36import com.android.systemui.statusbar.policy.NetworkController.NetworkSignalChangedCallback; 37 38/** Quick settings tile: Wifi **/ 39public class WifiTile extends QSTile<QSTile.SignalState> { 40 private static final Intent WIFI_SETTINGS = new Intent(Settings.ACTION_WIFI_SETTINGS); 41 42 private final NetworkController mController; 43 private final AccessPointController mWifiController; 44 private final WifiDetailAdapter mDetailAdapter; 45 private final QSTile.SignalState mStateBeforeClick = newTileState(); 46 47 public WifiTile(Host host) { 48 super(host); 49 mController = host.getNetworkController(); 50 mWifiController = mController.getAccessPointController(); 51 mDetailAdapter = new WifiDetailAdapter(); 52 } 53 54 @Override 55 public boolean supportsDualTargets() { 56 return true; 57 } 58 59 @Override 60 protected SignalState newTileState() { 61 return new SignalState(); 62 } 63 64 @Override 65 public void setListening(boolean listening) { 66 if (listening) { 67 mController.addNetworkSignalChangedCallback(mCallback); 68 mWifiController.addAccessPointCallback(mDetailAdapter); 69 } else { 70 mController.removeNetworkSignalChangedCallback(mCallback); 71 mWifiController.removeAccessPointCallback(mDetailAdapter); 72 } 73 } 74 75 @Override 76 public DetailAdapter getDetailAdapter() { 77 return mDetailAdapter; 78 } 79 80 @Override 81 public QSTileView createTileView(Context context) { 82 return new SignalTileView(context); 83 } 84 85 @Override 86 protected void handleClick() { 87 mState.copyTo(mStateBeforeClick); 88 mController.setWifiEnabled(!mState.enabled); 89 } 90 91 @Override 92 protected void handleSecondaryClick() { 93 if (!mWifiController.canConfigWifi()) { 94 mHost.startSettingsActivity(new Intent(Settings.ACTION_WIFI_SETTINGS)); 95 return; 96 } 97 if (!mState.enabled) { 98 mController.setWifiEnabled(true); 99 mState.enabled = true; 100 } 101 showDetail(true); 102 } 103 104 @Override 105 protected void handleUpdateState(SignalState state, Object arg) { 106 state.visible = true; 107 if (DEBUG) Log.d(TAG, "handleUpdateState arg=" + arg); 108 if (arg == null) return; 109 CallbackInfo cb = (CallbackInfo) arg; 110 111 boolean wifiConnected = cb.enabled && (cb.wifiSignalIconId > 0) && (cb.enabledDesc != null); 112 boolean wifiNotConnected = (cb.wifiSignalIconId > 0) && (cb.enabledDesc == null); 113 boolean enabledChanging = state.enabled != cb.enabled; 114 if (enabledChanging) { 115 mDetailAdapter.setItemsVisible(cb.enabled); 116 fireToggleStateChanged(cb.enabled); 117 } 118 state.enabled = cb.enabled; 119 state.connected = wifiConnected; 120 state.activityIn = cb.enabled && cb.activityIn; 121 state.activityOut = cb.enabled && cb.activityOut; 122 state.filter = true; 123 final String signalContentDescription; 124 final Resources r = mContext.getResources(); 125 if (!state.enabled) { 126 state.icon = ResourceIcon.get(R.drawable.ic_qs_wifi_disabled); 127 state.label = r.getString(R.string.quick_settings_wifi_label); 128 signalContentDescription = r.getString(R.string.accessibility_wifi_off); 129 } else if (wifiConnected) { 130 state.icon = ResourceIcon.get(cb.wifiSignalIconId); 131 state.label = removeDoubleQuotes(cb.enabledDesc); 132 signalContentDescription = cb.wifiSignalContentDescription; 133 } else if (wifiNotConnected) { 134 state.icon = ResourceIcon.get(R.drawable.ic_qs_wifi_0); 135 state.label = r.getString(R.string.quick_settings_wifi_label); 136 signalContentDescription = r.getString(R.string.accessibility_no_wifi); 137 } else { 138 state.icon = ResourceIcon.get(R.drawable.ic_qs_wifi_no_network); 139 state.label = r.getString(R.string.quick_settings_wifi_label); 140 signalContentDescription = r.getString(R.string.accessibility_wifi_off); 141 } 142 state.contentDescription = mContext.getString( 143 R.string.accessibility_quick_settings_wifi, 144 signalContentDescription); 145 String wifiName = state.label; 146 if (state.connected) { 147 wifiName = r.getString(R.string.accessibility_wifi_name, state.label); 148 } 149 state.dualLabelContentDescription = wifiName; 150 } 151 152 @Override 153 protected boolean shouldAnnouncementBeDelayed() { 154 return mStateBeforeClick.enabled == mState.enabled; 155 } 156 157 @Override 158 protected String composeChangeAnnouncement() { 159 if (mState.enabled) { 160 return mContext.getString(R.string.accessibility_quick_settings_wifi_changed_on); 161 } else { 162 return mContext.getString(R.string.accessibility_quick_settings_wifi_changed_off); 163 } 164 } 165 166 private static String removeDoubleQuotes(String string) { 167 if (string == null) return null; 168 final int length = string.length(); 169 if ((length > 1) && (string.charAt(0) == '"') && (string.charAt(length - 1) == '"')) { 170 return string.substring(1, length - 1); 171 } 172 return string; 173 } 174 175 private static final class CallbackInfo { 176 boolean enabled; 177 boolean connected; 178 int wifiSignalIconId; 179 String enabledDesc; 180 boolean activityIn; 181 boolean activityOut; 182 String wifiSignalContentDescription; 183 184 @Override 185 public String toString() { 186 return new StringBuilder("CallbackInfo[") 187 .append("enabled=").append(enabled) 188 .append(",connected=").append(connected) 189 .append(",wifiSignalIconId=").append(wifiSignalIconId) 190 .append(",enabledDesc=").append(enabledDesc) 191 .append(",activityIn=").append(activityIn) 192 .append(",activityOut=").append(activityOut) 193 .append(",wifiSignalContentDescription=").append(wifiSignalContentDescription) 194 .append(']').toString(); 195 } 196 } 197 198 private final NetworkSignalChangedCallback mCallback = new NetworkSignalChangedCallback() { 199 @Override 200 public void onWifiSignalChanged(boolean enabled, boolean connected, int wifiSignalIconId, 201 boolean activityIn, boolean activityOut, 202 String wifiSignalContentDescriptionId, String description) { 203 if (DEBUG) Log.d(TAG, "onWifiSignalChanged enabled=" + enabled); 204 final CallbackInfo info = new CallbackInfo(); 205 info.enabled = enabled; 206 info.connected = connected; 207 info.wifiSignalIconId = wifiSignalIconId; 208 info.enabledDesc = description; 209 info.activityIn = activityIn; 210 info.activityOut = activityOut; 211 info.wifiSignalContentDescription = wifiSignalContentDescriptionId; 212 refreshState(info); 213 } 214 215 @Override 216 public void onMobileDataSignalChanged(boolean enabled, 217 int mobileSignalIconId, 218 String mobileSignalContentDescriptionId, int dataTypeIconId, 219 boolean activityIn, boolean activityOut, 220 String dataTypeContentDescriptionId, String description, boolean noSim, 221 boolean isDataTypeIconWide) { 222 // noop 223 } 224 225 @Override 226 public void onAirplaneModeChanged(boolean enabled) { 227 // noop 228 } 229 230 @Override 231 public void onMobileDataEnabled(boolean enabled) { 232 // noop 233 } 234 }; 235 236 private final class WifiDetailAdapter implements DetailAdapter, 237 NetworkController.AccessPointController.AccessPointCallback, QSDetailItems.Callback { 238 239 private QSDetailItems mItems; 240 private AccessPoint[] mAccessPoints; 241 242 @Override 243 public int getTitle() { 244 return R.string.quick_settings_wifi_label; 245 } 246 247 public Intent getSettingsIntent() { 248 return WIFI_SETTINGS; 249 } 250 251 @Override 252 public Boolean getToggleState() { 253 return mState.enabled; 254 } 255 256 @Override 257 public void setToggleState(boolean state) { 258 if (DEBUG) Log.d(TAG, "setToggleState " + state); 259 mController.setWifiEnabled(state); 260 showDetail(false); 261 } 262 263 @Override 264 public View createDetailView(Context context, View convertView, ViewGroup parent) { 265 if (DEBUG) Log.d(TAG, "createDetailView convertView=" + (convertView != null)); 266 mAccessPoints = null; 267 mWifiController.scanForAccessPoints(); 268 fireScanStateChanged(true); 269 mItems = QSDetailItems.convertOrInflate(context, convertView, parent); 270 mItems.setTagSuffix("Wifi"); 271 mItems.setCallback(this); 272 mItems.setEmptyState(R.drawable.ic_qs_wifi_detail_empty, 273 R.string.quick_settings_wifi_detail_empty_text); 274 updateItems(); 275 setItemsVisible(mState.enabled); 276 return mItems; 277 } 278 279 @Override 280 public void onAccessPointsChanged(final AccessPoint[] accessPoints) { 281 mAccessPoints = accessPoints; 282 updateItems(); 283 if (accessPoints != null && accessPoints.length > 0) { 284 fireScanStateChanged(false); 285 } 286 } 287 288 @Override 289 public void onDetailItemClick(Item item) { 290 if (item == null || item.tag == null) return; 291 final AccessPoint ap = (AccessPoint) item.tag; 292 if (!ap.isConnected) { 293 if (mWifiController.connect(ap)) { 294 mHost.collapsePanels(); 295 } 296 } 297 showDetail(false); 298 } 299 300 @Override 301 public void onDetailItemDisconnect(Item item) { 302 // noop 303 } 304 305 public void setItemsVisible(boolean visible) { 306 if (mItems == null) return; 307 mItems.setItemsVisible(visible); 308 } 309 310 private void updateItems() { 311 if (mItems == null) return; 312 Item[] items = null; 313 if (mAccessPoints != null) { 314 items = new Item[mAccessPoints.length]; 315 for (int i = 0; i < mAccessPoints.length; i++) { 316 final AccessPoint ap = mAccessPoints[i]; 317 final Item item = new Item(); 318 item.tag = ap; 319 item.icon = ap.iconId; 320 item.line1 = ap.ssid; 321 if (ap.isConnected) { 322 item.line2 = mContext.getString(R.string.quick_settings_connected); 323 } 324 items[i] = item; 325 } 326 } 327 mItems.setItems(items); 328 } 329 }; 330} 331