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

Commit 27706fe5 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Move override logic from SysUI to Telephony"

parents 30bf3306 f283614f
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -25,6 +25,7 @@ import android.telephony.BarringInfo;
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;
@@ -200,6 +201,12 @@ public class DefaultPhoneNotifier implements PhoneNotifier {
            sender.getSubId(), sender.getPhoneId(), state);
    }

    @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
@@ -48,6 +48,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;
@@ -2396,6 +2397,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
@@ -25,6 +25,7 @@ import android.telephony.BarringInfo;
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;
@@ -86,6 +87,9 @@ public interface PhoneNotifier {
    /** Send a notification that the users mobile data setting has changed */
    void notifyUserMobileDataStateChanged(Phone sender, boolean state);

    /** 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
@@ -72,6 +72,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;
@@ -134,6 +135,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;
import java.util.stream.IntStream;

/**
@@ -335,6 +338,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) {
@@ -368,6 +376,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(
@@ -380,6 +402,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() {
@@ -911,6 +951,7 @@ public class DcTracker extends Handler {
        log("setActivity = " + activity);
        mActivity = activity;
        mPhone.notifyDataActivity();
        updateDisplayInfo();
    }

    public void requestNetwork(NetworkRequest networkRequest, @RequestNetworkType int type,
@@ -3777,7 +3818,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();
@@ -3945,7 +3990,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) {
@@ -3982,6 +4027,7 @@ public class DcTracker extends Handler {
                    mTelephonyManager.getNetworkType(mPhone.getSubId())));
            m5GWasConnected = false;
        }
        return updateDisplayInfo();
    }

    private void setDataConnectionUnmetered(boolean isUnmetered) {
@@ -4024,6 +4070,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;
    }

    private void log(String s) {
        Rlog.d(mLogTag, s);
    }
@@ -4425,6 +4557,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;
@@ -2023,6 +2024,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.