Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit fec291c8 authored by Bill Lin's avatar Bill Lin Committed by android-build-merger
Browse files

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

am: 6eb9ba37

Change-Id: Ie6c10e02f07fce5b50aa771933d549bc712e7a0a
parents b3ab4443 6eb9ba37
Loading
Loading
Loading
Loading
+63 −0
Original line number Diff line number Diff line
@@ -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 {
+27 −0
Original line number Diff line number Diff line
@@ -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;
        }
    }
}
+15 −0
Original line number Diff line number Diff line
@@ -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);
+182 −0
Original line number Diff line number Diff line
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();