blob: b4c3ecafa742b4f60c48dedb43027dc8d122f659 [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;
20import android.net.NetworkCapabilities;
Jason Monkda68f592015-01-07 10:55:58 -050021import android.net.wifi.WifiManager;
22import android.os.Handler;
Geoffrey Pitsch2c403db2016-08-26 09:09:39 -040023import android.os.Looper;
Jason Monkda68f592015-01-07 10:55:58 -050024import android.os.Message;
25import android.os.Messenger;
26import android.util.Log;
Winsonc0d70582016-01-29 10:24:39 -080027
Jason Monkda68f592015-01-07 10:55:58 -050028import com.android.internal.annotations.VisibleForTesting;
29import com.android.internal.util.AsyncChannel;
Jason Monk4cf95ae2015-11-16 15:59:53 -050030import com.android.settingslib.wifi.WifiStatusTracker;
Sundeep Ghuman9d10a3c2017-06-16 00:05:16 +000031import com.android.systemui.R;
Jason Monk07b75fe2015-05-14 16:47:03 -040032import com.android.systemui.statusbar.policy.NetworkController.IconState;
Jason Monke06b0652016-03-02 16:35:27 -050033import com.android.systemui.statusbar.policy.NetworkController.SignalCallback;
Jason Monkda68f592015-01-07 10:55:58 -050034
Jason Monkda68f592015-01-07 10:55:58 -050035import java.util.Objects;
36
37
38public class WifiSignalController extends
39 SignalController<WifiSignalController.WifiState, SignalController.IconGroup> {
40 private final WifiManager mWifiManager;
41 private final AsyncChannel mWifiChannel;
42 private final boolean mHasMobileData;
Jason Monk4cf95ae2015-11-16 15:59:53 -050043 private final WifiStatusTracker mWifiTracker;
Jason Monkda68f592015-01-07 10:55:58 -050044
45 public WifiSignalController(Context context, boolean hasMobileData,
Sundeep Ghuman9d10a3c2017-06-16 00:05:16 +000046 CallbackHandler callbackHandler, NetworkControllerImpl networkController) {
Jason Monkda68f592015-01-07 10:55:58 -050047 super("WifiSignalController", context, NetworkCapabilities.TRANSPORT_WIFI,
Jason Monk07b75fe2015-05-14 16:47:03 -040048 callbackHandler, networkController);
Jason Monkda68f592015-01-07 10:55:58 -050049 mWifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
Jason Monk4cf95ae2015-11-16 15:59:53 -050050 mWifiTracker = new WifiStatusTracker(mWifiManager);
Jason Monkda68f592015-01-07 10:55:58 -050051 mHasMobileData = hasMobileData;
Geoffrey Pitsch2c403db2016-08-26 09:09:39 -040052 Handler handler = new WifiHandler(Looper.getMainLooper());
Jason Monkda68f592015-01-07 10:55:58 -050053 mWifiChannel = new AsyncChannel();
54 Messenger wifiMessenger = mWifiManager.getWifiServiceMessenger();
55 if (wifiMessenger != null) {
56 mWifiChannel.connect(context, handler, wifiMessenger);
57 }
58 // WiFi only has one state.
59 mCurrentState.iconGroup = mLastState.iconGroup = new IconGroup(
60 "Wi-Fi Icons",
61 WifiIcons.WIFI_SIGNAL_STRENGTH,
62 WifiIcons.QS_WIFI_SIGNAL_STRENGTH,
63 AccessibilityContentDescriptions.WIFI_CONNECTION_STRENGTH,
64 WifiIcons.WIFI_NO_NETWORK,
65 WifiIcons.QS_WIFI_NO_NETWORK,
Jason Monk7e6c83c2017-04-26 14:35:24 -040066 WifiIcons.WIFI_NO_NETWORK,
Jason Monkda68f592015-01-07 10:55:58 -050067 WifiIcons.QS_WIFI_NO_NETWORK,
68 AccessibilityContentDescriptions.WIFI_NO_CONNECTION
69 );
Sundeep Ghumand57f3242017-01-13 15:31:48 -080070
Jason Monkda68f592015-01-07 10:55:58 -050071 }
72
73 @Override
74 protected WifiState cleanState() {
75 return new WifiState();
76 }
77
78 @Override
Jason Monke06b0652016-03-02 16:35:27 -050079 public void notifyListeners(SignalCallback callback) {
Jason Monkda68f592015-01-07 10:55:58 -050080 // only show wifi in the cluster if connected or if wifi-only
Jason Monk7e6c83c2017-04-26 14:35:24 -040081 boolean wifiVisible = mCurrentState.enabled
82 && (mCurrentState.connected || !mHasMobileData);
Jason Monkda68f592015-01-07 10:55:58 -050083 String wifiDesc = wifiVisible ? mCurrentState.ssid : null;
84 boolean ssidPresent = wifiVisible && mCurrentState.ssid != null;
85 String contentDescription = getStringIfExists(getContentDescription());
Julia Reynolds20aef8a2016-05-04 16:44:08 -040086 if (mCurrentState.inetCondition == 0) {
Amin Shaikh43ad7fe2018-03-05 14:34:44 -050087 contentDescription += ("," + mContext.getString(R.string.data_connection_no_internet));
Julia Reynolds20aef8a2016-05-04 16:44:08 -040088 }
Jason Monkda68f592015-01-07 10:55:58 -050089
Sundeep Ghuman9d10a3c2017-06-16 00:05:16 +000090 IconState statusIcon = new IconState(wifiVisible, getCurrentIconId(), contentDescription);
91 IconState qsIcon = new IconState(mCurrentState.connected, getQsCurrentIconId(),
92 contentDescription);
Jason Monke06b0652016-03-02 16:35:27 -050093 callback.setWifiIndicators(mCurrentState.enabled, statusIcon, qsIcon,
Jason Monk07b75fe2015-05-14 16:47:03 -040094 ssidPresent && mCurrentState.activityIn, ssidPresent && mCurrentState.activityOut,
Jason Monk110e5f62017-03-31 13:45:12 -040095 wifiDesc, mCurrentState.isTransient);
Jason Monkda68f592015-01-07 10:55:58 -050096 }
97
98 /**
99 * Extract wifi state directly from broadcasts about changes in wifi state.
100 */
101 public void handleBroadcast(Intent intent) {
Jason Monk4cf95ae2015-11-16 15:59:53 -0500102 mWifiTracker.handleBroadcast(intent);
103 mCurrentState.enabled = mWifiTracker.enabled;
104 mCurrentState.connected = mWifiTracker.connected;
105 mCurrentState.ssid = mWifiTracker.ssid;
106 mCurrentState.rssi = mWifiTracker.rssi;
107 mCurrentState.level = mWifiTracker.level;
Jason Monkda68f592015-01-07 10:55:58 -0500108 notifyListenersIfNecessary();
109 }
110
Jason Monkda68f592015-01-07 10:55:58 -0500111 @VisibleForTesting
112 void setActivity(int wifiActivity) {
113 mCurrentState.activityIn = wifiActivity == WifiManager.DATA_ACTIVITY_INOUT
114 || wifiActivity == WifiManager.DATA_ACTIVITY_IN;
115 mCurrentState.activityOut = wifiActivity == WifiManager.DATA_ACTIVITY_INOUT
116 || wifiActivity == WifiManager.DATA_ACTIVITY_OUT;
117 notifyListenersIfNecessary();
118 }
119
120 /**
121 * Handler to receive the data activity on wifi.
122 */
123 private class WifiHandler extends Handler {
Geoffrey Pitsch2c403db2016-08-26 09:09:39 -0400124 WifiHandler(Looper looper) {
125 super(looper);
126 }
127
Jason Monkda68f592015-01-07 10:55:58 -0500128 @Override
129 public void handleMessage(Message msg) {
130 switch (msg.what) {
131 case AsyncChannel.CMD_CHANNEL_HALF_CONNECTED:
132 if (msg.arg1 == AsyncChannel.STATUS_SUCCESSFUL) {
133 mWifiChannel.sendMessage(Message.obtain(this,
134 AsyncChannel.CMD_CHANNEL_FULL_CONNECTION));
135 } else {
136 Log.e(mTag, "Failed to connect to wifi");
137 }
138 break;
139 case WifiManager.DATA_ACTIVITY_NOTIFICATION:
140 setActivity(msg.arg1);
141 break;
142 default:
143 // Ignore
144 break;
145 }
146 }
147 }
148
149 static class WifiState extends SignalController.State {
150 String ssid;
Jason Monk110e5f62017-03-31 13:45:12 -0400151 boolean isTransient;
Jason Monkda68f592015-01-07 10:55:58 -0500152
153 @Override
154 public void copyFrom(State s) {
155 super.copyFrom(s);
156 WifiState state = (WifiState) s;
157 ssid = state.ssid;
Jason Monk110e5f62017-03-31 13:45:12 -0400158 isTransient = state.isTransient;
Jason Monkda68f592015-01-07 10:55:58 -0500159 }
160
161 @Override
162 protected void toString(StringBuilder builder) {
163 super.toString(builder);
164 builder.append(',').append("ssid=").append(ssid);
Jason Monk110e5f62017-03-31 13:45:12 -0400165 builder.append(',').append("isTransient=").append(isTransient);
Jason Monkda68f592015-01-07 10:55:58 -0500166 }
167
168 @Override
169 public boolean equals(Object o) {
170 return super.equals(o)
Sundeep Ghumand57f3242017-01-13 15:31:48 -0800171 && Objects.equals(((WifiState) o).ssid, ssid)
Jason Monk110e5f62017-03-31 13:45:12 -0400172 && (((WifiState) o).isTransient == isTransient);
Jason Monkda68f592015-01-07 10:55:58 -0500173 }
174 }
175}