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; } } }