Merge "Add 5G icon to System UI"

This commit is contained in:
Pengquan Meng
2018-12-17 19:07:57 +00:00
committed by Android (Google) Code Review
8 changed files with 271 additions and 2 deletions

View File

@@ -0,0 +1,27 @@
<!--
Copyright (C) 2018 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="14dp"
android:height="17dp"
android:viewportWidth="14"
android:viewportHeight="17">
<path
android:fillColor="#FF000000"
android:pathData="M13.9,12.24l-0.22,0.27c-0.63,0.73 -1.55,1.1 -2.76,1.1c-1.08,0 -1.92,-0.36 -2.53,-1.07s-0.93,-1.72 -0.94,-3.02V7.56c0,-1.39 0.28,-2.44 0.84,-3.13s1.39,-1.04 2.51,-1.04c0.95,0 1.69,0.26 2.23,0.79s0.83,1.28 0.89,2.26h-1.25c-0.05,-0.62 -0.22,-1.1 -0.52,-1.45s-0.74,-0.52 -1.34,-0.52c-0.72,0 -1.24,0.23 -1.57,0.7S8.72,6.37 8.71,7.4v2.03c0,1 0.19,1.77 0.57,2.31c0.38,0.54 0.93,0.8 1.65,0.8c0.67,0 1.19,-0.16 1.54,-0.49l0.18,-0.17V9.59h-1.82V8.52h3.07V12.24z"/>
<path
android:fillColor="#FF000000"
android:pathData="M1.15,8.47l0.43,-4.96h4.33v1.17H2.6L2.37,7.39C2.78,7.1 3.22,6.96 3.69,6.96c0.77,0 1.38,0.3 1.83,0.9s0.66,1.41 0.66,2.43c0,1.03 -0.24,1.84 -0.72,2.43S4.32,13.6 3.48,13.6c-0.75,0 -1.36,-0.24 -1.83,-0.73s-0.74,-1.16 -0.81,-2.02h1.13c0.07,0.57 0.23,1 0.49,1.29c0.26,0.29 0.59,0.43 1.01,0.43c0.47,0 0.84,-0.2 1.1,-0.61c0.26,-0.41 0.4,-0.96 0.4,-1.65c0,-0.65 -0.14,-1.18 -0.43,-1.59S3.88,8.09 3.4,8.09c-0.4,0 -0.72,0.1 -0.96,0.31L2.11,8.73L1.15,8.47z"/>
</vector>

View File

@@ -0,0 +1,33 @@
<!--
Copyright (C) 2018 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:viewportWidth="22"
android:viewportHeight="17"
android:width="22dp"
android:height="17dp">
<group>
<group>
<path android:fillColor="#FF000000"
android:pathData="M1.03 8.47l0.43-4.96h4.33v1.17H2.48L2.25 7.39C2.66 7.1 3.1 6.96 3.57 6.96c0.77 0 1.38 0.3 1.83 0.9 s0.66 1.41 0.66 2.43c0 1.03-0.24 1.84-0.72 2.43S4.2 13.6 3.36 13.6c-0.75 0-1.36-0.24-1.83-0.73s-0.74-1.16-0.81-2.02h1.13 c0.07 0.57 0.23 1 0.49 1.29s0.59 0.43 1.01 0.43c0.47 0 0.84-0.2 1.1-0.61c0.26-0.41 0.4-0.96 0.4-1.65 c0-0.65-0.14-1.18-0.43-1.59S3.76 8.09 3.28 8.09c-0.4 0-0.72 0.1-0.96 0.31L1.99 8.73L1.03 8.47z"/>
</group>
<group>
<path android:fillColor="#FF000000"
android:pathData="M 18.93,5.74 L 18.93,3.39 L 17.63,3.39 L 17.63,5.74 L 15.28,5.74 L 15.28,7.04 L 17.63,7.04 L 17.63,9.39 L 18.93,9.39 L 18.93,7.04 L 21.28,7.04 L 21.28,5.74 z"/>
</group>
<path android:fillColor="#FF000000"
android:pathData="M13.78 12.24l-0.22 0.27c-0.63 0.73-1.55 1.1-2.76 1.1c-1.08 0-1.92-0.36-2.53-1.07s-0.93-1.72-0.94-3.02V7.56 c0-1.39 0.28-2.44 0.84-3.13s1.39-1.04 2.51-1.04c0.95 0 1.69 0.26 2.23 0.79s0.83 1.28 0.89 2.26h-1.25 c-0.05-0.62-0.22-1.1-0.52-1.45s-0.74-0.52-1.34-0.52c-0.72 0-1.24 0.23-1.57 0.7S8.6 6.37 8.59 7.4v2.03c0 1 0.19 1.77 0.57 2.31 c0.38 0.54 0.93 0.8 1.65 0.8c0.67 0 1.19-0.16 1.54-0.49l0.18-0.17V9.59h-1.82V8.52h3.07V12.24z"/>
</group>
</vector>

View File

@@ -406,6 +406,12 @@
<!-- Content description of the data connection type LTE+. [CHAR LIMIT=NONE] -->
<string name="data_connection_lte_plus">LTE+</string>
<!-- Content description of the data connection type 5G. [CHAR LIMIT=NONE] -->
<string name="data_connection_5g" translate="false">5G</string>
<!-- Content description of the data connection type 5G+. [CHAR LIMIT=NONE] -->
<string name="data_connection_5g_plus" translate="false">5G+</string>
<!-- Content description of the data connection type CDMA. [CHAR LIMIT=NONE] -->
<string name="data_connection_cdma">1X</string>

View File

@@ -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());
}

View File

@@ -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<Integer, MobileIconGroup> 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<String, Integer> 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));
}
}
}
}

View File

@@ -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<String, MobileIconGroup> 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);
}
}

View File

@@ -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);

View File

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