Merge "Add timeout for displaying 5G icon in SystemUI" into qt-qpr1-dev

This commit is contained in:
TreeHugger Robot
2019-09-03 16:36:00 +00:00
committed by Android (Google) Code Review
4 changed files with 287 additions and 0 deletions

View File

@@ -21,6 +21,7 @@ import android.database.ContentObserver;
import android.net.NetworkCapabilities;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.provider.Settings.Global;
import android.telephony.NetworkRegistrationInfo;
import android.telephony.PhoneStateListener;
@@ -54,6 +55,10 @@ import java.util.regex.Pattern;
public class MobileSignalController extends SignalController<
MobileSignalController.MobileState, MobileSignalController.MobileIconGroup> {
// The message to display Nr5G icon gracfully by CarrierConfig timeout
private static final int MSG_DISPLAY_GRACE = 1;
private final TelephonyManager mPhone;
private final SubscriptionDefaults mDefaults;
private final String mNetworkNameDefault;
@@ -76,8 +81,11 @@ public class MobileSignalController extends SignalController<
private SignalStrength mSignalStrength;
private MobileIconGroup mDefaultIcons;
private Config mConfig;
private final Handler mDisplayGraceHandler;
@VisibleForTesting
boolean mInflateSignalStrengths = false;
@VisibleForTesting
boolean mIsShowingIconGracefully = false;
// Some specific carriers have 5GE network which is special LTE CA network.
private static final int NETWORK_TYPE_LTE_CA_5GE = TelephonyManager.MAX_NETWORK_TYPE + 1;
@@ -116,6 +124,16 @@ public class MobileSignalController extends SignalController<
updateTelephony();
}
};
mDisplayGraceHandler = new Handler(receiverLooper) {
@Override
public void handleMessage(Message msg) {
if (msg.what == MSG_DISPLAY_GRACE) {
mIsShowingIconGracefully = false;
updateTelephony();
}
}
};
}
public void setConfiguration(Config config) {
@@ -479,6 +497,10 @@ public class MobileSignalController extends SignalController<
// 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 (mConfig.nrIconDisplayGracePeriodMs > 0) {
nr5GIconGroup = adjustNr5GIconGroupByDisplayGraceTime(nr5GIconGroup);
}
if (nr5GIconGroup != null) {
mCurrentState.iconGroup = nr5GIconGroup;
} else if (mNetworkToIconLookup.indexOfKey(mDataNetType) >= 0) {
@@ -555,6 +577,46 @@ public class MobileSignalController extends SignalController<
return null;
}
/**
* The function to adjust MobileIconGroup depend on CarrierConfig's time
* nextIconGroup == null imply next state could be 2G/3G/4G/4G+
* nextIconGroup != null imply next state will be 5G/5G+
* Flag : mIsShowingIconGracefully
* ---------------------------------------------------------------------------------
* | Last state | Current state | Flag | Action |
* ---------------------------------------------------------------------------------
* | 5G/5G+ | 2G/3G/4G/4G+ | true | return previous IconGroup |
* | 5G/5G+ | 5G/5G+ | true | Bypass |
* | 2G/3G/4G/4G+ | 5G/5G+ | true | Bypass |
* | 2G/3G/4G/4G+ | 2G/3G/4G/4G+ | true | Bypass |
* | SS.connected | SS.disconnect | T|F | Reset timer |
* |NETWORK_TYPE_LTE|!NETWORK_TYPE_LTE| T|F | Reset timer |
* | 5G/5G+ | 2G/3G/4G/4G+ | false| Bypass |
* | 5G/5G+ | 5G/5G+ | false| Bypass |
* | 2G/3G/4G/4G+ | 5G/5G+ | false| SendMessageDelay(time), flag->true |
* | 2G/3G/4G/4G+ | 2G/3G/4G/4G+ | false| Bypass |
* ---------------------------------------------------------------------------------
*/
private MobileIconGroup adjustNr5GIconGroupByDisplayGraceTime(
MobileIconGroup candidateIconGroup) {
if (mIsShowingIconGracefully && candidateIconGroup == null) {
candidateIconGroup = (MobileIconGroup) mCurrentState.iconGroup;
} else if (!mIsShowingIconGracefully && candidateIconGroup != null
&& mLastState.iconGroup != candidateIconGroup) {
mDisplayGraceHandler.sendMessageDelayed(
mDisplayGraceHandler.obtainMessage(MSG_DISPLAY_GRACE),
mConfig.nrIconDisplayGracePeriodMs);
mIsShowingIconGracefully = true;
} else if (!mCurrentState.connected || mDataState == TelephonyManager.DATA_DISCONNECTED
|| candidateIconGroup == null) {
mDisplayGraceHandler.removeMessages(MSG_DISPLAY_GRACE);
mIsShowingIconGracefully = false;
candidateIconGroup = null;
}
return candidateIconGroup;
}
private boolean isDataDisabled() {
return !mPhone.isDataCapable();
}
@@ -580,6 +642,7 @@ public class MobileSignalController extends SignalController<
pw.println(" mDataNetType=" + mDataNetType + ",");
pw.println(" mInflateSignalStrengths=" + mInflateSignalStrengths + ",");
pw.println(" isDataDisabled=" + isDataDisabled() + ",");
pw.println(" mIsShowingIconGracefully=" + mIsShowingIconGracefully + ",");
}
class MobilePhoneStateListener extends PhoneStateListener {

View File

@@ -51,6 +51,7 @@ import android.telephony.SubscriptionManager;
import android.telephony.SubscriptionManager.OnSubscriptionsChangedListener;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
import android.text.format.DateUtils;
import android.util.Log;
import android.util.MathUtils;
import android.util.SparseArray;
@@ -829,6 +830,13 @@ public class NetworkControllerImpl extends BroadcastReceiver
pw.print(" mEmergencySource=");
pw.println(emergencyToString(mEmergencySource));
pw.println(" - config ------");
pw.print(" patternOfCarrierSpecificDataIcon=");
pw.println(mConfig.patternOfCarrierSpecificDataIcon);
pw.print(" nr5GIconMap=");
pw.println(mConfig.nr5GIconMap.toString());
pw.print(" nrIconDisplayGracePeriodMs=");
pw.println(mConfig.nrIconDisplayGracePeriodMs);
for (int i = 0; i < mMobileSignalControllers.size(); i++) {
MobileSignalController mobileSignalController = mMobileSignalControllers.valueAt(i);
mobileSignalController.dump(pw);
@@ -992,6 +1000,8 @@ public class NetworkControllerImpl extends BroadcastReceiver
datatype.equals("3g") ? TelephonyIcons.THREE_G :
datatype.equals("4g") ? TelephonyIcons.FOUR_G :
datatype.equals("4g+") ? TelephonyIcons.FOUR_G_PLUS :
datatype.equals("5g") ? TelephonyIcons.NR_5G :
datatype.equals("5g+") ? TelephonyIcons.NR_5G_PLUS :
datatype.equals("e") ? TelephonyIcons.E :
datatype.equals("g") ? TelephonyIcons.G :
datatype.equals("h") ? TelephonyIcons.H :
@@ -1123,6 +1133,7 @@ public class NetworkControllerImpl extends BroadcastReceiver
boolean inflateSignalStrengths = false;
boolean alwaysShowDataRatIcon = false;
public String patternOfCarrierSpecificDataIcon = "";
public long nrIconDisplayGracePeriodMs;
/**
* Mapping from NR 5G status string to an integer. The NR 5G status string should match
@@ -1175,6 +1186,9 @@ public class NetworkControllerImpl extends BroadcastReceiver
add5GIconMapping(pair, config);
}
}
setDisplayGraceTime(
b.getInt(CarrierConfigManager.KEY_5G_ICON_DISPLAY_GRACE_PERIOD_SEC_INT),
config);
}
return config;
@@ -1208,5 +1222,18 @@ public class NetworkControllerImpl extends BroadcastReceiver
TelephonyIcons.ICON_NAME_TO_ICON.get(value));
}
}
/**
* Set display gracefully period time(MS) depend on carrierConfig KEY
* KEY_5G_ICON_DISPLAY_GRACE_PERIOD_SEC_INT, and this function will convert to ms.
* {@link CarrierConfigManager}.
*
* @param time showing 5G icon gracefully in the period of the time(SECOND)
* @param config container that used to store the parsed configs.
*/
@VisibleForTesting
static void setDisplayGraceTime(int time, Config config) {
config.nrIconDisplayGracePeriodMs = time * DateUtils.SECOND_IN_MILLIS;
}
}
}

