Loading src/java/com/android/internal/telephony/NetworkTypeController.java +16 −4 Original line number Diff line number Diff line Loading @@ -23,6 +23,7 @@ import android.content.IntentFilter; import android.os.AsyncResult; import android.os.Message; import android.os.PersistableBundle; import android.provider.Settings; import android.telephony.AccessNetworkConstants; import android.telephony.Annotation; import android.telephony.CarrierConfigManager; Loading Loading @@ -87,13 +88,14 @@ public class NetworkTypeController extends StateMachine { private static final int EVENT_SECONDARY_TIMER_EXPIRED = 9; private static final int EVENT_RADIO_OFF_OR_UNAVAILABLE = 10; private static final int EVENT_DATA_CONNECTION_STATE_CHANGED = 11; private static final int EVENT_PREFERRED_NETWORK_MODE_CHANGED = 12; // events that don't reset the timer private static final int[] ALL_EVENTS = { EVENT_DATA_RAT_CHANGED, EVENT_NR_STATE_CHANGED, EVENT_NR_FREQUENCY_CHANGED, EVENT_DATA_ACTIVITY_CHANGED, EVENT_PHYSICAL_CHANNEL_CONFIG_NOTIF_CHANGED, EVENT_CARRIER_CONFIG_CHANGED, EVENT_PRIMARY_TIMER_EXPIRED, EVENT_SECONDARY_TIMER_EXPIRED, EVENT_DATA_CONNECTION_STATE_CHANGED}; EVENT_PHYSICAL_CHANNEL_CONFIG_NOTIF_CHANGED, EVENT_PRIMARY_TIMER_EXPIRED, EVENT_SECONDARY_TIMER_EXPIRED, EVENT_DATA_CONNECTION_STATE_CHANGED }; private static final String[] sEvents = new String[EVENT_DATA_CONNECTION_STATE_CHANGED + 1]; private static final String[] sEvents = new String[EVENT_PREFERRED_NETWORK_MODE_CHANGED + 1]; static { sEvents[EVENT_UPDATE] = "EVENT_UPDATE"; sEvents[EVENT_QUIT] = "EVENT_QUIT"; Loading @@ -108,11 +110,13 @@ public class NetworkTypeController extends StateMachine { sEvents[EVENT_SECONDARY_TIMER_EXPIRED] = "EVENT_SECONDARY_TIMER_EXPIRED"; sEvents[EVENT_RADIO_OFF_OR_UNAVAILABLE] = "EVENT_RADIO_OFF_OR_UNAVAILABLE"; sEvents[EVENT_DATA_CONNECTION_STATE_CHANGED] = "EVENT_DATA_CONNECTION_STATE_CHANGED"; sEvents[EVENT_PREFERRED_NETWORK_MODE_CHANGED] = "EVENT_PREFERRED_NETWORK_MODE_CHANGED"; } private final Phone mPhone; private final DisplayInfoController mDisplayInfoController; private final TelephonyManager mTelephonyManager; private final SettingsObserver mSettingsObserver; private final BroadcastReceiver mIntentReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { Loading Loading @@ -158,6 +162,7 @@ public class NetworkTypeController extends StateMachine { mDisplayInfoController = displayInfoController; mTelephonyManager = TelephonyManager.from(phone.getContext()) .createForSubscriptionId(phone.getSubId()); mSettingsObserver = new SettingsObserver(mPhone.getContext(), getHandler()); mOverrideNetworkType = TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NONE; mIsPhysicalChannelConfigOn = true; addState(mDefaultState); Loading Loading @@ -198,6 +203,8 @@ public class NetworkTypeController extends StateMachine { mTelephonyManager.listen(mPhoneStateListener, PhoneStateListener.LISTEN_DATA_ACTIVITY | PhoneStateListener.LISTEN_DATA_CONNECTION_STATE); } mSettingsObserver.observe(Settings.Global.getUriFor(Settings.Global.PREFERRED_NETWORK_MODE), EVENT_PREFERRED_NETWORK_MODE_CHANGED); } private void unRegisterForAllEvents() { Loading @@ -211,6 +218,7 @@ public class NetworkTypeController extends StateMachine { if (mTelephonyManager != null) { mTelephonyManager.listen(mPhoneStateListener, 0); } mSettingsObserver.unobserve(); } private void parseCarrierConfigs() { Loading Loading @@ -497,6 +505,10 @@ public class NetworkTypeController extends StateMachine { transitionToCurrentState(); } break; case EVENT_PREFERRED_NETWORK_MODE_CHANGED: resetAllTimers(); transitionToCurrentState(); break; default: throw new RuntimeException("Received invalid event: " + msg.what); } Loading src/java/com/android/internal/telephony/Phone.java +85 −18 Original line number Diff line number Diff line Loading @@ -95,9 +95,11 @@ import java.io.FileDescriptor; import java.io.PrintWriter; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Locale; import java.util.Map; import java.util.Set; import java.util.concurrent.atomic.AtomicReference; import java.util.function.Consumer; Loading Loading @@ -419,7 +421,7 @@ public abstract class Phone extends Handler implements PhoneInternalInterface { protected SimulatedRadioControl mSimulatedRadioControl; private boolean mUnitTestMode; private Map<Integer, Long> mAllowedNetworkTypesForReasons = new HashMap<>(); private final CarrierPrivilegesTracker mCarrierPrivilegesTracker; protected VoiceCallSessionStats mVoiceCallSessionStats; Loading Loading @@ -1715,6 +1717,23 @@ public abstract class Phone extends Handler implements PhoneInternalInterface { } } private @TelephonyManager.NetworkTypeBitMask long getAllowedNetworkTypes() { long allowedNetworkTypes = TelephonyManager.getAllNetworkTypesBitmask(); if (SubscriptionController.getInstance() != null) { String result = SubscriptionController.getInstance().getSubscriptionProperty( getSubId(), SubscriptionManager.ALLOWED_NETWORK_TYPES); if (result != null) { try { allowedNetworkTypes = Long.parseLong(result); } catch (NumberFormatException err) { Rlog.e(LOG_TAG, "allowedNetworkTypes NumberFormat exception"); } } } return allowedNetworkTypes; } /** * Set the properties by matching the carrier string in * a string-array resource Loading Loading @@ -2032,6 +2051,16 @@ public abstract class Phone extends Handler implements PhoneInternalInterface { editor.apply(); } private @TelephonyManager.NetworkTypeBitMask long getAllowedNetworkTypesForAllReasons() { long allowedNetworkTypes = TelephonyManager.getAllNetworkTypesBitmask(); synchronized (mAllowedNetworkTypesForReasons) { for (long networkTypes: mAllowedNetworkTypesForReasons.values()) { allowedNetworkTypes = allowedNetworkTypes & networkTypes; } } return allowedNetworkTypes; } public void setVoiceCallForwardingFlag(int line, boolean enable, String number) { setCallForwardingIndicatorInSharedPref(enable); IccRecords r = getIccRecords(); Loading Loading @@ -2146,6 +2175,55 @@ public abstract class Phone extends Handler implements PhoneInternalInterface { mCi.setCdmaSubscriptionSource(cdmaSubscriptionType, response); } /** * Get the effective allowed network types on the device. * @return effective network type */ public @TelephonyManager.NetworkTypeBitMask long getEffectiveAllowedNetworkTypes() { long allowedNetworkTypes = getAllowedNetworkTypes(); return allowedNetworkTypes & getAllowedNetworkTypesForAllReasons(); } /** * Get the allowed network types for a certain reason. * @param reason reason to configure allowed network types * @return the allowed network types. */ public @TelephonyManager.NetworkTypeBitMask long getAllowedNetworkTypes( @TelephonyManager.AllowedNetworkTypesReason int reason) { synchronized (mAllowedNetworkTypesForReasons) { switch (reason) { case TelephonyManager.ALLOWED_NETWORK_TYPES_REASON_POWER: return mAllowedNetworkTypesForReasons.getOrDefault( TelephonyManager.ALLOWED_NETWORK_TYPES_REASON_POWER, TelephonyManager.getAllNetworkTypesBitmask()); default: Rlog.e(LOG_TAG, "Invalid allowed network type reason: " + reason); return TelephonyManager.getAllNetworkTypesBitmask(); } } } /** * Requests to set the allowed network types for a specific reason * @param reason reason to configure allowed network type * @param networkTypes one of the network types */ public void setAllowedNetworkTypes(@TelephonyManager.AllowedNetworkTypesReason int reason, @TelephonyManager.NetworkTypeBitMask long networkTypes) { synchronized (mAllowedNetworkTypesForReasons) { switch (reason) { case TelephonyManager.ALLOWED_NETWORK_TYPES_REASON_POWER: mAllowedNetworkTypesForReasons.put( TelephonyManager.ALLOWED_NETWORK_TYPES_REASON_POWER, networkTypes); break; default: Rlog.e(LOG_TAG, "Invalid allowed network type reason: " + reason); break; } } } /** * Requests to set the preferred network type for searching and registering * (CS/PS domain, RAT, and operation mode) Loading @@ -2158,21 +2236,7 @@ public abstract class Phone extends Handler implements PhoneInternalInterface { int modemRaf = getRadioAccessFamily(); int rafFromType = RadioAccessFamily.getRafFromNetworkType(networkType); long allowedNetworkTypes = -1; if (SubscriptionController.getInstance() != null) { String result = SubscriptionController.getInstance().getSubscriptionProperty( getSubId(), SubscriptionManager.ALLOWED_NETWORK_TYPES); if (result != null) { try { allowedNetworkTypes = Long.parseLong(result); } catch (NumberFormatException err) { Rlog.d(LOG_TAG, "allowedNetworkTypes NumberFormat exception"); } } } long allowedNetworkTypes = getAllowedNetworkTypes(); if (modemRaf == RadioAccessFamily.RAF_UNKNOWN || rafFromType == RadioAccessFamily.RAF_UNKNOWN) { Rlog.d(LOG_TAG, "setPreferredNetworkType: Abort, unknown RAF: " Loading @@ -2187,13 +2251,16 @@ public abstract class Phone extends Handler implements PhoneInternalInterface { return; } int filteredRaf = (int) (rafFromType & modemRaf & allowedNetworkTypes); int filteredRaf = (int) (rafFromType & modemRaf & allowedNetworkTypes & getAllowedNetworkTypesForAllReasons()); int filteredType = RadioAccessFamily.getNetworkTypeFromRaf(filteredRaf); long powerAllowedNetworkTypes = getAllowedNetworkTypes( TelephonyManager.ALLOWED_NETWORK_TYPES_REASON_POWER); Rlog.d(LOG_TAG, "setPreferredNetworkType: networkType = " + networkType + " modemRaf = " + modemRaf + " rafFromType = " + rafFromType + " allowedNetworkTypes = " + allowedNetworkTypes + " power allowedNetworkTypes = " + powerAllowedNetworkTypes + " filteredType = " + filteredType); mCi.setPreferredNetworkType(filteredType, response); Loading src/java/com/android/internal/telephony/RIL.java +7 −38 Original line number Diff line number Diff line Loading @@ -4719,9 +4719,7 @@ public class RIL extends BaseCommands implements CommandsInterface { workSource = getDeafultWorkSourceIfInvalid(workSource); IRadio radioProxy = getRadioProxy(result); if (radioProxy == null) { return; } if (radioProxy == null) return; RILRequest rr = obtainRequest(RIL_REQUEST_SET_ALLOWED_CARRIERS, result, workSource); Loading Loading @@ -4801,9 +4799,7 @@ public class RIL extends BaseCommands implements CommandsInterface { workSource = getDeafultWorkSourceIfInvalid(workSource); IRadio radioProxy = getRadioProxy(result); if (radioProxy == null) { return; } if (radioProxy == null) return; RILRequest rr = obtainRequest(RIL_REQUEST_GET_ALLOWED_CARRIERS, result, workSource); Loading Loading @@ -5130,10 +5126,7 @@ public class RIL extends BaseCommands implements CommandsInterface { int contextId, KeepalivePacketData packetData, int intervalMillis, Message result) { checkNotNull(packetData, "KeepaliveRequest cannot be null."); IRadio radioProxy = getRadioProxy(result); if (radioProxy == null) { riljLoge("Radio Proxy object is null!"); return; } if (radioProxy == null) return; if (mRadioVersion.less(RADIO_HAL_VERSION_1_1)) { if (result != null) { Loading Loading @@ -5188,10 +5181,7 @@ public class RIL extends BaseCommands implements CommandsInterface { @Override public void stopNattKeepalive(int sessionHandle, Message result) { IRadio radioProxy = getRadioProxy(result); if (radioProxy == null) { Rlog.e(RIL.RILJ_LOG_TAG, "Radio Proxy object is null!"); return; } if (radioProxy == null) return; if (mRadioVersion.less(RADIO_HAL_VERSION_1_1)) { if (result != null) { Loading Loading @@ -5253,14 +5243,7 @@ public class RIL extends BaseCommands implements CommandsInterface { @Override public void enableUiccApplications(boolean enable, Message onCompleteMessage) { IRadio radioProxy = getRadioProxy(onCompleteMessage); if (radioProxy == null) { Rlog.e(RIL.RILJ_LOG_TAG, "Radio Proxy object is null!"); if (onCompleteMessage != null) { AsyncResult.forMessage(onCompleteMessage, null, CommandException.fromRilErrno(RADIO_NOT_AVAILABLE)); onCompleteMessage.sendToTarget(); } } if (radioProxy == null) return; if (mRadioVersion.less(RADIO_HAL_VERSION_1_5)) { if (onCompleteMessage != null) { Loading Loading @@ -5294,14 +5277,7 @@ public class RIL extends BaseCommands implements CommandsInterface { @Override public void areUiccApplicationsEnabled(Message onCompleteMessage) { IRadio radioProxy = getRadioProxy(onCompleteMessage); if (radioProxy == null) { Rlog.e(RIL.RILJ_LOG_TAG, "Radio Proxy object is null!"); if (onCompleteMessage != null) { AsyncResult.forMessage(onCompleteMessage, null, CommandException.fromRilErrno(RADIO_NOT_AVAILABLE)); onCompleteMessage.sendToTarget(); } } if (radioProxy == null) return; if (mRadioVersion.less(RADIO_HAL_VERSION_1_5)) { if (onCompleteMessage != null) { Loading Loading @@ -5389,14 +5365,7 @@ public class RIL extends BaseCommands implements CommandsInterface { @Override public void getBarringInfo(Message result) { IRadio radioProxy = getRadioProxy(result); if (radioProxy == null) { Rlog.e(RIL.RILJ_LOG_TAG, "Radio Proxy object is null!"); if (result != null) { AsyncResult.forMessage(result, null, CommandException.fromRilErrno(RADIO_NOT_AVAILABLE)); result.sendToTarget(); } } if (radioProxy == null) return; if (mRadioVersion.less(RADIO_HAL_VERSION_1_5)) { if (result != null) { Loading src/java/com/android/internal/telephony/RetryManager.java +8 −3 Original line number Diff line number Diff line Loading @@ -498,9 +498,10 @@ public class RetryManager { // If the modem had suggested a retry delay, we should retry the current APN again // (up to MAX_SAME_APN_RETRY times) instead of getting the next APN setting from // our own list. if (mModemSuggestedDelay != NO_SUGGESTED_RETRY_DELAY && mSameApnRetryCount < MAX_SAME_APN_RETRY) { // our own list. If the APN waiting list has been reset before a setup data responses // arrive (i.e. mCurrentApnIndex=-1), then ignore the modem suggested retry. if (mCurrentApnIndex != -1 && mModemSuggestedDelay != NO_SUGGESTED_RETRY_DELAY && mSameApnRetryCount < MAX_SAME_APN_RETRY) { mSameApnRetryCount++; return mWaitingApns.get(mCurrentApnIndex); } Loading Loading @@ -665,6 +666,10 @@ public class RetryManager { * @param delay The delay in milliseconds */ public void setModemSuggestedDelay(long delay) { if (mCurrentApnIndex == -1) { log("Waiting APN list has been reset. Ignore the value from modem."); return; } mModemSuggestedDelay = delay; } Loading tests/telephonytests/src/com/android/internal/telephony/NetworkTypeControllerTest.java +56 −1 Original line number Diff line number Diff line Loading @@ -54,6 +54,9 @@ public class NetworkTypeControllerTest extends TelephonyTest { private static final int EVENT_CARRIER_CONFIG_CHANGED = 7; private static final int EVENT_PRIMARY_TIMER_EXPIRED = 8; private static final int EVENT_SECONDARY_TIMER_EXPIRED = 9; private static final int EVENT_RADIO_OFF_OR_UNAVAILABLE = 10; private static final int EVENT_DATA_CONNECTION_STATE_CHANGED = 11; private static final int EVENT_PREFERRED_NETWORK_MODE_CHANGED = 12; private NetworkTypeController mNetworkTypeController; private PersistableBundle mBundle; Loading Loading @@ -88,7 +91,7 @@ public class NetworkTypeControllerTest extends TelephonyTest { broadcastCarrierConfigs(); replaceInstance(Handler.class, "mLooper", mDisplayInfoController, Looper.myLooper()); doReturn((int) TelephonyManager.NETWORK_MODE_NR_LTE_CDMA_EVDO_GSM_WCDMA).when(mPhone) doReturn(TelephonyManager.NETWORK_MODE_NR_LTE_CDMA_EVDO_GSM_WCDMA).when(mPhone) .getCachedPreferredNetworkType(); mNetworkTypeController = new NetworkTypeController(mPhone, mDisplayInfoController); } Loading Loading @@ -316,6 +319,58 @@ public class NetworkTypeControllerTest extends TelephonyTest { mNetworkTypeController.getOverrideNetworkType()); } @Test public void testEventRadioOffOrUnavailable() throws Exception { testTransitionToCurrentStateNrConnected(); assertEquals(TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_NSA, mNetworkTypeController.getOverrideNetworkType()); doReturn(NetworkRegistrationInfo.NR_STATE_NONE).when(mServiceState).getNrState(); doReturn(TelephonyManager.NETWORK_TYPE_UNKNOWN).when(mServiceState).getDataNetworkType(); mNetworkTypeController.sendMessage(EVENT_RADIO_OFF_OR_UNAVAILABLE); processAllMessages(); assertEquals(TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NONE, mNetworkTypeController.getOverrideNetworkType()); } @Test public void testEventDataConnectionStateChanged() throws Exception { testTransitionToCurrentStateNrConnected(); assertEquals(TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_NSA, mNetworkTypeController.getOverrideNetworkType()); // TelephonyDisplayInfo can't be mocked since it's final, so create a new one for testing TelephonyDisplayInfo telephonyDisplayInfo = new TelephonyDisplayInfo( TelephonyManager.NETWORK_TYPE_UNKNOWN, TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NONE); doReturn(NetworkRegistrationInfo.NR_STATE_NONE).when(mServiceState).getNrState(); doReturn(telephonyDisplayInfo).when(mDisplayInfoController).getTelephonyDisplayInfo(); doReturn(TelephonyManager.NETWORK_TYPE_HSPAP).when(mServiceState).getDataNetworkType(); mNetworkTypeController.sendMessage(EVENT_DATA_CONNECTION_STATE_CHANGED); processAllMessages(); assertEquals(TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NONE, mNetworkTypeController.getOverrideNetworkType()); } @Test public void testEventPreferredNetworkModeChanged() throws Exception { testTransitionToCurrentStateNrConnected(); assertEquals(TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_NSA, mNetworkTypeController.getOverrideNetworkType()); // remove NR from preferred network types doReturn(TelephonyManager.NETWORK_MODE_LTE_CDMA_EVDO_GSM_WCDMA).when(mPhone) .getCachedPreferredNetworkType(); mNetworkTypeController.sendMessage(EVENT_PREFERRED_NETWORK_MODE_CHANGED); processAllMessages(); assertEquals(TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NONE, mNetworkTypeController.getOverrideNetworkType()); } @Test public void testPrimaryTimerExpire() throws Exception { doReturn(NetworkRegistrationInfo.NR_STATE_CONNECTED).when(mServiceState).getNrState(); Loading Loading
src/java/com/android/internal/telephony/NetworkTypeController.java +16 −4 Original line number Diff line number Diff line Loading @@ -23,6 +23,7 @@ import android.content.IntentFilter; import android.os.AsyncResult; import android.os.Message; import android.os.PersistableBundle; import android.provider.Settings; import android.telephony.AccessNetworkConstants; import android.telephony.Annotation; import android.telephony.CarrierConfigManager; Loading Loading @@ -87,13 +88,14 @@ public class NetworkTypeController extends StateMachine { private static final int EVENT_SECONDARY_TIMER_EXPIRED = 9; private static final int EVENT_RADIO_OFF_OR_UNAVAILABLE = 10; private static final int EVENT_DATA_CONNECTION_STATE_CHANGED = 11; private static final int EVENT_PREFERRED_NETWORK_MODE_CHANGED = 12; // events that don't reset the timer private static final int[] ALL_EVENTS = { EVENT_DATA_RAT_CHANGED, EVENT_NR_STATE_CHANGED, EVENT_NR_FREQUENCY_CHANGED, EVENT_DATA_ACTIVITY_CHANGED, EVENT_PHYSICAL_CHANNEL_CONFIG_NOTIF_CHANGED, EVENT_CARRIER_CONFIG_CHANGED, EVENT_PRIMARY_TIMER_EXPIRED, EVENT_SECONDARY_TIMER_EXPIRED, EVENT_DATA_CONNECTION_STATE_CHANGED}; EVENT_PHYSICAL_CHANNEL_CONFIG_NOTIF_CHANGED, EVENT_PRIMARY_TIMER_EXPIRED, EVENT_SECONDARY_TIMER_EXPIRED, EVENT_DATA_CONNECTION_STATE_CHANGED }; private static final String[] sEvents = new String[EVENT_DATA_CONNECTION_STATE_CHANGED + 1]; private static final String[] sEvents = new String[EVENT_PREFERRED_NETWORK_MODE_CHANGED + 1]; static { sEvents[EVENT_UPDATE] = "EVENT_UPDATE"; sEvents[EVENT_QUIT] = "EVENT_QUIT"; Loading @@ -108,11 +110,13 @@ public class NetworkTypeController extends StateMachine { sEvents[EVENT_SECONDARY_TIMER_EXPIRED] = "EVENT_SECONDARY_TIMER_EXPIRED"; sEvents[EVENT_RADIO_OFF_OR_UNAVAILABLE] = "EVENT_RADIO_OFF_OR_UNAVAILABLE"; sEvents[EVENT_DATA_CONNECTION_STATE_CHANGED] = "EVENT_DATA_CONNECTION_STATE_CHANGED"; sEvents[EVENT_PREFERRED_NETWORK_MODE_CHANGED] = "EVENT_PREFERRED_NETWORK_MODE_CHANGED"; } private final Phone mPhone; private final DisplayInfoController mDisplayInfoController; private final TelephonyManager mTelephonyManager; private final SettingsObserver mSettingsObserver; private final BroadcastReceiver mIntentReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { Loading Loading @@ -158,6 +162,7 @@ public class NetworkTypeController extends StateMachine { mDisplayInfoController = displayInfoController; mTelephonyManager = TelephonyManager.from(phone.getContext()) .createForSubscriptionId(phone.getSubId()); mSettingsObserver = new SettingsObserver(mPhone.getContext(), getHandler()); mOverrideNetworkType = TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NONE; mIsPhysicalChannelConfigOn = true; addState(mDefaultState); Loading Loading @@ -198,6 +203,8 @@ public class NetworkTypeController extends StateMachine { mTelephonyManager.listen(mPhoneStateListener, PhoneStateListener.LISTEN_DATA_ACTIVITY | PhoneStateListener.LISTEN_DATA_CONNECTION_STATE); } mSettingsObserver.observe(Settings.Global.getUriFor(Settings.Global.PREFERRED_NETWORK_MODE), EVENT_PREFERRED_NETWORK_MODE_CHANGED); } private void unRegisterForAllEvents() { Loading @@ -211,6 +218,7 @@ public class NetworkTypeController extends StateMachine { if (mTelephonyManager != null) { mTelephonyManager.listen(mPhoneStateListener, 0); } mSettingsObserver.unobserve(); } private void parseCarrierConfigs() { Loading Loading @@ -497,6 +505,10 @@ public class NetworkTypeController extends StateMachine { transitionToCurrentState(); } break; case EVENT_PREFERRED_NETWORK_MODE_CHANGED: resetAllTimers(); transitionToCurrentState(); break; default: throw new RuntimeException("Received invalid event: " + msg.what); } Loading
src/java/com/android/internal/telephony/Phone.java +85 −18 Original line number Diff line number Diff line Loading @@ -95,9 +95,11 @@ import java.io.FileDescriptor; import java.io.PrintWriter; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Locale; import java.util.Map; import java.util.Set; import java.util.concurrent.atomic.AtomicReference; import java.util.function.Consumer; Loading Loading @@ -419,7 +421,7 @@ public abstract class Phone extends Handler implements PhoneInternalInterface { protected SimulatedRadioControl mSimulatedRadioControl; private boolean mUnitTestMode; private Map<Integer, Long> mAllowedNetworkTypesForReasons = new HashMap<>(); private final CarrierPrivilegesTracker mCarrierPrivilegesTracker; protected VoiceCallSessionStats mVoiceCallSessionStats; Loading Loading @@ -1715,6 +1717,23 @@ public abstract class Phone extends Handler implements PhoneInternalInterface { } } private @TelephonyManager.NetworkTypeBitMask long getAllowedNetworkTypes() { long allowedNetworkTypes = TelephonyManager.getAllNetworkTypesBitmask(); if (SubscriptionController.getInstance() != null) { String result = SubscriptionController.getInstance().getSubscriptionProperty( getSubId(), SubscriptionManager.ALLOWED_NETWORK_TYPES); if (result != null) { try { allowedNetworkTypes = Long.parseLong(result); } catch (NumberFormatException err) { Rlog.e(LOG_TAG, "allowedNetworkTypes NumberFormat exception"); } } } return allowedNetworkTypes; } /** * Set the properties by matching the carrier string in * a string-array resource Loading Loading @@ -2032,6 +2051,16 @@ public abstract class Phone extends Handler implements PhoneInternalInterface { editor.apply(); } private @TelephonyManager.NetworkTypeBitMask long getAllowedNetworkTypesForAllReasons() { long allowedNetworkTypes = TelephonyManager.getAllNetworkTypesBitmask(); synchronized (mAllowedNetworkTypesForReasons) { for (long networkTypes: mAllowedNetworkTypesForReasons.values()) { allowedNetworkTypes = allowedNetworkTypes & networkTypes; } } return allowedNetworkTypes; } public void setVoiceCallForwardingFlag(int line, boolean enable, String number) { setCallForwardingIndicatorInSharedPref(enable); IccRecords r = getIccRecords(); Loading Loading @@ -2146,6 +2175,55 @@ public abstract class Phone extends Handler implements PhoneInternalInterface { mCi.setCdmaSubscriptionSource(cdmaSubscriptionType, response); } /** * Get the effective allowed network types on the device. * @return effective network type */ public @TelephonyManager.NetworkTypeBitMask long getEffectiveAllowedNetworkTypes() { long allowedNetworkTypes = getAllowedNetworkTypes(); return allowedNetworkTypes & getAllowedNetworkTypesForAllReasons(); } /** * Get the allowed network types for a certain reason. * @param reason reason to configure allowed network types * @return the allowed network types. */ public @TelephonyManager.NetworkTypeBitMask long getAllowedNetworkTypes( @TelephonyManager.AllowedNetworkTypesReason int reason) { synchronized (mAllowedNetworkTypesForReasons) { switch (reason) { case TelephonyManager.ALLOWED_NETWORK_TYPES_REASON_POWER: return mAllowedNetworkTypesForReasons.getOrDefault( TelephonyManager.ALLOWED_NETWORK_TYPES_REASON_POWER, TelephonyManager.getAllNetworkTypesBitmask()); default: Rlog.e(LOG_TAG, "Invalid allowed network type reason: " + reason); return TelephonyManager.getAllNetworkTypesBitmask(); } } } /** * Requests to set the allowed network types for a specific reason * @param reason reason to configure allowed network type * @param networkTypes one of the network types */ public void setAllowedNetworkTypes(@TelephonyManager.AllowedNetworkTypesReason int reason, @TelephonyManager.NetworkTypeBitMask long networkTypes) { synchronized (mAllowedNetworkTypesForReasons) { switch (reason) { case TelephonyManager.ALLOWED_NETWORK_TYPES_REASON_POWER: mAllowedNetworkTypesForReasons.put( TelephonyManager.ALLOWED_NETWORK_TYPES_REASON_POWER, networkTypes); break; default: Rlog.e(LOG_TAG, "Invalid allowed network type reason: " + reason); break; } } } /** * Requests to set the preferred network type for searching and registering * (CS/PS domain, RAT, and operation mode) Loading @@ -2158,21 +2236,7 @@ public abstract class Phone extends Handler implements PhoneInternalInterface { int modemRaf = getRadioAccessFamily(); int rafFromType = RadioAccessFamily.getRafFromNetworkType(networkType); long allowedNetworkTypes = -1; if (SubscriptionController.getInstance() != null) { String result = SubscriptionController.getInstance().getSubscriptionProperty( getSubId(), SubscriptionManager.ALLOWED_NETWORK_TYPES); if (result != null) { try { allowedNetworkTypes = Long.parseLong(result); } catch (NumberFormatException err) { Rlog.d(LOG_TAG, "allowedNetworkTypes NumberFormat exception"); } } } long allowedNetworkTypes = getAllowedNetworkTypes(); if (modemRaf == RadioAccessFamily.RAF_UNKNOWN || rafFromType == RadioAccessFamily.RAF_UNKNOWN) { Rlog.d(LOG_TAG, "setPreferredNetworkType: Abort, unknown RAF: " Loading @@ -2187,13 +2251,16 @@ public abstract class Phone extends Handler implements PhoneInternalInterface { return; } int filteredRaf = (int) (rafFromType & modemRaf & allowedNetworkTypes); int filteredRaf = (int) (rafFromType & modemRaf & allowedNetworkTypes & getAllowedNetworkTypesForAllReasons()); int filteredType = RadioAccessFamily.getNetworkTypeFromRaf(filteredRaf); long powerAllowedNetworkTypes = getAllowedNetworkTypes( TelephonyManager.ALLOWED_NETWORK_TYPES_REASON_POWER); Rlog.d(LOG_TAG, "setPreferredNetworkType: networkType = " + networkType + " modemRaf = " + modemRaf + " rafFromType = " + rafFromType + " allowedNetworkTypes = " + allowedNetworkTypes + " power allowedNetworkTypes = " + powerAllowedNetworkTypes + " filteredType = " + filteredType); mCi.setPreferredNetworkType(filteredType, response); Loading
src/java/com/android/internal/telephony/RIL.java +7 −38 Original line number Diff line number Diff line Loading @@ -4719,9 +4719,7 @@ public class RIL extends BaseCommands implements CommandsInterface { workSource = getDeafultWorkSourceIfInvalid(workSource); IRadio radioProxy = getRadioProxy(result); if (radioProxy == null) { return; } if (radioProxy == null) return; RILRequest rr = obtainRequest(RIL_REQUEST_SET_ALLOWED_CARRIERS, result, workSource); Loading Loading @@ -4801,9 +4799,7 @@ public class RIL extends BaseCommands implements CommandsInterface { workSource = getDeafultWorkSourceIfInvalid(workSource); IRadio radioProxy = getRadioProxy(result); if (radioProxy == null) { return; } if (radioProxy == null) return; RILRequest rr = obtainRequest(RIL_REQUEST_GET_ALLOWED_CARRIERS, result, workSource); Loading Loading @@ -5130,10 +5126,7 @@ public class RIL extends BaseCommands implements CommandsInterface { int contextId, KeepalivePacketData packetData, int intervalMillis, Message result) { checkNotNull(packetData, "KeepaliveRequest cannot be null."); IRadio radioProxy = getRadioProxy(result); if (radioProxy == null) { riljLoge("Radio Proxy object is null!"); return; } if (radioProxy == null) return; if (mRadioVersion.less(RADIO_HAL_VERSION_1_1)) { if (result != null) { Loading Loading @@ -5188,10 +5181,7 @@ public class RIL extends BaseCommands implements CommandsInterface { @Override public void stopNattKeepalive(int sessionHandle, Message result) { IRadio radioProxy = getRadioProxy(result); if (radioProxy == null) { Rlog.e(RIL.RILJ_LOG_TAG, "Radio Proxy object is null!"); return; } if (radioProxy == null) return; if (mRadioVersion.less(RADIO_HAL_VERSION_1_1)) { if (result != null) { Loading Loading @@ -5253,14 +5243,7 @@ public class RIL extends BaseCommands implements CommandsInterface { @Override public void enableUiccApplications(boolean enable, Message onCompleteMessage) { IRadio radioProxy = getRadioProxy(onCompleteMessage); if (radioProxy == null) { Rlog.e(RIL.RILJ_LOG_TAG, "Radio Proxy object is null!"); if (onCompleteMessage != null) { AsyncResult.forMessage(onCompleteMessage, null, CommandException.fromRilErrno(RADIO_NOT_AVAILABLE)); onCompleteMessage.sendToTarget(); } } if (radioProxy == null) return; if (mRadioVersion.less(RADIO_HAL_VERSION_1_5)) { if (onCompleteMessage != null) { Loading Loading @@ -5294,14 +5277,7 @@ public class RIL extends BaseCommands implements CommandsInterface { @Override public void areUiccApplicationsEnabled(Message onCompleteMessage) { IRadio radioProxy = getRadioProxy(onCompleteMessage); if (radioProxy == null) { Rlog.e(RIL.RILJ_LOG_TAG, "Radio Proxy object is null!"); if (onCompleteMessage != null) { AsyncResult.forMessage(onCompleteMessage, null, CommandException.fromRilErrno(RADIO_NOT_AVAILABLE)); onCompleteMessage.sendToTarget(); } } if (radioProxy == null) return; if (mRadioVersion.less(RADIO_HAL_VERSION_1_5)) { if (onCompleteMessage != null) { Loading Loading @@ -5389,14 +5365,7 @@ public class RIL extends BaseCommands implements CommandsInterface { @Override public void getBarringInfo(Message result) { IRadio radioProxy = getRadioProxy(result); if (radioProxy == null) { Rlog.e(RIL.RILJ_LOG_TAG, "Radio Proxy object is null!"); if (result != null) { AsyncResult.forMessage(result, null, CommandException.fromRilErrno(RADIO_NOT_AVAILABLE)); result.sendToTarget(); } } if (radioProxy == null) return; if (mRadioVersion.less(RADIO_HAL_VERSION_1_5)) { if (result != null) { Loading
src/java/com/android/internal/telephony/RetryManager.java +8 −3 Original line number Diff line number Diff line Loading @@ -498,9 +498,10 @@ public class RetryManager { // If the modem had suggested a retry delay, we should retry the current APN again // (up to MAX_SAME_APN_RETRY times) instead of getting the next APN setting from // our own list. if (mModemSuggestedDelay != NO_SUGGESTED_RETRY_DELAY && mSameApnRetryCount < MAX_SAME_APN_RETRY) { // our own list. If the APN waiting list has been reset before a setup data responses // arrive (i.e. mCurrentApnIndex=-1), then ignore the modem suggested retry. if (mCurrentApnIndex != -1 && mModemSuggestedDelay != NO_SUGGESTED_RETRY_DELAY && mSameApnRetryCount < MAX_SAME_APN_RETRY) { mSameApnRetryCount++; return mWaitingApns.get(mCurrentApnIndex); } Loading Loading @@ -665,6 +666,10 @@ public class RetryManager { * @param delay The delay in milliseconds */ public void setModemSuggestedDelay(long delay) { if (mCurrentApnIndex == -1) { log("Waiting APN list has been reset. Ignore the value from modem."); return; } mModemSuggestedDelay = delay; } Loading
tests/telephonytests/src/com/android/internal/telephony/NetworkTypeControllerTest.java +56 −1 Original line number Diff line number Diff line Loading @@ -54,6 +54,9 @@ public class NetworkTypeControllerTest extends TelephonyTest { private static final int EVENT_CARRIER_CONFIG_CHANGED = 7; private static final int EVENT_PRIMARY_TIMER_EXPIRED = 8; private static final int EVENT_SECONDARY_TIMER_EXPIRED = 9; private static final int EVENT_RADIO_OFF_OR_UNAVAILABLE = 10; private static final int EVENT_DATA_CONNECTION_STATE_CHANGED = 11; private static final int EVENT_PREFERRED_NETWORK_MODE_CHANGED = 12; private NetworkTypeController mNetworkTypeController; private PersistableBundle mBundle; Loading Loading @@ -88,7 +91,7 @@ public class NetworkTypeControllerTest extends TelephonyTest { broadcastCarrierConfigs(); replaceInstance(Handler.class, "mLooper", mDisplayInfoController, Looper.myLooper()); doReturn((int) TelephonyManager.NETWORK_MODE_NR_LTE_CDMA_EVDO_GSM_WCDMA).when(mPhone) doReturn(TelephonyManager.NETWORK_MODE_NR_LTE_CDMA_EVDO_GSM_WCDMA).when(mPhone) .getCachedPreferredNetworkType(); mNetworkTypeController = new NetworkTypeController(mPhone, mDisplayInfoController); } Loading Loading @@ -316,6 +319,58 @@ public class NetworkTypeControllerTest extends TelephonyTest { mNetworkTypeController.getOverrideNetworkType()); } @Test public void testEventRadioOffOrUnavailable() throws Exception { testTransitionToCurrentStateNrConnected(); assertEquals(TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_NSA, mNetworkTypeController.getOverrideNetworkType()); doReturn(NetworkRegistrationInfo.NR_STATE_NONE).when(mServiceState).getNrState(); doReturn(TelephonyManager.NETWORK_TYPE_UNKNOWN).when(mServiceState).getDataNetworkType(); mNetworkTypeController.sendMessage(EVENT_RADIO_OFF_OR_UNAVAILABLE); processAllMessages(); assertEquals(TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NONE, mNetworkTypeController.getOverrideNetworkType()); } @Test public void testEventDataConnectionStateChanged() throws Exception { testTransitionToCurrentStateNrConnected(); assertEquals(TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_NSA, mNetworkTypeController.getOverrideNetworkType()); // TelephonyDisplayInfo can't be mocked since it's final, so create a new one for testing TelephonyDisplayInfo telephonyDisplayInfo = new TelephonyDisplayInfo( TelephonyManager.NETWORK_TYPE_UNKNOWN, TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NONE); doReturn(NetworkRegistrationInfo.NR_STATE_NONE).when(mServiceState).getNrState(); doReturn(telephonyDisplayInfo).when(mDisplayInfoController).getTelephonyDisplayInfo(); doReturn(TelephonyManager.NETWORK_TYPE_HSPAP).when(mServiceState).getDataNetworkType(); mNetworkTypeController.sendMessage(EVENT_DATA_CONNECTION_STATE_CHANGED); processAllMessages(); assertEquals(TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NONE, mNetworkTypeController.getOverrideNetworkType()); } @Test public void testEventPreferredNetworkModeChanged() throws Exception { testTransitionToCurrentStateNrConnected(); assertEquals(TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_NSA, mNetworkTypeController.getOverrideNetworkType()); // remove NR from preferred network types doReturn(TelephonyManager.NETWORK_MODE_LTE_CDMA_EVDO_GSM_WCDMA).when(mPhone) .getCachedPreferredNetworkType(); mNetworkTypeController.sendMessage(EVENT_PREFERRED_NETWORK_MODE_CHANGED); processAllMessages(); assertEquals(TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NONE, mNetworkTypeController.getOverrideNetworkType()); } @Test public void testPrimaryTimerExpire() throws Exception { doReturn(NetworkRegistrationInfo.NR_STATE_CONNECTED).when(mServiceState).getNrState(); Loading