diff --git a/packages/SettingsLib/res/drawable/ic_carrier_wifi.xml b/packages/SettingsLib/res/drawable/ic_carrier_wifi.xml
new file mode 100644
index 0000000000000..ed9d85e3cbe4e
--- /dev/null
+++ b/packages/SettingsLib/res/drawable/ic_carrier_wifi.xml
@@ -0,0 +1,30 @@
+
+
+
+
+
+
diff --git a/packages/SettingsLib/res/values/strings.xml b/packages/SettingsLib/res/values/strings.xml
index 0ce8dd85d2cef..792fb52802ff9 100644
--- a/packages/SettingsLib/res/values/strings.xml
+++ b/packages/SettingsLib/res/values/strings.xml
@@ -1447,6 +1447,9 @@
5G+
+
+ CWF
+
Mobile data off
diff --git a/packages/SettingsLib/src/com/android/settingslib/mobile/TelephonyIcons.java b/packages/SettingsLib/src/com/android/settingslib/mobile/TelephonyIcons.java
index c2613a5f4a4a1..0cb9906b9a829 100644
--- a/packages/SettingsLib/src/com/android/settingslib/mobile/TelephonyIcons.java
+++ b/packages/SettingsLib/src/com/android/settingslib/mobile/TelephonyIcons.java
@@ -43,6 +43,7 @@ public class TelephonyIcons {
public static final int ICON_1X = R.drawable.ic_1x_mobiledata;
public static final int ICON_5G = R.drawable.ic_5g_mobiledata;
public static final int ICON_5G_PLUS = R.drawable.ic_5g_plus_mobiledata;
+ public static final int ICON_CWF = R.drawable.ic_carrier_wifi;
public static final MobileIconGroup CARRIER_NETWORK_CHANGE = new MobileIconGroup(
"CARRIER_NETWORK_CHANGE",
@@ -276,6 +277,20 @@ public class TelephonyIcons {
0,
false);
+ public static final MobileIconGroup CARRIER_MERGED_WIFI = new MobileIconGroup(
+ "CWF",
+ /* sbIcons= */ null,
+ /* qsIcons= */ null,
+ AccessibilityContentDescriptions.PHONE_SIGNAL_STRENGTH,
+ /* sbNullState= */ 0,
+ /* qsNullState= */ 0,
+ /* sbDiscState= */ 0,
+ /* qsDiscState= */ 0,
+ AccessibilityContentDescriptions.PHONE_SIGNAL_STRENGTH[0],
+ R.string.data_connection_carrier_wifi,
+ TelephonyIcons.ICON_CWF,
+ /* isWide= */ true);
+
// When adding a new MobileIconGround, check if the dataContentDescription has to be filtered
// in QSCarrier#hasValidTypeContentDescription
diff --git a/packages/SettingsLib/src/com/android/settingslib/wifi/WifiStatusTracker.java b/packages/SettingsLib/src/com/android/settingslib/wifi/WifiStatusTracker.java
index cbb510505fddd..4614694a2bd84 100644
--- a/packages/SettingsLib/src/com/android/settingslib/wifi/WifiStatusTracker.java
+++ b/packages/SettingsLib/src/com/android/settingslib/wifi/WifiStatusTracker.java
@@ -33,6 +33,7 @@ import android.net.wifi.WifiNetworkScoreCache;
import android.os.Handler;
import android.os.Looper;
import android.provider.Settings;
+import android.util.FeatureFlagUtils;
import com.android.settingslib.R;
@@ -103,11 +104,14 @@ public class WifiStatusTracker {
private Network mDefaultNetwork = null;
private NetworkCapabilities mDefaultNetworkCapabilities = null;
private final Runnable mCallback;
+ private final boolean mProviderModel;
private WifiInfo mWifiInfo;
public boolean enabled;
public boolean isCaptivePortal;
public boolean isDefaultNetwork;
+ public boolean isCarrierMerged;
+ public int subId;
public int state;
public boolean connected;
public String ssid;
@@ -124,6 +128,8 @@ public class WifiStatusTracker {
mNetworkScoreManager = networkScoreManager;
mConnectivityManager = connectivityManager;
mCallback = callback;
+ mProviderModel = FeatureFlagUtils.isEnabled(
+ mContext, FeatureFlagUtils.SETTINGS_PROVIDER_MODEL);
}
public void setListening(boolean listening) {
@@ -193,6 +199,10 @@ public class WifiStatusTracker {
} else {
ssid = getValidSsid(mWifiInfo);
}
+ if (mProviderModel) {
+ isCarrierMerged = mWifiInfo.isCarrierMerged();
+ subId = mWifiInfo.getSubscriptionId();
+ }
updateRssi(mWifiInfo.getRssi());
maybeRequestNetworkScore();
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
index 291aefef7d9db..e41996604c999 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
@@ -359,7 +359,7 @@ public class NetworkControllerImpl extends BroadcastReceiver
// broadcasts
IntentFilter filter = new IntentFilter();
- filter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);
+ filter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION);
filter.addAction(Intent.ACTION_SIM_STATE_CHANGED);
filter.addAction(TelephonyManager.ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED);
filter.addAction(TelephonyManager.ACTION_DEFAULT_VOICE_SUBSCRIPTION_CHANGED);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/WifiIcons.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/WifiIcons.java
index 9db109de369bf..66e8082f22261 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/WifiIcons.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/WifiIcons.java
@@ -16,6 +16,8 @@
package com.android.systemui.statusbar.policy;
+import com.android.settingslib.AccessibilityContentDescriptions;
+import com.android.settingslib.SignalIcon.IconGroup;
import com.android.systemui.R;
public class WifiIcons {
@@ -40,6 +42,7 @@ public class WifiIcons {
WIFI_NO_INTERNET_ICONS,
WIFI_FULL_ICONS
};
+
static final int[][] WIFI_SIGNAL_STRENGTH = QS_WIFI_SIGNAL_STRENGTH;
public static final int QS_WIFI_DISABLED = com.android.internal.R.drawable.ic_wifi_signal_0;
@@ -47,4 +50,16 @@ public class WifiIcons {
static final int WIFI_NO_NETWORK = QS_WIFI_NO_NETWORK;
static final int WIFI_LEVEL_COUNT = WIFI_SIGNAL_STRENGTH[0].length;
+
+ public static final IconGroup UNMERGED_WIFI = new IconGroup(
+ "Wi-Fi Icons",
+ WifiIcons.WIFI_SIGNAL_STRENGTH,
+ WifiIcons.QS_WIFI_SIGNAL_STRENGTH,
+ AccessibilityContentDescriptions.WIFI_CONNECTION_STRENGTH,
+ WifiIcons.WIFI_NO_NETWORK,
+ WifiIcons.QS_WIFI_NO_NETWORK,
+ WifiIcons.WIFI_NO_NETWORK,
+ WifiIcons.QS_WIFI_NO_NETWORK,
+ AccessibilityContentDescriptions.WIFI_NO_CONNECTION
+ );
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/WifiSignalController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/WifiSignalController.java
index 6d109ac8d4a2a..4954286af3fe0 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/WifiSignalController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/WifiSignalController.java
@@ -25,12 +25,15 @@ import android.net.ConnectivityManager;
import android.net.NetworkCapabilities;
import android.net.NetworkScoreManager;
import android.net.wifi.WifiManager;
+import android.text.Html;
import android.text.TextUtils;
import com.android.internal.annotations.VisibleForTesting;
-import com.android.settingslib.AccessibilityContentDescriptions;
import com.android.settingslib.SignalIcon.IconGroup;
+import com.android.settingslib.SignalIcon.MobileIconGroup;
import com.android.settingslib.SignalIcon.State;
+import com.android.settingslib.graph.SignalDrawable;
+import com.android.settingslib.mobile.TelephonyIcons;
import com.android.settingslib.wifi.WifiStatusTracker;
import com.android.systemui.R;
import com.android.systemui.statusbar.policy.NetworkController.IconState;
@@ -42,6 +45,9 @@ public class WifiSignalController extends
SignalController {
private final boolean mHasMobileDataFeature;
private final WifiStatusTracker mWifiTracker;
+ private final IconGroup mUnmergedWifiIconGroup = WifiIcons.UNMERGED_WIFI;
+ private final MobileIconGroup mCarrierMergedWifiIconGroup = TelephonyIcons.CARRIER_MERGED_WIFI;
+ private final WifiManager mWifiManager;
public WifiSignalController(Context context, boolean hasMobileDataFeature,
CallbackHandler callbackHandler, NetworkControllerImpl networkController,
@@ -49,6 +55,7 @@ public class WifiSignalController extends
NetworkScoreManager networkScoreManager) {
super("WifiSignalController", context, NetworkCapabilities.TRANSPORT_WIFI,
callbackHandler, networkController);
+ mWifiManager = wifiManager;
mWifiTracker = new WifiStatusTracker(mContext, wifiManager, networkScoreManager,
connectivityManager, this::handleStatusUpdated);
mWifiTracker.setListening(true);
@@ -57,18 +64,7 @@ public class WifiSignalController extends
wifiManager.registerTrafficStateCallback(context.getMainExecutor(),
new WifiTrafficStateCallback());
}
- // WiFi only has one state.
- mCurrentState.iconGroup = mLastState.iconGroup = new IconGroup(
- "Wi-Fi Icons",
- WifiIcons.WIFI_SIGNAL_STRENGTH,
- WifiIcons.QS_WIFI_SIGNAL_STRENGTH,
- AccessibilityContentDescriptions.WIFI_CONNECTION_STRENGTH,
- WifiIcons.WIFI_NO_NETWORK,
- WifiIcons.QS_WIFI_NO_NETWORK,
- WifiIcons.WIFI_NO_NETWORK,
- WifiIcons.QS_WIFI_NO_NETWORK,
- AccessibilityContentDescriptions.WIFI_NO_CONNECTION
- );
+ mCurrentState.iconGroup = mLastState.iconGroup = mUnmergedWifiIconGroup;
}
@Override
@@ -82,6 +78,14 @@ public class WifiSignalController extends
@Override
public void notifyListeners(SignalCallback callback) {
+ if (mCurrentState.isCarrierMerged) {
+ notifyListenersForCarrierWifi(callback);
+ } else {
+ notifyListenersForNonCarrierWifi(callback);
+ }
+ }
+
+ private void notifyListenersForNonCarrierWifi(SignalCallback callback) {
// only show wifi in the cluster if connected or if wifi-only
boolean visibleWhenEnabled = mContext.getResources().getBoolean(
R.bool.config_showWifiIndicatorWhenEnabled);
@@ -104,14 +108,49 @@ public class WifiSignalController extends
wifiDesc, mCurrentState.isTransient, mCurrentState.statusLabel);
}
- private void copyWifiStates() {
- mCurrentState.enabled = mWifiTracker.enabled;
- mCurrentState.isDefault = mWifiTracker.isDefaultNetwork;
- mCurrentState.connected = mWifiTracker.connected;
- mCurrentState.ssid = mWifiTracker.ssid;
- mCurrentState.rssi = mWifiTracker.rssi;
- mCurrentState.level = mWifiTracker.level;
- mCurrentState.statusLabel = mWifiTracker.statusLabel;
+ private void notifyListenersForCarrierWifi(SignalCallback callback) {
+ MobileIconGroup icons = mCarrierMergedWifiIconGroup;
+ String contentDescription = getTextIfExists(getContentDescription()).toString();
+ CharSequence dataContentDescriptionHtml = getTextIfExists(icons.dataContentDescription);
+
+ CharSequence dataContentDescription = Html.fromHtml(
+ dataContentDescriptionHtml.toString(), 0).toString();
+ if (mCurrentState.inetCondition == 0) {
+ dataContentDescription = mContext.getString(R.string.data_connection_no_internet);
+ }
+ boolean qsVisible = mCurrentState.enabled
+ && (mCurrentState.connected && mCurrentState.inetCondition == 1);
+
+ IconState statusIcon =
+ new IconState(qsVisible, getCurrentIconIdForCarrierWifi(), contentDescription);
+ int qsTypeIcon = mCurrentState.connected ? icons.qsDataType : 0;
+ int typeIcon = mCurrentState.connected ? icons.dataType : 0;
+ IconState qsIcon = new IconState(
+ mCurrentState.connected, getQsCurrentIconIdForCarrierWifi(), contentDescription);
+ CharSequence description = mNetworkController.getMobileDataNetworkName();
+ callback.setMobileDataIndicators(statusIcon, qsIcon, typeIcon, qsTypeIcon,
+ mCurrentState.activityIn, mCurrentState.activityOut, dataContentDescription,
+ dataContentDescriptionHtml, description, icons.isWide,
+ mCurrentState.subId, /* roaming= */ false);
+ }
+
+ private int getCurrentIconIdForCarrierWifi() {
+ int level = mCurrentState.level;
+ // The WiFi signal level returned by WifiManager#calculateSignalLevel start from 0, so
+ // WifiManager#getMaxSignalLevel + 1 represents the total level buckets count.
+ int totalLevel = mWifiManager.getMaxSignalLevel() + 1;
+ boolean noInternet = mCurrentState.inetCondition == 0;
+ if (mCurrentState.connected) {
+ return SignalDrawable.getState(level, totalLevel, noInternet);
+ } else if (mCurrentState.enabled) {
+ return SignalDrawable.getEmptyState(totalLevel);
+ } else {
+ return 0;
+ }
+ }
+
+ private int getQsCurrentIconIdForCarrierWifi() {
+ return getCurrentIconIdForCarrierWifi();
}
/**
@@ -137,6 +176,21 @@ public class WifiSignalController extends
notifyListenersIfNecessary();
}
+ private void copyWifiStates() {
+ mCurrentState.enabled = mWifiTracker.enabled;
+ mCurrentState.isDefault = mWifiTracker.isDefaultNetwork;
+ mCurrentState.connected = mWifiTracker.connected;
+ mCurrentState.ssid = mWifiTracker.ssid;
+ mCurrentState.rssi = mWifiTracker.rssi;
+ mCurrentState.level = mWifiTracker.level;
+ mCurrentState.statusLabel = mWifiTracker.statusLabel;
+ mCurrentState.isCarrierMerged = mWifiTracker.isCarrierMerged;
+ mCurrentState.subId = mWifiTracker.subId;
+ mCurrentState.iconGroup =
+ mCurrentState.isCarrierMerged ? mCarrierMergedWifiIconGroup
+ : mUnmergedWifiIconGroup;
+ }
+
@VisibleForTesting
void setActivity(int wifiActivity) {
mCurrentState.activityIn = wifiActivity == DATA_ACTIVITY_INOUT
@@ -157,10 +211,12 @@ public class WifiSignalController extends
}
static class WifiState extends State {
- String ssid;
- boolean isTransient;
- boolean isDefault;
- String statusLabel;
+ public String ssid;
+ public boolean isTransient;
+ public boolean isDefault;
+ public String statusLabel;
+ public boolean isCarrierMerged;
+ public int subId;
@Override
public void copyFrom(State s) {
@@ -170,6 +226,8 @@ public class WifiSignalController extends
isTransient = state.isTransient;
isDefault = state.isDefault;
statusLabel = state.statusLabel;
+ isCarrierMerged = state.isCarrierMerged;
+ subId = state.subId;
}
@Override
@@ -178,7 +236,9 @@ public class WifiSignalController extends
builder.append(",ssid=").append(ssid)
.append(",isTransient=").append(isTransient)
.append(",isDefault=").append(isDefault)
- .append(",statusLabel=").append(statusLabel);
+ .append(",statusLabel=").append(statusLabel)
+ .append(",isCarrierMerged=").append(isCarrierMerged)
+ .append(",subId=").append(subId);
}
@Override
@@ -190,7 +250,9 @@ public class WifiSignalController extends
return Objects.equals(other.ssid, ssid)
&& other.isTransient == isTransient
&& other.isDefault == isDefault
- && TextUtils.equals(other.statusLabel, statusLabel);
+ && TextUtils.equals(other.statusLabel, statusLabel)
+ && other.isCarrierMerged == isCarrierMerged
+ && other.subId == subId;
}
}
}