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

Commit c5669111 authored by Sarah Chin's avatar Sarah Chin
Browse files

Support hiding roaming icon for display purposes

Test: atest DisplayInfoControllerTest
Change-Id: I8cd138ad8108bfbcd883321bcdbc100dd8d72dfd
parent fc0029bd
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -6,3 +6,10 @@ flag {
    description: "enabling this flag allows KEY_CARRIER_NR_AVAILABILITIES_INT_ARRAY to control N1 mode enablement"
    bug:"302033535"
}

flag {
  name: "hide_roaming_icon"
  namespace: "telephony"
  description: "Allow carriers to hide the roaming (R) icon when roaming."
  bug: "301467052"
}
+65 −16
Original line number Diff line number Diff line
@@ -19,9 +19,11 @@ package com.android.internal.telephony;
import android.annotation.NonNull;
import android.os.Handler;
import android.os.Message;
import android.os.PersistableBundle;
import android.os.Registrant;
import android.os.RegistrantList;
import android.telephony.AnomalyReporter;
import android.telephony.CarrierConfigManager;
import android.telephony.ServiceState;
import android.telephony.TelephonyDisplayInfo;
import android.telephony.TelephonyManager;
@@ -29,6 +31,7 @@ import android.util.IndentingPrintWriter;
import android.util.LocalLog;
import android.util.Pair;

import com.android.internal.telephony.flags.FeatureFlags;
import com.android.telephony.Rlog;

