blob: b7ce101cacab916e0779d781c58e387d0ad9aaa8 [file] [log] [blame]
John Spurlockaf8d6c42014-05-07 17:49:08 -04001/*
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;
Jason Monkba2318e2015-12-08 09:04:23 -050021import android.content.pm.PackageManager;
John Spurlockaf8d6c42014-05-07 17:49:08 -040022import android.content.res.Resources;
23import android.provider.Settings;
Jason Monk32508852017-01-18 09:17:13 -050024import android.service.quicksettings.Tile;
Fabian Kozynskiab141ea2019-02-25 11:14:13 -050025import android.text.TextUtils;
John Spurlockccb6b9a2014-05-17 15:54:40 -040026import android.util.Log;
John Spurlock7f8f22a2014-07-02 18:54:17 -040027import android.view.View;
John Spurlock7f8f22a2014-07-02 18:54:17 -040028import android.view.ViewGroup;
Julia Reynolds20aef8a2016-05-04 16:44:08 -040029import android.widget.Switch;
Chris Wrenf6e9228b2016-01-26 18:04:35 -050030
Chris Wren457a21c2015-05-06 17:50:34 -040031import com.android.internal.logging.MetricsLogger;
Tamas Berghammer383db5eb2016-06-22 15:21:38 +010032import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
Jason Monkd52356a2015-01-28 10:40:41 -050033import com.android.settingslib.wifi.AccessPoint;
John Spurlockaf8d6c42014-05-07 17:49:08 -040034import com.android.systemui.R;
Jason Monkec34da82017-02-24 15:57:05 -050035import com.android.systemui.plugins.ActivityStarter;
Jason Monke5b770e2017-03-03 21:49:29 -050036import com.android.systemui.plugins.qs.DetailAdapter;
Jason Monk702e2eb2017-03-03 16:53:44 -050037import com.android.systemui.plugins.qs.QSIconView;
38import com.android.systemui.plugins.qs.QSTile;
39import com.android.systemui.plugins.qs.QSTile.SignalState;
Evan Laird369ded02017-09-21 14:11:00 -040040import com.android.systemui.qs.AlphaControlledSignalTileView;
Jason Monk90950d92017-06-20 13:16:05 -040041import com.android.systemui.qs.QSDetailItems;
42import com.android.systemui.qs.QSDetailItems.Item;
43import com.android.systemui.qs.QSHost;
Amin Shaikha5902ea2018-03-29 14:23:29 -040044import com.android.systemui.qs.tileimpl.QSIconViewImpl;
Jason Monk90950d92017-06-20 13:16:05 -040045import com.android.systemui.qs.tileimpl.QSTileImpl;
John Spurlockaf8d6c42014-05-07 17:49:08 -040046import com.android.systemui.statusbar.policy.NetworkController;
Jason Monkd2263cd2014-11-10 14:22:56 -050047import com.android.systemui.statusbar.policy.NetworkController.AccessPointController;
Jason Monk07b75fe2015-05-14 16:47:03 -040048import com.android.systemui.statusbar.policy.NetworkController.IconState;
Jason Monk0f0de132016-12-19 15:36:13 -050049import com.android.systemui.statusbar.policy.NetworkController.SignalCallback;
Fabian Kozynski04e4cdf2018-12-17 14:00:51 -050050import com.android.systemui.statusbar.policy.WifiIcons;
Jason Monk07b75fe2015-05-14 16:47:03 -040051
52import java.util.List;
John Spurlockaf8d6c42014-05-07 17:49:08 -040053
Jason Monk5d577202018-12-26 15:43:06 -050054import javax.inject.Inject;
55
John Spurlockaf8d6c42014-05-07 17:49:08 -040056/** Quick settings tile: Wifi **/
Jason Monk702e2eb2017-03-03 16:53:44 -050057public class WifiTile extends QSTileImpl<SignalState> {
John Spurlockaf8d6c42014-05-07 17:49:08 -040058 private static final Intent WIFI_SETTINGS = new Intent(Settings.ACTION_WIFI_SETTINGS);
Fabian Kozynski99cf7982019-09-05 14:03:26 -040059 private static final Intent WIFI_PANEL = new Intent(Settings.Panel.ACTION_WIFI);
John Spurlockaf8d6c42014-05-07 17:49:08 -040060
Muyuan Li0e9f5382016-04-27 15:51:15 -070061 protected final NetworkController mController;
Jason Monkd2263cd2014-11-10 14:22:56 -050062 private final AccessPointController mWifiController;
John Spurlock7f8f22a2014-07-02 18:54:17 -040063 private final WifiDetailAdapter mDetailAdapter;
Selim Cinek4fda7b22014-08-18 22:07:25 +020064 private final QSTile.SignalState mStateBeforeClick = newTileState();
John Spurlockaf8d6c42014-05-07 17:49:08 -040065
Jason Monkf1179612015-09-23 11:11:00 -040066 protected final WifiSignalCallback mSignalCallback = new WifiSignalCallback();
Jason Monk9c7844c2017-01-18 15:21:53 -050067 private final ActivityStarter mActivityStarter;
Amin Shaikha5902ea2018-03-29 14:23:29 -040068 private boolean mExpectDisabled;
Jason Monk878c0932015-07-21 10:18:01 -040069
Jason Monk5d577202018-12-26 15:43:06 -050070 @Inject
Jason Monkc0e0e2b2018-12-26 16:47:41 -050071 public WifiTile(QSHost host, NetworkController networkController,
72 ActivityStarter activityStarter) {
John Spurlockaf8d6c42014-05-07 17:49:08 -040073 super(host);
Jason Monkc0e0e2b2018-12-26 16:47:41 -050074 mController = networkController;
Jason Monkd2263cd2014-11-10 14:22:56 -050075 mWifiController = mController.getAccessPointController();
Muyuan Li0e9f5382016-04-27 15:51:15 -070076 mDetailAdapter = (WifiDetailAdapter) createDetailAdapter();
Jason Monkc0e0e2b2018-12-26 16:47:41 -050077 mActivityStarter = activityStarter;
Jason Monkfa452ef2018-12-26 17:26:10 -050078 mController.observe(getLifecycle(), mSignalCallback);
John Spurlockccb6b9a2014-05-17 15:54:40 -040079 }
80
81 @Override
Jason Monk62b63a02016-02-02 15:15:31 -050082 public SignalState newTileState() {
John Spurlockaf8d6c42014-05-07 17:49:08 -040083 return new SignalState();
84 }
85
86 @Override
Jason Monk1c6116c2017-09-06 17:33:01 -040087 public void handleSetListening(boolean listening) {
Jason Monk0d6a1c42015-04-20 16:38:51 -040088 }
89
90 @Override
91 public void setDetailListening(boolean listening) {
92 if (listening) {
93 mWifiController.addAccessPointCallback(mDetailAdapter);
94 } else {
Jason Monkd2263cd2014-11-10 14:22:56 -050095 mWifiController.removeAccessPointCallback(mDetailAdapter);
John Spurlockccb6b9a2014-05-17 15:54:40 -040096 }
John Spurlockaf8d6c42014-05-07 17:49:08 -040097 }
98
99 @Override
John Spurlock7f8f22a2014-07-02 18:54:17 -0400100 public DetailAdapter getDetailAdapter() {
101 return mDetailAdapter;
102 }
103
104 @Override
Jason Monkbe3235a2017-04-05 09:29:53 -0400105 protected DetailAdapter createDetailAdapter() {
106 return new WifiDetailAdapter();
107 }
Muyuan Li0e9f5382016-04-27 15:51:15 -0700108
109 @Override
Jason Monkdc35dcb2015-12-04 16:36:15 -0500110 public QSIconView createTileView(Context context) {
Evan Laird369ded02017-09-21 14:11:00 -0400111 return new AlphaControlledSignalTileView(context);
John Spurlockaf8d6c42014-05-07 17:49:08 -0400112 }
113
114 @Override
Jason Monk76c67aa2016-02-19 14:49:42 -0500115 public Intent getLongClickIntent() {
Fabian Kozynski99cf7982019-09-05 14:03:26 -0400116 if (mQSSettingsPanelOption == QSSettingsPanel.OPEN_LONG_PRESS) return WIFI_PANEL;
117 else return WIFI_SETTINGS;
Jason Monk76c67aa2016-02-19 14:49:42 -0500118 }
119
120 @Override
Matt Pietalb3e8cbd2019-09-12 10:03:08 -0400121 public boolean supportsDetailView() {
122 return getDetailAdapter() != null && mQSSettingsPanelOption == QSSettingsPanel.OPEN_CLICK;
123 }
124
125 @Override
Jason Monk32508852017-01-18 09:17:13 -0500126 protected void handleClick() {
Fabian Kozynski99cf7982019-09-05 14:03:26 -0400127 if (mQSSettingsPanelOption == QSSettingsPanel.OPEN_CLICK) {
128 mActivityStarter.postStartActivityDismissingKeyguard(WIFI_PANEL, 0);
129 return;
130 }
Jason Monkdc35dcb2015-12-04 16:36:15 -0500131 // Secondary clicks are header clicks, just toggle.
Selim Cinek4fda7b22014-08-18 22:07:25 +0200132 mState.copyTo(mStateBeforeClick);
Amin Shaikhd03a7432018-03-01 15:46:55 -0500133 boolean wifiEnabled = mState.value;
134 // Immediately enter transient state when turning on wifi.
135 refreshState(wifiEnabled ? null : ARG_SHOW_TRANSIENT_ENABLING);
136 mController.setWifiEnabled(!wifiEnabled);
Amin Shaikha5902ea2018-03-29 14:23:29 -0400137 mExpectDisabled = wifiEnabled;
138 if (mExpectDisabled) {
139 mHandler.postDelayed(() -> {
140 if (mExpectDisabled) {
141 mExpectDisabled = false;
142 refreshState();
143 }
144 }, QSIconViewImpl.QS_ANIM_LENGTH);
145 }
John Spurlockaf8d6c42014-05-07 17:49:08 -0400146 }
147
148 @Override
Jason Monk32508852017-01-18 09:17:13 -0500149 protected void handleSecondaryClick() {
Jason Monkd2263cd2014-11-10 14:22:56 -0500150 if (!mWifiController.canConfigWifi()) {
Jason Monk9c7844c2017-01-18 15:21:53 -0500151 mActivityStarter.postStartActivityDismissingKeyguard(
152 new Intent(Settings.ACTION_WIFI_SETTINGS), 0);
Jason Monk5d325072014-10-27 11:38:47 -0400153 return;
154 }
Jason Monk48e093e2016-07-15 10:37:07 -0400155 showDetail(true);
Jason Monk3c3b6502017-07-27 15:41:26 -0400156 if (!mState.value) {
157 mController.setWifiEnabled(true);
158 }
John Spurlockaf8d6c42014-05-07 17:49:08 -0400159 }
160
161 @Override
Jason Monk39c98e62016-03-16 09:18:35 -0400162 public CharSequence getTileLabel() {
163 return mContext.getString(R.string.quick_settings_wifi_label);
164 }
165
166 @Override
John Spurlockaf8d6c42014-05-07 17:49:08 -0400167 protected void handleUpdateState(SignalState state, Object arg) {
John Spurlockccb6b9a2014-05-17 15:54:40 -0400168 if (DEBUG) Log.d(TAG, "handleUpdateState arg=" + arg);
Amin Shaikha5902ea2018-03-29 14:23:29 -0400169 final CallbackInfo cb = mSignalCallback.mInfo;
170 if (mExpectDisabled) {
171 if (cb.enabled) {
172 return; // Ignore updates until disabled event occurs.
173 } else {
174 mExpectDisabled = false;
175 }
Jason Monk878c0932015-07-21 10:18:01 -0400176 }
Amin Shaikhd03a7432018-03-01 15:46:55 -0500177 boolean transientEnabling = arg == ARG_SHOW_TRANSIENT_ENABLING;
Amin Shaikhe74dbdd2018-03-09 16:05:30 -0500178 boolean wifiConnected = cb.enabled && (cb.wifiSignalIconId > 0) && (cb.ssid != null);
179 boolean wifiNotConnected = (cb.wifiSignalIconId > 0) && (cb.ssid == null);
Julia Reynolds20aef8a2016-05-04 16:44:08 -0400180 boolean enabledChanging = state.value != cb.enabled;
John Spurlock7f8f22a2014-07-02 18:54:17 -0400181 if (enabledChanging) {
John Spurlock486b78e2014-07-07 08:37:56 -0400182 mDetailAdapter.setItemsVisible(cb.enabled);
John Spurlock7f8f22a2014-07-02 18:54:17 -0400183 fireToggleStateChanged(cb.enabled);
184 }
Jason Monk395617f2017-05-05 14:07:58 -0400185 if (state.slash == null) {
186 state.slash = new SlashState();
Evan Laird8d2e5402017-06-08 10:36:57 -0400187 state.slash.rotation = 6;
Jason Monk395617f2017-05-05 14:07:58 -0400188 }
189 state.slash.isSlashed = false;
Amin Shaikhd03a7432018-03-01 15:46:55 -0500190 boolean isTransient = transientEnabling || cb.isTransient;
Amin Shaikhe74dbdd2018-03-09 16:05:30 -0500191 state.secondaryLabel = getSecondaryLabel(isTransient, cb.statusLabel);
Jason Monk395617f2017-05-05 14:07:58 -0400192 state.state = Tile.STATE_ACTIVE;
Jason Monk2db46192017-02-01 17:18:22 -0500193 state.dualTarget = true;
Amin Shaikhd03a7432018-03-01 15:46:55 -0500194 state.value = transientEnabling || cb.enabled;
John Spurlockaf8d6c42014-05-07 17:49:08 -0400195 state.activityIn = cb.enabled && cb.activityIn;
196 state.activityOut = cb.enabled && cb.activityOut;
Julia Reynolds20aef8a2016-05-04 16:44:08 -0400197 final StringBuffer minimalContentDescription = new StringBuffer();
John Spurlockaf8d6c42014-05-07 17:49:08 -0400198 final Resources r = mContext.getResources();
Amin Shaikhd03a7432018-03-01 15:46:55 -0500199 if (isTransient) {
Amin Shaikh2cea8792019-04-30 09:19:01 -0400200 state.icon = ResourceIcon.get(
201 com.android.internal.R.drawable.ic_signal_wifi_transient_animation);
Jason Monk110e5f62017-03-31 13:45:12 -0400202 state.label = r.getString(R.string.quick_settings_wifi_label);
203 } else if (!state.value) {
Jason Monk395617f2017-05-05 14:07:58 -0400204 state.slash.isSlashed = true;
205 state.state = Tile.STATE_INACTIVE;
Fabian Kozynski04e4cdf2018-12-17 14:00:51 -0500206 state.icon = ResourceIcon.get(WifiIcons.QS_WIFI_DISABLED);
John Spurlockc1d48a52014-08-01 12:12:32 -0400207 state.label = r.getString(R.string.quick_settings_wifi_label);
John Spurlockc1d48a52014-08-01 12:12:32 -0400208 } else if (wifiConnected) {
John Spurlock2d695812014-10-30 13:25:21 -0400209 state.icon = ResourceIcon.get(cb.wifiSignalIconId);
Amin Shaikhe74dbdd2018-03-09 16:05:30 -0500210 state.label = removeDoubleQuotes(cb.ssid);
John Spurlockaf8d6c42014-05-07 17:49:08 -0400211 } else if (wifiNotConnected) {
Jason Monkbe83cc02016-03-31 13:38:59 -0400212 state.icon = ResourceIcon.get(R.drawable.ic_qs_wifi_disconnected);
John Spurlockaf8d6c42014-05-07 17:49:08 -0400213 state.label = r.getString(R.string.quick_settings_wifi_label);
John Spurlockaf8d6c42014-05-07 17:49:08 -0400214 } else {
Amin Shaikhdd73e162019-04-02 07:50:27 -0400215 state.icon = ResourceIcon.get(WifiIcons.QS_WIFI_NO_NETWORK);
John Spurlock012d4a22014-06-04 00:40:18 -0400216 state.label = r.getString(R.string.quick_settings_wifi_label);
John Spurlockaf8d6c42014-05-07 17:49:08 -0400217 }
Julia Reynolds20aef8a2016-05-04 16:44:08 -0400218 minimalContentDescription.append(
219 mContext.getString(R.string.quick_settings_wifi_label)).append(",");
220 if (state.value) {
Julia Reynolds20aef8a2016-05-04 16:44:08 -0400221 if (wifiConnected) {
222 minimalContentDescription.append(cb.wifiSignalContentDescription).append(",");
Amin Shaikhe74dbdd2018-03-09 16:05:30 -0500223 minimalContentDescription.append(removeDoubleQuotes(cb.ssid));
Fabian Kozynskiab141ea2019-02-25 11:14:13 -0500224 if (!TextUtils.isEmpty(state.secondaryLabel)) {
225 minimalContentDescription.append(",").append(state.secondaryLabel);
226 }
Julia Reynolds20aef8a2016-05-04 16:44:08 -0400227 }
Julia Reynolds20aef8a2016-05-04 16:44:08 -0400228 }
Jason Monk90950d92017-06-20 13:16:05 -0400229 state.contentDescription = minimalContentDescription.toString();
Jason Monk28df4ed2017-03-23 10:25:37 -0400230 state.dualLabelContentDescription = r.getString(
231 R.string.accessibility_quick_settings_open_settings, getTileLabel());
Jason Monk702e2eb2017-03-03 16:53:44 -0500232 state.expandedAccessibilityClassName = Switch.class.getName();
John Spurlockaf8d6c42014-05-07 17:49:08 -0400233 }
234
Amin Shaikhe74dbdd2018-03-09 16:05:30 -0500235 private CharSequence getSecondaryLabel(boolean isTransient, String statusLabel) {
Amin Shaikhd03a7432018-03-01 15:46:55 -0500236 return isTransient
237 ? mContext.getString(R.string.quick_settings_wifi_secondary_label_transient)
Amin Shaikhe74dbdd2018-03-09 16:05:30 -0500238 : statusLabel;
Amin Shaikhd03a7432018-03-01 15:46:55 -0500239 }
240
Selim Cinek4fda7b22014-08-18 22:07:25 +0200241 @Override
Chris Wren457a21c2015-05-06 17:50:34 -0400242 public int getMetricsCategory() {
Chris Wrenf6e9228b2016-01-26 18:04:35 -0500243 return MetricsEvent.QS_WIFI;
Chris Wren457a21c2015-05-06 17:50:34 -0400244 }
245
246 @Override
Selim Cinek4fda7b22014-08-18 22:07:25 +0200247 protected boolean shouldAnnouncementBeDelayed() {
Julia Reynolds20aef8a2016-05-04 16:44:08 -0400248 return mStateBeforeClick.value == mState.value;
Selim Cinek4fda7b22014-08-18 22:07:25 +0200249 }
250
251 @Override
252 protected String composeChangeAnnouncement() {
Julia Reynolds20aef8a2016-05-04 16:44:08 -0400253 if (mState.value) {
Selim Cinek4fda7b22014-08-18 22:07:25 +0200254 return mContext.getString(R.string.accessibility_quick_settings_wifi_changed_on);
255 } else {
256 return mContext.getString(R.string.accessibility_quick_settings_wifi_changed_off);
257 }
258 }
259
Jason Monkc3f42c12016-02-05 12:33:13 -0500260 @Override
261 public boolean isAvailable() {
262 return mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_WIFI);
263 }
264
John Spurlockaf8d6c42014-05-07 17:49:08 -0400265 private static String removeDoubleQuotes(String string) {
266 if (string == null) return null;
267 final int length = string.length();
268 if ((length > 1) && (string.charAt(0) == '"') && (string.charAt(length - 1) == '"')) {
269 return string.substring(1, length - 1);
270 }
271 return string;
272 }
273
Jason Monkf1179612015-09-23 11:11:00 -0400274 protected static final class CallbackInfo {
John Spurlockaf8d6c42014-05-07 17:49:08 -0400275 boolean enabled;
John Spurlockd5cd2fd2014-07-27 11:36:33 -0400276 boolean connected;
John Spurlockaf8d6c42014-05-07 17:49:08 -0400277 int wifiSignalIconId;
Amin Shaikhe74dbdd2018-03-09 16:05:30 -0500278 String ssid;
John Spurlockaf8d6c42014-05-07 17:49:08 -0400279 boolean activityIn;
280 boolean activityOut;
281 String wifiSignalContentDescription;
Jason Monk110e5f62017-03-31 13:45:12 -0400282 boolean isTransient;
Amin Shaikhe74dbdd2018-03-09 16:05:30 -0500283 public String statusLabel;
John Spurlockccb6b9a2014-05-17 15:54:40 -0400284
285 @Override
286 public String toString() {
287 return new StringBuilder("CallbackInfo[")
Jason Monkbe3235a2017-04-05 09:29:53 -0400288 .append("enabled=").append(enabled)
289 .append(",connected=").append(connected)
290 .append(",wifiSignalIconId=").append(wifiSignalIconId)
Amin Shaikhe74dbdd2018-03-09 16:05:30 -0500291 .append(",ssid=").append(ssid)
Jason Monkbe3235a2017-04-05 09:29:53 -0400292 .append(",activityIn=").append(activityIn)
293 .append(",activityOut=").append(activityOut)
294 .append(",wifiSignalContentDescription=").append(wifiSignalContentDescription)
295 .append(",isTransient=").append(isTransient)
296 .append(']').toString();
John Spurlockccb6b9a2014-05-17 15:54:40 -0400297 }
John Spurlockaf8d6c42014-05-07 17:49:08 -0400298 }
299
Jason Monk0f0de132016-12-19 15:36:13 -0500300 protected final class WifiSignalCallback implements SignalCallback {
Jason Monk878c0932015-07-21 10:18:01 -0400301 final CallbackInfo mInfo = new CallbackInfo();
302
John Spurlockaf8d6c42014-05-07 17:49:08 -0400303 @Override
Jason Monk07b75fe2015-05-14 16:47:03 -0400304 public void setWifiIndicators(boolean enabled, IconState statusIcon, IconState qsIcon,
Amin Shaikhe74dbdd2018-03-09 16:05:30 -0500305 boolean activityIn, boolean activityOut, String description, boolean isTransient,
306 String statusLabel) {
John Spurlockccb6b9a2014-05-17 15:54:40 -0400307 if (DEBUG) Log.d(TAG, "onWifiSignalChanged enabled=" + enabled);
Jason Monk878c0932015-07-21 10:18:01 -0400308 mInfo.enabled = enabled;
309 mInfo.connected = qsIcon.visible;
310 mInfo.wifiSignalIconId = qsIcon.icon;
Amin Shaikhe74dbdd2018-03-09 16:05:30 -0500311 mInfo.ssid = description;
Jason Monk878c0932015-07-21 10:18:01 -0400312 mInfo.activityIn = activityIn;
313 mInfo.activityOut = activityOut;
314 mInfo.wifiSignalContentDescription = qsIcon.contentDescription;
Jason Monk110e5f62017-03-31 13:45:12 -0400315 mInfo.isTransient = isTransient;
Amin Shaikhe74dbdd2018-03-09 16:05:30 -0500316 mInfo.statusLabel = statusLabel;
Jason Monkbe3235a2017-04-05 09:29:53 -0400317 if (isShowingDetail()) {
318 mDetailAdapter.updateItems();
319 }
Amin Shaikha5902ea2018-03-29 14:23:29 -0400320 refreshState();
John Spurlockaf8d6c42014-05-07 17:49:08 -0400321 }
Jason Monkbe3235a2017-04-05 09:29:53 -0400322 }
323
Muyuan Li0e9f5382016-04-27 15:51:15 -0700324 protected class WifiDetailAdapter implements DetailAdapter,
Jason Monkd2263cd2014-11-10 14:22:56 -0500325 NetworkController.AccessPointController.AccessPointCallback, QSDetailItems.Callback {
John Spurlock7f8f22a2014-07-02 18:54:17 -0400326
John Spurlock486b78e2014-07-07 08:37:56 -0400327 private QSDetailItems mItems;
John Spurlock7f8f22a2014-07-02 18:54:17 -0400328 private AccessPoint[] mAccessPoints;
329
330 @Override
Jason Monkc06fbb12016-01-08 14:12:18 -0500331 public CharSequence getTitle() {
332 return mContext.getString(R.string.quick_settings_wifi_label);
John Spurlock7f8f22a2014-07-02 18:54:17 -0400333 }
334
335 public Intent getSettingsIntent() {
336 return WIFI_SETTINGS;
337 }
338
339 @Override
340 public Boolean getToggleState() {
Julia Reynolds20aef8a2016-05-04 16:44:08 -0400341 return mState.value;
John Spurlock7f8f22a2014-07-02 18:54:17 -0400342 }
343
344 @Override
345 public void setToggleState(boolean state) {
346 if (DEBUG) Log.d(TAG, "setToggleState " + state);
Chris Wrenf6e9228b2016-01-26 18:04:35 -0500347 MetricsLogger.action(mContext, MetricsEvent.QS_WIFI_TOGGLE, state);
John Spurlock7f8f22a2014-07-02 18:54:17 -0400348 mController.setWifiEnabled(state);
John Spurlock7f8f22a2014-07-02 18:54:17 -0400349 }
350
351 @Override
Chris Wren457a21c2015-05-06 17:50:34 -0400352 public int getMetricsCategory() {
Chris Wrenf6e9228b2016-01-26 18:04:35 -0500353 return MetricsEvent.QS_WIFI_DETAILS;
Chris Wren457a21c2015-05-06 17:50:34 -0400354 }
355
356 @Override
John Spurlock7f8f22a2014-07-02 18:54:17 -0400357 public View createDetailView(Context context, View convertView, ViewGroup parent) {
John Spurlock486b78e2014-07-07 08:37:56 -0400358 if (DEBUG) Log.d(TAG, "createDetailView convertView=" + (convertView != null));
359 mAccessPoints = null;
John Spurlock486b78e2014-07-07 08:37:56 -0400360 mItems = QSDetailItems.convertOrInflate(context, convertView, parent);
361 mItems.setTagSuffix("Wifi");
362 mItems.setCallback(this);
Sundeep Ghumanc09b7f72017-07-26 20:23:32 -0700363 mWifiController.scanForAccessPoints(); // updates APs and items
Julia Reynolds20aef8a2016-05-04 16:44:08 -0400364 setItemsVisible(mState.value);
John Spurlock7f8f22a2014-07-02 18:54:17 -0400365 return mItems;
366 }
367
368 @Override
Jason Monkd52356a2015-01-28 10:40:41 -0500369 public void onAccessPointsChanged(final List<AccessPoint> accessPoints) {
370 mAccessPoints = accessPoints.toArray(new AccessPoint[accessPoints.size()]);
Sundeep Ghumance5fbd42017-07-18 15:16:01 -0700371 filterUnreachableAPs();
372
John Spurlock486b78e2014-07-07 08:37:56 -0400373 updateItems();
John Spurlock7f8f22a2014-07-02 18:54:17 -0400374 }
375
Sundeep Ghumance5fbd42017-07-18 15:16:01 -0700376 /** Filter unreachable APs from mAccessPoints */
377 private void filterUnreachableAPs() {
378 int numReachable = 0;
379 for (AccessPoint ap : mAccessPoints) {
380 if (ap.isReachable()) numReachable++;
381 }
382 if (numReachable != mAccessPoints.length) {
383 AccessPoint[] unfiltered = mAccessPoints;
384 mAccessPoints = new AccessPoint[numReachable];
385 int i = 0;
386 for (AccessPoint ap : unfiltered) {
387 if (ap.isReachable()) mAccessPoints[i++] = ap;
388 }
389 }
390 }
391
John Spurlock486b78e2014-07-07 08:37:56 -0400392 @Override
Jason Monk17f3c3f2015-01-14 10:13:22 -0500393 public void onSettingsActivityTriggered(Intent settingsIntent) {
Jason Monk9c7844c2017-01-18 15:21:53 -0500394 mActivityStarter.postStartActivityDismissingKeyguard(settingsIntent, 0);
Jason Monk17f3c3f2015-01-14 10:13:22 -0500395 }
396
397 @Override
John Spurlock486b78e2014-07-07 08:37:56 -0400398 public void onDetailItemClick(Item item) {
399 if (item == null || item.tag == null) return;
400 final AccessPoint ap = (AccessPoint) item.tag;
Jason Monkd52356a2015-01-28 10:40:41 -0500401 if (!ap.isActive()) {
Jason Monkd2263cd2014-11-10 14:22:56 -0500402 if (mWifiController.connect(ap)) {
Jason Monk5d325072014-10-27 11:38:47 -0400403 mHost.collapsePanels();
404 }
John Spurlock486b78e2014-07-07 08:37:56 -0400405 }
406 showDetail(false);
407 }
408
409 @Override
410 public void onDetailItemDisconnect(Item item) {
411 // noop
412 }
413
414 public void setItemsVisible(boolean visible) {
415 if (mItems == null) return;
416 mItems.setItemsVisible(visible);
John Spurlock7f8f22a2014-07-02 18:54:17 -0400417 }
418
419 private void updateItems() {
420 if (mItems == null) return;
Jason Monkd9fcc642017-08-01 10:13:43 -0400421 if ((mAccessPoints != null && mAccessPoints.length > 0)
422 || !mSignalCallback.mInfo.enabled) {
423 fireScanStateChanged(false);
424 } else {
425 fireScanStateChanged(true);
426 }
Evan Lairdf6139f92017-05-24 16:25:57 -0400427
428 // Wi-Fi is off
429 if (!mSignalCallback.mInfo.enabled) {
Amin Shaikhdd73e162019-04-02 07:50:27 -0400430 mItems.setEmptyState(WifiIcons.QS_WIFI_NO_NETWORK,
Jason Monkbe3235a2017-04-05 09:29:53 -0400431 R.string.wifi_is_off);
Evan Lairdf6139f92017-05-24 16:25:57 -0400432 mItems.setItems(null);
433 return;
Jason Monkbe3235a2017-04-05 09:29:53 -0400434 }
Evan Lairdf6139f92017-05-24 16:25:57 -0400435
436 // No available access points
Amin Shaikhdd73e162019-04-02 07:50:27 -0400437 mItems.setEmptyState(WifiIcons.QS_WIFI_NO_NETWORK,
Evan Lairdf6139f92017-05-24 16:25:57 -0400438 R.string.quick_settings_wifi_detail_empty_text);
439
440 // Build the list
John Spurlock486b78e2014-07-07 08:37:56 -0400441 Item[] items = null;
442 if (mAccessPoints != null) {
443 items = new Item[mAccessPoints.length];
444 for (int i = 0; i < mAccessPoints.length; i++) {
445 final AccessPoint ap = mAccessPoints[i];
446 final Item item = new Item();
447 item.tag = ap;
jackqdyulei786a4902017-10-24 13:27:53 -0700448 item.iconResId = mWifiController.getIcon(ap);
Jason Monkd52356a2015-01-28 10:40:41 -0500449 item.line1 = ap.getSsid();
Jason Monk283c8b72015-05-26 12:54:12 -0400450 item.line2 = ap.isActive() ? ap.getSummary() : null;
Sundeep Ghumanff0f1082017-02-10 11:49:36 -0800451 item.icon2 = ap.getSecurity() != AccessPoint.SECURITY_NONE
452 ? R.drawable.qs_ic_wifi_lock
453 : -1;
John Spurlock486b78e2014-07-07 08:37:56 -0400454 items[i] = item;
455 }
John Spurlock7f8f22a2014-07-02 18:54:17 -0400456 }
John Spurlock486b78e2014-07-07 08:37:56 -0400457 mItems.setItems(items);
John Spurlock7f8f22a2014-07-02 18:54:17 -0400458 }
Fan Zhang3bfda442016-07-15 10:39:03 -0700459 }
John Spurlockaf8d6c42014-05-07 17:49:08 -0400460}