diff options
| author | 2019-09-03 09:57:47 -0700 | |
|---|---|---|
| committer | 2019-09-03 09:57:47 -0700 | |
| commit | d732bd37ef03feae700fe4e1fa8b5bf9898192bb (patch) | |
| tree | 5aa8aceb580b4f0040b4276e97956ca384a12251 | |
| parent | de384db1ef5ec3b0df306438b9a09ed196ad72f2 (diff) | |
| parent | 6eb9ba375b01a17335fb5a3f72b0bdd1aefa91b8 (diff) | |
Merge "Add timeout for displaying 5G icon in SystemUI" into qt-qpr1-dev
am: 6eb9ba375b
Change-Id: I49c19b44316a0ecd4d8decf0f4887b77ae54490f
4 files changed, 287 insertions, 0 deletions
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 7acf4fd27ced..dbfb09f7fc41 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java @@ -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 { 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 621b16ab9f41..bb3742198117 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java @@ -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; + } } } 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 e691b7dec0d9..c03f07e59129 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 @@ -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); 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 f0394da6f479..3ddfbdac6db8 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,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; @@ -245,6 +247,186 @@ public class NetworkControllerDataTest extends NetworkControllerBaseTest { } @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(); when(mMockTm.isDataCapable()).thenReturn(false); |