View File

@@ -30,6 +30,7 @@ import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import android.app.Instrumentation;
import android.content.Intent;
import android.net.ConnectivityManager;
import android.net.Network;
@@ -48,6 +49,8 @@ import android.testing.TestableLooper;
import android.testing.TestableResources;
import android.util.Log;
import androidx.test.InstrumentationRegistry;
import com.android.internal.telephony.cdma.EriInfo;
import com.android.settingslib.graph.SignalDrawable;
import com.android.settingslib.net.DataUsageController;
@@ -95,6 +98,7 @@ public class NetworkControllerBaseTest extends SysuiTestCase {
protected SubscriptionDefaults mMockSubDefaults;
protected DeviceProvisionedController mMockProvisionController;
protected DeviceProvisionedListener mUserCallback;
protected Instrumentation mInstrumentation;
protected int mSubId;
@@ -116,6 +120,7 @@ public class NetworkControllerBaseTest extends SysuiTestCase {
@Before
public void setUp() throws Exception {
mInstrumentation = InstrumentationRegistry.getInstrumentation();
Settings.Global.putInt(mContext.getContentResolver(), Global.AIRPLANE_MODE_ON, 0);
TestableResources res = mContext.getOrCreateTestableResources();
res.addOverride(R.string.cell_data_off_content_description, NO_DATA_STRING);
@@ -240,6 +245,16 @@ public class NetworkControllerBaseTest extends SysuiTestCase {
NetworkControllerImpl.Config.add5GIconMapping("not_restricted_rrc_idle:5g", mConfig);
}
public void setupDefaultNr5GIconDisplayGracePeriodTime_enableThirtySeconds() {
final int enableDisplayGraceTimeSec = 30;
NetworkControllerImpl.Config.setDisplayGraceTime(enableDisplayGraceTimeSec, mConfig);
}
public void setupDefaultNr5GIconDisplayGracePeriodTime_disabled() {
final int disableDisplayGraceTimeSec = 0;
NetworkControllerImpl.Config.setDisplayGraceTime(disableDisplayGraceTimeSec, mConfig);
}
public void setConnectivityViaBroadcast(
int networkType, boolean validated, boolean isConnected) {
setConnectivityCommon(networkType, validated, isConnected);

View File

@@ -1,5 +1,7 @@
package com.android.systemui.statusbar.policy;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.mockito.Matchers.anyInt;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
@@ -244,6 +246,186 @@ public class NetworkControllerDataTest extends NetworkControllerBaseTest {
verifyDataIndicators(TelephonyIcons.ICON_LTE);
}
@Test
public void testNr5GIcon_displayGracePeriodTime_enabled() {
setupDefaultNr5GIconConfiguration();
setupDefaultNr5GIconDisplayGracePeriodTime_enableThirtySeconds();
setupDefaultSignal();
mNetworkController.handleConfigurationChanged();
mPhoneStateListener.onServiceStateChanged(mServiceState);
ServiceState ss = Mockito.mock(ServiceState.class);
// While nrIconDisplayGracePeriodMs > 0 & is Nr5G, mIsShowingIconGracefully should be true
doReturn(NetworkRegistrationInfo.NR_STATE_CONNECTED).when(ss).getNrState();
doReturn(ServiceState.FREQUENCY_RANGE_HIGH).when(ss).getNrFrequencyRange();
mPhoneStateListener.onDataConnectionStateChanged(TelephonyManager.DATA_CONNECTED,
TelephonyManager.NETWORK_TYPE_LTE);
mPhoneStateListener.onServiceStateChanged(ss);
assertTrue(mConfig.nrIconDisplayGracePeriodMs > 0);
assertTrue(mMobileSignalController.mIsShowingIconGracefully);
}
@Test
public void testNr5GIcon_displayGracePeriodTime_disabled() {
setupDefaultNr5GIconConfiguration();
setupDefaultNr5GIconDisplayGracePeriodTime_disabled();
setupDefaultSignal();
assertTrue(mConfig.nrIconDisplayGracePeriodMs == 0);
// While nrIconDisplayGracePeriodMs <= 0, mIsShowingIconGracefully should be false
doReturn(NetworkRegistrationInfo.NR_STATE_CONNECTED).when(mServiceState).getNrState();
doReturn(ServiceState.FREQUENCY_RANGE_HIGH).when(mServiceState).getNrFrequencyRange();
mPhoneStateListener.onDataConnectionStateChanged(TelephonyManager.DATA_CONNECTED,
TelephonyManager.NETWORK_TYPE_LTE);
assertFalse(mMobileSignalController.mIsShowingIconGracefully);
}
@Test
public void testNr5GIcon_enableDisplayGracePeriodTime_showIconGracefully() {
setupDefaultNr5GIconConfiguration();
setupDefaultNr5GIconDisplayGracePeriodTime_enableThirtySeconds();
setupDefaultSignal();
mNetworkController.handleConfigurationChanged();
mPhoneStateListener.onServiceStateChanged(mServiceState);
ServiceState ss = Mockito.mock(ServiceState.class);
doReturn(NetworkRegistrationInfo.NR_STATE_CONNECTED).when(ss).getNrState();
doReturn(ServiceState.FREQUENCY_RANGE_HIGH).when(ss).getNrFrequencyRange();
mPhoneStateListener.onDataConnectionStateChanged(TelephonyManager.DATA_CONNECTED,
TelephonyManager.NETWORK_TYPE_LTE);
mPhoneStateListener.onServiceStateChanged(ss);
verifyDataIndicators(TelephonyIcons.ICON_5G);
// Enabled timer Nr5G switch to None Nr5G, showing 5G icon gracefully
ServiceState ssLte = Mockito.mock(ServiceState.class);
doReturn(NetworkRegistrationInfo.NR_STATE_NONE).when(ssLte).getNrState();
doReturn(ServiceState.FREQUENCY_RANGE_UNKNOWN).when(ssLte).getNrFrequencyRange();
mPhoneStateListener.onDataConnectionStateChanged(TelephonyManager.DATA_CONNECTED,
TelephonyManager.NETWORK_TYPE_LTE);
mPhoneStateListener.onServiceStateChanged(ssLte);
verifyDataIndicators(TelephonyIcons.ICON_5G);
}
@Test
public void testNr5GIcon_disableDisplayGracePeriodTime_showLatestIconImmediately() {
setupDefaultNr5GIconConfiguration();
setupDefaultNr5GIconDisplayGracePeriodTime_disabled();
setupDefaultSignal();
mNetworkController.handleConfigurationChanged();
doReturn(NetworkRegistrationInfo.NR_STATE_CONNECTED).when(mServiceState).getNrState();
doReturn(ServiceState.FREQUENCY_RANGE_HIGH).when(mServiceState).getNrFrequencyRange();
mPhoneStateListener.onDataConnectionStateChanged(TelephonyManager.DATA_CONNECTED,
TelephonyManager.NETWORK_TYPE_LTE);
verifyDataIndicators(TelephonyIcons.ICON_5G);
doReturn(NetworkRegistrationInfo.NR_STATE_NONE).when(mServiceState).getNrState();
doReturn(ServiceState.FREQUENCY_RANGE_UNKNOWN).when(mServiceState).getNrFrequencyRange();
mPhoneStateListener.onDataConnectionStateChanged(TelephonyManager.DATA_CONNECTED,
TelephonyManager.NETWORK_TYPE_LTE);
verifyDataIndicators(TelephonyIcons.ICON_LTE);
}
@Test
public void testNr5GIcon_resetDisplayGracePeriodTime_whenDataDisconnected() {
setupDefaultNr5GIconConfiguration();
setupDefaultNr5GIconDisplayGracePeriodTime_enableThirtySeconds();
setupDefaultSignal();
mNetworkController.handleConfigurationChanged();
doReturn(NetworkRegistrationInfo.NR_STATE_CONNECTED).when(mServiceState).getNrState();
doReturn(ServiceState.FREQUENCY_RANGE_HIGH).when(mServiceState).getNrFrequencyRange();
mPhoneStateListener.onDataConnectionStateChanged(TelephonyManager.DATA_CONNECTED,
TelephonyManager.NETWORK_TYPE_LTE);
verifyDataIndicators(TelephonyIcons.ICON_5G);
// Disabled timer, when out of service, reset timer to display latest state
updateDataConnectionState(TelephonyManager.DATA_CONNECTED,
TelephonyManager.NETWORK_TYPE_LTE);
doReturn(NetworkRegistrationInfo.NR_STATE_NONE).when(mServiceState).getNrState();
doReturn(ServiceState.FREQUENCY_RANGE_UNKNOWN).when(mServiceState).getNrFrequencyRange();
mPhoneStateListener.onDataConnectionStateChanged(TelephonyManager.DATA_DISCONNECTED,
TelephonyManager.NETWORK_TYPE_UMTS);
verifyDataIndicators(0);
}
@Test
public void testNr5GIcon_enableDisplayGracePeriodTime_show5G_switching_5GPlus() {
setupDefaultNr5GIconConfiguration();
setupDefaultNr5GIconDisplayGracePeriodTime_enableThirtySeconds();
setupDefaultSignal();
mNetworkController.handleConfigurationChanged();
mPhoneStateListener.onServiceStateChanged(mServiceState);
ServiceState ss5G = Mockito.mock(ServiceState.class);
doReturn(NetworkRegistrationInfo.NR_STATE_CONNECTED).when(ss5G).getNrState();
doReturn(ServiceState.FREQUENCY_RANGE_HIGH).when(ss5G).getNrFrequencyRange();
mPhoneStateListener.onDataConnectionStateChanged(TelephonyManager.DATA_CONNECTED,
TelephonyManager.NETWORK_TYPE_LTE);
mPhoneStateListener.onServiceStateChanged(ss5G);
verifyDataIndicators(TelephonyIcons.ICON_5G);
// When timeout enabled, 5G/5G+ switching should be updated immediately
ServiceState ss5GPlus = Mockito.mock(ServiceState.class);
doReturn(NetworkRegistrationInfo.NR_STATE_CONNECTED).when(ss5GPlus).getNrState();
doReturn(ServiceState.FREQUENCY_RANGE_MMWAVE).when(ss5GPlus).getNrFrequencyRange();
mPhoneStateListener.onDataConnectionStateChanged(TelephonyManager.DATA_CONNECTED,
TelephonyManager.NETWORK_TYPE_LTE);
mPhoneStateListener.onServiceStateChanged(ss5GPlus);
verifyDataIndicators(TelephonyIcons.ICON_5G_PLUS);
}
@Test
public void testNr5GIcon_carrierDisabledDisplayGracePeriodTime_shouldUpdateIconImmediately() {
setupDefaultNr5GIconConfiguration();
setupDefaultNr5GIconDisplayGracePeriodTime_enableThirtySeconds();
setupDefaultSignal();
mNetworkController.handleConfigurationChanged();
mPhoneStateListener.onServiceStateChanged(mServiceState);
ServiceState ss5G = Mockito.mock(ServiceState.class);
doReturn(NetworkRegistrationInfo.NR_STATE_CONNECTED).when(ss5G).getNrState();
doReturn(ServiceState.FREQUENCY_RANGE_HIGH).when(ss5G).getNrFrequencyRange();
mPhoneStateListener.onDataConnectionStateChanged(TelephonyManager.DATA_CONNECTED,
TelephonyManager.NETWORK_TYPE_LTE);
mPhoneStateListener.onServiceStateChanged(ss5G);
verifyDataIndicators(TelephonyIcons.ICON_5G);
// State from NR_5G to NONE NR_5G with timeout, should show previous 5G icon
ServiceState ssLte = Mockito.mock(ServiceState.class);
doReturn(NetworkRegistrationInfo.NR_STATE_NONE).when(ssLte).getNrState();
doReturn(ServiceState.FREQUENCY_RANGE_UNKNOWN).when(ssLte).getNrFrequencyRange();
mPhoneStateListener.onDataConnectionStateChanged(TelephonyManager.DATA_CONNECTED,
TelephonyManager.NETWORK_TYPE_LTE);
mPhoneStateListener.onServiceStateChanged(ssLte);
verifyDataIndicators(TelephonyIcons.ICON_5G);
// Update nrIconDisplayGracePeriodMs to 0
setupDefaultNr5GIconDisplayGracePeriodTime_disabled();
mNetworkController.handleConfigurationChanged();
// State from NR_5G to NONE NR_STATE_RESTRICTED, showing corresponding icon
doReturn(NetworkRegistrationInfo.NR_STATE_RESTRICTED).when(mServiceState).getNrState();
doReturn(TelephonyManager.NETWORK_TYPE_LTE).when(mServiceState).getDataNetworkType();
mPhoneStateListener.onDataConnectionStateChanged(TelephonyManager.DATA_CONNECTED,
TelephonyManager.NETWORK_TYPE_LTE);
assertTrue(mConfig.nrIconDisplayGracePeriodMs == 0);
verifyDataIndicators(TelephonyIcons.ICON_LTE);
}
@Test
public void testDataDisabledIcon_UserNotSetup() {
setupNetworkController();