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

Commit b023773a authored by Fabian Kozynski's avatar Fabian Kozynski
Browse files

Change carrier name shown No Service to ECO

In the case where at least one SIM supports EC (either it has service or
it supports them), we replace "No service" carrier name into "Emergency calls
only". This does not replace the string if the sub is already mark as
ECO.

Test: manual
Test: atest KeyguardUpdateMonitorTest
Test: atest CarrierTextControllerTest
Fixes: 130857483
Fixes: 133201131
Fixes: 132291669
Change-Id: Ia0ba2076c9750a8bb081994291753dbea68a2270
parent aa21a4a7
Loading
Loading
Loading
Loading
+15 −4
Original line number Diff line number Diff line
@@ -324,13 +324,25 @@ public class CarrierTextController {
        final CharSequence[] carrierNames = new CharSequence[numSubs];
        if (DEBUG) Log.d(TAG, "updateCarrierText(): " + numSubs);

        boolean anySimEmergency = mKeyguardUpdateMonitor.isAnySimEmergencyAble();
        for (int i = 0; i < numSubs; i++) {
            int subId = subs.get(i).getSubscriptionId();
            carrierNames[i] = "";
            subsIds[i] = subId;
            subOrderBySlot[subs.get(i).getSimSlotIndex()] = i;
            IccCardConstants.State simState = mKeyguardUpdateMonitor.getSimState(subId);
            ServiceState s = mKeyguardUpdateMonitor.getServiceState(subId);
            CharSequence carrierName = subs.get(i).getCarrierName();
            // If this sub is showing No service but at least one slot currently supports emergency
            // calls, it should replace it by Emergency calls only
            if (s != null && s.getState() != ServiceState.STATE_IN_SERVICE && !s.isEmergencyOnly()
                    && anySimEmergency) {
                carrierName = getContext().getText(
                        com.android.internal.R.string.emergency_calls_only);
                if (DEBUG) {
                    Log.d(TAG, "Subscription " + subId + "switched to ECO");
                }
            }
            CharSequence carrierTextForSimState = getCarrierTextForSimState(simState, carrierName);
            if (DEBUG) {
                Log.d(TAG, "Handling (subId=" + subId + "): " + simState + " " + carrierName);
@@ -340,16 +352,15 @@ public class CarrierTextController {
                carrierNames[i] = carrierTextForSimState;
            }
            if (simState == IccCardConstants.State.READY) {
                ServiceState ss = mKeyguardUpdateMonitor.mServiceStates.get(subId);
                if (ss != null && ss.getDataRegState() == ServiceState.STATE_IN_SERVICE) {
                if (s != null && s.getDataRegState() == ServiceState.STATE_IN_SERVICE) {
                    // hack for WFC (IWLAN) not turning off immediately once
                    // Wi-Fi is disassociated or disabled
                    if (ss.getRilDataRadioTechnology() != ServiceState.RIL_RADIO_TECHNOLOGY_IWLAN
                    if (s.getRilDataRadioTechnology() != ServiceState.RIL_RADIO_TECHNOLOGY_IWLAN
                            || (mWifiManager.isWifiEnabled()
                            && mWifiManager.getConnectionInfo() != null
                            && mWifiManager.getConnectionInfo().getBSSID() != null)) {
                        if (DEBUG) {
                            Log.d(TAG, "SIM ready and in service: subId=" + subId + ", ss=" + ss);
                            Log.d(TAG, "SIM ready and in service: subId=" + subId + ", ss=" + s);
                        }
                        anySimReadyAndInService = true;
                    }
+34 −3
Original line number Diff line number Diff line
@@ -195,6 +195,12 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener {
    HashMap<Integer, SimData> mSimDatas = new HashMap<Integer, SimData>();
    HashMap<Integer, ServiceState> mServiceStates = new HashMap<Integer, ServiceState>();

    /**
     * Support up to 3 slots which is what's supported by {@link TelephonyManager#getPhoneCount}
     */
    private static final int SIM_SLOTS = 3;
    private final ServiceState[] mServiceStatesBySlot = new ServiceState[SIM_SLOTS];

    private int mRingMode;
    private int mPhoneState;
    private boolean mKeyguardIsVisible;
@@ -326,7 +332,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener {
                    handleAirplaneModeChanged();
                    break;
                case MSG_SERVICE_STATE_CHANGE:
                    handleServiceStateChange(msg.arg1, (ServiceState) msg.obj);
                    handleServiceStateChange(msg.arg1, msg.arg2, (ServiceState) msg.obj);
                    break;
                case MSG_SCREEN_TURNED_ON:
                    handleScreenTurnedOn();
@@ -1038,12 +1044,13 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener {
                ServiceState serviceState = ServiceState.newFromBundle(intent.getExtras());
                int subId = intent.getIntExtra(PhoneConstants.SUBSCRIPTION_KEY,
                        SubscriptionManager.INVALID_SUBSCRIPTION_ID);
                int slotId = intent.getIntExtra(PhoneConstants.SLOT_KEY, -1);
                if (DEBUG) {
                    Log.v(TAG, "action " + action + " serviceState=" + serviceState + " subId="
                            + subId);
                }
                mHandler.sendMessage(
                        mHandler.obtainMessage(MSG_SERVICE_STATE_CHANGE, subId, 0, serviceState));
                mHandler.obtainMessage(MSG_SERVICE_STATE_CHANGE, subId, slotId, serviceState)
                        .sendToTarget();
            } else if (DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED.equals(
                    action)) {
                mHandler.sendEmptyMessage(MSG_DEVICE_POLICY_MANAGER_STATE_CHANGED);
@@ -2042,6 +2049,14 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener {
     */
    @VisibleForTesting
    void handleServiceStateChange(int subId, ServiceState serviceState) {
        handleServiceStateChange(subId, -1, serviceState);
    }

    /**
     * Handle {@link #MSG_SERVICE_STATE_CHANGE}
     */
    @VisibleForTesting
    void handleServiceStateChange(int subId, int slotId, ServiceState serviceState) {
        if (DEBUG) {
            Log.d(TAG,
                    "handleServiceStateChange(subId=" + subId + ", serviceState=" + serviceState);
@@ -2055,6 +2070,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener {
        }

        mServiceStates.put(subId, serviceState);
        if (slotId >= 0 && slotId < SIM_SLOTS) mServiceStatesBySlot[slotId] = serviceState;

        for (int j = 0; j < mCallbacks.size(); j++) {
            KeyguardUpdateMonitorCallback cb = mCallbacks.get(j).get();
@@ -2280,6 +2296,21 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener {
        return mServiceStates.get(subId);
    }

    /**
     * @return true iff at least one slot currently supports emergency calls
     */
    public boolean isAnySimEmergencyAble() {
        for (int i = 0; i < SIM_SLOTS; i++) {
            ServiceState s = mServiceStatesBySlot[i];
            if (s != null) {
                if (s.getState() == ServiceState.STATE_IN_SERVICE || s.isEmergencyOnly()) {
                    return true;
                }
            }
        }
        return false;
    }

    public void clearBiometricRecognized() {
        mUserFingerprintAuthenticated.clear();
        mUserFaceAuthenticated.clear();
+127 −13
Original line number Diff line number Diff line
@@ -27,6 +27,7 @@ import static org.junit.Assert.assertEquals;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.verify;
@@ -36,6 +37,7 @@ import android.content.Context;
import android.net.ConnectivityManager;
import android.net.wifi.WifiManager;
import android.os.Handler;
import android.telephony.ServiceState;
import android.telephony.SubscriptionInfo;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
@@ -43,6 +45,7 @@ import android.test.suitebuilder.annotation.SmallTest;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;

import com.android.internal.R;
import com.android.internal.telephony.IccCardConstants;
import com.android.systemui.Dependency;
import com.android.systemui.SysuiTestCase;
@@ -56,7 +59,6 @@ import org.mockito.Mock;
import org.mockito.MockitoAnnotations;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

@SmallTest
@@ -68,6 +70,7 @@ public class CarrierTextControllerTest extends SysuiTestCase {
    private static final String TEST_CARRIER = "TEST_CARRIER";
    private static final String TEST_CARRIER_2 = "TEST_CARRIER_2";
    private static final String TEST_GROUP_UUID = "59b5c870-fc4c-47a4-a99e-9db826b48b24";
    private static final String EMERGENCY = "Emergency";
    private static final int TEST_CARRIER_ID = 1;
    private static final SubscriptionInfo TEST_SUBSCRIPTION = new SubscriptionInfo(0, "", 0,
            TEST_CARRIER, TEST_CARRIER, NAME_SOURCE_DEFAULT_SOURCE, 0xFFFFFF, "",
@@ -106,6 +109,8 @@ public class CarrierTextControllerTest extends SysuiTestCase {
        mContext.addMockSystemService(ConnectivityManager.class, mConnectivityManager);
        mContext.addMockSystemService(TelephonyManager.class, mTelephonyManager);
        mContext.addMockSystemService(SubscriptionManager.class, mSubscriptionManager);
        mContext.getOrCreateTestableResources().addOverride(
                R.string.emergency_calls_only, EMERGENCY);
        mDependency.injectMockDependency(WakefulnessLifecycle.class);
        mDependency.injectTestDependency(Dependency.MAIN_HANDLER,
                new Handler(mTestableLooper.getLooper()));
@@ -190,8 +195,6 @@ public class CarrierTextControllerTest extends SysuiTestCase {
        when(mKeyguardUpdateMonitor.getSimState(anyInt())).thenReturn(IccCardConstants.State.READY);
        when(mKeyguardUpdateMonitor.getSubscriptionInfo(anyBoolean())).thenReturn(list);

        mKeyguardUpdateMonitor.mServiceStates = new HashMap<>();

        ArgumentCaptor<CarrierTextController.CarrierTextCallbackInfo> captor =
                ArgumentCaptor.forClass(
                        CarrierTextController.CarrierTextCallbackInfo.class);
@@ -214,8 +217,6 @@ public class CarrierTextControllerTest extends SysuiTestCase {
        when(mKeyguardUpdateMonitor.getSimState(anyInt())).thenReturn(IccCardConstants.State.READY);
        when(mKeyguardUpdateMonitor.getSubscriptionInfo(anyBoolean())).thenReturn(list);

        mKeyguardUpdateMonitor.mServiceStates = new HashMap<>();

        ArgumentCaptor<CarrierTextController.CarrierTextCallbackInfo> captor =
                ArgumentCaptor.forClass(
                        CarrierTextController.CarrierTextCallbackInfo.class);
@@ -259,8 +260,6 @@ public class CarrierTextControllerTest extends SysuiTestCase {
        when(mKeyguardUpdateMonitor.getSimState(anyInt())).thenReturn(IccCardConstants.State.READY);
        when(mKeyguardUpdateMonitor.getSubscriptionInfo(anyBoolean())).thenReturn(list);

        mKeyguardUpdateMonitor.mServiceStates = new HashMap<>();

        ArgumentCaptor<CarrierTextController.CarrierTextCallbackInfo> captor =
                ArgumentCaptor.forClass(
                        CarrierTextController.CarrierTextCallbackInfo.class);
@@ -284,8 +283,6 @@ public class CarrierTextControllerTest extends SysuiTestCase {
                .thenReturn(IccCardConstants.State.NOT_READY);
        when(mKeyguardUpdateMonitor.getSubscriptionInfo(anyBoolean())).thenReturn(list);

        mKeyguardUpdateMonitor.mServiceStates = new HashMap<>();

        ArgumentCaptor<CarrierTextController.CarrierTextCallbackInfo> captor =
                ArgumentCaptor.forClass(
                        CarrierTextController.CarrierTextCallbackInfo.class);
@@ -309,8 +306,6 @@ public class CarrierTextControllerTest extends SysuiTestCase {
                .thenReturn(IccCardConstants.State.READY);
        when(mKeyguardUpdateMonitor.getSubscriptionInfo(anyBoolean())).thenReturn(list);

        mKeyguardUpdateMonitor.mServiceStates = new HashMap<>();

        ArgumentCaptor<CarrierTextController.CarrierTextCallbackInfo> captor =
                ArgumentCaptor.forClass(
                        CarrierTextController.CarrierTextCallbackInfo.class);
@@ -335,7 +330,6 @@ public class CarrierTextControllerTest extends SysuiTestCase {
                .thenReturn(IccCardConstants.State.NOT_READY)
                .thenReturn(IccCardConstants.State.READY);
        when(mKeyguardUpdateMonitor.getSubscriptionInfo(anyBoolean())).thenReturn(list);
        mKeyguardUpdateMonitor.mServiceStates = new HashMap<>();

        ArgumentCaptor<CarrierTextController.CarrierTextCallbackInfo> captor =
                ArgumentCaptor.forClass(
@@ -358,7 +352,6 @@ public class CarrierTextControllerTest extends SysuiTestCase {
        when(mKeyguardUpdateMonitor.getSimState(anyInt()))
            .thenReturn(IccCardConstants.State.READY);

        mKeyguardUpdateMonitor.mServiceStates = new HashMap<>();
        mCarrierTextController.updateDisplayOpportunisticSubscriptionCarrierText(true);
        when(mSubscriptionManager.getActiveSubscriptionInfoList(anyBoolean())).thenReturn(list);

@@ -373,6 +366,127 @@ public class CarrierTextControllerTest extends SysuiTestCase {
        assertEquals(TEST_CARRIER_2, captor.getValue().carrierText);
    }

    @Test
    public void testCarrierText_replaceOutOfServiceWithEmergency() {
        reset(mCarrierTextCallback);

        List<SubscriptionInfo> list = new ArrayList<>();
        list.add(TEST_SUBSCRIPTION);
        when(mKeyguardUpdateMonitor.getSubscriptionInfo(anyBoolean())).thenReturn(list);

        when(mKeyguardUpdateMonitor.getSimState(anyInt()))
                .thenReturn(IccCardConstants.State.READY);
        ServiceState s = mock(ServiceState.class);
        when(mKeyguardUpdateMonitor.getServiceState(anyInt())).thenReturn(s);
        when(s.getState()).thenReturn(ServiceState.STATE_OUT_OF_SERVICE);

        when(mKeyguardUpdateMonitor.isAnySimEmergencyAble()).thenReturn(true);

        ArgumentCaptor<CarrierTextController.CarrierTextCallbackInfo> captor =
                ArgumentCaptor.forClass(
                        CarrierTextController.CarrierTextCallbackInfo.class);

        mCarrierTextController.updateCarrierText();
        mTestableLooper.processAllMessages();
        verify(mCarrierTextCallback).updateCarrierInfo(captor.capture());

        assertEquals(1, captor.getValue().listOfCarriers.length);
        assertEquals(EMERGENCY, captor.getValue().listOfCarriers[0]);
    }

    @Test
    public void testCarrierText_replaceOutOfServiceWithEmergencyOnlyInNoService() {
        reset(mCarrierTextCallback);

        List<SubscriptionInfo> list = new ArrayList<>();
        list.add(TEST_SUBSCRIPTION);
        list.add(TEST_SUBSCRIPTION_2);
        when(mKeyguardUpdateMonitor.getSubscriptionInfo(anyBoolean())).thenReturn(list);

        when(mKeyguardUpdateMonitor.getSimState(anyInt()))
                .thenReturn(IccCardConstants.State.READY);
        ServiceState sInService = mock(ServiceState.class);
        ServiceState sOutOfService = mock(ServiceState.class);
        when(mKeyguardUpdateMonitor.getServiceState(anyInt()))
                .thenReturn(sInService)
                .thenReturn(sOutOfService);
        when(sInService.getState()).thenReturn(ServiceState.STATE_IN_SERVICE);
        when(sOutOfService.getState()).thenReturn(ServiceState.STATE_OUT_OF_SERVICE);

        when(mKeyguardUpdateMonitor.isAnySimEmergencyAble()).thenReturn(true);

        ArgumentCaptor<CarrierTextController.CarrierTextCallbackInfo> captor =
                ArgumentCaptor.forClass(
                        CarrierTextController.CarrierTextCallbackInfo.class);

        mCarrierTextController.updateCarrierText();
        mTestableLooper.processAllMessages();
        verify(mCarrierTextCallback).updateCarrierInfo(captor.capture());

        assertEquals(2, captor.getValue().listOfCarriers.length);
        assertEquals(TEST_CARRIER, captor.getValue().listOfCarriers[0]);
        assertEquals(EMERGENCY, captor.getValue().listOfCarriers[1]);
    }

    @Test
    public void testCarrierText_dontReplaceWithEmergencyIfNotAble() {
        reset(mCarrierTextCallback);

        List<SubscriptionInfo> list = new ArrayList<>();
        list.add(TEST_SUBSCRIPTION);
        list.add(TEST_SUBSCRIPTION_2);
        when(mKeyguardUpdateMonitor.getSubscriptionInfo(anyBoolean())).thenReturn(list);

        when(mKeyguardUpdateMonitor.getSimState(anyInt()))
                .thenReturn(IccCardConstants.State.READY);
        ServiceState sOutOfService = mock(ServiceState.class);
        when(mKeyguardUpdateMonitor.getServiceState(anyInt())).thenReturn(sOutOfService);
        when(sOutOfService.getState()).thenReturn(ServiceState.STATE_OUT_OF_SERVICE);

        when(mKeyguardUpdateMonitor.isAnySimEmergencyAble()).thenReturn(false);

        ArgumentCaptor<CarrierTextController.CarrierTextCallbackInfo> captor =
                ArgumentCaptor.forClass(
                        CarrierTextController.CarrierTextCallbackInfo.class);

        mCarrierTextController.updateCarrierText();
        mTestableLooper.processAllMessages();
        verify(mCarrierTextCallback).updateCarrierInfo(captor.capture());

        assertEquals(2, captor.getValue().listOfCarriers.length);
        assertEquals(TEST_CARRIER, captor.getValue().listOfCarriers[0]);
        assertEquals(TEST_CARRIER_2, captor.getValue().listOfCarriers[1]);
    }

    @Test
    public void testCarrierText_dontReplaceWithEmergencyIfAlreadyEmergency() {
        reset(mCarrierTextCallback);

        List<SubscriptionInfo> list = new ArrayList<>();
        list.add(TEST_SUBSCRIPTION);
        when(mKeyguardUpdateMonitor.getSubscriptionInfo(anyBoolean())).thenReturn(list);

        when(mKeyguardUpdateMonitor.getSimState(anyInt()))
                .thenReturn(IccCardConstants.State.READY);
        ServiceState sOutOfService = mock(ServiceState.class);
        when(mKeyguardUpdateMonitor.getServiceState(anyInt())).thenReturn(sOutOfService);
        when(sOutOfService.getState()).thenReturn(ServiceState.STATE_OUT_OF_SERVICE);
        when(sOutOfService.isEmergencyOnly()).thenReturn(true);

        when(mKeyguardUpdateMonitor.isAnySimEmergencyAble()).thenReturn(false);

        ArgumentCaptor<CarrierTextController.CarrierTextCallbackInfo> captor =
                ArgumentCaptor.forClass(
                        CarrierTextController.CarrierTextCallbackInfo.class);

        mCarrierTextController.updateCarrierText();
        mTestableLooper.processAllMessages();
        verify(mCarrierTextCallback).updateCarrierInfo(captor.capture());

        assertEquals(1, captor.getValue().listOfCarriers.length);
        assertEquals(TEST_CARRIER, captor.getValue().listOfCarriers[0]);
    }

    public static class TestCarrierTextController extends CarrierTextController {
        private KeyguardUpdateMonitor mKUM;

+47 −0
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@ import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.spy;
@@ -361,6 +362,52 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase {
        assertThat(mKeyguardUpdateMonitor.getUserCanSkipBouncer(user)).isTrue();
    }

    @Test
    public void testAnySimEmergency_allSimsInService() {
        ServiceState s0 = mock(ServiceState.class);
        when(s0.getState()).thenReturn(ServiceState.STATE_IN_SERVICE);

        mKeyguardUpdateMonitor.handleServiceStateChange(0, 0, s0);
        assertThat(mKeyguardUpdateMonitor.isAnySimEmergencyAble()).isTrue();
    }

    @Test
    public void testAnySimEmergency_someSimsInServiceOthersNotECC() {
        ServiceState s0 = mock(ServiceState.class);
        when(s0.getState()).thenReturn(ServiceState.STATE_OUT_OF_SERVICE);
        ServiceState s1 = mock(ServiceState.class);
        when(s1.getState()).thenReturn(ServiceState.STATE_IN_SERVICE);

        mKeyguardUpdateMonitor.handleServiceStateChange(0, 0, s0);
        mKeyguardUpdateMonitor.handleServiceStateChange(0, 1, s1);
        assertThat(mKeyguardUpdateMonitor.isAnySimEmergencyAble()).isTrue();
    }

    @Test
    public void testAnySimEmergency_someSimsEmergencyCapable() {
        ServiceState s0 = mock(ServiceState.class);
        when(s0.getState()).thenReturn(ServiceState.STATE_POWER_OFF);
        ServiceState s1 = mock(ServiceState.class);
        when(s1.getState()).thenReturn(ServiceState.STATE_OUT_OF_SERVICE);
        when(s1.isEmergencyOnly()).thenReturn(true);

        mKeyguardUpdateMonitor.handleServiceStateChange(0, 0, s0);
        mKeyguardUpdateMonitor.handleServiceStateChange(0, 1, s1);
        assertThat(mKeyguardUpdateMonitor.isAnySimEmergencyAble()).isTrue();
    }

    @Test
    public void testAnySimEmergency_noEmergencyCapable() {
        ServiceState s0 = mock(ServiceState.class);
        when(s0.getState()).thenReturn(ServiceState.STATE_POWER_OFF);
        ServiceState s1 = mock(ServiceState.class);
        when(s1.getState()).thenReturn(ServiceState.STATE_OUT_OF_SERVICE);

        mKeyguardUpdateMonitor.handleServiceStateChange(0, 0, s0);
        mKeyguardUpdateMonitor.handleServiceStateChange(0, 1, s1);
        assertThat(mKeyguardUpdateMonitor.isAnySimEmergencyAble()).isFalse();
    }

    private Intent putPhoneInfo(Intent intent, Bundle data, Boolean simInited) {
        int subscription = simInited
                ? 1/* mock subid=1 */ : SubscriptionManager.DUMMY_SUBSCRIPTION_ID_BASE;