blob: cf80988ba61dbb258b6006aa332f409bcf625634 [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
18import android.content.Context;
19import android.content.Intent;
Amin Shaikhe74dbdd2018-03-09 16:05:30 -050020import android.net.ConnectivityManager;
Jason Monkda68f592015-01-07 10:55:58 -050021import android.net.NetworkCapabilities;
Amin Shaikhe74dbdd2018-03-09 16:05:30 -050022import android.net.NetworkScoreManager;
Jason Monkda68f592015-01-07 10:55:58 -050023import android.net.wifi.WifiManager;
24import android.os.Handler;
Geoffrey Pitsch2c403db2016-08-26 09:09:39 -040025import android.os.Looper;
Jason Monkda68f592015-01-07 10:55:58 -050026import android.os.Message;
27import android.os.Messenger;
Amin Shaikhe74dbdd2018-03-09 16:05:30 -050028import android.text.TextUtils;
Jason Monkda68f592015-01-07 10:55:58 -050029import android.util.Log;
Winsonc0d70582016-01-29 10:24:39 -080030
Jason Monkda68f592015-01-07 10:55:58 -050031import com.android.internal.annotations.VisibleForTesting;
32import com.android.internal.util.AsyncChannel;
Jason Monk4cf95ae2015-11-16 15:59:53 -050033import com.android.settingslib.wifi.WifiStatusTracker;
Sundeep Ghuman9d10a3c2017-06-16 00:05:16 +000034import com.android.systemui.R;
Jason Monk07b75fe2015-05-14 16:47:03 -040035import com.android.systemui.statusbar.policy.NetworkController.IconState;
Jason Monke06b0652016-03-02 16:35:27 -050036import com.android.systemui.statusbar.policy.NetworkController.SignalCallback;
Jason Monkda68f592015-01-07 10:55:58 -050037
Jason Monkda68f592015-01-07 10:55:58 -050038import java.util.Objects;
39
40
41public class WifiSignalController extends
42 SignalController<WifiSignalController.WifiState, SignalController.IconGroup> {
Jason Monkda68f592015-01-07 10:55:58 -050043 private final AsyncChannel mWifiChannel;
44 private final boolean mHasMobileData;
Jason Monk4cf95ae2015-11-16 15:59:53 -050045 private final WifiStatusTracker mWifiTracker;
Jason Monkda68f592015-01-07 10:55:58 -050046
47 public WifiSignalController(Context context, boolean hasMobileData,
Amin Shaikhc7593b12018-03-09 16:07:09 -050048 CallbackHandler callbackHandler, NetworkControllerImpl networkController,
49 WifiManager wifiManager) {
Jason Monkda68f592015-01-07 10:55:58 -050050 super("WifiSignalController", context, NetworkCapabilities.TRANSPORT_WIFI,
Jason Monk07b75fe2015-05-14 16:47:03 -040051 callbackHandler, networkController);
Amin Shaikhe74dbdd2018-03-09 16:05:30 -050052 NetworkScoreManager networkScoreManager =
53 context.getSystemService(NetworkScoreManager.class);
54 ConnectivityManager connectivityManager =
55 context.getSystemService(ConnectivityManager.class);
56 mWifiTracker = new WifiStatusTracker(mContext, wifiManager, networkScoreManager,
57 connectivityManager, this::handleStatusUpdated);
58 mWifiTracker.setListening(true);
Jason Monkda68f592015-01-07 10:55:58 -050059 mHasMobileData = hasMobileData;
Geoffrey Pitsch2c403db2016-08-26 09:09:39 -040060 Handler handler = new WifiHandler(Looper.getMainLooper());
Jason Monkda68f592015-01-07 10:55:58 -050061 mWifiChannel = new AsyncChannel();
Amin Shaikhe74dbdd2018-03-09 16:05:30 -050062 Messenger wifiMessenger = wifiManager.getWifiServiceMessenger();
Jason Monkda68f592015-01-07 10:55:58 -050063 if (wifiMessenger != null) {
64 mWifiChannel.connect(context, handler, wifiMessenger);
65 }
66 // WiFi only has one state.
67 mCurrentState.iconGroup = mLastState.iconGroup = new IconGroup(
68 "Wi-Fi Icons",
69 WifiIcons.WIFI_SIGNAL_STRENGTH,
70 WifiIcons.QS_WIFI_SIGNAL_STRENGTH,
71 AccessibilityContentDescriptions.WIFI_CONNECTION_STRENGTH,
72 WifiIcons.WIFI_NO_NETWORK,
73 WifiIcons.QS_WIFI_NO_NETWORK,
Jason Monk7e6c83c2017-04-26 14:35:24 -040074 WifiIcons.WIFI_NO_NETWORK,
Jason Monkda68f592015-01-07 10:55:58 -050075 WifiIcons.QS_WIFI_NO_NETWORK,
76 AccessibilityContentDescriptions.WIFI_NO_CONNECTION
77 );
78 }
79
80 @Override
81 protected WifiState cleanState() {
82 return new WifiState();
83 }
84
85 @Override
Jason Monke06b0652016-03-02 16:35:27 -050086 public void notifyListeners(SignalCallback callback) {
Jason Monkda68f592015-01-07 10:55:58 -050087 // only show wifi in the cluster if connected or if wifi-only
Minming Qie2d48ca2017-03-10 13:56:44 +080088 boolean visibleWhenEnabled = mContext.getResources().getBoolean(
89 R.bool.config_showWifiIndicatorWhenEnabled);
Jason Monk7e6c83c2017-04-26 14:35:24 -040090 boolean wifiVisible = mCurrentState.enabled
Minming Qie2d48ca2017-03-10 13:56:44 +080091 && (mCurrentState.connected || !mHasMobileData || visibleWhenEnabled);
Jason Monkda68f592015-01-07 10:55:58 -050092 String wifiDesc = wifiVisible ? mCurrentState.ssid : null;
93 boolean ssidPresent = wifiVisible && mCurrentState.ssid != null;
94 String contentDescription = getStringIfExists(getContentDescription());
Julia Reynolds20aef8a2016-05-04 16:44:08 -040095 if (mCurrentState.inetCondition == 0) {
Amin Shaikh43ad7fe2018-03-05 14:34:44 -050096 contentDescription += ("," + mContext.getString(R.string.data_connection_no_internet));
Julia Reynolds20aef8a2016-05-04 16:44:08 -040097 }
Sundeep Ghuman9d10a3c2017-06-16 00:05:16 +000098 IconState statusIcon = new IconState(wifiVisible, getCurrentIconId(), contentDescription);
99 IconState qsIcon = new IconState(mCurrentState.connected, getQsCurrentIconId(),
100 contentDescription);
Jason Monke06b0652016-03-02 16:35:27 -0500101 callback.setWifiIndicators(mCurrentState.enabled, statusIcon, qsIcon,
Jason Monk07b75fe2015-05-14 16:47:03 -0400102 ssidPresent && mCurrentState.activityIn, ssidPresent && mCurrentState.activityOut,
Amin Shaikhe74dbdd2018-03-09 16:05:30 -0500103 wifiDesc, mCurrentState.isTransient, mCurrentState.statusLabel);
Jason Monkda68f592015-01-07 10:55:58 -0500104 }
105
106 /**
107 * Extract wifi state directly from broadcasts about changes in wifi state.
108 */
109 public void handleBroadcast(Intent intent) {
Jason Monk4cf95ae2015-11-16 15:59:53 -0500110 mWifiTracker.handleBroadcast(intent);
111 mCurrentState.enabled = mWifiTracker.enabled;
112 mCurrentState.connected = mWifiTracker.connected;
113 mCurrentState.ssid = mWifiTracker.ssid;
114 mCurrentState.rssi = mWifiTracker.rssi;
115 mCurrentState.level = mWifiTracker.level;
Amin Shaikhe74dbdd2018-03-09 16:05:30 -0500116 mCurrentState.statusLabel = mWifiTracker.statusLabel;
117 notifyListenersIfNecessary();
118 }
119
120 private void handleStatusUpdated() {
121 mCurrentState.statusLabel = mWifiTracker.statusLabel;
Jason Monkda68f592015-01-07 10:55:58 -0500122 notifyListenersIfNecessary();
123 }
124
Jason Monkda68f592015-01-07 10:55:58 -0500125 @VisibleForTesting
126 void setActivity(int wifiActivity) {
127 mCurrentState.activityIn = wifiActivity == WifiManager.DATA_ACTIVITY_INOUT
128 || wifiActivity == WifiManager.DATA_ACTIVITY_IN;
129 mCurrentState.activityOut = wifiActivity == WifiManager.DATA_ACTIVITY_INOUT
130 || wifiActivity == WifiManager.DATA_ACTIVITY_OUT;
131 notifyListenersIfNecessary();
132 }
133
134 /**
135 * Handler to receive the data activity on wifi.
136 */
137 private class WifiHandler extends Handler {
Geoffrey Pitsch2c403db2016-08-26 09:09:39 -0400138 WifiHandler(Looper looper) {
139 super(looper);
140 }
141
Jason Monkda68f592015-01-07 10:55:58 -0500142 @Override
143 public void handleMessage(Message msg) {
144 switch (msg.what) {
145 case AsyncChannel.CMD_CHANNEL_HALF_CONNECTED:
146 if (msg.arg1 == AsyncChannel.STATUS_SUCCESSFUL) {
147 mWifiChannel.sendMessage(Message.obtain(this,
148 AsyncChannel.CMD_CHANNEL_FULL_CONNECTION));
149 } else {
150 Log.e(mTag, "Failed to connect to wifi");
151 }
152 break;
153 case WifiManager.DATA_ACTIVITY_NOTIFICATION:
154 setActivity(msg.arg1);
155 break;
156 default:
157 // Ignore
158 break;
159 }
160 }
161 }
162
163 static class WifiState extends SignalController.State {
164 String ssid;
Jason Monk110e5f62017-03-31 13:45:12 -0400165 boolean isTransient;
Amin Shaikhe74dbdd2018-03-09 16:05:30 -0500166 String statusLabel;
Jason Monkda68f592015-01-07 10:55:58 -0500167
168 @Override
169 public void copyFrom(State s) {
170 super.copyFrom(s);
171 WifiState state = (WifiState) s;
172 ssid = state.ssid;
Jason Monk110e5f62017-03-31 13:45:12 -0400173 isTransient = state.isTransient;
Amin Shaikhe74dbdd2018-03-09 16:05:30 -0500174 statusLabel = state.statusLabel;
Jason Monkda68f592015-01-07 10:55:58 -0500175 }
176
177 @Override
178 protected void toString(StringBuilder builder) {
179 super.toString(builder);
Amin Shaikhe74dbdd2018-03-09 16:05:30 -0500180 builder.append(",ssid=").append(ssid)
181 .append(",isTransient=").append(isTransient)
182 .append(",statusLabel=").append(statusLabel);
Jason Monkda68f592015-01-07 10:55:58 -0500183 }
184
185 @Override
186 public boolean equals(Object o) {
Amin Shaikhe74dbdd2018-03-09 16:05:30 -0500187 if (!super.equals(o)) {
188 return false;
189 }
190 WifiState other = (WifiState) o;
191 return Objects.equals(other.ssid, ssid)
192 && other.isTransient == isTransient
193 && TextUtils.equals(other.statusLabel, statusLabel);
Jason Monkda68f592015-01-07 10:55:58 -0500194 }
195 }
196}