blob: 6baf36c81d30b1797c3a278653de6622def6504b [file] [log] [blame]
Jason Monkda68f592015-01-07 10:55:58 -05001/*
2 * Copyright (C) 2015 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 */
16package com.android.systemui.statusbar.policy;
17
Roshan Pius80fb1372018-07-16 15:43:03 -070018import static android.net.wifi.WifiManager.TrafficStateCallback.DATA_ACTIVITY_IN;
19import static android.net.wifi.WifiManager.TrafficStateCallback.DATA_ACTIVITY_INOUT;
20import static android.net.wifi.WifiManager.TrafficStateCallback.DATA_ACTIVITY_OUT;
21
Jason Monkda68f592015-01-07 10:55:58 -050022import android.content.Context;
23import android.content.Intent;
Amin Shaikhe74dbdd2018-03-09 16:05:30 -050024import android.net.ConnectivityManager;
Jason Monkda68f592015-01-07 10:55:58 -050025import android.net.NetworkCapabilities;
Amin Shaikhe74dbdd2018-03-09 16:05:30 -050026import android.net.NetworkScoreManager;
Jason Monkda68f592015-01-07 10:55:58 -050027import android.net.wifi.WifiManager;
Amin Shaikhe74dbdd2018-03-09 16:05:30 -050028import android.text.TextUtils;
Winsonc0d70582016-01-29 10:24:39 -080029
Jason Monkda68f592015-01-07 10:55:58 -050030import com.android.internal.annotations.VisibleForTesting;
Jason Monk4cf95ae2015-11-16 15:59:53 -050031import com.android.settingslib.wifi.WifiStatusTracker;
Sundeep Ghuman9d10a3c2017-06-16 00:05:16 +000032import com.android.systemui.R;
Jason Monk07b75fe2015-05-14 16:47:03 -040033import com.android.systemui.statusbar.policy.NetworkController.IconState;
Jason Monke06b0652016-03-02 16:35:27 -050034import com.android.systemui.statusbar.policy.NetworkController.SignalCallback;
Jason Monkda68f592015-01-07 10:55:58 -050035
Jason Monkda68f592015-01-07 10:55:58 -050036import java.util.Objects;
37
Jason Monkda68f592015-01-07 10:55:58 -050038public class WifiSignalController extends
39 SignalController<WifiSignalController.WifiState, SignalController.IconGroup> {
Jason Monkda68f592015-01-07 10:55:58 -050040 private final boolean mHasMobileData;
Jason Monk4cf95ae2015-11-16 15:59:53 -050041 private final WifiStatusTracker mWifiTracker;
Jason Monkda68f592015-01-07 10:55:58 -050042
43 public WifiSignalController(Context context, boolean hasMobileData,
Amin Shaikhc7593b12018-03-09 16:07:09 -050044 CallbackHandler callbackHandler, NetworkControllerImpl networkController,
45 WifiManager wifiManager) {
Jason Monkda68f592015-01-07 10:55:58 -050046 super("WifiSignalController", context, NetworkCapabilities.TRANSPORT_WIFI,
Jason Monk07b75fe2015-05-14 16:47:03 -040047 callbackHandler, networkController);
Amin Shaikhe74dbdd2018-03-09 16:05:30 -050048 NetworkScoreManager networkScoreManager =
49 context.getSystemService(NetworkScoreManager.class);
50 ConnectivityManager connectivityManager =
51 context.getSystemService(ConnectivityManager.class);
52 mWifiTracker = new WifiStatusTracker(mContext, wifiManager, networkScoreManager,
53 connectivityManager, this::handleStatusUpdated);
54 mWifiTracker.setListening(true);
Jason Monkda68f592015-01-07 10:55:58 -050055 mHasMobileData = hasMobileData;
Roshan Piusad32dbf2019-11-19 06:18:51 -080056 if (wifiManager != null) {
David Su09daba12020-01-23 12:47:24 -080057 wifiManager.registerTrafficStateCallback(context.getMainExecutor(),
58 new WifiTrafficStateCallback());
Roshan Piusad32dbf2019-11-19 06:18:51 -080059 }
Jason Monkda68f592015-01-07 10:55:58 -050060 // WiFi only has one state.
61 mCurrentState.iconGroup = mLastState.iconGroup = new IconGroup(
62 "Wi-Fi Icons",
63 WifiIcons.WIFI_SIGNAL_STRENGTH,
64 WifiIcons.QS_WIFI_SIGNAL_STRENGTH,
65 AccessibilityContentDescriptions.WIFI_CONNECTION_STRENGTH,
66 WifiIcons.WIFI_NO_NETWORK,
67 WifiIcons.QS_WIFI_NO_NETWORK,
Jason Monk7e6c83c2017-04-26 14:35:24 -040068 WifiIcons.WIFI_NO_NETWORK,
Jason Monkda68f592015-01-07 10:55:58 -050069 WifiIcons.QS_WIFI_NO_NETWORK,
70 AccessibilityContentDescriptions.WIFI_NO_CONNECTION
71 );
72 }
73
74 @Override
75 protected WifiState cleanState() {
76 return new WifiState();
77 }
78
Fabian Kozynskid9cb3842018-09-28 13:34:14 -040079 void refreshLocale() {
80 mWifiTracker.refreshLocale();
81 }
82
Jason Monkda68f592015-01-07 10:55:58 -050083 @Override
Jason Monke06b0652016-03-02 16:35:27 -050084 public void notifyListeners(SignalCallback callback) {
Jason Monkda68f592015-01-07 10:55:58 -050085 // only show wifi in the cluster if connected or if wifi-only
Minming Qie2d48ca2017-03-10 13:56:44 +080086 boolean visibleWhenEnabled = mContext.getResources().getBoolean(
87 R.bool.config_showWifiIndicatorWhenEnabled);
Jason Monk7e6c83c2017-04-26 14:35:24 -040088 boolean wifiVisible = mCurrentState.enabled
Evan Lairdb0b399a2019-12-16 15:22:52 -050089 && ((mCurrentState.connected && mCurrentState.inetCondition == 1)
90 || !mHasMobileData || visibleWhenEnabled);
Jason Monkda68f592015-01-07 10:55:58 -050091 String wifiDesc = wifiVisible ? mCurrentState.ssid : null;
92 boolean ssidPresent = wifiVisible && mCurrentState.ssid != null;
93 String contentDescription = getStringIfExists(getContentDescription());
Julia Reynolds20aef8a2016-05-04 16:44:08 -040094 if (mCurrentState.inetCondition == 0) {
Amin Shaikh43ad7fe2018-03-05 14:34:44 -050095 contentDescription += ("," + mContext.getString(R.string.data_connection_no_internet));
Julia Reynolds20aef8a2016-05-04 16:44:08 -040096 }
Sundeep Ghuman9d10a3c2017-06-16 00:05:16 +000097 IconState statusIcon = new IconState(wifiVisible, getCurrentIconId(), contentDescription);
98 IconState qsIcon = new IconState(mCurrentState.connected, getQsCurrentIconId(),
99 contentDescription);
Jason Monke06b0652016-03-02 16:35:27 -0500100 callback.setWifiIndicators(mCurrentState.enabled, statusIcon, qsIcon,
Jason Monk07b75fe2015-05-14 16:47:03 -0400101 ssidPresent && mCurrentState.activityIn, ssidPresent && mCurrentState.activityOut,
Amin Shaikhe74dbdd2018-03-09 16:05:30 -0500102 wifiDesc, mCurrentState.isTransient, mCurrentState.statusLabel);
Jason Monkda68f592015-01-07 10:55:58 -0500103 }
104
105 /**
106 * Extract wifi state directly from broadcasts about changes in wifi state.
107 */
108 public void handleBroadcast(Intent intent) {
Jason Monk4cf95ae2015-11-16 15:59:53 -0500109 mWifiTracker.handleBroadcast(intent);
110 mCurrentState.enabled = mWifiTracker.enabled;
111 mCurrentState.connected = mWifiTracker.connected;
112 mCurrentState.ssid = mWifiTracker.ssid;
113 mCurrentState.rssi = mWifiTracker.rssi;
114 mCurrentState.level = mWifiTracker.level;
Amin Shaikhe74dbdd2018-03-09 16:05:30 -0500115 mCurrentState.statusLabel = mWifiTracker.statusLabel;
116 notifyListenersIfNecessary();
117 }
118
119 private void handleStatusUpdated() {
120 mCurrentState.statusLabel = mWifiTracker.statusLabel;
Jason Monkda68f592015-01-07 10:55:58 -0500121 notifyListenersIfNecessary();
122 }
123
Jason Monkda68f592015-01-07 10:55:58 -0500124 @VisibleForTesting
125 void setActivity(int wifiActivity) {
Roshan Pius80fb1372018-07-16 15:43:03 -0700126 mCurrentState.activityIn = wifiActivity == DATA_ACTIVITY_INOUT
127 || wifiActivity == DATA_ACTIVITY_IN;
128 mCurrentState.activityOut = wifiActivity == DATA_ACTIVITY_INOUT
129 || wifiActivity == DATA_ACTIVITY_OUT;
Jason Monkda68f592015-01-07 10:55:58 -0500130 notifyListenersIfNecessary();
131 }
132
133 /**
134 * Handler to receive the data activity on wifi.
135 */
Roshan Pius80fb1372018-07-16 15:43:03 -0700136 private class WifiTrafficStateCallback implements WifiManager.TrafficStateCallback {
Jason Monkda68f592015-01-07 10:55:58 -0500137 @Override
Roshan Pius80fb1372018-07-16 15:43:03 -0700138 public void onStateChanged(int state) {
139 setActivity(state);
Jason Monkda68f592015-01-07 10:55:58 -0500140 }
141 }
142
143 static class WifiState extends SignalController.State {
144 String ssid;
Jason Monk110e5f62017-03-31 13:45:12 -0400145 boolean isTransient;
Amin Shaikhe74dbdd2018-03-09 16:05:30 -0500146 String statusLabel;
Jason Monkda68f592015-01-07 10:55:58 -0500147
148 @Override
149 public void copyFrom(State s) {
150 super.copyFrom(s);
151 WifiState state = (WifiState) s;
152 ssid = state.ssid;
Jason Monk110e5f62017-03-31 13:45:12 -0400153 isTransient = state.isTransient;
Amin Shaikhe74dbdd2018-03-09 16:05:30 -0500154 statusLabel = state.statusLabel;
Jason Monkda68f592015-01-07 10:55:58 -0500155 }
156
157 @Override
158 protected void toString(StringBuilder builder) {
159 super.toString(builder);
Amin Shaikhe74dbdd2018-03-09 16:05:30 -0500160 builder.append(",ssid=").append(ssid)
161 .append(",isTransient=").append(isTransient)
162 .append(",statusLabel=").append(statusLabel);
Jason Monkda68f592015-01-07 10:55:58 -0500163 }
164
165 @Override
166 public boolean equals(Object o) {
Amin Shaikhe74dbdd2018-03-09 16:05:30 -0500167 if (!super.equals(o)) {
168 return false;
169 }
170 WifiState other = (WifiState) o;
171 return Objects.equals(other.ssid, ssid)
172 && other.isTransient == isTransient
173 && TextUtils.equals(other.statusLabel, statusLabel);
Jason Monkda68f592015-01-07 10:55:58 -0500174 }
175 }
176}