Loading src/java/com/android/internal/telephony/DefaultPhoneNotifier.java +7 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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); Loading src/java/com/android/internal/telephony/Phone.java +6 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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); } Loading src/java/com/android/internal/telephony/PhoneNotifier.java +4 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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); Loading src/java/com/android/internal/telephony/dataconnection/DcTracker.java +135 −2 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; /** Loading Loading @@ -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) { Loading Loading @@ -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( Loading @@ -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() { Loading Loading @@ -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, Loading Loading @@ -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(); Loading Loading @@ -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) { Loading Loading @@ -3982,6 +4027,7 @@ public class DcTracker extends Handler { mTelephonyManager.getNetworkType(mPhone.getSubId()))); m5GWasConnected = false; } return updateDisplayInfo(); } private void setDataConnectionUnmetered(boolean isUnmetered) { Loading Loading @@ -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); } Loading Loading @@ -4425,6 +4557,7 @@ public class DcTracker extends Handler { log("updateDataActivity: newActivity=" + newActivity); mActivity = newActivity; mPhone.notifyDataActivity(); updateDisplayInfo(); } } } Loading tests/telephonytests/src/com/android/internal/telephony/dataconnection/DcTrackerTest.java +102 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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. Loading Loading
src/java/com/android/internal/telephony/DefaultPhoneNotifier.java +7 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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); Loading
src/java/com/android/internal/telephony/Phone.java +6 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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); } Loading
src/java/com/android/internal/telephony/PhoneNotifier.java +4 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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); Loading
src/java/com/android/internal/telephony/dataconnection/DcTracker.java +135 −2 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; /** Loading Loading @@ -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) { Loading Loading @@ -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( Loading @@ -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() { Loading Loading @@ -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, Loading Loading @@ -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(); Loading Loading @@ -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) { Loading Loading @@ -3982,6 +4027,7 @@ public class DcTracker extends Handler { mTelephonyManager.getNetworkType(mPhone.getSubId()))); m5GWasConnected = false; } return updateDisplayInfo(); } private void setDataConnectionUnmetered(boolean isUnmetered) { Loading Loading @@ -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); } Loading Loading @@ -4425,6 +4557,7 @@ public class DcTracker extends Handler { log("updateDataActivity: newActivity=" + newActivity); mActivity = newActivity; mPhone.notifyDataActivity(); updateDisplayInfo(); } } } Loading
tests/telephonytests/src/com/android/internal/telephony/dataconnection/DcTrackerTest.java +102 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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. Loading