import java.io.FileDescriptor;
@@ -66,34 +69,55 @@ public class DisplayInfoController extends Handler {

    /** Event for service state changed (roaming). */
    private static final int EVENT_SERVICE_STATE_CHANGED = 1;
    /** Event for carrier config changed. */
    private static final int EVENT_CARRIER_CONFIG_CHANGED = 2;

    private final Phone mPhone;
    private final NetworkTypeController mNetworkTypeController;
    private final RegistrantList mTelephonyDisplayInfoChangedRegistrants = new RegistrantList();
    private @NonNull TelephonyDisplayInfo mTelephonyDisplayInfo;
    private @NonNull ServiceState mServiceState;
    @NonNull private final Phone mPhone;
    @NonNull private final NetworkTypeController mNetworkTypeController;
    @NonNull private final RegistrantList mTelephonyDisplayInfoChangedRegistrants =
            new RegistrantList();
    @NonNull private final FeatureFlags mFeatureFlags;
    @NonNull private TelephonyDisplayInfo mTelephonyDisplayInfo;
    @NonNull private ServiceState mServiceState;
    @NonNull private PersistableBundle mConfigs;

    public DisplayInfoController(Phone phone) {
    public DisplayInfoController(@NonNull Phone phone, @NonNull FeatureFlags featureFlags) {
        mPhone = phone;
        mFeatureFlags = featureFlags;
        mLogTag = "DIC-" + mPhone.getPhoneId();
        mTelephonyDisplayInfo = new TelephonyDisplayInfo(
                TelephonyManager.NETWORK_TYPE_UNKNOWN,
                TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NONE);
        mNetworkTypeController = new NetworkTypeController(phone, this);
        mNetworkTypeController.sendMessage(NetworkTypeController.EVENT_UPDATE);

        mServiceState = mPhone.getServiceStateTracker().getServiceState();
        post(() -> {
        mConfigs = new PersistableBundle();
        try {
            mConfigs = mPhone.getContext().getSystemService(CarrierConfigManager.class)
                    .getConfigForSubId(mPhone.getSubId(),
                            CarrierConfigManager.KEY_SHOW_ROAMING_INDICATOR_BOOL);
        } catch (Exception ignored) {
            // CarrierConfigLoader might not be available yet.
            // Once it's available, configs will be updated through the listener.
        }
        mPhone.getServiceStateTracker()
                .registerForServiceStateChanged(this, EVENT_SERVICE_STATE_CHANGED, null);
            updateTelephonyDisplayInfo();
        mPhone.getContext().getSystemService(CarrierConfigManager.class)
                .registerCarrierConfigChangeListener(Runnable::run,
                        (slotIndex, subId, carrierId, specificCarrierId) -> {
                            if (slotIndex == mPhone.getPhoneId()) {
                                obtainMessage(EVENT_CARRIER_CONFIG_CHANGED).sendToTarget();
                            }
                        });
        mTelephonyDisplayInfo = new TelephonyDisplayInfo(
                TelephonyManager.NETWORK_TYPE_UNKNOWN,
                TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NONE,
                false);
        mNetworkTypeController = new NetworkTypeController(phone, this);
        // EVENT_UPDATE will transition from DefaultState to the current state
        // and update the TelephonyDisplayInfo based on the current state.
        mNetworkTypeController.sendMessage(NetworkTypeController.EVENT_UPDATE);
    }

    /**
     * @return the current TelephonyDisplayInfo
     */
    public @NonNull TelephonyDisplayInfo getTelephonyDisplayInfo() {
    @NonNull public TelephonyDisplayInfo getTelephonyDisplayInfo() {
        return mTelephonyDisplayInfo;
    }

@@ -105,7 +129,7 @@ public class DisplayInfoController extends Handler {
        TelephonyDisplayInfo newDisplayInfo = new TelephonyDisplayInfo(
                mNetworkTypeController.getDataNetworkType(),
                mNetworkTypeController.getOverrideNetworkType(),
                mServiceState.getRoaming());
                isRoaming());
        if (!newDisplayInfo.equals(mTelephonyDisplayInfo)) {
            logl("TelephonyDisplayInfo changed from " + mTelephonyDisplayInfo + " to "
                    + newDisplayInfo);
@@ -116,6 +140,24 @@ public class DisplayInfoController extends Handler {
        }
    }

    /**
     * Determine the roaming status for icon display only.
     * If this is {@code true}, the roaming indicator will be shown, and if this is {@code false},
     * the roaming indicator will not be shown.
     * To get the actual roaming status, use {@link ServiceState#getRoaming()} instead.
     *
     * @return Whether the device is considered roaming for display purposes.
     */
    private boolean isRoaming() {
        boolean roaming = mServiceState.getRoaming();
        if (roaming && mFeatureFlags.hideRoamingIcon()
                && !mConfigs.getBoolean(CarrierConfigManager.KEY_SHOW_ROAMING_INDICATOR_BOOL)) {
            logl("Override roaming for display due to carrier configs.");
            roaming = false;
        }
        return roaming;
    }

    /**
     * Validate the display info and trigger anomaly report if needed.
     *
@@ -175,6 +217,13 @@ public class DisplayInfoController extends Handler {
                log("ServiceState updated, isRoaming=" + mServiceState.getRoaming());
                updateTelephonyDisplayInfo();
                break;
            case EVENT_CARRIER_CONFIG_CHANGED:
                mConfigs = mPhone.getContext().getSystemService(CarrierConfigManager.class)
                        .getConfigForSubId(mPhone.getSubId(),
                                CarrierConfigManager.KEY_SHOW_ROAMING_INDICATOR_BOOL);
                log("Carrier configs updated: " + mConfigs);
                updateTelephonyDisplayInfo();
                break;
        }
    }

+2 −1
Original line number Diff line number Diff line
@@ -364,7 +364,8 @@ public class GsmCdmaPhone extends Phone {
        // DisplayInfoController creates an OverrideNetworkTypeController, which uses
        // DeviceStateMonitor so needs to be crated after it is instantiated.
        mDisplayInfoController = mTelephonyComponentFactory.inject(
                DisplayInfoController.class.getName()).makeDisplayInfoController(this);
                DisplayInfoController.class.getName())
                .makeDisplayInfoController(this, featureFlags);

        mDataNetworkController = mTelephonyComponentFactory.inject(
                DataNetworkController.class.getName())
+2 −2
Original line number Diff line number Diff line
@@ -448,8 +448,8 @@ public class TelephonyComponentFactory {
    /**
     * Create a new DisplayInfoController.
     */
    public DisplayInfoController makeDisplayInfoController(Phone phone) {
        return new DisplayInfoController(phone);
    public DisplayInfoController makeDisplayInfoController(Phone phone, FeatureFlags featureFlags) {
        return new DisplayInfoController(phone, featureFlags);
    }

    /**
+36 −9
Original line number Diff line number Diff line
@@ -42,11 +42,14 @@ import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
import android.text.TextUtils;

import com.android.internal.telephony.flags.FeatureFlags;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Mockito;

import java.util.Collections;
import java.util.concurrent.Executor;
@@ -54,17 +57,18 @@ import java.util.concurrent.Executor;
@RunWith(AndroidTestingRunner.class)
@TestableLooper.RunWithLooper
public class DisplayInfoControllerTest extends TelephonyTest {

    private static final int PHONE_ID = 0;
    private static final String MCC = "600";
    private static final String MNC = "01";
    private static final String NUMERIC = MCC + MNC;
    private static final String NETWORK = "TestNet";

    // Mocked classes
    private FeatureFlags mFeatureFlags;

    private DisplayInfoController mDic;
    private ServiceStateTracker mSst;
    private ServiceStateTrackerTestHandler mSstHandler;
    private SignalStrengthController mSsc;
    private PersistableBundle mBundle;
    private CarrierConfigManager.CarrierConfigChangeListener mCarrierConfigChangeListener;

@@ -75,8 +79,8 @@ public class DisplayInfoControllerTest extends TelephonyTest {

        @Override
        public void onLooperPrepared() {
            mSsc = new SignalStrengthController(mPhone);
            doReturn(mSsc).when(mPhone).getSignalStrengthController();
            SignalStrengthController ssc = new SignalStrengthController(mPhone);
            doReturn(ssc).when(mPhone).getSignalStrengthController();
            doReturn(new ServiceState()).when(mPhone).getServiceState();
            doReturn(NUMERIC).when(mTelephonyManager).getSimOperatorNumericForPhone(eq(PHONE_ID));
            doReturn(NETWORK).when(mTelephonyManager).getSimOperatorNameForPhone(eq(PHONE_ID));
@@ -101,6 +105,7 @@ public class DisplayInfoControllerTest extends TelephonyTest {
        logd("DisplayInfoControllerTest setup!");
        super.setUp(getClass().getSimpleName());

        mFeatureFlags = Mockito.mock(FeatureFlags.class);
        doReturn((Executor) Runnable::run).when(mContext).getMainExecutor();
        mBundle = mContextFixture.getCarrierConfigBundle();
        mSstHandler = new ServiceStateTrackerTestHandler(getClass().getSimpleName());
@@ -191,7 +196,7 @@ public class DisplayInfoControllerTest extends TelephonyTest {
        assertFalse(ss.getRoaming()); // home

        doReturn(mSst).when(mPhone).getServiceStateTracker();
        mDic = new DisplayInfoController(mPhone);
        mDic = new DisplayInfoController(mPhone, mFeatureFlags);
        mDic.updateTelephonyDisplayInfo();
        TelephonyDisplayInfo tdi = mDic.getTelephonyDisplayInfo();

@@ -211,7 +216,7 @@ public class DisplayInfoControllerTest extends TelephonyTest {
        assertFalse(ss.getRoaming()); // home

        doReturn(mSst).when(mPhone).getServiceStateTracker();
        mDic = new DisplayInfoController(mPhone);
        mDic = new DisplayInfoController(mPhone, mFeatureFlags);
        mDic.updateTelephonyDisplayInfo();
        TelephonyDisplayInfo tdi = mDic.getTelephonyDisplayInfo();

@@ -232,7 +237,7 @@ public class DisplayInfoControllerTest extends TelephonyTest {
        assertTrue(ss1.getRoaming()); // roam

        doReturn(mSst).when(mPhone).getServiceStateTracker();
        mDic = new DisplayInfoController(mPhone);
        mDic = new DisplayInfoController(mPhone, mFeatureFlags);
        mDic.updateTelephonyDisplayInfo();
        TelephonyDisplayInfo tdi = mDic.getTelephonyDisplayInfo();

@@ -254,7 +259,7 @@ public class DisplayInfoControllerTest extends TelephonyTest {
        assertFalse(ss.getRoaming()); // home

        doReturn(mSst).when(mPhone).getServiceStateTracker();
        mDic = new DisplayInfoController(mPhone);
        mDic = new DisplayInfoController(mPhone, mFeatureFlags);
        mDic.updateTelephonyDisplayInfo();
        TelephonyDisplayInfo tdi = mDic.getTelephonyDisplayInfo();

@@ -275,10 +280,32 @@ public class DisplayInfoControllerTest extends TelephonyTest {
        assertTrue(ss1.getRoaming()); // roam

        doReturn(mSst).when(mPhone).getServiceStateTracker();
        mDic = new DisplayInfoController(mPhone);
        mDic = new DisplayInfoController(mPhone, mFeatureFlags);
        mDic.updateTelephonyDisplayInfo();
        TelephonyDisplayInfo tdi = mDic.getTelephonyDisplayInfo();

        assertTrue(tdi.isRoaming());
    }

    @Test
    public void testIsRoamingOverride_HideRoamingIndicator() {
        doReturn(true).when(mPhone).isPhoneTypeGsm();
        mBundle.putStringArray(
                CarrierConfigManager.KEY_GSM_ROAMING_NETWORKS_STRING_ARRAY, new String[] {NUMERIC});
        mBundle.putBoolean(CarrierConfigManager.KEY_SHOW_ROAMING_INDICATOR_BOOL, false);
        doReturn(true).when(mFeatureFlags).hideRoamingIcon();
        sendCarrierConfigUpdate();

        changeRegState(NetworkRegistrationInfo.REGISTRATION_STATE_HOME);
        ServiceState ss1 = mSst.getServiceState();

        assertTrue(ss1.getRoaming()); // roam

        doReturn(mSst).when(mPhone).getServiceStateTracker();
        mDic = new DisplayInfoController(mPhone, mFeatureFlags);
        mDic.updateTelephonyDisplayInfo();
        TelephonyDisplayInfo tdi = mDic.getTelephonyDisplayInfo();

        assertFalse(tdi.isRoaming()); // display override
    }
}
Loading