Loading src/java/com/android/internal/telephony/GsmCdmaPhone.java +9 −0 Original line number Diff line number Diff line Loading @@ -90,6 +90,7 @@ import com.android.internal.annotations.VisibleForTesting; import com.android.internal.telephony.cdma.CdmaMmiCode; import com.android.internal.telephony.cdma.CdmaSubscriptionSourceManager; import com.android.internal.telephony.data.DataNetworkController; import com.android.internal.telephony.dataconnection.AccessNetworksManager; import com.android.internal.telephony.dataconnection.DataEnabledSettings; import com.android.internal.telephony.dataconnection.DcTracker; import com.android.internal.telephony.dataconnection.LinkBandwidthEstimator; Loading Loading @@ -307,6 +308,9 @@ public class GsmCdmaPhone extends Phone { .makeCarrierActionAgent(this); mCarrierSignalAgent = mTelephonyComponentFactory.inject(CarrierSignalAgent.class.getName()) .makeCarrierSignalAgent(this); mAccessNetworksManager = mTelephonyComponentFactory .inject(AccessNetworksManager.class.getName()) .makeAccessNetworksManager(this); mTransportManager = mTelephonyComponentFactory.inject(TransportManager.class.getName()) .makeTransportManager(this); // SST/DSM depends on SSC, so SSC is instanced before SST/DSM Loading Loading @@ -657,6 +661,11 @@ public class GsmCdmaPhone extends Phone { return mTransportManager; } @Override public AccessNetworksManager getAccessNetworksManager() { return mAccessNetworksManager; } @Override public DeviceStateMonitor getDeviceStateMonitor() { return mDeviceStateMonitor; Loading src/java/com/android/internal/telephony/Phone.java +10 −1 Original line number Diff line number Diff line Loading @@ -78,6 +78,7 @@ import com.android.ims.ImsManager; import com.android.internal.R; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.telephony.data.DataNetworkController; import com.android.internal.telephony.dataconnection.AccessNetworksManager; import com.android.internal.telephony.dataconnection.DataConnectionReasons; import com.android.internal.telephony.dataconnection.DataEnabledSettings; import com.android.internal.telephony.dataconnection.DcTracker; Loading Loading @@ -342,6 +343,7 @@ public abstract class Phone extends Handler implements PhoneInternalInterface { protected DeviceStateMonitor mDeviceStateMonitor; protected DisplayInfoController mDisplayInfoController; protected TransportManager mTransportManager; protected AccessNetworksManager mAccessNetworksManager; protected DataEnabledSettings mDataEnabledSettings; // Used for identify the carrier of current subscription protected CarrierResolver mCarrierResolver; Loading Loading @@ -1882,12 +1884,19 @@ public abstract class Phone extends Handler implements PhoneInternalInterface { } /** * @return The instance of transport manager * @return The instance of transport manager. */ public TransportManager getTransportManager() { return null; } /** * @return The instance of access networks manager. */ public AccessNetworksManager getAccessNetworksManager() { return null; } /** * Retrieves the DeviceStateMonitor of the phone instance. */ Loading src/java/com/android/internal/telephony/TelephonyComponentFactory.java +11 −0 Original line number Diff line number Diff line Loading @@ -34,6 +34,7 @@ import com.android.ims.ImsManager; import com.android.internal.telephony.cdma.CdmaSubscriptionSourceManager; import com.android.internal.telephony.cdma.EriManager; import com.android.internal.telephony.data.DataNetworkController; import com.android.internal.telephony.dataconnection.AccessNetworksManager; import com.android.internal.telephony.dataconnection.DataEnabledSettings; import com.android.internal.telephony.dataconnection.DcTracker; import com.android.internal.telephony.dataconnection.LinkBandwidthEstimator; Loading Loading @@ -403,6 +404,16 @@ public class TelephonyComponentFactory { return new TransportManager(phone); } /** * Make access networks manager * * @param phone The phone instance * @return The access networks manager */ public AccessNetworksManager makeAccessNetworksManager(Phone phone) { return new AccessNetworksManager(phone); } public CdmaSubscriptionSourceManager getCdmaSubscriptionSourceManagerInstance(Context context, CommandsInterface ci, Handler h, int what, Object obj) { Loading src/java/com/android/internal/telephony/data/DataNetworkController.java +4 −58 Original line number Diff line number Diff line Loading @@ -17,14 +17,12 @@ package com.android.internal.telephony.data; import android.annotation.NonNull; import android.annotation.StringDef; import android.net.NetworkAgent; import android.net.NetworkRequest; import android.os.Handler; import android.os.Looper; import android.os.Message; import android.os.RegistrantList; import android.os.SystemProperties; import android.telephony.AccessNetworkConstants; import android.telephony.data.DataProfile; import android.util.IndentingPrintWriter; Loading @@ -34,13 +32,11 @@ import android.util.SparseArray; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.telephony.Phone; import com.android.internal.telephony.RIL; import com.android.internal.telephony.dataconnection.AccessNetworksManager; import com.android.telephony.Rlog; import java.io.FileDescriptor; import java.io.PrintWriter; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.ArrayList; import java.util.LinkedList; import java.util.List; Loading @@ -52,36 +48,6 @@ import java.util.List; public class DataNetworkController extends Handler { private final boolean VDBG; public static final String SYSTEM_PROPERTIES_IWLAN_OPERATION_MODE = "ro.telephony.iwlan_operation_mode"; @Retention(RetentionPolicy.SOURCE) @StringDef(prefix = {"IWLAN_OPERATION_MODE_"}, value = { IWLAN_OPERATION_MODE_DEFAULT, IWLAN_OPERATION_MODE_LEGACY, IWLAN_OPERATION_MODE_AP_ASSISTED}) public @interface IwlanOperationMode {} /** * IWLAN default mode. On device that has IRadio 1.4 or above, it means * {@link #IWLAN_OPERATION_MODE_AP_ASSISTED}. On device that has IRadio 1.3 or below, it means * {@link #IWLAN_OPERATION_MODE_LEGACY}. */ public static final String IWLAN_OPERATION_MODE_DEFAULT = "default"; /** * IWLAN legacy mode. IWLAN is completely handled by the modem, and when the device is on * IWLAN, modem reports IWLAN as a RAT. */ public static final String IWLAN_OPERATION_MODE_LEGACY = "legacy"; /** * IWLAN application processor assisted mode. IWLAN is handled by the bound IWLAN data service * and network service separately. */ public static final String IWLAN_OPERATION_MODE_AP_ASSISTED = "AP-assisted"; /** Event for data config updated. */ private static final int EVENT_DATA_CONFIG_UPDATED = 1; Loading Loading @@ -109,6 +75,7 @@ public class DataNetworkController extends Handler { private final @NonNull DataProfileManager mDataProfileManager; private final @NonNull DataStallRecoveryManager mDataStallRecoveryManager; private final @NonNull DataTaskManager mDataTaskManager; private final @NonNull AccessNetworksManager mAccessNetworksManager; private final @NonNull SparseArray<DataServiceManager> mDataServiceManagers = new SparseArray<>(); Loading Loading @@ -209,9 +176,10 @@ public class DataNetworkController extends Handler { VDBG = Rlog.isLoggable(mLogTag, Log.VERBOSE); log("DataNetworkController created."); mAccessNetworksManager = phone.getAccessNetworksManager(); mDataServiceManagers.put(AccessNetworkConstants.TRANSPORT_TYPE_WWAN, new DataServiceManager(mPhone, looper, AccessNetworkConstants.TRANSPORT_TYPE_WWAN)); if (!isIwlanLegacyMode()) { if (!mAccessNetworksManager.isInLegacyMode()) { mDataServiceManagers.put(AccessNetworkConstants.TRANSPORT_TYPE_WLAN, new DataServiceManager(mPhone, looper, AccessNetworkConstants.TRANSPORT_TYPE_WWAN)); Loading Loading @@ -402,26 +370,6 @@ public class DataNetworkController extends Handler { return mDataConfigManager; } /** * @return {@code true} if the device operates in IWLAN legacy mode, otherwise {@code false}. In * legacy mode, IWLAN registration state is reported through cellular * {@link android.telephony.NetworkRegistrationInfo}. */ public boolean isIwlanLegacyMode() { // Get IWLAN operation mode from the system property. If the system property is configured // to default or not configured, the mode is tied to IRadio version. For 1.4 or above, it's // AP-assisted mode, for 1.3 or below, it's legacy mode. String mode = SystemProperties.get(SYSTEM_PROPERTIES_IWLAN_OPERATION_MODE); if (mode.equals(IWLAN_OPERATION_MODE_AP_ASSISTED)) { return false; } else if (mode.equals(IWLAN_OPERATION_MODE_LEGACY)) { return true; } return mPhone.getHalVersion().less(RIL.RADIO_HAL_VERSION_1_4); } /** * Register for internet data network validation status changed event. * Loading Loading @@ -476,8 +424,6 @@ public class DataNetworkController extends Handler { IndentingPrintWriter pw = new IndentingPrintWriter(printWriter, " "); pw.println(DataNetworkController.class.getSimpleName() + "-" + mPhone.getPhoneId() + ":"); pw.increaseIndent(); pw.println("IWLAN operation mode=" + SystemProperties.get(SYSTEM_PROPERTIES_IWLAN_OPERATION_MODE)); pw.println("Current data networks:"); pw.increaseIndent(); for (DataNetwork dn : mDataNetworkList) { Loading src/java/com/android/internal/telephony/dataconnection/AccessNetworksManager.java +231 −13 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ package com.android.internal.telephony.dataconnection; import android.annotation.NonNull; import android.annotation.StringDef; import android.content.BroadcastReceiver; import android.content.ComponentName; import android.content.Context; Loading @@ -30,8 +31,11 @@ import android.os.PersistableBundle; import android.os.Registrant; import android.os.RegistrantList; import android.os.RemoteException; import android.os.SystemProperties; import android.os.UserHandle; import android.telephony.AccessNetworkConstants; import android.telephony.AccessNetworkConstants.AccessNetworkType; import android.telephony.AccessNetworkConstants.TransportType; import android.telephony.Annotation.ApnType; import android.telephony.AnomalyReporter; import android.telephony.CarrierConfigManager; Loading @@ -41,17 +45,26 @@ import android.telephony.data.IQualifiedNetworksServiceCallback; import android.telephony.data.QualifiedNetworksService; import android.telephony.data.ThrottleStatus; import android.text.TextUtils; import android.util.IndentingPrintWriter; import android.util.LocalLog; import android.util.SparseArray; import com.android.internal.telephony.Phone; import com.android.internal.telephony.RIL; import com.android.telephony.Rlog; import java.io.FileDescriptor; import java.io.PrintWriter; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.ArrayList; import java.util.Arrays; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import java.util.UUID; import java.util.concurrent.ConcurrentHashMap; import java.util.stream.Collectors; /** Loading @@ -60,8 +73,39 @@ import java.util.stream.Collectors; * networks changes. */ public class AccessNetworksManager extends Handler { private final String mLogTag; private static final boolean DBG = false; public static final String SYSTEM_PROPERTIES_IWLAN_OPERATION_MODE = "ro.telephony.iwlan_operation_mode"; @Retention(RetentionPolicy.SOURCE) @StringDef(prefix = {"IWLAN_OPERATION_MODE_"}, value = { IWLAN_OPERATION_MODE_DEFAULT, IWLAN_OPERATION_MODE_LEGACY, IWLAN_OPERATION_MODE_AP_ASSISTED}) public @interface IwlanOperationMode {} /** * IWLAN default mode. On device that has IRadio 1.4 or above, it means * {@link #IWLAN_OPERATION_MODE_AP_ASSISTED}. On device that has IRadio 1.3 or below, it means * {@link #IWLAN_OPERATION_MODE_LEGACY}. */ public static final String IWLAN_OPERATION_MODE_DEFAULT = "default"; /** * IWLAN legacy mode. IWLAN is completely handled by the modem, and when the device is on * IWLAN, modem reports IWLAN as a RAT. */ public static final String IWLAN_OPERATION_MODE_LEGACY = "legacy"; /** * IWLAN application processor assisted mode. IWLAN is handled by the bound IWLAN data service * and network service separately. */ public static final String IWLAN_OPERATION_MODE_AP_ASSISTED = "AP-assisted"; private final String mLogTag; private final LocalLog mLocalLog = new LocalLog(64); private final UUID mAnomalyUUID = UUID.fromString("c2d1a639-00e2-4561-9619-6acf37d90590"); private String mLastBoundPackageName; Loading Loading @@ -91,6 +135,8 @@ public class AccessNetworksManager extends Handler { // Available networks. Key is the APN type. private final SparseArray<int[]> mAvailableNetworks = new SparseArray<>(); private final @TransportType int[] mAvailableTransports; private final RegistrantList mQualifiedNetworksChangedRegistrants = new RegistrantList(); private final Set<DataThrottler> mDataThrottlers = new HashSet<>(); Loading @@ -111,6 +157,19 @@ public class AccessNetworksManager extends Handler { } }; /** * The current transport of the APN type. The key is the APN type, and the value is the * transport. */ private final Map<Integer, Integer> mCurrentTransports = new ConcurrentHashMap<>(); /** * The preferred transport of the APN type. The key is the APN type, and the value is the * transport. The preferred transports are updated as soon as QNS changes the preference, while * the current transports are updated after handover complete. */ private final Map<Integer, Integer> mPreferredTransports = new ConcurrentHashMap<>(); /** * Registers the data throttler in order to receive APN status changes. * Loading Loading @@ -261,8 +320,6 @@ public class AccessNetworksManager extends Handler { List<QualifiedNetworks> qualifiedNetworksList = new ArrayList<>(); for (int supportedApnType : SUPPORTED_APN_TYPES) { if ((apnTypes & supportedApnType) == supportedApnType) { // TODO: Verify the preference from data settings manager to make sure the order // of the networks do not violate users/carrier's preference. if (mAvailableNetworks.get(supportedApnType) != null) { if (Arrays.equals(mAvailableNetworks.get(supportedApnType), qualifiedNetworkTypes)) { Loading @@ -280,6 +337,7 @@ public class AccessNetworksManager extends Handler { if (!qualifiedNetworksList.isEmpty()) { mQualifiedNetworksChangedRegistrants.notifyResult(qualifiedNetworksList); setPreferredTransports(qualifiedNetworksList); } } } Loading @@ -295,6 +353,15 @@ public class AccessNetworksManager extends Handler { Context.CARRIER_CONFIG_SERVICE); mLogTag = "ANM-" + mPhone.getPhoneId(); if (isInLegacyMode()) { log("operates in legacy mode."); // For legacy mode, WWAN is the only transport to handle all data connections, even // the IWLAN ones. mAvailableTransports = new int[]{AccessNetworkConstants.TRANSPORT_TYPE_WWAN}; } else { log("operates in AP-assisted mode."); mAvailableTransports = new int[]{AccessNetworkConstants.TRANSPORT_TYPE_WWAN, AccessNetworkConstants.TRANSPORT_TYPE_WLAN}; IntentFilter intentFilter = new IntentFilter(); intentFilter.addAction(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED); try { Loading @@ -307,6 +374,7 @@ public class AccessNetworksManager extends Handler { } bindQualifiedNetworksService(); } } /** * Find the qualified network service from configuration and binds to it. It reads the Loading Loading @@ -446,6 +514,113 @@ public class AccessNetworksManager extends Handler { } } /** * @return {@code true} if the device operates in legacy mode, otherwise {@code false}. */ public boolean isInLegacyMode() { // Get IWLAN operation mode from the system property. If the system property is configured // to default or not configured, the mode is tied to IRadio version. For 1.4 or above, it's // AP-assisted mode, for 1.3 or below, it's legacy mode. String mode = SystemProperties.get(SYSTEM_PROPERTIES_IWLAN_OPERATION_MODE); if (mode.equals(IWLAN_OPERATION_MODE_AP_ASSISTED)) { return false; } else if (mode.equals(IWLAN_OPERATION_MODE_LEGACY)) { return true; } return mPhone.getHalVersion().less(RIL.RADIO_HAL_VERSION_1_4); } /** * @return The available transports. Note that on legacy devices, the only available transport * would be WWAN only. If the device is configured as AP-assisted mode, the available transport * will always be WWAN and WLAN (even if the device is not camped on IWLAN). * See {@link #isInLegacyMode()} for mode details. */ public synchronized @NonNull int[] getAvailableTransports() { return mAvailableTransports; } /** * Get the transport based on the APN type. * * @param apnType APN type * @return The transport type */ public int getCurrentTransport(@ApnType int apnType) { // In legacy mode, always route to cellular. if (isInLegacyMode()) { return AccessNetworkConstants.TRANSPORT_TYPE_WWAN; } // If we can't find the corresponding transport, always route to cellular. return mCurrentTransports.get(apnType) == null ? AccessNetworkConstants.TRANSPORT_TYPE_WWAN : mCurrentTransports.get(apnType); } /** * Set the current transport of apn type. * * @param apnType The APN type * @param transport The transport. Must be WWAN or WLAN. */ public void setCurrentTransport(@ApnType int apnType, int transport) { Integer previousTransport = mCurrentTransports.put(apnType, transport); if (previousTransport == null || previousTransport != transport) { logl("setCurrentTransport: apnType=" + ApnSetting.getApnTypeString(apnType) + ", transport=" + AccessNetworkConstants.transportTypeToString(transport)); } } private static @TransportType int getTransportFromAccessNetwork(int accessNetwork) { return accessNetwork == AccessNetworkType.IWLAN ? AccessNetworkConstants.TRANSPORT_TYPE_WLAN : AccessNetworkConstants.TRANSPORT_TYPE_WWAN; } private void setPreferredTransports(@NonNull List<QualifiedNetworks> networksList) { for (QualifiedNetworks networks : networksList) { if (networks.qualifiedNetworks.length > 0) { int transport = getTransportFromAccessNetwork(networks.qualifiedNetworks[0]); mPreferredTransports.put(networks.apnType, transport); logl("setPreferredTransports: apnType=" + ApnSetting.getApnTypeString(networks.apnType) + ", transport=" + AccessNetworkConstants.transportTypeToString(transport)); } } } /** * Get the preferred transport. * * @param apnType APN type * @return The preferred transport. */ public @TransportType int getPreferredTransport(@ApnType int apnType) { // In legacy mode, always preferred on cellular. if (isInLegacyMode()) { return AccessNetworkConstants.TRANSPORT_TYPE_WWAN; } return mPreferredTransports.get(apnType) == null ? AccessNetworkConstants.TRANSPORT_TYPE_WWAN : mPreferredTransports.get(apnType); } /** * Check if there is any APN type's current transport is on IWLAN. * * @return {@code true} if there is any APN is on IWLAN, otherwise {@code false}. */ public boolean isAnyApnOnIwlan() { for (int apnType : AccessNetworksManager.SUPPORTED_APN_TYPES) { if (getCurrentTransport(apnType) == AccessNetworkConstants.TRANSPORT_TYPE_WLAN) { return true; } } return false; } /** * Unregister for qualified networks changed event. * Loading @@ -469,4 +644,47 @@ public class AccessNetworksManager extends Handler { Rlog.e(mLogTag, s, ex); } private void logl(String s) { log(s); mLocalLog.log(s); } /** * Dump the state of access networks manager * * @param fd File descriptor * @param printWriter Print writer * @param args Arguments */ public void dump(FileDescriptor fd, PrintWriter printWriter, String[] args) { IndentingPrintWriter pw = new IndentingPrintWriter(printWriter, " "); pw.println(AccessNetworksManager.class.getSimpleName() + "-" + mPhone.getPhoneId() + ":"); pw.increaseIndent(); pw.println("current transports="); pw.increaseIndent(); for (int apnType : AccessNetworksManager.SUPPORTED_APN_TYPES) { pw.println(ApnSetting.getApnTypeString(apnType) + ": " + AccessNetworkConstants.transportTypeToString( getCurrentTransport(apnType))); } pw.decreaseIndent(); pw.println("preferred transports="); pw.increaseIndent(); for (int apnType : AccessNetworksManager.SUPPORTED_APN_TYPES) { pw.println(ApnSetting.getApnTypeString(apnType) + ": " + AccessNetworkConstants.transportTypeToString( getPreferredTransport(apnType))); } pw.decreaseIndent(); pw.println("isInLegacy=" + isInLegacyMode()); pw.println("IWLAN operation mode=" + SystemProperties.get(SYSTEM_PROPERTIES_IWLAN_OPERATION_MODE)); pw.println("Local logs="); pw.increaseIndent(); mLocalLog.dump(fd, pw, args); pw.decreaseIndent(); pw.decreaseIndent(); pw.flush(); } } Loading
src/java/com/android/internal/telephony/GsmCdmaPhone.java +9 −0 Original line number Diff line number Diff line Loading @@ -90,6 +90,7 @@ import com.android.internal.annotations.VisibleForTesting; import com.android.internal.telephony.cdma.CdmaMmiCode; import com.android.internal.telephony.cdma.CdmaSubscriptionSourceManager; import com.android.internal.telephony.data.DataNetworkController; import com.android.internal.telephony.dataconnection.AccessNetworksManager; import com.android.internal.telephony.dataconnection.DataEnabledSettings; import com.android.internal.telephony.dataconnection.DcTracker; import com.android.internal.telephony.dataconnection.LinkBandwidthEstimator; Loading Loading @@ -307,6 +308,9 @@ public class GsmCdmaPhone extends Phone { .makeCarrierActionAgent(this); mCarrierSignalAgent = mTelephonyComponentFactory.inject(CarrierSignalAgent.class.getName()) .makeCarrierSignalAgent(this); mAccessNetworksManager = mTelephonyComponentFactory .inject(AccessNetworksManager.class.getName()) .makeAccessNetworksManager(this); mTransportManager = mTelephonyComponentFactory.inject(TransportManager.class.getName()) .makeTransportManager(this); // SST/DSM depends on SSC, so SSC is instanced before SST/DSM Loading Loading @@ -657,6 +661,11 @@ public class GsmCdmaPhone extends Phone { return mTransportManager; } @Override public AccessNetworksManager getAccessNetworksManager() { return mAccessNetworksManager; } @Override public DeviceStateMonitor getDeviceStateMonitor() { return mDeviceStateMonitor; Loading
src/java/com/android/internal/telephony/Phone.java +10 −1 Original line number Diff line number Diff line Loading @@ -78,6 +78,7 @@ import com.android.ims.ImsManager; import com.android.internal.R; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.telephony.data.DataNetworkController; import com.android.internal.telephony.dataconnection.AccessNetworksManager; import com.android.internal.telephony.dataconnection.DataConnectionReasons; import com.android.internal.telephony.dataconnection.DataEnabledSettings; import com.android.internal.telephony.dataconnection.DcTracker; Loading Loading @@ -342,6 +343,7 @@ public abstract class Phone extends Handler implements PhoneInternalInterface { protected DeviceStateMonitor mDeviceStateMonitor; protected DisplayInfoController mDisplayInfoController; protected TransportManager mTransportManager; protected AccessNetworksManager mAccessNetworksManager; protected DataEnabledSettings mDataEnabledSettings; // Used for identify the carrier of current subscription protected CarrierResolver mCarrierResolver; Loading Loading @@ -1882,12 +1884,19 @@ public abstract class Phone extends Handler implements PhoneInternalInterface { } /** * @return The instance of transport manager * @return The instance of transport manager. */ public TransportManager getTransportManager() { return null; } /** * @return The instance of access networks manager. */ public AccessNetworksManager getAccessNetworksManager() { return null; } /** * Retrieves the DeviceStateMonitor of the phone instance. */ Loading
src/java/com/android/internal/telephony/TelephonyComponentFactory.java +11 −0 Original line number Diff line number Diff line Loading @@ -34,6 +34,7 @@ import com.android.ims.ImsManager; import com.android.internal.telephony.cdma.CdmaSubscriptionSourceManager; import com.android.internal.telephony.cdma.EriManager; import com.android.internal.telephony.data.DataNetworkController; import com.android.internal.telephony.dataconnection.AccessNetworksManager; import com.android.internal.telephony.dataconnection.DataEnabledSettings; import com.android.internal.telephony.dataconnection.DcTracker; import com.android.internal.telephony.dataconnection.LinkBandwidthEstimator; Loading Loading @@ -403,6 +404,16 @@ public class TelephonyComponentFactory { return new TransportManager(phone); } /** * Make access networks manager * * @param phone The phone instance * @return The access networks manager */ public AccessNetworksManager makeAccessNetworksManager(Phone phone) { return new AccessNetworksManager(phone); } public CdmaSubscriptionSourceManager getCdmaSubscriptionSourceManagerInstance(Context context, CommandsInterface ci, Handler h, int what, Object obj) { Loading
src/java/com/android/internal/telephony/data/DataNetworkController.java +4 −58 Original line number Diff line number Diff line Loading @@ -17,14 +17,12 @@ package com.android.internal.telephony.data; import android.annotation.NonNull; import android.annotation.StringDef; import android.net.NetworkAgent; import android.net.NetworkRequest; import android.os.Handler; import android.os.Looper; import android.os.Message; import android.os.RegistrantList; import android.os.SystemProperties; import android.telephony.AccessNetworkConstants; import android.telephony.data.DataProfile; import android.util.IndentingPrintWriter; Loading @@ -34,13 +32,11 @@ import android.util.SparseArray; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.telephony.Phone; import com.android.internal.telephony.RIL; import com.android.internal.telephony.dataconnection.AccessNetworksManager; import com.android.telephony.Rlog; import java.io.FileDescriptor; import java.io.PrintWriter; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.ArrayList; import java.util.LinkedList; import java.util.List; Loading @@ -52,36 +48,6 @@ import java.util.List; public class DataNetworkController extends Handler { private final boolean VDBG; public static final String SYSTEM_PROPERTIES_IWLAN_OPERATION_MODE = "ro.telephony.iwlan_operation_mode"; @Retention(RetentionPolicy.SOURCE) @StringDef(prefix = {"IWLAN_OPERATION_MODE_"}, value = { IWLAN_OPERATION_MODE_DEFAULT, IWLAN_OPERATION_MODE_LEGACY, IWLAN_OPERATION_MODE_AP_ASSISTED}) public @interface IwlanOperationMode {} /** * IWLAN default mode. On device that has IRadio 1.4 or above, it means * {@link #IWLAN_OPERATION_MODE_AP_ASSISTED}. On device that has IRadio 1.3 or below, it means * {@link #IWLAN_OPERATION_MODE_LEGACY}. */ public static final String IWLAN_OPERATION_MODE_DEFAULT = "default"; /** * IWLAN legacy mode. IWLAN is completely handled by the modem, and when the device is on * IWLAN, modem reports IWLAN as a RAT. */ public static final String IWLAN_OPERATION_MODE_LEGACY = "legacy"; /** * IWLAN application processor assisted mode. IWLAN is handled by the bound IWLAN data service * and network service separately. */ public static final String IWLAN_OPERATION_MODE_AP_ASSISTED = "AP-assisted"; /** Event for data config updated. */ private static final int EVENT_DATA_CONFIG_UPDATED = 1; Loading Loading @@ -109,6 +75,7 @@ public class DataNetworkController extends Handler { private final @NonNull DataProfileManager mDataProfileManager; private final @NonNull DataStallRecoveryManager mDataStallRecoveryManager; private final @NonNull DataTaskManager mDataTaskManager; private final @NonNull AccessNetworksManager mAccessNetworksManager; private final @NonNull SparseArray<DataServiceManager> mDataServiceManagers = new SparseArray<>(); Loading Loading @@ -209,9 +176,10 @@ public class DataNetworkController extends Handler { VDBG = Rlog.isLoggable(mLogTag, Log.VERBOSE); log("DataNetworkController created."); mAccessNetworksManager = phone.getAccessNetworksManager(); mDataServiceManagers.put(AccessNetworkConstants.TRANSPORT_TYPE_WWAN, new DataServiceManager(mPhone, looper, AccessNetworkConstants.TRANSPORT_TYPE_WWAN)); if (!isIwlanLegacyMode()) { if (!mAccessNetworksManager.isInLegacyMode()) { mDataServiceManagers.put(AccessNetworkConstants.TRANSPORT_TYPE_WLAN, new DataServiceManager(mPhone, looper, AccessNetworkConstants.TRANSPORT_TYPE_WWAN)); Loading Loading @@ -402,26 +370,6 @@ public class DataNetworkController extends Handler { return mDataConfigManager; } /** * @return {@code true} if the device operates in IWLAN legacy mode, otherwise {@code false}. In * legacy mode, IWLAN registration state is reported through cellular * {@link android.telephony.NetworkRegistrationInfo}. */ public boolean isIwlanLegacyMode() { // Get IWLAN operation mode from the system property. If the system property is configured // to default or not configured, the mode is tied to IRadio version. For 1.4 or above, it's // AP-assisted mode, for 1.3 or below, it's legacy mode. String mode = SystemProperties.get(SYSTEM_PROPERTIES_IWLAN_OPERATION_MODE); if (mode.equals(IWLAN_OPERATION_MODE_AP_ASSISTED)) { return false; } else if (mode.equals(IWLAN_OPERATION_MODE_LEGACY)) { return true; } return mPhone.getHalVersion().less(RIL.RADIO_HAL_VERSION_1_4); } /** * Register for internet data network validation status changed event. * Loading Loading @@ -476,8 +424,6 @@ public class DataNetworkController extends Handler { IndentingPrintWriter pw = new IndentingPrintWriter(printWriter, " "); pw.println(DataNetworkController.class.getSimpleName() + "-" + mPhone.getPhoneId() + ":"); pw.increaseIndent(); pw.println("IWLAN operation mode=" + SystemProperties.get(SYSTEM_PROPERTIES_IWLAN_OPERATION_MODE)); pw.println("Current data networks:"); pw.increaseIndent(); for (DataNetwork dn : mDataNetworkList) { Loading
src/java/com/android/internal/telephony/dataconnection/AccessNetworksManager.java +231 −13 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ package com.android.internal.telephony.dataconnection; import android.annotation.NonNull; import android.annotation.StringDef; import android.content.BroadcastReceiver; import android.content.ComponentName; import android.content.Context; Loading @@ -30,8 +31,11 @@ import android.os.PersistableBundle; import android.os.Registrant; import android.os.RegistrantList; import android.os.RemoteException; import android.os.SystemProperties; import android.os.UserHandle; import android.telephony.AccessNetworkConstants; import android.telephony.AccessNetworkConstants.AccessNetworkType; import android.telephony.AccessNetworkConstants.TransportType; import android.telephony.Annotation.ApnType; import android.telephony.AnomalyReporter; import android.telephony.CarrierConfigManager; Loading @@ -41,17 +45,26 @@ import android.telephony.data.IQualifiedNetworksServiceCallback; import android.telephony.data.QualifiedNetworksService; import android.telephony.data.ThrottleStatus; import android.text.TextUtils; import android.util.IndentingPrintWriter; import android.util.LocalLog; import android.util.SparseArray; import com.android.internal.telephony.Phone; import com.android.internal.telephony.RIL; import com.android.telephony.Rlog; import java.io.FileDescriptor; import java.io.PrintWriter; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.ArrayList; import java.util.Arrays; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import java.util.UUID; import java.util.concurrent.ConcurrentHashMap; import java.util.stream.Collectors; /** Loading @@ -60,8 +73,39 @@ import java.util.stream.Collectors; * networks changes. */ public class AccessNetworksManager extends Handler { private final String mLogTag; private static final boolean DBG = false; public static final String SYSTEM_PROPERTIES_IWLAN_OPERATION_MODE = "ro.telephony.iwlan_operation_mode"; @Retention(RetentionPolicy.SOURCE) @StringDef(prefix = {"IWLAN_OPERATION_MODE_"}, value = { IWLAN_OPERATION_MODE_DEFAULT, IWLAN_OPERATION_MODE_LEGACY, IWLAN_OPERATION_MODE_AP_ASSISTED}) public @interface IwlanOperationMode {} /** * IWLAN default mode. On device that has IRadio 1.4 or above, it means * {@link #IWLAN_OPERATION_MODE_AP_ASSISTED}. On device that has IRadio 1.3 or below, it means * {@link #IWLAN_OPERATION_MODE_LEGACY}. */ public static final String IWLAN_OPERATION_MODE_DEFAULT = "default"; /** * IWLAN legacy mode. IWLAN is completely handled by the modem, and when the device is on * IWLAN, modem reports IWLAN as a RAT. */ public static final String IWLAN_OPERATION_MODE_LEGACY = "legacy"; /** * IWLAN application processor assisted mode. IWLAN is handled by the bound IWLAN data service * and network service separately. */ public static final String IWLAN_OPERATION_MODE_AP_ASSISTED = "AP-assisted"; private final String mLogTag; private final LocalLog mLocalLog = new LocalLog(64); private final UUID mAnomalyUUID = UUID.fromString("c2d1a639-00e2-4561-9619-6acf37d90590"); private String mLastBoundPackageName; Loading Loading @@ -91,6 +135,8 @@ public class AccessNetworksManager extends Handler { // Available networks. Key is the APN type. private final SparseArray<int[]> mAvailableNetworks = new SparseArray<>(); private final @TransportType int[] mAvailableTransports; private final RegistrantList mQualifiedNetworksChangedRegistrants = new RegistrantList(); private final Set<DataThrottler> mDataThrottlers = new HashSet<>(); Loading @@ -111,6 +157,19 @@ public class AccessNetworksManager extends Handler { } }; /** * The current transport of the APN type. The key is the APN type, and the value is the * transport. */ private final Map<Integer, Integer> mCurrentTransports = new ConcurrentHashMap<>(); /** * The preferred transport of the APN type. The key is the APN type, and the value is the * transport. The preferred transports are updated as soon as QNS changes the preference, while * the current transports are updated after handover complete. */ private final Map<Integer, Integer> mPreferredTransports = new ConcurrentHashMap<>(); /** * Registers the data throttler in order to receive APN status changes. * Loading Loading @@ -261,8 +320,6 @@ public class AccessNetworksManager extends Handler { List<QualifiedNetworks> qualifiedNetworksList = new ArrayList<>(); for (int supportedApnType : SUPPORTED_APN_TYPES) { if ((apnTypes & supportedApnType) == supportedApnType) { // TODO: Verify the preference from data settings manager to make sure the order // of the networks do not violate users/carrier's preference. if (mAvailableNetworks.get(supportedApnType) != null) { if (Arrays.equals(mAvailableNetworks.get(supportedApnType), qualifiedNetworkTypes)) { Loading @@ -280,6 +337,7 @@ public class AccessNetworksManager extends Handler { if (!qualifiedNetworksList.isEmpty()) { mQualifiedNetworksChangedRegistrants.notifyResult(qualifiedNetworksList); setPreferredTransports(qualifiedNetworksList); } } } Loading @@ -295,6 +353,15 @@ public class AccessNetworksManager extends Handler { Context.CARRIER_CONFIG_SERVICE); mLogTag = "ANM-" + mPhone.getPhoneId(); if (isInLegacyMode()) { log("operates in legacy mode."); // For legacy mode, WWAN is the only transport to handle all data connections, even // the IWLAN ones. mAvailableTransports = new int[]{AccessNetworkConstants.TRANSPORT_TYPE_WWAN}; } else { log("operates in AP-assisted mode."); mAvailableTransports = new int[]{AccessNetworkConstants.TRANSPORT_TYPE_WWAN, AccessNetworkConstants.TRANSPORT_TYPE_WLAN}; IntentFilter intentFilter = new IntentFilter(); intentFilter.addAction(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED); try { Loading @@ -307,6 +374,7 @@ public class AccessNetworksManager extends Handler { } bindQualifiedNetworksService(); } } /** * Find the qualified network service from configuration and binds to it. It reads the Loading Loading @@ -446,6 +514,113 @@ public class AccessNetworksManager extends Handler { } } /** * @return {@code true} if the device operates in legacy mode, otherwise {@code false}. */ public boolean isInLegacyMode() { // Get IWLAN operation mode from the system property. If the system property is configured // to default or not configured, the mode is tied to IRadio version. For 1.4 or above, it's // AP-assisted mode, for 1.3 or below, it's legacy mode. String mode = SystemProperties.get(SYSTEM_PROPERTIES_IWLAN_OPERATION_MODE); if (mode.equals(IWLAN_OPERATION_MODE_AP_ASSISTED)) { return false; } else if (mode.equals(IWLAN_OPERATION_MODE_LEGACY)) { return true; } return mPhone.getHalVersion().less(RIL.RADIO_HAL_VERSION_1_4); } /** * @return The available transports. Note that on legacy devices, the only available transport * would be WWAN only. If the device is configured as AP-assisted mode, the available transport * will always be WWAN and WLAN (even if the device is not camped on IWLAN). * See {@link #isInLegacyMode()} for mode details. */ public synchronized @NonNull int[] getAvailableTransports() { return mAvailableTransports; } /** * Get the transport based on the APN type. * * @param apnType APN type * @return The transport type */ public int getCurrentTransport(@ApnType int apnType) { // In legacy mode, always route to cellular. if (isInLegacyMode()) { return AccessNetworkConstants.TRANSPORT_TYPE_WWAN; } // If we can't find the corresponding transport, always route to cellular. return mCurrentTransports.get(apnType) == null ? AccessNetworkConstants.TRANSPORT_TYPE_WWAN : mCurrentTransports.get(apnType); } /** * Set the current transport of apn type. * * @param apnType The APN type * @param transport The transport. Must be WWAN or WLAN. */ public void setCurrentTransport(@ApnType int apnType, int transport) { Integer previousTransport = mCurrentTransports.put(apnType, transport); if (previousTransport == null || previousTransport != transport) { logl("setCurrentTransport: apnType=" + ApnSetting.getApnTypeString(apnType) + ", transport=" + AccessNetworkConstants.transportTypeToString(transport)); } } private static @TransportType int getTransportFromAccessNetwork(int accessNetwork) { return accessNetwork == AccessNetworkType.IWLAN ? AccessNetworkConstants.TRANSPORT_TYPE_WLAN : AccessNetworkConstants.TRANSPORT_TYPE_WWAN; } private void setPreferredTransports(@NonNull List<QualifiedNetworks> networksList) { for (QualifiedNetworks networks : networksList) { if (networks.qualifiedNetworks.length > 0) { int transport = getTransportFromAccessNetwork(networks.qualifiedNetworks[0]); mPreferredTransports.put(networks.apnType, transport); logl("setPreferredTransports: apnType=" + ApnSetting.getApnTypeString(networks.apnType) + ", transport=" + AccessNetworkConstants.transportTypeToString(transport)); } } } /** * Get the preferred transport. * * @param apnType APN type * @return The preferred transport. */ public @TransportType int getPreferredTransport(@ApnType int apnType) { // In legacy mode, always preferred on cellular. if (isInLegacyMode()) { return AccessNetworkConstants.TRANSPORT_TYPE_WWAN; } return mPreferredTransports.get(apnType) == null ? AccessNetworkConstants.TRANSPORT_TYPE_WWAN : mPreferredTransports.get(apnType); } /** * Check if there is any APN type's current transport is on IWLAN. * * @return {@code true} if there is any APN is on IWLAN, otherwise {@code false}. */ public boolean isAnyApnOnIwlan() { for (int apnType : AccessNetworksManager.SUPPORTED_APN_TYPES) { if (getCurrentTransport(apnType) == AccessNetworkConstants.TRANSPORT_TYPE_WLAN) { return true; } } return false; } /** * Unregister for qualified networks changed event. * Loading @@ -469,4 +644,47 @@ public class AccessNetworksManager extends Handler { Rlog.e(mLogTag, s, ex); } private void logl(String s) { log(s); mLocalLog.log(s); } /** * Dump the state of access networks manager * * @param fd File descriptor * @param printWriter Print writer * @param args Arguments */ public void dump(FileDescriptor fd, PrintWriter printWriter, String[] args) { IndentingPrintWriter pw = new IndentingPrintWriter(printWriter, " "); pw.println(AccessNetworksManager.class.getSimpleName() + "-" + mPhone.getPhoneId() + ":"); pw.increaseIndent(); pw.println("current transports="); pw.increaseIndent(); for (int apnType : AccessNetworksManager.SUPPORTED_APN_TYPES) { pw.println(ApnSetting.getApnTypeString(apnType) + ": " + AccessNetworkConstants.transportTypeToString( getCurrentTransport(apnType))); } pw.decreaseIndent(); pw.println("preferred transports="); pw.increaseIndent(); for (int apnType : AccessNetworksManager.SUPPORTED_APN_TYPES) { pw.println(ApnSetting.getApnTypeString(apnType) + ": " + AccessNetworkConstants.transportTypeToString( getPreferredTransport(apnType))); } pw.decreaseIndent(); pw.println("isInLegacy=" + isInLegacyMode()); pw.println("IWLAN operation mode=" + SystemProperties.get(SYSTEM_PROPERTIES_IWLAN_OPERATION_MODE)); pw.println("Local logs="); pw.increaseIndent(); mLocalLog.dump(fd, pw, args); pw.decreaseIndent(); pw.decreaseIndent(); pw.flush(); } }