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

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

Move override logic from SysUI to Telephony

Test: atest FrameworksTelephonyTests
Bug: none
Change-Id: Id96c4b76bd6a5e4321489dacb32dcacd462aef46
Merged-In: Id96c4b76bd6a5e4321489dacb32dcacd462aef46
parent 83cadde6
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -27,6 +27,7 @@ import android.telephony.Annotation.SrvccState;
import android.telephony.CallQuality;
import android.telephony.CellIdentity;
import android.telephony.CellInfo;
import android.telephony.DisplayInfo;
import android.telephony.PhoneCapability;
import android.telephony.PreciseCallState;
import android.telephony.PreciseDataConnectionState;
@@ -211,6 +212,12 @@ public class DefaultPhoneNotifier implements PhoneNotifier {
            sender.getPhoneId(), rawData);
    }

    @Override
    public void notifyDisplayInfoChanged(Phone sender, DisplayInfo displayInfo) {
        mTelephonyRegistryMgr.notifyDisplayInfoChanged(
                sender.getSubId(), sender.getPhoneId(), displayInfo);
    }

    @Override
    public void notifyPhoneCapabilityChanged(PhoneCapability capability) {
        mTelephonyRegistryMgr.notifyPhoneCapabilityChanged(capability);
+6 −0
Original line number Diff line number Diff line
@@ -47,6 +47,7 @@ import android.telephony.CarrierRestrictionRules;
import android.telephony.CellIdentity;
import android.telephony.CellInfo;
import android.telephony.ClientRequestStats;
import android.telephony.DisplayInfo;
import android.telephony.ImsiEncryptionInfo;
import android.telephony.PhoneStateListener;
import android.telephony.PhysicalChannelConfig;
@@ -2393,6 +2394,11 @@ public abstract class Phone extends Handler implements PhoneInternalInterface {
        mNotifier.notifyUserMobileDataStateChanged(this, state);
    }

    /** Send notification that display info has changed. */
    public void notifyDisplayInfoChanged(DisplayInfo displayInfo) {
        mNotifier.notifyDisplayInfoChanged(this, displayInfo);
    }

    public void notifySignalStrength() {
        mNotifier.notifySignalStrength(this);
    }
+4 −0
Original line number Diff line number Diff line
@@ -24,6 +24,7 @@ import android.telephony.Annotation.SrvccState;
import android.telephony.CallQuality;
import android.telephony.CellIdentity;
import android.telephony.CellInfo;
import android.telephony.DisplayInfo;
import android.telephony.PhoneCapability;
import android.telephony.PreciseDataConnectionState;
import android.telephony.emergency.EmergencyNumber;
@@ -88,6 +89,9 @@ public interface PhoneNotifier {
    /** Send a notification with an OEM hook payload */
    void notifyOemHookRawEventForSubscriber(Phone sender, byte[] rawData);

    /** Send a notification that the display info has changed */
    void notifyDisplayInfoChanged(Phone sender, DisplayInfo displayInfo);

    /** Send a notification that the phone capability has changed */
    void notifyPhoneCapabilityChanged(PhoneCapability capability);

+135 −2
Original line number Diff line number Diff line
@@ -74,6 +74,7 @@ import android.telephony.Annotation.NetworkType;
import android.telephony.CarrierConfigManager;
import android.telephony.CellLocation;
import android.telephony.DataFailCause;
import android.telephony.DisplayInfo;
import android.telephony.NetworkRegistrationInfo;
import android.telephony.PcoData;
import android.telephony.PreciseDataConnectionState;
@@ -133,6 +134,8 @@ import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReference;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * {@hide}
@@ -353,6 +356,11 @@ public class DcTracker extends Handler {
    /* Used to check whether phone was recently connected to 5G. */
    private boolean m5GWasConnected = false;

    /* Used to determine DisplayInfo to send to SysUI. */
    private DisplayInfo mDisplayInfo = null;
    private final Map<String, Integer> m5GIconMapping = new HashMap<>();
    private String mDataIconPattern = "";

    private final BroadcastReceiver mIntentReceiver = new BroadcastReceiver () {
        @Override
        public void onReceive(Context context, Intent intent) {
@@ -386,6 +394,20 @@ public class DcTracker extends Handler {
                if (configManager != null) {
                    PersistableBundle b = configManager.getConfigForSubId(mPhone.getSubId());
                    if (b != null) {
                        String nr5GIconConfiguration = b.getString(
                                CarrierConfigManager.KEY_5G_ICON_CONFIGURATION_STRING);
                        if (nr5GIconConfiguration == null) {
                            nr5GIconConfiguration =
                                    CarrierConfigManager.getDefaultConfig().getString(
                                    CarrierConfigManager.KEY_5G_ICON_CONFIGURATION_STRING);
                        }
                        process5GIconMapping(nr5GIconConfiguration);
                        mDataIconPattern = b.getString(
                                CarrierConfigManager.KEY_SHOW_CARRIER_DATA_ICON_PATTERN_STRING);
                        if (mDataIconPattern == null) {
                            mDataIconPattern = CarrierConfigManager.getDefaultConfig().getString(
                                    CarrierConfigManager.KEY_SHOW_CARRIER_DATA_ICON_PATTERN_STRING);
                        }
                        mHysteresisTimeMs = b.getLong(
                                CarrierConfigManager.KEY_5G_ICON_DISPLAY_GRACE_PERIOD_SEC_INT);
                        mWatchdogTimeMs = b.getLong(
@@ -398,6 +420,24 @@ public class DcTracker extends Handler {
        }
    };

    private void process5GIconMapping(String config) {
        m5GIconMapping.clear();
        for (String pair : config.trim().split(",")) {
            String[] kv = (pair.trim().toLowerCase()).split(":");
            if (kv.length != 2) {
                if (DBG) log("Invalid 5G icon configuration, config = " + pair);
                continue;
            }
            int value = DisplayInfo.OVERRIDE_NETWORK_TYPE_NONE;
            if (kv[1].equals("5g")) {
                value = DisplayInfo.OVERRIDE_NETWORK_TYPE_NR_NSA;
            } else if (kv[1].equals("5g_plus")) {
                value = DisplayInfo.OVERRIDE_NETWORK_TYPE_NR_NSA_MMWAVE;
            }
            m5GIconMapping.put(kv[0], value);
        }
    }

    private final Runnable mPollNetStat = new Runnable() {
        @Override
        public void run() {
@@ -929,6 +969,7 @@ public class DcTracker extends Handler {
        log("setActivity = " + activity);
        mActivity = activity;
        mPhone.notifyDataActivity();
        updateDisplayInfo();
    }

    public void requestNetwork(NetworkRequest networkRequest, @RequestNetworkType int type,
@@ -3831,7 +3872,11 @@ public class DcTracker extends Handler {
                onDataEnabledOverrideRulesChanged();
                break;
            case DctConstants.EVENT_SERVICE_STATE_CHANGED:
                reevaluateUnmeteredConnections();
                if (!reevaluateUnmeteredConnections()) {
                    // always update on ServiceState changed so MobileSignalController gets
                    // accurate display info
                    mPhone.notifyDisplayInfoChanged(mDisplayInfo);
                }
                break;
            case DctConstants.EVENT_5G_TIMER_HYSTERESIS:
                reevaluateUnmeteredConnections();
@@ -3999,7 +4044,7 @@ public class DcTracker extends Handler {
        }
    }

    private void reevaluateUnmeteredConnections() {
    private boolean reevaluateUnmeteredConnections() {
        if (isNetworkTypeUnmetered(NETWORK_TYPE_NR)) {
            if (mPhone.getServiceState().getNrState()
                    == NetworkRegistrationInfo.NR_STATE_CONNECTED) {
@@ -4036,6 +4081,7 @@ public class DcTracker extends Handler {
                    mTelephonyManager.getNetworkType(mPhone.getSubId())));
            m5GWasConnected = false;
        }
        return updateDisplayInfo();
    }

    private void setDataConnectionUnmetered(boolean isUnmetered) {
@@ -4079,6 +4125,92 @@ public class DcTracker extends Handler {
                || plan.getDataLimitBehavior() == SubscriptionPlan.LIMIT_BEHAVIOR_THROTTLED);
    }

    private boolean updateDisplayInfo() {
        int displayNetworkType = DisplayInfo.OVERRIDE_NETWORK_TYPE_NONE;
        int dataNetworkType = mPhone.getServiceState().getDataNetworkType();
        if (mPhone.getServiceState().getNrState() != NetworkRegistrationInfo.NR_STATE_NONE
                || dataNetworkType == TelephonyManager.NETWORK_TYPE_NR || mHysteresis) {
            // process NR display network type
            displayNetworkType = getNrDisplayType();
            if (displayNetworkType == DisplayInfo.OVERRIDE_NETWORK_TYPE_NONE) {
                // use LTE values if 5G values aren't defined
                displayNetworkType = getLteDisplayType();
            }
        } else if (dataNetworkType == TelephonyManager.NETWORK_TYPE_LTE
                || dataNetworkType == TelephonyManager.NETWORK_TYPE_LTE_CA) {
            // process LTE display network type
            displayNetworkType = getLteDisplayType();
        }
        DisplayInfo displayInfo = new DisplayInfo(dataNetworkType, displayNetworkType);
        if (!displayInfo.equals(mDisplayInfo)) {
            mDisplayInfo = displayInfo;
            mPhone.notifyDisplayInfoChanged(displayInfo);
            return true;
        }
        return false;
    }

    private int getNrDisplayType() {
        // icon display keys in order of priority
        List<String> keys = new ArrayList<>();
        switch (mPhone.getServiceState().getNrState()) {
            case NetworkRegistrationInfo.NR_STATE_CONNECTED:
                if (mPhone.getServiceState().getNrFrequencyRange()
                        == ServiceState.FREQUENCY_RANGE_MMWAVE) {
                    keys.add("connected_mmwave");
                }
                keys.add("connected");
                break;
            case NetworkRegistrationInfo.NR_STATE_NOT_RESTRICTED:
                if (mActivity == DctConstants.Activity.DORMANT) {
                    keys.add("not_restricted_rrc_idle");
                } else {
                    keys.add("not_restricted_rrc_con");
                }
                break;
            case NetworkRegistrationInfo.NR_STATE_RESTRICTED:
                keys.add("restricted");
                break;
        }

        for (String key : keys) {
            if (m5GIconMapping.containsKey(key)
                    && m5GIconMapping.get(key) != DisplayInfo.OVERRIDE_NETWORK_TYPE_NONE) {
                return m5GIconMapping.get(key);
            }
        }
        return DisplayInfo.OVERRIDE_NETWORK_TYPE_NONE;
    }

    private int getLteDisplayType() {
        int value = DisplayInfo.OVERRIDE_NETWORK_TYPE_NONE;
        if (mPhone.getServiceState().getDataNetworkType() == TelephonyManager.NETWORK_TYPE_LTE_CA
                || mPhone.getServiceState().isUsingCarrierAggregation()) {
            value = DisplayInfo.OVERRIDE_NETWORK_TYPE_LTE_CA;
        }
        if (isLteEnhancedAvailable()) {
            value = DisplayInfo.OVERRIDE_NETWORK_TYPE_LTE_ADVANCED_PRO;
        }
        return value;
    }

    private boolean isLteEnhancedAvailable() {
        if (TextUtils.isEmpty(mDataIconPattern)) {
            return false;
        }
        Pattern stringPattern = Pattern.compile(mDataIconPattern);
        for (String opName : new String[] {mPhone.getServiceState().getOperatorAlphaLongRaw(),
                mPhone.getServiceState().getOperatorAlphaShortRaw()}) {
            if (!TextUtils.isEmpty(opName)) {
                Matcher matcher = stringPattern.matcher(opName);
                if (matcher.find()) {
                    return true;
                }
            }
        }
        return false;
    }

    protected void log(String s) {
        Rlog.d(mLogTag, s);
    }
@@ -4480,6 +4612,7 @@ public class DcTracker extends Handler {
                    log("updateDataActivity: newActivity=" + newActivity);
                mActivity = newActivity;
                mPhone.notifyDataActivity();
                updateDisplayInfo();
            }
        }
    }
+102 −0
Original line number Diff line number Diff line
@@ -65,6 +65,7 @@ import android.provider.Telephony;
import android.telephony.AccessNetworkConstants;
import android.telephony.AccessNetworkConstants.AccessNetworkType;
import android.telephony.CarrierConfigManager;
import android.telephony.DisplayInfo;
import android.telephony.NetworkRegistrationInfo;
import android.telephony.ServiceState;
import android.telephony.SignalStrength;
@@ -2017,6 +2018,107 @@ public class DcTrackerTest extends TelephonyTest {
        assertFalse(getWatchdogStatus());
    }

    @Test
    public void testGetNrDisplayType() {
        ArgumentCaptor<DisplayInfo> captor = ArgumentCaptor.forClass(DisplayInfo.class);
        doReturn(TelephonyManager.NETWORK_TYPE_LTE).when(mServiceState).getDataNetworkType();

        // set up 5G icon configuration
        mBundle.putString(CarrierConfigManager.KEY_5G_ICON_CONFIGURATION_STRING,
                "connected_mmwave:5G_Plus,connected:5G,not_restricted_rrc_idle:5G,"
                        + "not_restricted_rrc_con:5G");
        Intent intent = new Intent(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED);
        intent.putExtra(SubscriptionManager.EXTRA_SUBSCRIPTION_INDEX, mPhone.getSubId());
        mContext.sendBroadcast(intent);
        waitForLastHandlerAction(mDcTrackerTestHandler.getThreadHandler());

        // not NR
        doReturn(NetworkRegistrationInfo.NR_STATE_NONE).when(mServiceState).getNrState();
        mDct.sendMessage(mDct.obtainMessage(DctConstants.EVENT_SERVICE_STATE_CHANGED));
        waitForLastHandlerAction(mDcTrackerTestHandler.getThreadHandler());

        verify(mPhone, times(1)).notifyDisplayInfoChanged(captor.capture());
        assertEquals(DisplayInfo.OVERRIDE_NETWORK_TYPE_NONE,
                captor.getValue().getOverrideNetworkType());

        // NR NSA, restricted
        doReturn(NetworkRegistrationInfo.NR_STATE_RESTRICTED).when(mServiceState).getNrState();
        mDct.sendMessage(mDct.obtainMessage(DctConstants.EVENT_SERVICE_STATE_CHANGED));
        waitForLastHandlerAction(mDcTrackerTestHandler.getThreadHandler());

        verify(mPhone, times(2)).notifyDisplayInfoChanged(captor.capture());
        assertEquals(DisplayInfo.OVERRIDE_NETWORK_TYPE_NONE,
                captor.getValue().getOverrideNetworkType());

        // NR NSA, not restricted
        doReturn(NetworkRegistrationInfo.NR_STATE_NOT_RESTRICTED).when(mServiceState).getNrState();
        mDct.sendMessage(mDct.obtainMessage(DctConstants.EVENT_SERVICE_STATE_CHANGED));
        waitForLastHandlerAction(mDcTrackerTestHandler.getThreadHandler());

        verify(mPhone, times(3)).notifyDisplayInfoChanged(captor.capture());
        assertEquals(DisplayInfo.OVERRIDE_NETWORK_TYPE_NR_NSA,
                captor.getValue().getOverrideNetworkType());

        doReturn(NetworkRegistrationInfo.NR_STATE_CONNECTED).when(mServiceState).getNrState();

        // NR NSA, sub 6 frequency
        doReturn(ServiceState.FREQUENCY_RANGE_UNKNOWN).when(mServiceState).getNrFrequencyRange();
        mDct.sendMessage(mDct.obtainMessage(DctConstants.EVENT_SERVICE_STATE_CHANGED));
        waitForLastHandlerAction(mDcTrackerTestHandler.getThreadHandler());

        verify(mPhone, times(4)).notifyDisplayInfoChanged(captor.capture());
        assertEquals(DisplayInfo.OVERRIDE_NETWORK_TYPE_NR_NSA,
                captor.getValue().getOverrideNetworkType());

        // NR NSA, millimeter wave frequency
        doReturn(ServiceState.FREQUENCY_RANGE_MMWAVE).when(mServiceState).getNrFrequencyRange();
        mDct.sendMessage(mDct.obtainMessage(DctConstants.EVENT_SERVICE_STATE_CHANGED));
        waitForLastHandlerAction(mDcTrackerTestHandler.getThreadHandler());

        verify(mPhone, times(5)).notifyDisplayInfoChanged(captor.capture());
        assertEquals(DisplayInfo.OVERRIDE_NETWORK_TYPE_NR_NSA_MMWAVE,
                captor.getValue().getOverrideNetworkType());
    }

    @Test
    public void testGetLteDisplayType() {
        ArgumentCaptor<DisplayInfo> captor = ArgumentCaptor.forClass(DisplayInfo.class);

        // normal LTE
        doReturn(TelephonyManager.NETWORK_TYPE_LTE).when(mServiceState).getDataNetworkType();
        mDct.sendMessage(mDct.obtainMessage(DctConstants.EVENT_SERVICE_STATE_CHANGED));
        waitForLastHandlerAction(mDcTrackerTestHandler.getThreadHandler());

        verify(mPhone, times(1)).notifyDisplayInfoChanged(captor.capture());
        assertEquals(DisplayInfo.OVERRIDE_NETWORK_TYPE_NONE,
                captor.getValue().getOverrideNetworkType());

        // LTE CA
        doReturn(TelephonyManager.NETWORK_TYPE_LTE_CA).when(mServiceState).getDataNetworkType();
        mDct.sendMessage(mDct.obtainMessage(DctConstants.EVENT_SERVICE_STATE_CHANGED));
        waitForLastHandlerAction(mDcTrackerTestHandler.getThreadHandler());

        verify(mPhone, times(2)).notifyDisplayInfoChanged(captor.capture());
        assertEquals(DisplayInfo.OVERRIDE_NETWORK_TYPE_LTE_CA,
                captor.getValue().getOverrideNetworkType());

        // TODO: LTE ADVANCED PRO
    }

    @Test
    public void testUpdateDisplayInfo() {
        ArgumentCaptor<DisplayInfo> captor = ArgumentCaptor.forClass(DisplayInfo.class);
        doReturn(TelephonyManager.NETWORK_TYPE_HSPAP).when(mServiceState).getDataNetworkType();

        mDct.sendMessage(mDct.obtainMessage(DctConstants.EVENT_SERVICE_STATE_CHANGED));
        waitForLastHandlerAction(mDcTrackerTestHandler.getThreadHandler());

        verify(mPhone, times(1)).notifyDisplayInfoChanged(captor.capture());
        DisplayInfo displayInfo = captor.getValue();
        assertEquals(TelephonyManager.NETWORK_TYPE_HSPAP, displayInfo.getNetworkType());
        assertEquals(DisplayInfo.OVERRIDE_NETWORK_TYPE_NONE, displayInfo.getOverrideNetworkType());
    }

    /**
     * Test if this is a path prefix match against the given Uri. Verifies that
     * scheme, authority, and atomic path segments match.