diff options
Diffstat (limited to 'src/java/com/android/internal/telephony/data/DataProfileManager.java')
-rw-r--r-- | src/java/com/android/internal/telephony/data/DataProfileManager.java | 136 |
1 files changed, 108 insertions, 28 deletions
diff --git a/src/java/com/android/internal/telephony/data/DataProfileManager.java b/src/java/com/android/internal/telephony/data/DataProfileManager.java index 0878ccf48a..b4055a3e4c 100644 --- a/src/java/com/android/internal/telephony/data/DataProfileManager.java +++ b/src/java/com/android/internal/telephony/data/DataProfileManager.java @@ -48,6 +48,7 @@ import android.util.LocalLog; import com.android.internal.telephony.Phone; import com.android.internal.telephony.data.DataConfigManager.DataConfigManagerCallback; import com.android.internal.telephony.data.DataNetworkController.DataNetworkControllerCallback; +import com.android.internal.telephony.flags.FeatureFlags; import com.android.telephony.Rlog; import java.io.FileDescriptor; @@ -113,6 +114,9 @@ public class DataProfileManager extends Handler { /** SIM state. */ private @SimState int mSimState = TelephonyManager.SIM_STATE_UNKNOWN; + /** Feature flags controlling which feature is enabled. */ + private final @NonNull FeatureFlags mFeatureFlags; + /** * Data profile manager callback. This should be only used by {@link DataNetworkController}. */ @@ -140,15 +144,18 @@ public class DataProfileManager extends Handler { * @param dataServiceManager WWAN data service manager. * @param looper The looper to be used by the handler. Currently the handler thread is the * phone process's main thread. + * @param featureFlags Feature flags controlling which feature is enabled. * @param callback Data profile manager callback. */ public DataProfileManager(@NonNull Phone phone, @NonNull DataNetworkController dataNetworkController, @NonNull DataServiceManager dataServiceManager, @NonNull Looper looper, + @NonNull FeatureFlags featureFlags, @NonNull DataProfileManagerCallback callback) { super(looper); mPhone = phone; mLogTag = "DPM-" + mPhone.getPhoneId(); + mFeatureFlags = featureFlags; mDataNetworkController = dataNetworkController; mWwanDataServiceManager = dataServiceManager; mDataConfigManager = dataNetworkController.getDataConfigManager(); @@ -163,8 +170,9 @@ public class DataProfileManager extends Handler { mDataNetworkController.registerDataNetworkControllerCallback( new DataNetworkControllerCallback(this::post) { @Override - public void onInternetDataNetworkConnected( - @NonNull List<DataNetwork> internetNetworks) { + public void onConnectedInternetDataNetworksChanged( + @NonNull Set<DataNetwork> internetNetworks) { + if (internetNetworks.isEmpty()) return; DataProfileManager.this.onInternetDataNetworkConnected(internetNetworks); } @@ -247,6 +255,7 @@ public class DataProfileManager extends Handler { cursor.close(); return dataProfile; } + /** * Update all data profiles, including preferred data profile, and initial attach data profile. * Also send those profiles down to the modem if needed. @@ -405,27 +414,40 @@ public class DataProfileManager extends Handler { } /** - * Called when internet data is connected. + * Called when new internet data connect. * * @param internetNetworks The connected internet data networks. */ - private void onInternetDataNetworkConnected(@NonNull List<DataNetwork> internetNetworks) { + private void onInternetDataNetworkConnected(@NonNull Set<DataNetwork> internetNetworks) { DataProfile defaultProfile = null; - if (internetNetworks.size() == 1) { + if (mFeatureFlags.refinePreferredDataProfileSelection()) { // Most of the cases there should be only one. - defaultProfile = internetNetworks.get(0).getDataProfile(); - } else if (internetNetworks.size() > 1) { // but in case there are multiple, find the default internet network, and choose the // one which has longest life cycle. - logv("onInternetDataNetworkConnected: mPreferredDataProfile=" + mPreferredDataProfile - + " internetNetworks=" + internetNetworks); defaultProfile = internetNetworks.stream() .filter(network -> mPreferredDataProfile == null + // Find the one most resembles the current preferred profile, + // avoiding e.g. DUN default network. || canPreferredDataProfileSatisfy( network.getAttachedNetworkRequestList())) .map(DataNetwork::getDataProfile) .min(Comparator.comparingLong(DataProfile::getLastSetupTimestamp)) .orElse(null); + } else { + if (internetNetworks.size() == 1) { + // Most of the cases there should be only one. + defaultProfile = internetNetworks.stream().findFirst().get().getDataProfile(); + } else if (internetNetworks.size() > 1) { + // but in case there are multiple, find the default internet network, and choose the + // one which has longest life cycle. + defaultProfile = internetNetworks.stream() + .filter(network -> mPreferredDataProfile == null + || canPreferredDataProfileSatisfy( + network.getAttachedNetworkRequestList())) + .map(DataNetwork::getDataProfile) + .min(Comparator.comparingLong(DataProfile::getLastSetupTimestamp)) + .orElse(null); + } } // Update a working internet data profile as a future candidate for preferred data profile @@ -436,6 +458,9 @@ public class DataProfileManager extends Handler { // brought up a network means it passed sophisticated checks, update the preferred data // profile so that this network won't be torn down in future network evaluations. if (defaultProfile == null || defaultProfile.equals(mPreferredDataProfile)) return; + logv("onInternetDataNetworkConnected: defaultProfile=" + defaultProfile + + " previous preferredDataProfile=" + mPreferredDataProfile + + " internetNetworks=" + internetNetworks); // Save the preferred data profile into database. setPreferredDataProfile(defaultProfile); updateDataProfiles(false/*force update IA*/); @@ -627,18 +652,19 @@ public class DataProfileManager extends Handler { * * @param networkRequest The network request. * @param networkType The current data network type. + * @param isNtn {@code true} if the device is currently attached to non-terrestrial network. * @param ignorePermanentFailure {@code true} to ignore {@link ApnSetting#getPermanentFailed()}. * This should be set to true for condition-based retry/setup. * @return The data profile. {@code null} if can't find any satisfiable data profile. */ public @Nullable DataProfile getDataProfileForNetworkRequest( @NonNull TelephonyNetworkRequest networkRequest, @NetworkType int networkType, - boolean ignorePermanentFailure) { + boolean isNtn, boolean isEsimBootstrapProvisioning, boolean ignorePermanentFailure) { ApnSetting apnSetting = null; if (networkRequest.hasAttribute(TelephonyNetworkRequest .CAPABILITY_ATTRIBUTE_APN_SETTING)) { - apnSetting = getApnSettingForNetworkRequest(networkRequest, networkType, - ignorePermanentFailure); + apnSetting = getApnSettingForNetworkRequest(networkRequest, networkType, isNtn, + isEsimBootstrapProvisioning, ignorePermanentFailure); } TrafficDescriptor.Builder trafficDescriptorBuilder = new TrafficDescriptor.Builder(); @@ -697,32 +723,60 @@ public class DataProfileManager extends Handler { * * @param networkRequest The network request. * @param networkType The current data network type. + * @param isNtn {@code true} if the device is currently attached to non-terrestrial network. * @param ignorePermanentFailure {@code true} to ignore {@link ApnSetting#getPermanentFailed()}. * This should be set to true for condition-based retry/setup. * @return The APN setting. {@code null} if can't find any satisfiable data profile. */ private @Nullable ApnSetting getApnSettingForNetworkRequest( @NonNull TelephonyNetworkRequest networkRequest, @NetworkType int networkType, - boolean ignorePermanentFailure) { + boolean isNtn, boolean isEsimBootStrapProvisioning, boolean ignorePermanentFailure) { if (!networkRequest.hasAttribute( TelephonyNetworkRequest.CAPABILITY_ATTRIBUTE_APN_SETTING)) { loge("Network request does not have APN setting attribute."); return null; } - // If the preferred data profile can be used, always use it if it can satisfy the network - // request with current network type (even though it's been marked as permanent failed.) - if (mPreferredDataProfile != null - && networkRequest.canBeSatisfiedBy(mPreferredDataProfile) - && mPreferredDataProfile.getApnSetting() != null - && mPreferredDataProfile.getApnSetting().canSupportNetworkType(networkType)) { - if (ignorePermanentFailure || !mPreferredDataProfile.getApnSetting() - .getPermanentFailed()) { - return mPreferredDataProfile.getApnSetting(); + // if esim bootstrap provisioning in progress, do not apply preferred data profile + if (!isEsimBootStrapProvisioning) { + if (mFeatureFlags.carrierEnabledSatelliteFlag()) { + // If the preferred data profile can be used, always use it if it can satisfy the + // network request with current network type (even though it's been marked as + // permanent failed.) + if (mPreferredDataProfile != null + && networkRequest.canBeSatisfiedBy(mPreferredDataProfile) + && mPreferredDataProfile.getApnSetting() != null + && mPreferredDataProfile.getApnSetting().canSupportNetworkType(networkType) + && ((isNtn && mPreferredDataProfile.getApnSetting().isForInfrastructure( + ApnSetting.INFRASTRUCTURE_SATELLITE)) + || (!isNtn && mPreferredDataProfile.getApnSetting().isForInfrastructure( + ApnSetting.INFRASTRUCTURE_CELLULAR)))) { + if (ignorePermanentFailure || !mPreferredDataProfile.getApnSetting() + .getPermanentFailed()) { + return mPreferredDataProfile.getApnSetting(); + } + log("The preferred data profile is permanently failed. Only condition based " + + "retry can happen."); + return null; + } + } else { + // If the preferred data profile can be used, always use it if it can satisfy the + // network request with current network type (even though it's been marked as + // permanent failed.) + if (mPreferredDataProfile != null + && networkRequest.canBeSatisfiedBy(mPreferredDataProfile) + && mPreferredDataProfile.getApnSetting() != null + && mPreferredDataProfile.getApnSetting() + .canSupportNetworkType(networkType)) { + if (ignorePermanentFailure || !mPreferredDataProfile.getApnSetting() + .getPermanentFailed()) { + return mPreferredDataProfile.getApnSetting(); + } + log("The preferred data profile is permanently failed. Only condition based " + + "retry can happen."); + return null; + } } - log("The preferred data profile is permanently failed. Only condition based retry " - + "can happen."); - return null; } // Filter out the data profile that can't satisfy the request. @@ -744,8 +798,24 @@ public class DataProfileManager extends Handler { // Check if the remaining data profiles can used in current data network type. dataProfiles = dataProfiles.stream() - .filter(dp -> dp.getApnSetting() != null - && dp.getApnSetting().canSupportNetworkType(networkType)) + .filter((dp) -> { + if (dp.getApnSetting() == null) return false; + if (!dp.getApnSetting().canSupportNetworkType(networkType)) return false; + if (isEsimBootStrapProvisioning + != dp.getApnSetting().isEsimBootstrapProvisioning()) return false; + if (mFeatureFlags.carrierEnabledSatelliteFlag()) { + if (isNtn && !dp.getApnSetting().isForInfrastructure( + ApnSetting.INFRASTRUCTURE_SATELLITE)) { + return false; + } + if (!isNtn && !dp.getApnSetting().isForInfrastructure( + ApnSetting.INFRASTRUCTURE_CELLULAR)) { + return false; + } + } + + return true; + }) .collect(Collectors.toList()); if (dataProfiles.size() == 0) { log("Can't find any data profile for network type " @@ -775,6 +845,10 @@ public class DataProfileManager extends Handler { return null; } + if (isEsimBootStrapProvisioning) { + log("Found esim bootstrap provisioning data profile for network request: " + + dataProfiles.get(0).getApnSetting()); + } return dataProfiles.get(0).getApnSetting(); } @@ -819,7 +893,10 @@ public class DataProfileManager extends Handler { new NetworkRequest.Builder() .addCapability(NetworkCapabilities.NET_CAPABILITY_DUN) .build(), mPhone); - return getDataProfileForNetworkRequest(networkRequest, networkType, true) != null; + return getDataProfileForNetworkRequest(networkRequest, networkType, + mPhone.getServiceState().isUsingNonTerrestrialNetwork(), + mDataNetworkController.isEsimBootStrapProvisioningActivated(), + true) != null; } /** @@ -979,6 +1056,7 @@ public class DataProfileManager extends Handler { // The following fields in apn1 and apn2 should be the same, otherwise ApnSetting.similar() // should fail earlier. apnBuilder.setApnName(apn1.getApnName()); + apnBuilder.setOperatorNumeric(apn1.getOperatorNumeric()); apnBuilder.setProtocol(apn1.getProtocol()); apnBuilder.setRoamingProtocol(apn1.getRoamingProtocol()); apnBuilder.setCarrierEnabled(apn1.isEnabled()); @@ -993,6 +1071,8 @@ public class DataProfileManager extends Handler { apnBuilder.setCarrierId(apn1.getCarrierId()); apnBuilder.setSkip464Xlat(apn1.getSkip464Xlat()); apnBuilder.setAlwaysOn(apn1.isAlwaysOn()); + apnBuilder.setInfrastructureBitmask(apn1.getInfrastructureBitmask()); + apnBuilder.setEsimBootstrapProvisioning(apn1.isEsimBootstrapProvisioning()); return new DataProfile.Builder() .setApnSetting(apnBuilder.build()) |