blob: 0e7362c3d0816bfb5b05a87294a4e63ca97d542c [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);
59
Muyuan Li0e9f5382016-04-27 15:51:15 -070060 protected final NetworkController mController;
Jason Monkd2263cd2014-11-10 14:22:56 -050061 private final AccessPointController mWifiController;
John Spurlock7f8f22a2014-07-02 18:54:17 -040062 private final WifiDetailAdapter mDetailAdapter;
Selim Cinek4fda7b22014-08-18 22:07:25 +020063 private final QSTile.SignalState mStateBeforeClick = newTileState();
John Spurlockaf8d6c42014-05-07 17:49:08 -040064
Jason Monkf1179612015-09-23 11:11:00 -040065 protected final WifiSignalCallback mSignalCallback = new WifiSignalCallback();
Jason Monk9c7844c2017-01-18 15:21:53 -050066 private final ActivityStarter mActivityStarter;
Amin Shaikha5902ea2018-03-29 14:23:29 -040067 private boolean mExpectDisabled;
Jason Monk878c0932015-07-21 10:18:01 -040068
Jason Monk5d577202018-12-26 15:43:06 -050069 @Inject
Jason Monkc0e0e2b2018-12-26 16:47:41 -050070 public WifiTile(QSHost host, NetworkController networkController,
71 ActivityStarter activityStarter) {
John Spurlockaf8d6c42014-05-07 17:49:08 -040072 super(host);
Jason Monkc0e0e2b2018-12-26 16:47:41 -050073 mController = networkController;
Jason Monkd2263cd2014-11-10 14:22:56 -050074 mWifiController = mController.getAccessPointController();
Muyuan Li0e9f5382016-04-27 15:51:15 -070075 mDetailAdapter = (WifiDetailAdapter) createDetailAdapter();
Jason Monkc0e0e2b2018-12-26 16:47:41 -050076 mActivityStarter = activityStarter;
Jason Monkfa452ef2018-12-26 17:26:10 -050077 mController.observe(getLifecycle(), mSignalCallback);
John Spurlockccb6b9a2014-05-17 15:54:40 -040078 }
79
80 @Override
Jason Monk62b63a02016-02-02 15:15:31 -050081 public SignalState newTileState() {
John Spurlockaf8d6c42014-05-07 17:49:08 -040082 return new SignalState();
83 }
84
85 @Override
Jason Monk1c6116c2017-09-06 17:33:01 -040086 public void handleSetListening(boolean listening) {
Jason Monk0d6a1c42015-04-20 16:38:51 -040087 }
88
89 @Override
90 public void setDetailListening(boolean listening) {
91 if (listening) {
92 mWifiController.addAccessPointCallback(mDetailAdapter);
93 } else {
Jason Monkd2263cd2014-11-10 14:22:56 -050094 mWifiController.removeAccessPointCallback(mDetailAdapter);
John Spurlockccb6b9a2014-05-17 15:54:40 -040095 }
John Spurlockaf8d6c42014-05-07 17:49:08 -040096 }
97
98 @Override
John Spurlock7f8f22a2014-07-02 18:54:17 -040099 public DetailAdapter getDetailAdapter() {
100 return mDetailAdapter;
101 }
102
103 @Override
Jason Monkbe3235a2017-04-05 09:29:53 -0400104 protected DetailAdapter createDetailAdapter() {
105 return new WifiDetailAdapter();
106 }
Muyuan Li0e9f5382016-04-27 15:51:15 -0700107
108 @Override
Jason Monkdc35dcb2015-12-04 16:36:15 -0500109 public QSIconView createTileView(Context context) {
Evan Laird369ded02017-09-21 14:11:00 -0400110 return new AlphaControlledSignalTileView(context);
John Spurlockaf8d6c42014-05-07 17:49:08 -0400111 }
112
113 @Override
Jason Monk76c67aa2016-02-19 14:49:42 -0500114 public Intent getLongClickIntent() {
115 return WIFI_SETTINGS;
116 }
117
118 @Override
Jason Monk32508852017-01-18 09:17:13 -0500119 protected void handleClick() {
Jason Monkdc35dcb2015-12-04 16:36:15 -0500120 // Secondary clicks are header clicks, just toggle.
Selim Cinek4fda7b22014-08-18 22:07:25 +0200121 mState.copyTo(mStateBeforeClick);
Amin Shaikhd03a7432018-03-01 15:46:55 -0500122 boolean wifiEnabled = mState.value;
123 // Immediately enter transient state when turning on wifi.
124 refreshState(wifiEnabled ? null : ARG_SHOW_TRANSIENT_ENABLING);
125 mController.setWifiEnabled(!wifiEnabled);
Amin Shaikha5902ea2018-03-29 14:23:29 -0400126 mExpectDisabled = wifiEnabled;
127 if (mExpectDisabled) {
128 mHandler.postDelayed(() -> {
129 if (mExpectDisabled) {
130 mExpectDisabled = false;
131 refreshState();
132 }
133 }, QSIconViewImpl.QS_ANIM_LENGTH);
134 }
John Spurlockaf8d6c42014-05-07 17:49:08 -0400135 }
136
137 @Override
Jason Monk32508852017-01-18 09:17:13 -0500138 protected void handleSecondaryClick() {
Jason Monkd2263cd2014-11-10 14:22:56 -0500139 if (!mWifiController.canConfigWifi()) {
Jason Monk9c7844c2017-01-18 15:21:53 -0500140 mActivityStarter.postStartActivityDismissingKeyguard(
141 new Intent(Settings.ACTION_WIFI_SETTINGS), 0);
Jason Monk5d325072014-10-27 11:38:47 -0400142 return;
143 }
Jason Monk48e093e2016-07-15 10:37:07 -0400144 showDetail(true);
Jason Monk3c3b6502017-07-27 15:41:26 -0400145 if (!mState.value) {
146 mController.setWifiEnabled(true);
147 }
John Spurlockaf8d6c42014-05-07 17:49:08 -0400148 }
149
150 @Override
Jason Monk39c98e62016-03-16 09:18:35 -0400151 public CharSequence getTileLabel() {
152 return mContext.getString(R.string.quick_settings_wifi_label);
153 }
154
155 @Override
John Spurlockaf8d6c42014-05-07 17:49:08 -0400156 protected void handleUpdateState(SignalState state, Object arg) {
John Spurlockccb6b9a2014-05-17 15:54:40 -0400157 if (DEBUG) Log.d(TAG, "handleUpdateState arg=" + arg);
Amin Shaikha5902ea2018-03-29 14:23:29 -0400158 final CallbackInfo cb = mSignalCallback.mInfo;
159 if (mExpectDisabled) {
160 if (cb.enabled) {
161 return; // Ignore updates until disabled event occurs.
162 } else {
163 mExpectDisabled = false;
164 }
Jason Monk878c0932015-07-21 10:18:01 -0400165 }
Amin Shaikhd03a7432018-03-01 15:46:55 -0500166 boolean transientEnabling = arg == ARG_SHOW_TRANSIENT_ENABLING;
Amin Shaikhe74dbdd2018-03-09 16:05:30 -0500167 boolean wifiConnected = cb.enabled && (cb.wifiSignalIconId > 0) && (cb.ssid != null);
168 boolean wifiNotConnected = (cb.wifiSignalIconId > 0) && (cb.ssid == null);
Julia Reynolds20aef8a2016-05-04 16:44:08 -0400169 boolean enabledChanging = state.value != cb.enabled;
John Spurlock7f8f22a2014-07-02 18:54:17 -0400170 if (enabledChanging) {
John Spurlock486b78e2014-07-07 08:37:56 -0400171 mDetailAdapter.setItemsVisible(cb.enabled);
John Spurlock7f8f22a2014-07-02 18:54:17 -0400172 fireToggleStateChanged(cb.enabled);
173 }
Jason Monk395617f2017-05-05 14:07:58 -0400174 if (state.slash == null) {
175 state.slash = new SlashState();
Evan Laird8d2e5402017-06-08 10:36:57 -0400176 state.slash.rotation = 6;
Jason Monk395617f2017-05-05 14:07:58 -0400177 }
178 state.slash.isSlashed = false;
Amin Shaikhd03a7432018-03-01 15:46:55 -0500179 boolean isTransient = transientEnabling || cb.isTransient;
Amin Shaikhe74dbdd2018-03-09 16:05:30 -0500180 state.secondaryLabel = getSecondaryLabel(isTransient, cb.statusLabel);
Jason Monk395617f2017-05-05 14:07:58 -0400181 state.state = Tile.STATE_ACTIVE;
Jason Monk2db46192017-02-01 17:18:22 -0500182 state.dualTarget = true;
Amin Shaikhd03a7432018-03-01 15:46:55 -0500183 state.value = transientEnabling || cb.enabled;
John Spurlockaf8d6c42014-05-07 17:49:08 -0400184 state.activityIn = cb.enabled && cb.activityIn;
185 state.activityOut = cb.enabled && cb.activityOut;
Julia Reynolds20aef8a2016-05-04 16:44:08 -0400186 final StringBuffer minimalContentDescription = new StringBuffer();
John Spurlockaf8d6c42014-05-07 17:49:08 -0400187 final Resources r = mContext.getResources();
Amin Shaikhd03a7432018-03-01 15:46:55 -0500188 if (isTransient) {
Amin Shaikh2cea8792019-04-30 09:19:01 -0400189 state.icon = ResourceIcon.get(
190 com.android.internal.R.drawable.ic_signal_wifi_transient_animation);
Jason Monk110e5f62017-03-31 13:45:12 -0400191 state.label = r.getString(R.string.quick_settings_wifi_label);
192 } else if (!state.value) {
Jason Monk395617f2017-05-05 14:07:58 -0400193 state.slash.isSlashed = true;
194 state.state = Tile.STATE_INACTIVE;
Fabian Kozynski04e4cdf2018-12-17 14:00:51 -0500195 state.icon = ResourceIcon.get(WifiIcons.QS_WIFI_DISABLED);
John Spurlockc1d48a52014-08-01 12:12:32 -0400196 state.label = r.getString(R.string.quick_settings_wifi_label);
John Spurlockc1d48a52014-08-01 12:12:32 -0400197 } else if (wifiConnected) {
John Spurlock2d695812014-10-30 13:25:21 -0400198 state.icon = ResourceIcon.get(cb.wifiSignalIconId);
Amin Shaikhe74dbdd2018-03-09 16:05:30 -0500199 state.label = removeDoubleQuotes(cb.ssid);
John Spurlockaf8d6c42014-05-07 17:49:08 -0400200 } else if (wifiNotConnected) {
Jason Monkbe83cc02016-03-31 13:38:59 -0400201 state.icon = ResourceIcon.get(R.drawable.ic_qs_wifi_disconnected);
John Spurlockaf8d6c42014-05-07 17:49:08 -0400202 state.label = r.getString(R.string.quick_settings_wifi_label);
John Spurlockaf8d6c42014-05-07 17:49:08 -0400203 } else {
Amin Shaikhdd73e162019-04-02 07:50:27 -0400204 state.icon = ResourceIcon.get(WifiIcons.QS_WIFI_NO_NETWORK);
John Spurlock012d4a22014-06-04 00:40:18 -0400205 state.label = r.getString(R.string.quick_settings_wifi_label);
John Spurlockaf8d6c42014-05-07 17:49:08 -0400206 }
Julia Reynolds20aef8a2016-05-04 16:44:08 -0400207 minimalContentDescription.append(
208 mContext.getString(R.string.quick_settings_wifi_label)).append(",");
209 if (state.value) {
Julia Reynolds20aef8a2016-05-04 16:44:08 -0400210 if (wifiConnected) {
211 minimalContentDescription.append(cb.wifiSignalContentDescription).append(",");
Amin Shaikhe74dbdd2018-03-09 16:05:30 -0500212 minimalContentDescription.append(removeDoubleQuotes(cb.ssid));
Fabian Kozynskiab141ea2019-02-25 11:14:13 -0500213 if (!TextUtils.isEmpty(state.secondaryLabel)) {
214 minimalContentDescription.append(",").append(state.secondaryLabel);
215 }
Julia Reynolds20aef8a2016-05-04 16:44:08 -0400216 }
Julia Reynolds20aef8a2016-05-04 16:44:08 -0400217 }
Jason Monk90950d92017-06-20 13:16:05 -0400218 state.contentDescription = minimalContentDescription.toString();
Jason Monk28df4ed2017-03-23 10:25:37 -0400219 state.dualLabelContentDescription = r.getString(
220 R.string.accessibility_quick_settings_open_settings, getTileLabel());
Jason Monk702e2eb2017-03-03 16:53:44 -0500221 state.expandedAccessibilityClassName = Switch.class.getName();
John Spurlockaf8d6c42014-05-07 17:49:08 -0400222 }
223
Amin Shaikhe74dbdd2018-03-09 16:05:30 -0500224 private CharSequence getSecondaryLabel(boolean isTransient, String statusLabel) {
Amin Shaikhd03a7432018-03-01 15:46:55 -0500225 return isTransient
226 ? mContext.getString(R.string.quick_settings_wifi_secondary_label_transient)
Amin Shaikhe74dbdd2018-03-09 16:05:30 -0500227 : statusLabel;
Amin Shaikhd03a7432018-03-01 15:46:55 -0500228 }
229
Selim Cinek4fda7b22014-08-18 22:07:25 +0200230 @Override
Chris Wren457a21c2015-05-06 17:50:34 -0400231 public int getMetricsCategory() {
Chris Wrenf6e9228b2016-01-26 18:04:35 -0500232 return MetricsEvent.QS_WIFI;
Chris Wren457a21c2015-05-06 17:50:34 -0400233 }
234
235 @Override
Selim Cinek4fda7b22014-08-18 22:07:25 +0200236 protected boolean shouldAnnouncementBeDelayed() {
Julia Reynolds20aef8a2016-05-04 16:44:08 -0400237 return mStateBeforeClick.value == mState.value;
Selim Cinek4fda7b22014-08-18 22:07:25 +0200238 }
239
240 @Override
241 protected String composeChangeAnnouncement() {
Julia Reynolds20aef8a2016-05-04 16:44:08 -0400242 if (mState.value) {
Selim Cinek4fda7b22014-08-18 22:07:25 +0200243 return mContext.getString(R.string.accessibility_quick_settings_wifi_changed_on);
244 } else {
245 return mContext.getString(R.string.accessibility_quick_settings_wifi_changed_off);
246 }
247 }
248
Jason Monkc3f42c12016-02-05 12:33:13 -0500249 @Override
250 public boolean isAvailable() {
251 return mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_WIFI);
252 }
253
John Spurlockaf8d6c42014-05-07 17:49:08 -0400254 private static String removeDoubleQuotes(String string) {
255 if (string == null) return null;
256 final int length = string.length();
257 if ((length > 1) && (string.charAt(0) == '"') && (string.charAt(length - 1) == '"')) {
258 return string.substring(1, length - 1);
259 }
260 return string;
261 }
262
Jason Monkf1179612015-09-23 11:11:00 -0400263 protected static final class CallbackInfo {
John Spurlockaf8d6c42014-05-07 17:49:08 -0400264 boolean enabled;
John Spurlockd5cd2fd2014-07-27 11:36:33 -0400265 boolean connected;
John Spurlockaf8d6c42014-05-07 17:49:08 -0400266 int wifiSignalIconId;
Amin Shaikhe74dbdd2018-03-09 16:05:30 -0500267 String ssid;
John Spurlockaf8d6c42014-05-07 17:49:08 -0400268 boolean activityIn;
269 boolean activityOut;
270 String wifiSignalContentDescription;
Jason Monk110e5f62017-03-31 13:45:12 -0400271 boolean isTransient;
Amin Shaikhe74dbdd2018-03-09 16:05:30 -0500272 public String statusLabel;
John Spurlockccb6b9a2014-05-17 15:54:40 -0400273
274 @Override
275 public String toString() {
276 return new StringBuilder("CallbackInfo[")
Jason Monkbe3235a2017-04-05 09:29:53 -0400277 .append("enabled=").append(enabled)
278 .append(",connected=").append(connected)
279 .append(",wifiSignalIconId=").append(wifiSignalIconId)
Amin Shaikhe74dbdd2018-03-09 16:05:30 -0500280 .append(",ssid=").append(ssid)
Jason Monkbe3235a2017-04-05 09:29:53 -0400281 .append(",activityIn=").append(activityIn)
282 .append(",activityOut=").append(activityOut)
283 .append(",wifiSignalContentDescription=").append(wifiSignalContentDescription)
284 .append(",isTransient=").append(isTransient)
285 .append(']').toString();
John Spurlockccb6b9a2014-05-17 15:54:40 -0400286 }
John Spurlockaf8d6c42014-05-07 17:49:08 -0400287 }
288
Jason Monk0f0de132016-12-19 15:36:13 -0500289 protected final class WifiSignalCallback implements SignalCallback {
Jason Monk878c0932015-07-21 10:18:01 -0400290 final CallbackInfo mInfo = new CallbackInfo();
291
John Spurlockaf8d6c42014-05-07 17:49:08 -0400292 @Override
Jason Monk07b75fe2015-05-14 16:47:03 -0400293 public void setWifiIndicators(boolean enabled, IconState statusIcon, IconState qsIcon,
Amin Shaikhe74dbdd2018-03-09 16:05:30 -0500294 boolean activityIn, boolean activityOut, String description, boolean isTransient,
295 String statusLabel) {
John Spurlockccb6b9a2014-05-17 15:54:40 -0400296 if (DEBUG) Log.d(TAG, "onWifiSignalChanged enabled=" + enabled);
Jason Monk878c0932015-07-21 10:18:01 -0400297 mInfo.enabled = enabled;
298 mInfo.connected = qsIcon.visible;
299 mInfo.wifiSignalIconId = qsIcon.icon;
Amin Shaikhe74dbdd2018-03-09 16:05:30 -0500300 mInfo.ssid = description;
Jason Monk878c0932015-07-21 10:18:01 -0400301 mInfo.activityIn = activityIn;
302 mInfo.activityOut = activityOut;
303 mInfo.wifiSignalContentDescription = qsIcon.contentDescription;
Jason Monk110e5f62017-03-31 13:45:12 -0400304 mInfo.isTransient = isTransient;
Amin Shaikhe74dbdd2018-03-09 16:05:30 -0500305 mInfo.statusLabel = statusLabel;
Jason Monkbe3235a2017-04-05 09:29:53 -0400306 if (isShowingDetail()) {
307 mDetailAdapter.updateItems();
308 }
Amin Shaikha5902ea2018-03-29 14:23:29 -0400309 refreshState();
John Spurlockaf8d6c42014-05-07 17:49:08 -0400310 }
Jason Monkbe3235a2017-04-05 09:29:53 -0400311 }
312
Muyuan Li0e9f5382016-04-27 15:51:15 -0700313 protected class WifiDetailAdapter implements DetailAdapter,
Jason Monkd2263cd2014-11-10 14:22:56 -0500314 NetworkController.AccessPointController.AccessPointCallback, QSDetailItems.Callback {
John Spurlock7f8f22a2014-07-02 18:54:17 -0400315
John Spurlock486b78e2014-07-07 08:37:56 -0400316 private QSDetailItems mItems;
John Spurlock7f8f22a2014-07-02 18:54:17 -0400317 private AccessPoint[] mAccessPoints;
318
319 @Override
Jason Monkc06fbb12016-01-08 14:12:18 -0500320 public CharSequence getTitle() {
321 return mContext.getString(R.string.quick_settings_wifi_label);
John Spurlock7f8f22a2014-07-02 18:54:17 -0400322 }
323
324 public Intent getSettingsIntent() {
325 return WIFI_SETTINGS;
326 }
327
328 @Override
329 public Boolean getToggleState() {
Julia Reynolds20aef8a2016-05-04 16:44:08 -0400330 return mState.value;
John Spurlock7f8f22a2014-07-02 18:54:17 -0400331 }
332
333 @Override
334 public void setToggleState(boolean state) {
335 if (DEBUG) Log.d(TAG, "setToggleState " + state);
Chris Wrenf6e9228b2016-01-26 18:04:35 -0500336 MetricsLogger.action(mContext, MetricsEvent.QS_WIFI_TOGGLE, state);
John Spurlock7f8f22a2014-07-02 18:54:17 -0400337 mController.setWifiEnabled(state);
John Spurlock7f8f22a2014-07-02 18:54:17 -0400338 }
339
340 @Override
Chris Wren457a21c2015-05-06 17:50:34 -0400341 public int getMetricsCategory() {
Chris Wrenf6e9228b2016-01-26 18:04:35 -0500342 return MetricsEvent.QS_WIFI_DETAILS;
Chris Wren457a21c2015-05-06 17:50:34 -0400343 }
344
345 @Override
John Spurlock7f8f22a2014-07-02 18:54:17 -0400346 public View createDetailView(Context context, View convertView, ViewGroup parent) {
John Spurlock486b78e2014-07-07 08:37:56 -0400347 if (DEBUG) Log.d(TAG, "createDetailView convertView=" + (convertView != null));
348 mAccessPoints = null;
John Spurlock486b78e2014-07-07 08:37:56 -0400349 mItems = QSDetailItems.convertOrInflate(context, convertView, parent);
350 mItems.setTagSuffix("Wifi");
351 mItems.setCallback(this);
Sundeep Ghumanc09b7f72017-07-26 20:23:32 -0700352 mWifiController.scanForAccessPoints(); // updates APs and items
Julia Reynolds20aef8a2016-05-04 16:44:08 -0400353 setItemsVisible(mState.value);
John Spurlock7f8f22a2014-07-02 18:54:17 -0400354 return mItems;
355 }
356
357 @Override
Jason Monkd52356a2015-01-28 10:40:41 -0500358 public void onAccessPointsChanged(final List<AccessPoint> accessPoints) {
359 mAccessPoints = accessPoints.toArray(new AccessPoint[accessPoints.size()]);
Sundeep Ghumance5fbd42017-07-18 15:16:01 -0700360 filterUnreachableAPs();
361
John Spurlock486b78e2014-07-07 08:37:56 -0400362 updateItems();
John Spurlock7f8f22a2014-07-02 18:54:17 -0400363 }
364
Sundeep Ghumance5fbd42017-07-18 15:16:01 -0700365 /** Filter unreachable APs from mAccessPoints */
366 private void filterUnreachableAPs() {
367 int numReachable = 0;
368 for (AccessPoint ap : mAccessPoints) {
369 if (ap.isReachable()) numReachable++;
370 }
371 if (numReachable != mAccessPoints.length) {
372 AccessPoint[] unfiltered = mAccessPoints;
373 mAccessPoints = new AccessPoint[numReachable];
374 int i = 0;
375 for (AccessPoint ap : unfiltered) {
376 if (ap.isReachable()) mAccessPoints[i++] = ap;
377 }
378 }
379 }
380
John Spurlock486b78e2014-07-07 08:37:56 -0400381 @Override
Jason Monk17f3c3f2015-01-14 10:13:22 -0500382 public void onSettingsActivityTriggered(Intent settingsIntent) {
Jason Monk9c7844c2017-01-18 15:21:53 -0500383 mActivityStarter.postStartActivityDismissingKeyguard(settingsIntent, 0);
Jason Monk17f3c3f2015-01-14 10:13:22 -0500384 }
385
386 @Override
John Spurlock486b78e2014-07-07 08:37:56 -0400387 public void onDetailItemClick(Item item) {
388 if (item == null || item.tag == null) return;
389 final AccessPoint ap = (AccessPoint) item.tag;
Jason Monkd52356a2015-01-28 10:40:41 -0500390 if (!ap.isActive()) {
Jason Monkd2263cd2014-11-10 14:22:56 -0500391 if (mWifiController.connect(ap)) {
Jason Monk5d325072014-10-27 11:38:47 -0400392 mHost.collapsePanels();
393 }
John Spurlock486b78e2014-07-07 08:37:56 -0400394 }
395 showDetail(false);
396 }
397
398 @Override
399 public void onDetailItemDisconnect(Item item) {
400 // noop
401 }
402
403 public void setItemsVisible(boolean visible) {
404 if (mItems == null) return;
405 mItems.setItemsVisible(visible);
John Spurlock7f8f22a2014-07-02 18:54:17 -0400406 }
407
408 private void updateItems() {
409 if (mItems == null) return;
Jason Monkd9fcc642017-08-01 10:13:43 -0400410 if ((mAccessPoints != null && mAccessPoints.length > 0)
411 || !mSignalCallback.mInfo.enabled) {
412 fireScanStateChanged(false);
413 } else {
414 fireScanStateChanged(true);
415 }
Evan Lairdf6139f92017-05-24 16:25:57 -0400416
417 // Wi-Fi is off
418 if (!mSignalCallback.mInfo.enabled) {
Amin Shaikhdd73e162019-04-02 07:50:27 -0400419 mItems.setEmptyState(WifiIcons.QS_WIFI_NO_NETWORK,
Jason Monkbe3235a2017-04-05 09:29:53 -0400420 R.string.wifi_is_off);
Evan Lairdf6139f92017-05-24 16:25:57 -0400421 mItems.setItems(null);
422 return;
Jason Monkbe3235a2017-04-05 09:29:53 -0400423 }
Evan Lairdf6139f92017-05-24 16:25:57 -0400424
425 // No available access points
Amin Shaikhdd73e162019-04-02 07:50:27 -0400426 mItems.setEmptyState(WifiIcons.QS_WIFI_NO_NETWORK,
Evan Lairdf6139f92017-05-24 16:25:57 -0400427 R.string.quick_settings_wifi_detail_empty_text);
428
429 // Build the list
John Spurlock486b78e2014-07-07 08:37:56 -0400430 Item[] items = null;
431 if (mAccessPoints != null) {
432 items = new Item[mAccessPoints.length];
433 for (int i = 0; i < mAccessPoints.length; i++) {
434 final AccessPoint ap = mAccessPoints[i];
435 final Item item = new Item();
436 item.tag = ap;
jackqdyulei786a4902017-10-24 13:27:53 -0700437 item.iconResId = mWifiController.getIcon(ap);
Jason Monkd52356a2015-01-28 10:40:41 -0500438 item.line1 = ap.getSsid();
Jason Monk283c8b72015-05-26 12:54:12 -0400439 item.line2 = ap.isActive() ? ap.getSummary() : null;
Sundeep Ghumanff0f1082017-02-10 11:49:36 -0800440 item.icon2 = ap.getSecurity() != AccessPoint.SECURITY_NONE
441 ? R.drawable.qs_ic_wifi_lock
442 : -1;
John Spurlock486b78e2014-07-07 08:37:56 -0400443 items[i] = item;
444 }
John Spurlock7f8f22a2014-07-02 18:54:17 -0400445 }
John Spurlock486b78e2014-07-07 08:37:56 -0400446 mItems.setItems(items);
John Spurlock7f8f22a2014-07-02 18:54:17 -0400447 }
Fan Zhang3bfda442016-07-15 10:39:03 -0700448 }
John Spurlockaf8d6c42014-05-07 17:49:08 -0400449}