From a62d32b6565f71da426b1242511eb718dccc909e Mon Sep 17 00:00:00 2001 From: Pengquan Meng Date: Thu, 6 Dec 2018 17:38:38 -0800 Subject: Add 5G icon to System UI This add the 5G and 5G+ icon to the system UI for 5G Non-Standalone network. System UI uses the ServiceState & CarrierConfig to determine whether and which 5G icon should be displayed in 5G Non-Standalone network. Bug: 111497313, 111453000 Test: build & manually test Change-Id: I6fba0f9c42fff3cb1398895b122f18f13de239f7 --- .../SystemUI/res/drawable/ic_5g_mobiledata.xml | 27 ++++++++++ .../res/drawable/ic_5g_plus_mobiledata.xml | 33 ++++++++++++ packages/SystemUI/res/values/strings.xml | 6 +++ .../statusbar/policy/MobileSignalController.java | 39 +++++++++++++- .../statusbar/policy/NetworkControllerImpl.java | 62 ++++++++++++++++++++++ .../systemui/statusbar/policy/TelephonyIcons.java | 55 +++++++++++++++++++ .../policy/NetworkControllerBaseTest.java | 5 ++ .../policy/NetworkControllerDataTest.java | 46 +++++++++++++++- 8 files changed, 271 insertions(+), 2 deletions(-) create mode 100644 packages/SystemUI/res/drawable/ic_5g_mobiledata.xml create mode 100644 packages/SystemUI/res/drawable/ic_5g_plus_mobiledata.xml diff --git a/packages/SystemUI/res/drawable/ic_5g_mobiledata.xml b/packages/SystemUI/res/drawable/ic_5g_mobiledata.xml new file mode 100644 index 000000000000..2aa6e57f6f82 --- /dev/null +++ b/packages/SystemUI/res/drawable/ic_5g_mobiledata.xml @@ -0,0 +1,27 @@ + + + + + diff --git a/packages/SystemUI/res/drawable/ic_5g_plus_mobiledata.xml b/packages/SystemUI/res/drawable/ic_5g_plus_mobiledata.xml new file mode 100644 index 000000000000..10bbcc7b3737 --- /dev/null +++ b/packages/SystemUI/res/drawable/ic_5g_plus_mobiledata.xml @@ -0,0 +1,33 @@ + + + + + + + + + + + + diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml index 9917257bba8a..63736759773f 100644 --- a/packages/SystemUI/res/values/strings.xml +++ b/packages/SystemUI/res/values/strings.xml @@ -406,6 +406,12 @@ LTE+ + + 5G + + + 5G+ + 1X diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java index e943261bda7b..3deede091a05 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java @@ -22,6 +22,7 @@ import android.net.NetworkCapabilities; import android.os.Handler; import android.os.Looper; import android.provider.Settings.Global; +import android.telephony.NetworkRegistrationState; import android.telephony.PhoneStateListener; import android.telephony.ServiceState; import android.telephony.SignalStrength; @@ -437,7 +438,13 @@ public class MobileSignalController extends SignalController< mCurrentState.level = mSignalStrength.getLevel(); } } - if (mNetworkToIconLookup.indexOfKey(mDataNetType) >= 0) { + + // When the device is camped on a 5G Non-Standalone network, the data network type is still + // LTE. In this case, we first check which 5G icon should be shown. + MobileIconGroup nr5GIconGroup = getNr5GIconGroup(); + if (nr5GIconGroup != null) { + mCurrentState.iconGroup = nr5GIconGroup; + } else if (mNetworkToIconLookup.indexOfKey(mDataNetType) >= 0) { mCurrentState.iconGroup = mNetworkToIconLookup.get(mDataNetType); } else { mCurrentState.iconGroup = mDefaultIcons; @@ -464,6 +471,36 @@ public class MobileSignalController extends SignalController< notifyListenersIfNecessary(); } + private MobileIconGroup getNr5GIconGroup() { + if (mServiceState == null) return null; + + int nrStatus = mServiceState.getNrStatus(); + if (nrStatus == NetworkRegistrationState.NR_STATUS_CONNECTED) { + // Check if the NR 5G is using millimeter wave and the icon is config. + if (mServiceState.getNrFrequencyRange() == ServiceState.FREQUENCY_RANGE_MMWAVE) { + if (mConfig.nr5GIconMap.containsKey(Config.NR_CONNECTED_MMWAVE)) { + return mConfig.nr5GIconMap.get(Config.NR_CONNECTED_MMWAVE); + } + } + + // If NR 5G is not using millimeter wave or there is no icon for millimeter wave, we + // check the normal 5G icon. + if (mConfig.nr5GIconMap.containsKey(Config.NR_CONNECTED)) { + return mConfig.nr5GIconMap.get(Config.NR_CONNECTED); + } + } else if (nrStatus == NetworkRegistrationState.NR_STATUS_NOT_RESTRICTED) { + if (mConfig.nr5GIconMap.containsKey(Config.NR_NOT_RESTRICTED)) { + return mConfig.nr5GIconMap.get(Config.NR_NOT_RESTRICTED); + } + } else if (nrStatus == NetworkRegistrationState.NR_STATUS_RESTRICTED) { + if (mConfig.nr5GIconMap.containsKey(Config.NR_RESTRICTED)) { + return mConfig.nr5GIconMap.get(Config.NR_RESTRICTED); + } + } + + return null; + } + private boolean isDataDisabled() { return !mPhone.getDataEnabled(mSubscriptionInfo.getSubscriptionId()); } 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 70a35892da98..bc43120fcefa 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java @@ -60,15 +60,19 @@ import com.android.systemui.Dumpable; import com.android.systemui.R; import com.android.systemui.settings.CurrentUserTracker; import com.android.systemui.statusbar.policy.DeviceProvisionedController.DeviceProvisionedListener; +import com.android.systemui.statusbar.policy.MobileSignalController.MobileIconGroup; import java.io.FileDescriptor; import java.io.PrintWriter; import java.util.ArrayList; +import java.util.Arrays; import java.util.BitSet; import java.util.Collections; import java.util.Comparator; +import java.util.HashMap; import java.util.List; import java.util.Locale; +import java.util.Map; /** Platform implementation of the network controller. **/ public class NetworkControllerImpl extends BroadcastReceiver @@ -1029,6 +1033,13 @@ public class NetworkControllerImpl extends BroadcastReceiver @VisibleForTesting static class Config { + static final int NR_CONNECTED_MMWAVE = 1; + static final int NR_CONNECTED = 2; + static final int NR_NOT_RESTRICTED = 3; + static final int NR_RESTRICTED = 4; + + Map nr5GIconMap = new HashMap<>(); + boolean showAtLeast3G = false; boolean alwaysShowCdmaRssi = false; boolean show4gForLte = false; @@ -1037,6 +1048,19 @@ public class NetworkControllerImpl extends BroadcastReceiver boolean inflateSignalStrengths = false; boolean alwaysShowDataRatIcon = false; + /** + * Mapping from NR 5G status string to an integer. The NR 5G status string should match + * those in carrier config. + */ + private static final Map NR_STATUS_STRING_TO_INDEX; + static { + NR_STATUS_STRING_TO_INDEX = new HashMap<>(4); + NR_STATUS_STRING_TO_INDEX.put("connected_mmwave", NR_CONNECTED_MMWAVE); + NR_STATUS_STRING_TO_INDEX.put("connected", NR_CONNECTED); + NR_STATUS_STRING_TO_INDEX.put("not_restricted", NR_NOT_RESTRICTED); + NR_STATUS_STRING_TO_INDEX.put("restricted", NR_RESTRICTED); + } + static Config readConfig(Context context) { Config config = new Config(); Resources res = context.getResources(); @@ -1061,8 +1085,46 @@ public class NetworkControllerImpl extends BroadcastReceiver CarrierConfigManager.KEY_SHOW_4G_FOR_LTE_DATA_ICON_BOOL); config.hideLtePlus = b.getBoolean( CarrierConfigManager.KEY_HIDE_LTE_PLUS_DATA_ICON_BOOL); + String nr5GIconConfiguration = + b.getString(CarrierConfigManager.KEY_5G_ICON_CONFIGURATION_STRING); + if (!TextUtils.isEmpty(nr5GIconConfiguration)) { + String[] nr5GIconConfigPairs = nr5GIconConfiguration.trim().split(","); + for (String pair : nr5GIconConfigPairs) { + add5GIconMapping(pair, config); + } + } } + return config; } + + /** + * Add a mapping from NR 5G status to the 5G icon. All the icon resources come from + * {@link TelephonyIcons}. + * + * @param keyValuePair the NR 5G status and icon name separated by a colon. + * @param config container that used to store the parsed configs. + */ + @VisibleForTesting + static void add5GIconMapping(String keyValuePair, Config config) { + String[] kv = (keyValuePair.trim().toLowerCase()).split(":"); + + if (kv.length != 2) { + if (DEBUG) Log.e(TAG, "Invalid 5G icon configuration, config = " + keyValuePair); + return; + } + + String key = kv[0], value = kv[1]; + + // There is no icon config for the specific 5G status. + if (value.equals("none")) return; + + if (NR_STATUS_STRING_TO_INDEX.containsKey(key) + && TelephonyIcons.ICON_NAME_TO_ICON.containsKey(value)) { + config.nr5GIconMap.put( + NR_STATUS_STRING_TO_INDEX.get(key), + TelephonyIcons.ICON_NAME_TO_ICON.get(value)); + } + } } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/TelephonyIcons.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/TelephonyIcons.java index bd768202aa7a..7347f66de8ce 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/TelephonyIcons.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/TelephonyIcons.java @@ -19,6 +19,9 @@ package com.android.systemui.statusbar.policy; import com.android.systemui.R; import com.android.systemui.statusbar.policy.MobileSignalController.MobileIconGroup; +import java.util.HashMap; +import java.util.Map; + class TelephonyIcons { //***** Data connection icons static final int FLIGHT_MODE_ICON = R.drawable.stat_sys_airplane_mode; @@ -33,6 +36,8 @@ class TelephonyIcons { static final int ICON_4G = R.drawable.ic_4g_mobiledata; static final int ICON_4G_PLUS = R.drawable.ic_4g_plus_mobiledata; static final int ICON_1X = R.drawable.ic_1x_mobiledata; + static final int ICON_5G = R.drawable.ic_5g_mobiledata; + static final int ICON_5G_PLUS = R.drawable.ic_5g_plus_mobiledata; static final MobileIconGroup CARRIER_NETWORK_CHANGE = new MobileIconGroup( "CARRIER_NETWORK_CHANGE", @@ -199,6 +204,34 @@ class TelephonyIcons { TelephonyIcons.ICON_LTE_PLUS, true); + static final MobileIconGroup NR_5G = new MobileIconGroup( + "5G", + null, + null, + AccessibilityContentDescriptions.PHONE_SIGNAL_STRENGTH, + 0, + 0, + 0, + 0, + AccessibilityContentDescriptions.PHONE_SIGNAL_STRENGTH[0], + R.string.data_connection_5g, + TelephonyIcons.ICON_5G, + true); + + static final MobileIconGroup NR_5G_PLUS = new MobileIconGroup( + "5G_PLUS", + null, + null, + AccessibilityContentDescriptions.PHONE_SIGNAL_STRENGTH, + 0, + 0, + 0, + 0, + AccessibilityContentDescriptions.PHONE_SIGNAL_STRENGTH[0], + R.string.data_connection_5g_plus, + TelephonyIcons.ICON_5G_PLUS, + true); + static final MobileIconGroup DATA_DISABLED = new MobileIconGroup( "DataDisabled", null, @@ -211,5 +244,27 @@ class TelephonyIcons { R.string.cell_data_off_content_description, 0, false); + + /** Mapping icon name(lower case) to the icon object. */ + static final Map ICON_NAME_TO_ICON; + static { + ICON_NAME_TO_ICON = new HashMap<>(); + ICON_NAME_TO_ICON.put("carrier_network_change", CARRIER_NETWORK_CHANGE); + ICON_NAME_TO_ICON.put("3g", THREE_G); + ICON_NAME_TO_ICON.put("wfc", WFC); + ICON_NAME_TO_ICON.put("unknown", UNKNOWN); + ICON_NAME_TO_ICON.put("e", E); + ICON_NAME_TO_ICON.put("1x", ONE_X); + ICON_NAME_TO_ICON.put("g", G); + ICON_NAME_TO_ICON.put("h", H); + ICON_NAME_TO_ICON.put("h+", H_PLUS); + ICON_NAME_TO_ICON.put("4g", FOUR_G); + ICON_NAME_TO_ICON.put("4g+", FOUR_G_PLUS); + ICON_NAME_TO_ICON.put("lte", LTE); + ICON_NAME_TO_ICON.put("lte+", LTE_PLUS); + ICON_NAME_TO_ICON.put("5g", NR_5G); + ICON_NAME_TO_ICON.put("5g_plus", NR_5G_PLUS); + ICON_NAME_TO_ICON.put("datadisable", DATA_DISABLED); + } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java index 35f0dba12cb9..fdbf09083a4e 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java @@ -212,6 +212,11 @@ public class NetworkControllerBaseTest extends SysuiTestCase { NetworkCapabilities.TRANSPORT_CELLULAR, true, true); } + public void setupDefaultNr5GIconConfiguration() { + NetworkControllerImpl.Config.add5GIconMapping("connected_mmwave:5g_plus", mConfig); + NetworkControllerImpl.Config.add5GIconMapping("connected:5g", mConfig); + } + public void setConnectivityViaBroadcast( int networkType, boolean validated, boolean isConnected) { setConnectivityCommon(networkType, validated, isConnected); diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerDataTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerDataTest.java index d42940a3d2a2..2baea1ae3b19 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerDataTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerDataTest.java @@ -1,11 +1,14 @@ package com.android.systemui.statusbar.policy; import static org.mockito.Matchers.anyInt; +import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; import android.net.NetworkCapabilities; import android.os.Looper; +import android.telephony.NetworkRegistrationState; +import android.telephony.ServiceState; import android.telephony.TelephonyManager; import android.test.suitebuilder.annotation.SmallTest; import android.testing.AndroidTestingRunner; @@ -16,6 +19,7 @@ import com.android.settingslib.net.DataUsageController; import org.junit.Test; import org.junit.runner.RunWith; +import org.mockito.Mockito; @SmallTest @RunWith(AndroidTestingRunner.class) @@ -140,6 +144,47 @@ public class NetworkControllerDataTest extends NetworkControllerBaseTest { false, true); } + @Test + public void testNr5GIcon_NrConnectedWithoutMMWave_show5GIcon() { + setupDefaultNr5GIconConfiguration(); + setupDefaultSignal(); + updateDataConnectionState(TelephonyManager.DATA_CONNECTED, + TelephonyManager.NETWORK_TYPE_LTE); + ServiceState ss = Mockito.mock(ServiceState.class); + doReturn(NetworkRegistrationState.NR_STATUS_CONNECTED).when(ss).getNrStatus(); + doReturn(ServiceState.FREQUENCY_RANGE_HIGH).when(ss).getNrFrequencyRange(); + mPhoneStateListener.onServiceStateChanged(ss); + + verifyDataIndicators(TelephonyIcons.ICON_5G); + } + + @Test + public void testNr5GIcon_NrConnectedWithMMWave_show5GPlusIcon() { + setupDefaultNr5GIconConfiguration(); + setupDefaultSignal(); + updateDataConnectionState(TelephonyManager.DATA_CONNECTED, + TelephonyManager.NETWORK_TYPE_LTE); + ServiceState ss = Mockito.mock(ServiceState.class); + doReturn(NetworkRegistrationState.NR_STATUS_CONNECTED).when(ss).getNrStatus(); + doReturn(ServiceState.FREQUENCY_RANGE_MMWAVE).when(ss).getNrFrequencyRange(); + mPhoneStateListener.onServiceStateChanged(ss); + + verifyDataIndicators(TelephonyIcons.ICON_5G_PLUS); + } + + @Test + public void testNr5GIcon_NrRestricted_showLteIcon() { + setupDefaultNr5GIconConfiguration(); + setupDefaultSignal(); + updateDataConnectionState(TelephonyManager.DATA_CONNECTED, + TelephonyManager.NETWORK_TYPE_LTE); + ServiceState ss = Mockito.mock(ServiceState.class); + doReturn(NetworkRegistrationState.NR_STATUS_RESTRICTED).when(ss).getNrStatus(); + mPhoneStateListener.onServiceStateChanged(mServiceState); + + verifyDataIndicators(TelephonyIcons.ICON_LTE); + } + @Test public void testDataDisabledIcon_UserNotSetup() { setupNetworkController(); @@ -222,5 +267,4 @@ public class NetworkControllerDataTest extends NetworkControllerBaseTest { true, DEFAULT_QS_SIGNAL_STRENGTH, dataIcon, false, false); } - } -- cgit v1.2.3-59-g8ed1b