Merge "Add Call Tracker null check" into main
diff --git a/src/java/com/android/internal/telephony/Phone.java b/src/java/com/android/internal/telephony/Phone.java
index 324e881..d327a45 100644
--- a/src/java/com/android/internal/telephony/Phone.java
+++ b/src/java/com/android/internal/telephony/Phone.java
@@ -4915,7 +4915,7 @@
     /**
      * @return The data network controller
      */
-    public @Nullable DataNetworkController getDataNetworkController() {
+    public @NonNull DataNetworkController getDataNetworkController() {
         return mDataNetworkController;
     }
 
diff --git a/src/java/com/android/internal/telephony/data/AccessNetworksManager.java b/src/java/com/android/internal/telephony/data/AccessNetworksManager.java
index 1d720ac..bc684af 100644
--- a/src/java/com/android/internal/telephony/data/AccessNetworksManager.java
+++ b/src/java/com/android/internal/telephony/data/AccessNetworksManager.java
@@ -148,7 +148,9 @@
         @ApnType
         public final int apnType;
         // The qualified networks in preferred order. Each network is a AccessNetworkType.
-        public final @NonNull @RadioAccessNetworkType int[] qualifiedNetworks;
+        @NonNull
+        @RadioAccessNetworkType
+        public final int[] qualifiedNetworks;
         public QualifiedNetworks(@ApnType int apnType, @NonNull int[] qualifiedNetworks) {
             this.apnType = apnType;
             this.qualifiedNetworks = Arrays.stream(qualifiedNetworks)
@@ -313,7 +315,7 @@
 
         /**
          * Called when QualifiedNetworksService requests network validation.
-         *
+         * <p>
          * Since the data network in the connected state corresponding to the given network
          * capability must be validated, a request is tossed to the data network controller.
          * @param networkCapability network capability
@@ -429,7 +431,8 @@
             mPhone.getDataNetworkController().getDataRetryManager().registerCallback(
                     new DataRetryManager.DataRetryManagerCallback(this::post) {
                         @Override
-                        public void onThrottleStatusChanged(List<ThrottleStatus> throttleStatuses) {
+                        public void onThrottleStatusChanged(
+                                @NonNull List<ThrottleStatus> throttleStatuses) {
                             try {
                                 logl("onThrottleStatusChanged: " + throttleStatuses);
                                 if (mIQualifiedNetworksService != null) {
@@ -471,7 +474,7 @@
      */
     private void bindQualifiedNetworksService() {
         post(() -> {
-            Intent intent = null;
+            Intent intent;
             String packageName = getQualifiedNetworksServicePackageName();
             String className = getQualifiedNetworksServiceClassName();
 
@@ -538,7 +541,7 @@
             b = mCarrierConfigManager.getConfigForSubId(mPhone.getSubId(),
                     CarrierConfigManager
                             .KEY_CARRIER_QUALIFIED_NETWORKS_SERVICE_PACKAGE_OVERRIDE_STRING);
-            if (b != null && !b.isEmpty()) {
+            if (!b.isEmpty()) {
                 // If carrier config overrides it, use the one from carrier config
                 String carrierConfigPackageName = b.getString(CarrierConfigManager
                         .KEY_CARRIER_QUALIFIED_NETWORKS_SERVICE_PACKAGE_OVERRIDE_STRING);
@@ -569,7 +572,7 @@
             b = mCarrierConfigManager.getConfigForSubId(mPhone.getSubId(),
                     CarrierConfigManager
                             .KEY_CARRIER_QUALIFIED_NETWORKS_SERVICE_CLASS_OVERRIDE_STRING);
-            if (b != null && !b.isEmpty()) {
+            if (!b.isEmpty()) {
                 // If carrier config overrides it, use the one from carrier config
                 String carrierConfigClassName = b.getString(CarrierConfigManager
                         .KEY_CARRIER_QUALIFIED_NETWORKS_SERVICE_CLASS_OVERRIDE_STRING);
@@ -585,7 +588,8 @@
         return className;
     }
 
-    private @NonNull List<QualifiedNetworks> getQualifiedNetworksList() {
+    @NonNull
+    private List<QualifiedNetworks> getQualifiedNetworksList() {
         List<QualifiedNetworks> qualifiedNetworksList = new ArrayList<>();
         for (int i = 0; i < mAvailableNetworks.size(); i++) {
             qualifiedNetworksList.add(new QualifiedNetworks(mAvailableNetworks.keyAt(i),
@@ -617,11 +621,13 @@
     /**
      * @return The available transports.
      */
-    public @NonNull int[] getAvailableTransports() {
+    @NonNull
+    public int[] getAvailableTransports() {
         return mAvailableTransports;
     }
 
-    private static @TransportType int getTransportFromAccessNetwork(int accessNetwork) {
+    @TransportType
+    private static int getTransportFromAccessNetwork(int accessNetwork) {
         return accessNetwork == AccessNetworkType.IWLAN
                 ? AccessNetworkConstants.TRANSPORT_TYPE_WLAN
                 : AccessNetworkConstants.TRANSPORT_TYPE_WWAN;
@@ -654,7 +660,8 @@
      * @param apnType APN type
      * @return The preferred transport.
      */
-    public @TransportType int getPreferredTransport(@ApnType int apnType) {
+    @TransportType
+    public int getPreferredTransport(@ApnType int apnType) {
         return mPreferredTransports.get(apnType) == null
                 ? AccessNetworkConstants.TRANSPORT_TYPE_WWAN : mPreferredTransports.get(apnType);
     }
@@ -666,8 +673,8 @@
      * supported.)
      * @return The preferred transport.
      */
-    public @TransportType int getPreferredTransportByNetworkCapability(
-            @NetCapability int networkCapability) {
+    @TransportType
+    public int getPreferredTransportByNetworkCapability(@NetCapability int networkCapability) {
         int apnType = DataUtils.networkCapabilityToApnType(networkCapability);
         // For non-APN type capabilities, always route to WWAN.
         if (apnType == ApnSetting.TYPE_NONE) {
diff --git a/src/java/com/android/internal/telephony/data/DataConfigManager.java b/src/java/com/android/internal/telephony/data/DataConfigManager.java
index 40039f2..4177cc4 100644
--- a/src/java/com/android/internal/telephony/data/DataConfigManager.java
+++ b/src/java/com/android/internal/telephony/data/DataConfigManager.java
@@ -200,8 +200,8 @@
     private @interface DataConfigNetworkType {}
 
     /** Data config update callbacks. */
-    private final @NonNull Set<DataConfigManagerCallback> mDataConfigManagerCallbacks =
-            new ArraySet<>();
+    @NonNull
+    private final Set<DataConfigManagerCallback> mDataConfigManagerCallbacks = new ArraySet<>();
 
     /** DeviceConfig key of anomaly report threshold for back to back ims release-request. */
     private static final String KEY_ANOMALY_IMS_RELEASE_REQUEST = "anomaly_ims_release_request";
@@ -266,55 +266,77 @@
      */
     private boolean mIsApnConfigAnomalyReportEnabled;
 
-    private @NonNull final Phone mPhone;
-    private @NonNull final String mLogTag;
-
-    @NonNull private final FeatureFlags mFeatureFlags;
-    private @NonNull final CarrierConfigManager mCarrierConfigManager;
-    private @NonNull PersistableBundle mCarrierConfig = null;
-    private @NonNull Resources mResources = null;
+    @NonNull
+    private final Phone mPhone;
+    @NonNull
+    private final String mLogTag;
+    @NonNull
+    private final FeatureFlags mFeatureFlags;
+    @NonNull
+    private final CarrierConfigManager mCarrierConfigManager;
+    @NonNull
+    private PersistableBundle mCarrierConfig = null;
+    @NonNull
+    private Resources mResources = null;
 
     /** The network capability priority map */
-    private @NonNull final Map<Integer, Integer> mNetworkCapabilityPriorityMap =
-            new ConcurrentHashMap<>();
+    @NonNull
+    private final Map<Integer, Integer> mNetworkCapabilityPriorityMap = new ConcurrentHashMap<>();
     /** The data setup retry rules */
-    private @NonNull final List<DataSetupRetryRule> mDataSetupRetryRules = new ArrayList<>();
+    @NonNull
+    private final List<DataSetupRetryRule> mDataSetupRetryRules = new ArrayList<>();
     /** The data handover retry rules */
-    private @NonNull final List<DataHandoverRetryRule> mDataHandoverRetryRules = new ArrayList<>();
+    @NonNull
+    private final List<DataHandoverRetryRule> mDataHandoverRetryRules = new ArrayList<>();
     /** The metered APN types for home network */
-    private @NonNull final @ApnType Set<Integer> mMeteredApnTypes = new HashSet<>();
+    @NonNull
+    @ApnType
+    private final Set<Integer> mMeteredApnTypes = new HashSet<>();
     /** The metered APN types for roaming network */
-    private @NonNull final @ApnType Set<Integer> mRoamingMeteredApnTypes = new HashSet<>();
+    @NonNull
+    @ApnType
+    private final Set<Integer> mRoamingMeteredApnTypes = new HashSet<>();
     /** The network types that only support single data networks */
-    private @NonNull final @NetworkType List<Integer> mSingleDataNetworkTypeList =
-            new ArrayList<>();
-    private @NonNull final @NetCapability Set<Integer> mCapabilitiesExemptFromSingleDataList =
-            new HashSet<>();
+    @NonNull
+    @NetworkType
+    private final List<Integer> mSingleDataNetworkTypeList = new ArrayList<>();
+    @NonNull
+    @NetCapability
+    private final Set<Integer> mCapabilitiesExemptFromSingleDataList = new HashSet<>();
     /** The network types that support temporarily not metered */
-    private @NonNull final @DataConfigNetworkType Set<String> mUnmeteredNetworkTypes =
-            new HashSet<>();
+    @NonNull
+    @DataConfigNetworkType
+    private final Set<String> mUnmeteredNetworkTypes = new HashSet<>();
     /** The network types that support temporarily not metered when roaming */
-    private @NonNull final @DataConfigNetworkType Set<String> mRoamingUnmeteredNetworkTypes =
-            new HashSet<>();
+    @NonNull
+    @DataConfigNetworkType
+    private final Set<String> mRoamingUnmeteredNetworkTypes = new HashSet<>();
     /** A map of network types to the downlink and uplink bandwidth values for that network type */
-    private @NonNull final @DataConfigNetworkType Map<String, DataNetwork.NetworkBandwidth>
-            mBandwidthMap = new ConcurrentHashMap<>();
-    /** A map of network types to the TCP buffer sizes for that network type */
-    private @NonNull final @DataConfigNetworkType Map<String, String> mTcpBufferSizeMap =
+    @NonNull
+    @DataConfigNetworkType
+    private final Map<String, DataNetwork.NetworkBandwidth> mBandwidthMap =
             new ConcurrentHashMap<>();
+    /** A map of network types to the TCP buffer sizes for that network type */
+    @NonNull
+    @DataConfigNetworkType
+    private final Map<String, String> mTcpBufferSizeMap = new ConcurrentHashMap<>();
     /** Rules for handover between IWLAN and cellular network. */
-    private @NonNull final List<HandoverRule> mHandoverRuleList = new ArrayList<>();
+    @NonNull
+    private final List<HandoverRule> mHandoverRuleList = new ArrayList<>();
     /** {@code True} keep IMS network in case of moving to non VOPS area; {@code false} otherwise.*/
     private boolean mShouldKeepNetworkUpInNonVops = false;
     /** The set of network types that enable VOPS even in non VOPS area. */
-    @NonNull private final @CarrierConfigManager.Ims.NetworkType List<Integer>
-            mEnabledVopsNetworkTypesInNonVops = new ArrayList<>();
+    @NonNull
+    @CarrierConfigManager.Ims.NetworkType
+    private final List<Integer> mEnabledVopsNetworkTypesInNonVops = new ArrayList<>();
     /**
      * A map of network types to the estimated downlink values by signal strength 0 - 4 for that
      * network type
      */
-    private @NonNull final @DataConfigNetworkType Map<String, int[]>
-            mAutoDataSwitchNetworkTypeSignalMap = new ConcurrentHashMap<>();
+    @NonNull
+    @DataConfigNetworkType
+    private final Map<String, int[]> mAutoDataSwitchNetworkTypeSignalMap =
+            new ConcurrentHashMap<>();
 
     /**
      * Constructor
@@ -554,14 +576,16 @@
     /**
      * @return The data setup retry rules from carrier config.
      */
-    public @NonNull List<DataSetupRetryRule> getDataSetupRetryRules() {
+    @NonNull
+    public List<DataSetupRetryRule> getDataSetupRetryRules() {
         return Collections.unmodifiableList(mDataSetupRetryRules);
     }
 
     /**
      * @return The data handover retry rules from carrier config.
      */
-    public @NonNull List<DataHandoverRetryRule> getDataHandoverRetryRules() {
+    @NonNull
+    public List<DataHandoverRetryRule> getDataHandoverRetryRules() {
         return Collections.unmodifiableList(mDataHandoverRetryRules);
     }
 
@@ -604,7 +628,9 @@
      *
      * @return The metered network capabilities when connected to a home network.
      */
-    public @NonNull @NetCapability Set<Integer> getMeteredNetworkCapabilities(boolean isRoaming) {
+    @NonNull
+    @NetCapability
+    public Set<Integer> getMeteredNetworkCapabilities(boolean isRoaming) {
         Set<Integer> meteredApnTypes = isRoaming ? mRoamingMeteredApnTypes : mMeteredApnTypes;
         Set<Integer> meteredCapabilities = meteredApnTypes.stream()
                 .map(DataUtils::apnTypeToNetworkCapability)
@@ -703,7 +729,9 @@
     /**
      * @return The list of {@link NetworkType} that only supports single data networks
      */
-    public @NonNull @NetworkType List<Integer> getNetworkTypesOnlySupportSingleDataNetwork() {
+    @NonNull
+    @NetworkType
+    public List<Integer> getNetworkTypesOnlySupportSingleDataNetwork() {
         return Collections.unmodifiableList(mSingleDataNetworkTypeList);
     }
 
@@ -711,7 +739,9 @@
      * @return The list of {@link android.net.NetworkCapabilities.NetCapability} that every of which
      * is exempt from the single PDN check.
      */
-    public @NonNull @NetCapability Set<Integer> getCapabilitiesExemptFromSingleDataNetwork() {
+    @NonNull
+    @NetCapability
+    public Set<Integer> getCapabilitiesExemptFromSingleDataNetwork() {
         return Collections.unmodifiableSet(mCapabilitiesExemptFromSingleDataList);
     }
 
@@ -844,7 +874,8 @@
      * @param displayInfo The {@link TelephonyDisplayInfo} to get the bandwidth for.
      * @return The pre-configured bandwidth estimate from carrier config.
      */
-    public @NonNull DataNetwork.NetworkBandwidth getBandwidthForNetworkType(
+    @NonNull
+    public DataNetwork.NetworkBandwidth getBandwidthForNetworkType(
             @NonNull TelephonyDisplayInfo displayInfo) {
         DataNetwork.NetworkBandwidth bandwidth = mBandwidthMap.get(
                 getDataConfigNetworkType(displayInfo));
@@ -931,7 +962,8 @@
      * Anomaly report thresholds for frequent setup data call failure.
      * @return EventFrequency to trigger the anomaly report
      */
-    public @NonNull EventFrequency getAnomalySetupDataCallThreshold() {
+    @NonNull
+    public EventFrequency getAnomalySetupDataCallThreshold() {
         return mSetupDataCallAnomalyReportThreshold;
     }
 
@@ -940,7 +972,8 @@
      * at {@link TelephonyNetworkAgent#onNetworkUnwanted}
      * @return EventFrequency to trigger the anomaly report
      */
-    public @NonNull EventFrequency getAnomalyNetworkUnwantedThreshold() {
+    @NonNull
+    public EventFrequency getAnomalyNetworkUnwantedThreshold() {
         return mNetworkUnwantedAnomalyReportThreshold;
     }
 
@@ -948,7 +981,8 @@
      * Anomaly report thresholds for back to back release-request of IMS.
      * @return EventFrequency to trigger the anomaly report
      */
-    public @NonNull EventFrequency getAnomalyImsReleaseRequestThreshold() {
+    @NonNull
+    public EventFrequency getAnomalyImsReleaseRequestThreshold() {
         return mImsReleaseRequestAnomalyReportThreshold;
     }
 
@@ -1119,7 +1153,8 @@
      * @return The TCP configuration string for the given display info or the default value from
      *         {@code config_tcp_buffers} if unavailable.
      */
-    public @NonNull String getTcpConfigString(@NonNull TelephonyDisplayInfo displayInfo) {
+    @NonNull
+    public String getTcpConfigString(@NonNull TelephonyDisplayInfo displayInfo) {
         String config = mTcpBufferSizeMap.get(getDataConfigNetworkType(displayInfo));
         if (TextUtils.isEmpty(config)) {
             config = getDefaultTcpConfigString();
@@ -1130,7 +1165,8 @@
     /**
      * @return The fixed TCP buffer size configured based on the device's memory and performance.
      */
-    public @NonNull String getDefaultTcpConfigString() {
+    @NonNull
+    public String getDefaultTcpConfigString() {
         return mResources.getString(com.android.internal.R.string.config_tcp_buffers);
     }
 
@@ -1173,20 +1209,21 @@
     /**
      * @return The bandwidth estimation source.
      */
-    public @DataNetwork.BandwidthEstimationSource int getBandwidthEstimateSource() {
+    @DataNetwork.BandwidthEstimationSource
+    public int getBandwidthEstimateSource() {
         String source = mResources.getString(
                 com.android.internal.R.string.config_bandwidthEstimateSource);
-        switch (source) {
-            case BANDWIDTH_SOURCE_MODEM_STRING_VALUE:
-                return DataNetwork.BANDWIDTH_SOURCE_MODEM;
-            case BANDWIDTH_SOURCE_CARRIER_CONFIG_STRING_VALUE:
-                return DataNetwork.BANDWIDTH_SOURCE_CARRIER_CONFIG;
-            case BANDWIDTH_SOURCE_BANDWIDTH_ESTIMATOR_STRING_VALUE:
-                return DataNetwork.BANDWIDTH_SOURCE_BANDWIDTH_ESTIMATOR;
-            default:
+        return switch (source) {
+            case BANDWIDTH_SOURCE_MODEM_STRING_VALUE -> DataNetwork.BANDWIDTH_SOURCE_MODEM;
+            case BANDWIDTH_SOURCE_CARRIER_CONFIG_STRING_VALUE ->
+                    DataNetwork.BANDWIDTH_SOURCE_CARRIER_CONFIG;
+            case BANDWIDTH_SOURCE_BANDWIDTH_ESTIMATOR_STRING_VALUE ->
+                    DataNetwork.BANDWIDTH_SOURCE_BANDWIDTH_ESTIMATOR;
+            default -> {
                 loge("Invalid bandwidth estimation source config: " + source);
-                return DataNetwork.BANDWIDTH_SOURCE_UNKNOWN;
-        }
+                yield DataNetwork.BANDWIDTH_SOURCE_UNKNOWN;
+            }
+        };
     }
 
     /**
@@ -1195,8 +1232,9 @@
      * @param displayInfo The {@link TelephonyDisplayInfo} used to determine the type.
      * @return The equivalent {@link DataConfigNetworkType}.
      */
-    private static @NonNull @DataConfigNetworkType String getDataConfigNetworkType(
-            @NonNull TelephonyDisplayInfo displayInfo) {
+    @NonNull
+    @DataConfigNetworkType
+    private static String getDataConfigNetworkType(@NonNull TelephonyDisplayInfo displayInfo) {
         int networkType = displayInfo.getNetworkType();
         switch (displayInfo.getOverrideNetworkType()) {
             case TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_ADVANCED:
@@ -1305,7 +1343,8 @@
      *
      * @see CarrierConfigManager#KEY_IWLAN_HANDOVER_POLICY_STRING_ARRAY
      */
-    public @NonNull List<HandoverRule> getHandoverRules() {
+    @NonNull
+    public List<HandoverRule> getHandoverRules() {
         return Collections.unmodifiableList(mHandoverRuleList);
     }
 
@@ -1323,52 +1362,33 @@
      * @param networkType The network type
      * @return The equivalent data config network type
      */
-    private static @NonNull @DataConfigNetworkType String networkTypeToDataConfigNetworkType(
+    @NonNull
+    @DataConfigNetworkType
+    private static String networkTypeToDataConfigNetworkType(
             @NetworkType int networkType) {
-        switch (networkType) {
-            case TelephonyManager.NETWORK_TYPE_GPRS:
-                return DATA_CONFIG_NETWORK_TYPE_GPRS;
-            case TelephonyManager.NETWORK_TYPE_EDGE:
-                return DATA_CONFIG_NETWORK_TYPE_EDGE;
-            case TelephonyManager.NETWORK_TYPE_UMTS:
-                return DATA_CONFIG_NETWORK_TYPE_UMTS;
-            case TelephonyManager.NETWORK_TYPE_HSDPA:
-                return DATA_CONFIG_NETWORK_TYPE_HSDPA;
-            case TelephonyManager.NETWORK_TYPE_HSUPA:
-                return DATA_CONFIG_NETWORK_TYPE_HSUPA;
-            case TelephonyManager.NETWORK_TYPE_HSPA:
-                return DATA_CONFIG_NETWORK_TYPE_HSPA;
-            case TelephonyManager.NETWORK_TYPE_CDMA:
-                return DATA_CONFIG_NETWORK_TYPE_CDMA;
-            case TelephonyManager.NETWORK_TYPE_EVDO_0:
-                return DATA_CONFIG_NETWORK_TYPE_EVDO_0;
-            case TelephonyManager.NETWORK_TYPE_EVDO_A:
-                return DATA_CONFIG_NETWORK_TYPE_EVDO_A;
-            case TelephonyManager.NETWORK_TYPE_EVDO_B:
-                return DATA_CONFIG_NETWORK_TYPE_EVDO_B;
-            case TelephonyManager.NETWORK_TYPE_1xRTT:
-                return DATA_CONFIG_NETWORK_TYPE_1xRTT;
-            case TelephonyManager.NETWORK_TYPE_LTE:
-                return DATA_CONFIG_NETWORK_TYPE_LTE;
-            case TelephonyManager.NETWORK_TYPE_EHRPD:
-                return DATA_CONFIG_NETWORK_TYPE_EHRPD;
-            case TelephonyManager.NETWORK_TYPE_IDEN:
-                return DATA_CONFIG_NETWORK_TYPE_IDEN;
-            case TelephonyManager.NETWORK_TYPE_HSPAP:
-                return DATA_CONFIG_NETWORK_TYPE_HSPAP;
-            case TelephonyManager.NETWORK_TYPE_GSM:
-                return DATA_CONFIG_NETWORK_TYPE_GSM;
-            case TelephonyManager.NETWORK_TYPE_TD_SCDMA:
-                return DATA_CONFIG_NETWORK_TYPE_TD_SCDMA;
-            case TelephonyManager.NETWORK_TYPE_IWLAN:
-                return DATA_CONFIG_NETWORK_TYPE_IWLAN;
-            case TelephonyManager.NETWORK_TYPE_LTE_CA:
-                return DATA_CONFIG_NETWORK_TYPE_LTE_CA;
-            case TelephonyManager.NETWORK_TYPE_NR:
-                return DATA_CONFIG_NETWORK_TYPE_NR_SA;
-            default:
-                return "";
-        }
+        return switch (networkType) {
+            case TelephonyManager.NETWORK_TYPE_GPRS -> DATA_CONFIG_NETWORK_TYPE_GPRS;
+            case TelephonyManager.NETWORK_TYPE_EDGE -> DATA_CONFIG_NETWORK_TYPE_EDGE;
+            case TelephonyManager.NETWORK_TYPE_UMTS -> DATA_CONFIG_NETWORK_TYPE_UMTS;
+            case TelephonyManager.NETWORK_TYPE_HSDPA -> DATA_CONFIG_NETWORK_TYPE_HSDPA;
+            case TelephonyManager.NETWORK_TYPE_HSUPA -> DATA_CONFIG_NETWORK_TYPE_HSUPA;
+            case TelephonyManager.NETWORK_TYPE_HSPA -> DATA_CONFIG_NETWORK_TYPE_HSPA;
+            case TelephonyManager.NETWORK_TYPE_CDMA -> DATA_CONFIG_NETWORK_TYPE_CDMA;
+            case TelephonyManager.NETWORK_TYPE_EVDO_0 -> DATA_CONFIG_NETWORK_TYPE_EVDO_0;
+            case TelephonyManager.NETWORK_TYPE_EVDO_A -> DATA_CONFIG_NETWORK_TYPE_EVDO_A;
+            case TelephonyManager.NETWORK_TYPE_EVDO_B -> DATA_CONFIG_NETWORK_TYPE_EVDO_B;
+            case TelephonyManager.NETWORK_TYPE_1xRTT -> DATA_CONFIG_NETWORK_TYPE_1xRTT;
+            case TelephonyManager.NETWORK_TYPE_LTE -> DATA_CONFIG_NETWORK_TYPE_LTE;
+            case TelephonyManager.NETWORK_TYPE_EHRPD -> DATA_CONFIG_NETWORK_TYPE_EHRPD;
+            case TelephonyManager.NETWORK_TYPE_IDEN -> DATA_CONFIG_NETWORK_TYPE_IDEN;
+            case TelephonyManager.NETWORK_TYPE_HSPAP -> DATA_CONFIG_NETWORK_TYPE_HSPAP;
+            case TelephonyManager.NETWORK_TYPE_GSM -> DATA_CONFIG_NETWORK_TYPE_GSM;
+            case TelephonyManager.NETWORK_TYPE_TD_SCDMA -> DATA_CONFIG_NETWORK_TYPE_TD_SCDMA;
+            case TelephonyManager.NETWORK_TYPE_IWLAN -> DATA_CONFIG_NETWORK_TYPE_IWLAN;
+            case TelephonyManager.NETWORK_TYPE_LTE_CA -> DATA_CONFIG_NETWORK_TYPE_LTE_CA;
+            case TelephonyManager.NETWORK_TYPE_NR -> DATA_CONFIG_NETWORK_TYPE_NR_SA;
+            default -> "";
+        };
     }
 
     /**
@@ -1376,7 +1396,8 @@
      *
      * @see CarrierConfigManager#KEY_DATA_STALL_RECOVERY_TIMERS_LONG_ARRAY
      */
-    public @NonNull long[] getDataStallRecoveryDelayMillis() {
+    @NonNull
+    public long[] getDataStallRecoveryDelayMillis() {
         return mCarrierConfig.getLongArray(
             CarrierConfigManager.KEY_DATA_STALL_RECOVERY_TIMERS_LONG_ARRAY);
     }
@@ -1386,7 +1407,8 @@
      *
      * @see CarrierConfigManager#KEY_DATA_STALL_RECOVERY_SHOULD_SKIP_BOOL_ARRAY
      */
-    public @NonNull boolean[] getDataStallRecoveryShouldSkipArray() {
+    @NonNull
+    public boolean[] getDataStallRecoveryShouldSkipArray() {
         return mCarrierConfig.getBooleanArray(
             CarrierConfigManager.KEY_DATA_STALL_RECOVERY_SHOULD_SKIP_BOOL_ARRAY);
     }
@@ -1395,7 +1417,8 @@
      * @return The default preferred APN. An empty string if not configured. This is used for the
      * first time boot up where preferred APN is not set.
      */
-    public @NonNull String getDefaultPreferredApn() {
+    @NonNull
+    public String getDefaultPreferredApn() {
         return TextUtils.emptyIfNull(mCarrierConfig.getString(
                 CarrierConfigManager.KEY_DEFAULT_PREFERRED_APN_NAME_STRING));
     }
@@ -1414,7 +1437,9 @@
      * cases that we need to use "user-added" APN for initial attach. The regular way to configure
      * IA APN is by adding "IA" type to the APN in APN config.
      */
-    public @NonNull @ApnType List<Integer> getAllowedInitialAttachApnTypes() {
+    @NonNull
+    @ApnType
+    public List<Integer> getAllowedInitialAttachApnTypes() {
         String[] apnTypesArray = mCarrierConfig.getStringArray(
                 CarrierConfigManager.KEY_ALLOWED_INITIAL_ATTACH_APN_TYPES_STRING_ARRAY);
         if (apnTypesArray != null) {
@@ -1461,7 +1486,8 @@
     /**
      * @return The capabilities that network will be forced to mark as cellular transport.
      */
-    public @NetCapability Set<Integer> getForcedCellularTransportCapabilities() {
+    @NetCapability
+    public Set<Integer> getForcedCellularTransportCapabilities() {
         String[] forcedCellularTransportCapabilities = mResources.getStringArray(
                 com.android.internal.R.array.config_force_cellular_transport_capabilities);
 
diff --git a/src/java/com/android/internal/telephony/data/DataEvaluation.java b/src/java/com/android/internal/telephony/data/DataEvaluation.java
index ae7023e..f5eae91 100644
--- a/src/java/com/android/internal/telephony/data/DataEvaluation.java
+++ b/src/java/com/android/internal/telephony/data/DataEvaluation.java
@@ -59,7 +59,7 @@
      *
      * @param reason The reason for this evaluation.
      */
-    public DataEvaluation(DataEvaluationReason reason) {
+    public DataEvaluation(@NonNull DataEvaluationReason reason) {
         mDataEvaluationReason = reason;
     }
 
@@ -105,14 +105,16 @@
     /**
      * @return List of data disallowed reasons.
      */
-    public @NonNull List<DataDisallowedReason> getDataDisallowedReasons() {
+    @NonNull
+    public List<DataDisallowedReason> getDataDisallowedReasons() {
         return new ArrayList<>(mDataDisallowedReasons);
     }
 
     /**
      * @return The data allowed reason.
      */
-    public @NonNull DataAllowedReason getDataAllowedReason() {
+    @NonNull
+    public DataAllowedReason getDataAllowedReason() {
         return mDataAllowedReason;
     }
 
@@ -128,7 +130,8 @@
     /**
      * @return The candidate data profile for setup data network.
      */
-    public @Nullable DataProfile getCandidateDataProfile() {
+    @Nullable
+    public DataProfile getCandidateDataProfile() {
         return mCandidateDataProfile;
     }
 
@@ -136,7 +139,7 @@
      * @return {@code true} if the evaluation contains disallowed reasons.
      */
     public boolean containsDisallowedReasons() {
-        return mDataDisallowedReasons.size() != 0;
+        return !mDataDisallowedReasons.isEmpty();
     }
 
     /**
@@ -422,7 +425,8 @@
     @Override
     public String toString() {
         StringBuilder evaluationStr = new StringBuilder();
-        evaluationStr.append("Data evaluation: evaluation reason:" + mDataEvaluationReason + ", ");
+        evaluationStr.append("Data evaluation: evaluation reason:")
+                .append(mDataEvaluationReason).append(", ");
         if (!mDataDisallowedReasons.isEmpty()) {
             evaluationStr.append("Data disallowed reasons:");
             for (DataDisallowedReason reason : mDataDisallowedReasons) {
@@ -432,8 +436,8 @@
             evaluationStr.append("Data allowed reason:");
             evaluationStr.append(" ").append(mDataAllowedReason);
         }
-        evaluationStr.append(", candidate profile=" + mCandidateDataProfile);
-        evaluationStr.append(", time=" + DataUtils.systemTimeToString(mEvaluatedTime));
+        evaluationStr.append(", candidate profile=").append(mCandidateDataProfile);
+        evaluationStr.append(", time=").append(DataUtils.systemTimeToString(mEvaluatedTime));
         return evaluationStr.toString();
     }
 
diff --git a/src/java/com/android/internal/telephony/data/DataNetwork.java b/src/java/com/android/internal/telephony/data/DataNetwork.java
index 347312f..57d242b 100644
--- a/src/java/com/android/internal/telephony/data/DataNetwork.java
+++ b/src/java/com/android/internal/telephony/data/DataNetwork.java
@@ -125,6 +125,7 @@
 import java.util.Comparator;
 import java.util.HashSet;
 import java.util.List;
+import java.util.ListIterator;
 import java.util.Map;
 import java.util.Objects;
 import java.util.Set;
@@ -136,11 +137,11 @@
 
 /**
  * DataNetwork class represents a single PDN (Packet Data Network).
- *
+ * <p>
  * The life cycle of a data network starts from {@link ConnectingState}. If setup data request
  * succeeds, then it enters {@link ConnectedState}, otherwise it enters
  * {@link DisconnectedState}.
- *
+ * <p>
  * When data network is in {@link ConnectingState}, it can enter {@link HandoverState} if handover
  * between IWLAN and cellular occurs. After handover completes or fails, it return back to
  * {@link ConnectedState}. When the data network is about to be disconnected, it first enters
@@ -149,9 +150,9 @@
  * notifies data disconnected. Note that an unsolicited disconnected event from {@link DataService}
  * or any vendor HAL failure response can immediately move data network from {@link ConnectedState}
  * to {@link DisconnectedState}. {@link DisconnectedState} is the final state of a data network.
- *
+ * <p>
  * State machine diagram:
- *
+ * <p>
  *
  *                                  ┌─────────┐
  *                                  │Handover │
@@ -504,10 +505,12 @@
     private final DisconnectedState mDisconnectedState = new DisconnectedState();
 
     /** The phone instance. */
-    private final @NonNull Phone mPhone;
+    @NonNull
+    private final Phone mPhone;
 
     /** Feature flags */
-    private final @NonNull FeatureFlags mFlags;
+    @NonNull
+    private final FeatureFlags mFlags;
 
     /**
      * The subscription id. This is assigned when the network is created, and not supposed to
@@ -516,7 +519,8 @@
     private final int mSubId;
 
     /** The network score of this network. */
-    private @NonNull NetworkScore mNetworkScore;
+    @NonNull
+    private NetworkScore mNetworkScore;
 
     /**
      * Indicates that
@@ -531,13 +535,15 @@
     private boolean mEverConnected = false;
 
     /** RIL interface. */
-    private final @NonNull CommandsInterface mRil;
+    @NonNull
+    private final CommandsInterface mRil;
 
     /** Local log. */
     private final LocalLog mLocalLog = new LocalLog(128);
 
     /** The callback to receives data network state update. */
-    private final @NonNull DataNetworkCallback mDataNetworkCallback;
+    @NonNull
+    private final DataNetworkCallback mDataNetworkCallback;
 
     /** The log tag. */
     private String mLogTag;
@@ -546,7 +552,8 @@
     private final DataCallSessionStats mDataCallSessionStats;
 
     /** Metrics of per data network validation. */
-    private final @NonNull DataNetworkValidationStats mDataNetworkValidationStats;
+    @NonNull
+    private final DataNetworkValidationStats mDataNetworkValidationStats;
 
     /**
      * The unique context id assigned by the data service in {@link DataCallResponse#getId()}. One
@@ -570,71 +577,92 @@
      * Data service managers for accessing {@link AccessNetworkConstants#TRANSPORT_TYPE_WWAN} and
      * {@link AccessNetworkConstants#TRANSPORT_TYPE_WLAN} data services.
      */
-    private final @NonNull SparseArray<DataServiceManager> mDataServiceManagers;
+    @NonNull
+    private final SparseArray<DataServiceManager> mDataServiceManagers;
 
     /** Access networks manager. */
-    private final @NonNull AccessNetworksManager mAccessNetworksManager;
+    @NonNull
+    private final AccessNetworksManager mAccessNetworksManager;
 
     /** Data network controller. */
-    private final @NonNull DataNetworkController mDataNetworkController;
+    @NonNull
+    private final DataNetworkController mDataNetworkController;
 
     /** Data network controller callback. */
-    private final @NonNull DataNetworkController.DataNetworkControllerCallback
+    @NonNull
+    private final DataNetworkController.DataNetworkControllerCallback
             mDataNetworkControllerCallback;
 
     /** Data settings manager callback. */
-    private @NonNull DataSettingsManagerCallback mDataSettingsManagerCallback;
+    @NonNull
+    private DataSettingsManagerCallback mDataSettingsManagerCallback;
 
     /** Data config manager. */
-    private final @NonNull DataConfigManager mDataConfigManager;
+    @NonNull
+    private final DataConfigManager mDataConfigManager;
 
     /** VCN manager. */
-    private final @Nullable VcnManager mVcnManager;
+    @Nullable
+    private final VcnManager mVcnManager;
 
     /** VCN policy changed listener. */
-    private @Nullable VcnNetworkPolicyChangeListener mVcnPolicyChangeListener;
+    @Nullable
+    private VcnNetworkPolicyChangeListener mVcnPolicyChangeListener;
 
     /** The network agent associated with this data network. */
-    private @NonNull TelephonyNetworkAgent mNetworkAgent;
+    @NonNull
+    private TelephonyNetworkAgent mNetworkAgent;
 
     /** QOS callback tracker. This is only created after network connected on WWAN. */
-    private @Nullable QosCallbackTracker mQosCallbackTracker;
+    @Nullable
+    private QosCallbackTracker mQosCallbackTracker;
 
     /** NAT keepalive tracker. */
-    private @Nullable KeepaliveTracker mKeepaliveTracker;
+    @Nullable
+    private KeepaliveTracker mKeepaliveTracker;
 
     /** The data profile used to establish this data network. */
-    private @NonNull DataProfile mDataProfile;
+    @NonNull
+    private DataProfile mDataProfile;
 
     /**
      * The data profile used for data handover. Some carriers might use different data profile
      * between IWLAN and cellular. Only set before handover started.
      */
-    private @Nullable DataProfile mHandoverDataProfile;
+    @Nullable
+    private DataProfile mHandoverDataProfile;
 
     /** The network capabilities of this data network. */
-    private @NonNull NetworkCapabilities mNetworkCapabilities;
+    @NonNull
+    private NetworkCapabilities mNetworkCapabilities;
 
     /** The matched traffic descriptor returned from setup data call request. */
-    private final @NonNull List<TrafficDescriptor> mTrafficDescriptors = new ArrayList<>();
+    @NonNull
+    private final List<TrafficDescriptor> mTrafficDescriptors = new ArrayList<>();
 
     /** The link properties of this data network. */
-    private @NonNull LinkProperties mLinkProperties;
+    @NonNull
+    private LinkProperties mLinkProperties;
 
     /** The network slice info. */
-    private @Nullable NetworkSliceInfo mNetworkSliceInfo;
+    @Nullable
+    private NetworkSliceInfo mNetworkSliceInfo;
 
     /** The link status (i.e. RRC state). */
-    private @LinkStatus int mLinkStatus = DataCallResponse.LINK_STATUS_UNKNOWN;
+    @LinkStatus
+    private int mLinkStatus = DataCallResponse.LINK_STATUS_UNKNOWN;
 
     /** The network bandwidth. */
-    private @NonNull NetworkBandwidth mNetworkBandwidth = new NetworkBandwidth(14, 14);
+    @NonNull
+    private NetworkBandwidth mNetworkBandwidth = new NetworkBandwidth(14, 14);
 
     /** The TCP buffer sizes config. */
-    private @NonNull String mTcpBufferSizes;
+    @NonNull
+    private String mTcpBufferSizes;
 
     /** The telephony display info. */
-    private @NonNull TelephonyDisplayInfo mTelephonyDisplayInfo;
+    @NonNull
+    private TelephonyDisplayInfo mTelephonyDisplayInfo;
 
     /** Whether {@link NetworkCapabilities#NET_CAPABILITY_TEMPORARILY_NOT_METERED} is supported. */
     private boolean mTempNotMeteredSupported = false;
@@ -646,7 +674,8 @@
     private boolean mCongested = false;
 
     /** The network requests associated with this data network */
-    private final @NonNull NetworkRequestList mAttachedNetworkRequestList =
+    @NonNull
+    private final NetworkRequestList mAttachedNetworkRequestList =
             new NetworkRequestList();
 
     /**
@@ -655,18 +684,21 @@
      * {@link DataServiceCallback#onDataCallListChanged(List)}. The very first update must be
      * from {@link DataServiceCallback#onSetupDataCallComplete(int, DataCallResponse)}.
      */
-    private @Nullable DataCallResponse mDataCallResponse = null;
+    @Nullable
+    private DataCallResponse mDataCallResponse = null;
 
     /**
      * The fail cause from either setup data failure or unsolicited disconnect reported by data
      * service.
      */
-    private @DataFailureCause int mFailCause = DataFailCause.NONE;
+    @DataFailureCause
+    private int mFailCause = DataFailCause.NONE;
 
     /**
      * The tear down reason if the data call is voluntarily deactivated, not due to failure.
      */
-    private @TearDownReason int mTearDownReason = TEAR_DOWN_REASON_NONE;
+    @TearDownReason
+    private int mTearDownReason = TEAR_DOWN_REASON_NONE;
 
     /**
      * The retry delay in milliseconds from setup data failure.
@@ -686,12 +718,14 @@
      * The current transport of the data network. For handover, the current transport will be set
      * after handover completes.
      */
-    private @TransportType int mTransport;
+    @TransportType
+    private int mTransport;
 
     /**
      * The last known data network type.
      */
-    private @NetworkType int mLastKnownDataNetworkType;
+    @NetworkType
+    private int mLastKnownDataNetworkType;
 
     /**
      * The last known roaming state of this data network.
@@ -704,27 +738,33 @@
     private final boolean mIsSatellite;
 
     /** The reason that why setting up this data network is allowed. */
-    private final @NonNull DataAllowedReason mDataAllowedReason;
+    @NonNull
+    private final DataAllowedReason mDataAllowedReason;
 
     /**
      * PCO (Protocol Configuration Options) data received from the network. The first key is the
      * cid of the PCO data, the second key is the PCO id, the value is the PCO data.
      */
-    private final @NonNull Map<Integer, Map<Integer, PcoData>> mPcoData = new ArrayMap<>();
+    @NonNull
+    private final Map<Integer, Map<Integer, PcoData>> mPcoData = new ArrayMap<>();
 
     /** The QOS bearer sessions. */
-    private final @NonNull List<QosBearerSession> mQosBearerSessions = new ArrayList<>();
+    @NonNull
+    private final List<QosBearerSession> mQosBearerSessions = new ArrayList<>();
 
     /** The QOS for the Default Bearer, should be non-null on LTE and NR */
-    private @Nullable Qos mDefaultQos;
+    @Nullable
+    private Qos mDefaultQos;
 
     /**
      * The UIDs of packages that have carrier privilege.
      */
-    private @NonNull int[] mAdministratorUids = new int[0];
+    @NonNull
+    private int[] mAdministratorUids = new int[0];
 
     /** Carrier privileges callback to monitor administrator UID change. */
-    private @Nullable TelephonyManager.CarrierPrivilegesCallback mCarrierPrivilegesCallback;
+    @Nullable
+    private TelephonyManager.CarrierPrivilegesCallback mCarrierPrivilegesCallback;
 
     /**
      * Carrier service package uid. This UID will not change through the life cycle of data network.
@@ -734,36 +774,42 @@
     /**
      * Link bandwidth estimator callback for receiving latest link bandwidth information.
      */
-    private @Nullable LinkBandwidthEstimatorCallback mLinkBandwidthEstimatorCallback;
+    @Nullable
+    private LinkBandwidthEstimatorCallback mLinkBandwidthEstimatorCallback;
 
     /**
      * Data config callback for carrier config update.
      */
-    private @Nullable DataConfigManagerCallback mDataConfigManagerCallback;
+    @Nullable
+    private DataConfigManagerCallback mDataConfigManagerCallback;
 
     /**
      * Network validation status for this data network. If the data service provider does not
      * support the network validation feature, should be UNSUPPORTED.
      */
-    private @PreciseDataConnectionState.NetworkValidationStatus int mNetworkValidationStatus =
+    @PreciseDataConnectionState.NetworkValidationStatus
+    private int mNetworkValidationStatus =
             PreciseDataConnectionState.NETWORK_VALIDATION_UNSUPPORTED;
 
     /**
      * Callback used to respond to a network validation request to determine whether the request is
      * successfully submitted. If the request has been submitted, change it to null.
      */
-    private @Nullable Consumer<Integer> mNetworkValidationResultCodeCallback;
+    @Nullable
+    private Consumer<Integer> mNetworkValidationResultCodeCallback;
 
     /**
      * Callback used to listen QNS preference changes.
      */
-    private @Nullable AccessNetworksManagerCallback mAccessNetworksManagerCallback;
+    @Nullable
+    private AccessNetworksManagerCallback mAccessNetworksManagerCallback;
 
     /**
      * PreciseDataConnectionState, the most recently notified. If it has never been notified, it is
      * null.
      */
-    private @Nullable PreciseDataConnectionState mPreciseDataConnectionState;
+    @Nullable
+    private PreciseDataConnectionState mPreciseDataConnectionState;
 
     /**
      * The network bandwidth.
@@ -1004,23 +1050,36 @@
                 && transport == AccessNetworkConstants.TRANSPORT_TYPE_WWAN;
         mDataAllowedReason = dataAllowedReason;
         dataProfile.setLastSetupTimestamp(SystemClock.elapsedRealtime());
-        mAttachedNetworkRequestList.addAll(networkRequestList);
         for (int transportType : mAccessNetworksManager.getAvailableTransports()) {
             mCid.put(transportType, INVALID_CID);
         }
         mTelephonyDisplayInfo = mPhone.getDisplayInfoController().getTelephonyDisplayInfo();
         mTcpBufferSizes = mDataConfigManager.getTcpConfigString(mTelephonyDisplayInfo);
 
-        for (TelephonyNetworkRequest networkRequest : networkRequestList) {
-            networkRequest.setAttachedNetwork(DataNetwork.this);
-            networkRequest.setState(TelephonyNetworkRequest.REQUEST_STATE_SATISFIED);
-        }
-
+        // network capabilities infer connectivity transport and MMTEL from the requested
+        // capabilities.
+        // TODO: Ideally we shouldn't infer network capabilities base on the requested capabilities,
+        // but currently there are 2 hacks associated with getForcedCellularTransportCapabilities
+        // and IMS service requesting IMS|MMTEL that need to support. When we stop supporting these
+        // cases, we shouldn't consider the requests when determining the network capabilities.
+        mAttachedNetworkRequestList.addAll(networkRequestList);
         // Update the capabilities in the constructor is to make sure the data network has initial
         // capability immediately after created. Doing this connecting state creates the window that
         // DataNetworkController might check if existing data network's capability can satisfy the
         // next network request within this window.
         updateNetworkCapabilities();
+
+        // Remove the requests that can't use the initial capabilities
+        ListIterator<TelephonyNetworkRequest> iter = mAttachedNetworkRequestList.listIterator();
+        while (iter.hasNext()) {
+            TelephonyNetworkRequest request = iter.next();
+            if (request.canBeSatisfiedBy(mNetworkCapabilities)) {
+                request.setAttachedNetwork(DataNetwork.this);
+                request.setState(TelephonyNetworkRequest.REQUEST_STATE_SATISFIED);
+            } else {
+                iter.remove();
+            }
+        }
     }
 
     /**
@@ -1064,7 +1123,8 @@
      *
      * @return The telephony network agent.
      */
-    private @NonNull TelephonyNetworkAgent createNetworkAgent() {
+    @NonNull
+    private TelephonyNetworkAgent createNetworkAgent() {
         final NetworkAgentConfig.Builder configBuilder = new NetworkAgentConfig.Builder();
         configBuilder.setLegacyType(ConnectivityManager.TYPE_MOBILE);
         configBuilder.setLegacyTypeName("MOBILE");
@@ -2517,21 +2577,24 @@
     /**
      * @return The network capabilities of this data network.
      */
-    public @NonNull NetworkCapabilities getNetworkCapabilities() {
+    @NonNull
+    public NetworkCapabilities getNetworkCapabilities() {
         return mNetworkCapabilities;
     }
 
     /**
      * @return The link properties of this data network.
      */
-    public @NonNull LinkProperties getLinkProperties() {
+    @NonNull
+    public LinkProperties getLinkProperties() {
         return mLinkProperties;
     }
 
     /**
      * @return The data profile of this data network.
      */
-    public @NonNull DataProfile getDataProfile() {
+    @NonNull
+    public DataProfile getDataProfile() {
         return mDataProfile;
     }
 
@@ -2595,7 +2658,8 @@
      *
      * @return The fail cause. {@link DataFailCause#NONE} if succeeds.
      */
-    private @DataFailureCause int getFailCauseFromDataCallResponse(
+    @DataFailureCause
+    private int getFailCauseFromDataCallResponse(
             @DataServiceCallback.ResultCode int resultCode, @Nullable DataCallResponse response) {
         int failCause = DataFailCause.NONE;
         switch (resultCode) {
@@ -2626,7 +2690,8 @@
      *
      * @param response The data call response from data service.
      */
-    private void updateDataNetwork(@NonNull DataCallResponse response) {
+    private void updateDataNetwork(@Nullable DataCallResponse response) {
+        if (response == null) return;
         mCid.put(mTransport, response.getId());
         LinkProperties linkProperties = new LinkProperties();
 
@@ -2932,8 +2997,8 @@
      * will be performed. {@code null} if the data network is already disconnected or being
      * disconnected.
      */
-    public @Nullable Runnable tearDownWhenConditionMet(@TearDownReason int reason,
-            long timeoutMillis) {
+    @Nullable
+    public Runnable tearDownWhenConditionMet(@TearDownReason int reason, long timeoutMillis) {
         if (getCurrentState() == null || isDisconnected() || isDisconnecting()) {
             loge("tearDownWhenConditionMet: Not in the right state. State=" + getCurrentState());
             return null;
@@ -3196,7 +3261,8 @@
     /**
      * @return The current network type reported by the network service.
      */
-    private @NetworkType int getDataNetworkType() {
+    @NetworkType
+    private int getDataNetworkType() {
         return getDataNetworkType(mTransport);
     }
 
@@ -3206,7 +3272,8 @@
      * @param transport The transport.
      * @return The data network type.
      */
-    private @NetworkType int getDataNetworkType(@TransportType int transport) {
+    @NetworkType
+    private int getDataNetworkType(@TransportType int transport) {
         // WLAN transport can't have network type other than IWLAN. Ideally service state tracker
         // should report the correct RAT, but sometimes race condition could happen that service
         // state is reset to out of service and RAT not updated to IWLAN yet.
@@ -3226,7 +3293,8 @@
     /**
      * @return The physical link status (i.e. RRC state).
      */
-    public @LinkStatus int getLinkStatus() {
+    @LinkStatus
+    public int getLinkStatus() {
         return mLinkStatus;
     }
 
@@ -3249,7 +3317,8 @@
     /**
      * @return Network registration info on the current transport.
      */
-    private @Nullable NetworkRegistrationInfo getNetworkRegistrationInfo() {
+    @Nullable
+    private NetworkRegistrationInfo getNetworkRegistrationInfo() {
         NetworkRegistrationInfo nri = mPhone.getServiceStateTracker().getServiceState()
                 .getNetworkRegistrationInfo(NetworkRegistrationInfo.DOMAIN_PS, mTransport);
         if (nri == null) {
@@ -3271,7 +3340,8 @@
      *
      * @see #getPriority()
      */
-    public @NetCapability int getApnTypeNetworkCapability() {
+    @NetCapability
+    public int getApnTypeNetworkCapability() {
         if (!mAttachedNetworkRequestList.isEmpty()) {
             // The highest priority network request is always at the top of list.
             return mAttachedNetworkRequestList.get(0).getApnTypeNetworkCapability();
@@ -3312,7 +3382,8 @@
     /**
      * @return The attached network request list.
      */
-    public @NonNull NetworkRequestList getAttachedNetworkRequestList() {
+    @NonNull
+    public NetworkRequestList getAttachedNetworkRequestList() {
         return mAttachedNetworkRequestList;
     }
 
@@ -3361,11 +3432,13 @@
     /**
      * @return The current transport of the data network.
      */
-    public @TransportType int getTransport() {
+    @TransportType
+    public int getTransport() {
         return mTransport;
     }
 
-    private @DataState int getState() {
+    @DataState
+    private int getState() {
         IState state = getCurrentState();
         if (state == null || isDisconnected()) {
             return TelephonyManager.DATA_DISCONNECTED;
@@ -3424,7 +3497,7 @@
     /**
      * Send the precise data connection state to the listener of
      * {@link android.telephony.TelephonyCallback.PreciseDataConnectionStateListener}.
-     *
+     * <p>
      * Note that notify only when {@link DataState} or {@link
      * PreciseDataConnectionState.NetworkValidationStatus} or {@link TelephonyNetworkAgent#getId}
      * changes.
@@ -3444,7 +3517,7 @@
 
     /**
      * Request the data network to handover to the target transport.
-     *
+     * <p>
      * This is the starting point of initiating IWLAN/cellular handover. It will first call
      * {@link DataServiceManager#startHandover(int, Message)} to notify source transport that
      * handover is about to start, and then call {@link DataServiceManager#setupDataCall(int,
@@ -3655,7 +3728,8 @@
     /**
      * @return The last known data network type of the data network.
      */
-    public @NetworkType int getLastKnownDataNetworkType() {
+    @NetworkType
+    public int getLastKnownDataNetworkType() {
         return mLastKnownDataNetworkType;
     }
 
@@ -3669,7 +3743,8 @@
     /**
      * @return The PCO data received from the network.
      */
-    public @NonNull Map<Integer, PcoData> getPcoData() {
+    @NonNull
+    public Map<Integer, PcoData> getPcoData() {
         if (mTransport == AccessNetworkConstants.TRANSPORT_TYPE_WLAN
                 || mCid.get(mTransport) == INVALID_CID) {
             return Collections.emptyMap();
@@ -3789,7 +3864,8 @@
      * @param reason Data deactivation reason.
      * @return The deactivation reason in string format.
      */
-    public static @NonNull String tearDownReasonToString(@TearDownReason int reason) {
+    @NonNull
+    public static String tearDownReasonToString(@TearDownReason int reason) {
         return switch (reason) {
             case TEAR_DOWN_REASON_NONE -> "NONE";
             case TEAR_DOWN_REASON_CONNECTIVITY_SERVICE_UNWANTED -> "CONNECTIVITY_SERVICE_UNWANTED";
@@ -3844,7 +3920,8 @@
      * @param event The event
      * @return The event in string format.
      */
-    private static @NonNull String eventToString(int event) {
+    @NonNull
+    private static String eventToString(int event) {
         return switch (event) {
             case EVENT_DATA_CONFIG_UPDATED -> "EVENT_DATA_CONFIG_UPDATED";
             case EVENT_ATTACH_NETWORK_REQUEST -> "EVENT_ATTACH_NETWORK_REQUEST";
@@ -3892,7 +3969,8 @@
     /**
      * @return The short name of the data network (e.g. DN-C-1)
      */
-    public @NonNull String name() {
+    @NonNull
+    public String name() {
         return mLogTag;
     }
 
diff --git a/src/java/com/android/internal/telephony/data/DataNetworkController.java b/src/java/com/android/internal/telephony/data/DataNetworkController.java
index 66b20a2..a720e03 100644
--- a/src/java/com/android/internal/telephony/data/DataNetworkController.java
+++ b/src/java/com/android/internal/telephony/data/DataNetworkController.java
@@ -266,17 +266,26 @@
     private final String mLogTag;
     private final LocalLog mLocalLog = new LocalLog(128);
 
-    private final @NonNull DataConfigManager mDataConfigManager;
-    private final @NonNull DataSettingsManager mDataSettingsManager;
-    private final @NonNull DataProfileManager mDataProfileManager;
-    private final @NonNull DataStallRecoveryManager mDataStallRecoveryManager;
-    private final @NonNull AccessNetworksManager mAccessNetworksManager;
-    private final @NonNull DataRetryManager mDataRetryManager;
-    private final @NonNull ImsManager mImsManager;
-    private final @NonNull TelecomManager mTelecomManager;
-    private final @NonNull NetworkPolicyManager mNetworkPolicyManager;
-    private final @NonNull SparseArray<DataServiceManager> mDataServiceManagers =
-            new SparseArray<>();
+    @NonNull
+    private final DataConfigManager mDataConfigManager;
+    @NonNull
+    private final DataSettingsManager mDataSettingsManager;
+    @NonNull
+    private final DataProfileManager mDataProfileManager;
+    @NonNull
+    private final DataStallRecoveryManager mDataStallRecoveryManager;
+    @NonNull
+    private final AccessNetworksManager mAccessNetworksManager;
+    @NonNull
+    private final DataRetryManager mDataRetryManager;
+    @NonNull
+    private final ImsManager mImsManager;
+    @NonNull
+    private final TelecomManager mTelecomManager;
+    @NonNull
+    private final NetworkPolicyManager mNetworkPolicyManager;
+    @NonNull
+    private final SparseArray<DataServiceManager> mDataServiceManagers = new SparseArray<>();
 
     /** The subscription index associated with this data network controller. */
     private int mSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
@@ -284,35 +293,41 @@
     /** The current service state of the device. */
     // Note that keeping a copy here instead of directly using ServiceStateTracker.getServiceState()
     // is intended for detecting the delta.
-    private @NonNull ServiceState mServiceState;
+    @NonNull
+    private ServiceState mServiceState;
 
     /** The list of SubscriptionPlans, updated when initialized and when plans are changed. */
-    private final @NonNull List<SubscriptionPlan> mSubscriptionPlans = new ArrayList<>();
+    @NonNull
+    private final List<SubscriptionPlan> mSubscriptionPlans = new ArrayList<>();
 
     /**
      * The set of network types an unmetered override applies to, set by onSubscriptionOverride
      * and cleared when the device is rebooted or the override expires.
      */
-    private final @NonNull @NetworkType Set<Integer> mUnmeteredOverrideNetworkTypes =
-            new ArraySet<>();
+    @NonNull
+    @NetworkType
+    private final Set<Integer> mUnmeteredOverrideNetworkTypes = new ArraySet<>();
 
     /**
      * The set of network types a congested override applies to, set by onSubscriptionOverride
      * and cleared when the device is rebooted or the override expires.
      */
-    private final @NonNull @NetworkType Set<Integer> mCongestedOverrideNetworkTypes =
-            new ArraySet<>();
+    @NonNull
+    @NetworkType
+    private final Set<Integer> mCongestedOverrideNetworkTypes = new ArraySet<>();
 
     /**
      * The list of all network requests.
      */
-    private final @NonNull NetworkRequestList mAllNetworkRequestList = new NetworkRequestList();
+    @NonNull
+    private final NetworkRequestList mAllNetworkRequestList = new NetworkRequestList();
 
     /**
      * The current data network list, including the ones that are connected, connecting, or
      * disconnecting.
      */
-    private final @NonNull List<DataNetwork> mDataNetworkList = new ArrayList<>();
+    @NonNull
+    private final List<DataNetwork> mDataNetworkList = new ArrayList<>();
 
     /** {@code true} indicating at least one data network exists. */
     private boolean mAnyDataNetworkExisting;
@@ -320,27 +335,33 @@
     /**
      * Contain the last 10 data networks that were connected. This is for debugging purposes only.
      */
-    private final @NonNull List<DataNetwork> mPreviousConnectedDataNetworkList = new ArrayList<>();
+    @NonNull
+    private final List<DataNetwork> mPreviousConnectedDataNetworkList = new ArrayList<>();
 
     /**
      * The internet data network state. Note that this is the best effort if more than one
      * data network supports internet.
      */
-    private @DataState int mInternetDataNetworkState = TelephonyManager.DATA_DISCONNECTED;
+    @DataState
+    private int mInternetDataNetworkState = TelephonyManager.DATA_DISCONNECTED;
 
     /** All the current connected/handover internet networks.  */
-    @NonNull private Set<DataNetwork> mConnectedInternetNetworks = new HashSet<>();
+    @NonNull
+    private Set<DataNetwork> mConnectedInternetNetworks = new HashSet<>();
 
     /**
      * The IMS data network state. For now this is just for debugging purposes.
      */
-    private @DataState int mImsDataNetworkState = TelephonyManager.DATA_DISCONNECTED;
+    @DataState
+    private int mImsDataNetworkState = TelephonyManager.DATA_DISCONNECTED;
 
     /** Overall aggregated link status from internet data networks. */
-    private @LinkStatus int mInternetLinkStatus = DataCallResponse.LINK_STATUS_UNKNOWN;
+    @LinkStatus
+    private int mInternetLinkStatus = DataCallResponse.LINK_STATUS_UNKNOWN;
 
     /** Data network controller callbacks. */
-    private final @NonNull Set<DataNetworkControllerCallback> mDataNetworkControllerCallbacks =
+    @NonNull
+    private final Set<DataNetworkControllerCallback> mDataNetworkControllerCallbacks =
             new ArraySet<>();
 
     /** Indicates if packet switch data is restricted by the cellular network. */
@@ -356,48 +377,59 @@
      * Indicates if the data services are bound. Key if the transport type, and value is the boolean
      * indicating service is bound or not.
      */
-    private final @NonNull SparseBooleanArray mDataServiceBound = new SparseBooleanArray();
+    @NonNull
+    private final SparseBooleanArray mDataServiceBound = new SparseBooleanArray();
 
     /** SIM state. */
-    private @SimState int mSimState = TelephonyManager.SIM_STATE_UNKNOWN;
+    @SimState
+    private int mSimState = TelephonyManager.SIM_STATE_UNKNOWN;
 
     /** Data activity. */
-    private @DataActivityType int mDataActivity = TelephonyManager.DATA_ACTIVITY_NONE;
+    @DataActivityType
+    private int mDataActivity = TelephonyManager.DATA_ACTIVITY_NONE;
 
     /**
      * IMS state callbacks. Key is the IMS feature, value is the callback.
      */
-    private final @NonNull SparseArray<ImsStateCallback> mImsStateCallbacks = new SparseArray<>();
+    @NonNull
+    private final SparseArray<ImsStateCallback> mImsStateCallbacks = new SparseArray<>();
 
     /** Registered IMS features. Unregistered IMS features are removed from the set. */
-    private final @NonNull Set<Integer> mRegisteredImsFeatures = new ArraySet<>();
+    @NonNull
+    private final Set<Integer> mRegisteredImsFeatures = new ArraySet<>();
 
     /** IMS feature package names. Key is the IMS feature, value is the package name. */
-    private final @NonNull SparseArray<String> mImsFeaturePackageName = new SparseArray<>();
+    @NonNull
+    private final SparseArray<String> mImsFeaturePackageName = new SparseArray<>();
 
     /**
      * Networks that are pending IMS de-registration. Key is the data network, value is the function
      * to tear down the network.
      */
-    private final @NonNull Map<DataNetwork, Runnable> mPendingImsDeregDataNetworks =
-            new ArrayMap<>();
+    @NonNull
+    private final Map<DataNetwork, Runnable> mPendingImsDeregDataNetworks = new ArrayMap<>();
 
     /**
      * IMS feature registration callback. The key is the IMS feature, the value is the registration
      * callback. When new SIM inserted, the old callbacks associated with the old subscription index
      * will be unregistered.
      */
-    private final @NonNull SparseArray<RegistrationManager.RegistrationCallback>
+    @NonNull
+    private final SparseArray<RegistrationManager.RegistrationCallback>
             mImsFeatureRegistrationCallbacks = new SparseArray<>();
 
     /** The counter to detect back to back release/request IMS network. */
-    private @NonNull SlidingWindowEventCounter mImsThrottleCounter;
+    @NonNull
+    private SlidingWindowEventCounter mImsThrottleCounter;
     /** Event counter for unwanted network within time window, is used to trigger anomaly report. */
-    private @NonNull SlidingWindowEventCounter mNetworkUnwantedCounter;
+    @NonNull
+    private SlidingWindowEventCounter mNetworkUnwantedCounter;
     /** Event counter for WLAN setup data failure within time window to trigger anomaly report. */
-    private @NonNull SlidingWindowEventCounter mSetupDataCallWlanFailureCounter;
+    @NonNull
+    private SlidingWindowEventCounter mSetupDataCallWlanFailureCounter;
     /** Event counter for WWAN setup data failure within time window to trigger anomaly report. */
-    private @NonNull SlidingWindowEventCounter mSetupDataCallWwanFailureCounter;
+    @NonNull
+    private SlidingWindowEventCounter mSetupDataCallWwanFailureCounter;
 
     /**
      * The capabilities of the latest released IMS request. To detect back to back release/request
@@ -408,7 +440,8 @@
     /** True after try to release an IMS network; False after try to request an IMS network. */
     private boolean mLastImsOperationIsRelease;
 
-    private final @NonNull FeatureFlags mFeatureFlags;
+    @NonNull
+    private final FeatureFlags mFeatureFlags;
 
     /** The broadcast receiver. */
     private final BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {
@@ -437,7 +470,7 @@
     /**
      * The sorted network request list by priority. The highest priority network request stays at
      * the head of the list. The highest priority is 100, the lowest is 0.
-     *
+     * <p>
      * Note this list is not thread-safe. Do not access the list from different threads.
      */
     @VisibleForTesting
@@ -520,7 +553,8 @@
          * @return The first network request in the list that contains all the provided
          * capabilities.
          */
-        public @Nullable TelephonyNetworkRequest get(@NonNull @NetCapability int[] netCaps) {
+        @Nullable
+        public TelephonyNetworkRequest get(@NonNull @NetCapability int[] netCaps) {
             int index = 0;
             while (index < size()) {
                 TelephonyNetworkRequest networkRequest = get(index);
@@ -529,7 +563,7 @@
                         .boxed()
                         .collect(Collectors.toSet())
                         .containsAll(Arrays.stream(netCaps).boxed()
-                                .collect(Collectors.toList()))) {
+                                .toList())) {
                     return networkRequest;
                 }
                 index++;
@@ -560,6 +594,16 @@
         }
 
         /**
+         * Print "capabilities - connectivity transport". e.g. INTERNET|NOT_RESTRICTED-SATELLITE
+         */
+        @NonNull
+        public String toStringSimplified() {
+            return size() > 0 ? DataUtils.networkCapabilitiesToString(get(0).getCapabilities())
+                    + "-" + DataUtils.connectivityTransportsToString(get(0).getTransportTypes())
+                    : "";
+        }
+
+        /**
          * Dump the network request list.
          *
          * @param pw print writer.
@@ -697,19 +741,26 @@
         private static final String RULE_TAG_ROAMING = "roaming";
 
         /** Handover rule type. */
-        public final @HandoverRuleType int type;
+        @HandoverRuleType
+        public final int type;
 
         /** The applicable source access networks for handover. */
-        public final @NonNull @RadioAccessNetworkType Set<Integer> sourceAccessNetworks;
+        @NonNull
+        @RadioAccessNetworkType
+        public final Set<Integer> sourceAccessNetworks;
 
         /** The applicable target access networks for handover. */
-        public final @NonNull @RadioAccessNetworkType Set<Integer> targetAccessNetworks;
+        @NonNull
+        @RadioAccessNetworkType
+        public final Set<Integer> targetAccessNetworks;
 
         /**
          * The network capabilities to any of which this handover rule applies.
          * If is empty, then capability is ignored as a rule matcher.
          */
-        public final @NonNull @NetCapability Set<Integer> networkCapabilities;
+        @NonNull
+        @NetCapability
+        public final Set<Integer> networkCapabilities;
 
         /** {@code true} indicates this policy is only applicable when the device is roaming. */
         public final boolean isOnlyForRoaming;
@@ -1186,7 +1237,7 @@
                 mSubscriptionPlans.clear();
                 mSubscriptionPlans.addAll(Arrays.asList(plans));
                 mDataNetworkControllerCallbacks.forEach(cb -> cb.invokeFromExecutor(
-                        () -> cb.onSubscriptionPlanOverride()));
+                        cb::onSubscriptionPlanOverride));
                 break;
             case EVENT_SUBSCRIPTION_OVERRIDE:
                 int overrideMask = msg.arg1;
@@ -1206,7 +1257,7 @@
                         }
                     }
                     mDataNetworkControllerCallbacks.forEach(cb -> cb.invokeFromExecutor(
-                            () -> cb.onSubscriptionPlanOverride()));
+                            cb::onSubscriptionPlanOverride));
                 } else if (overrideMask == NetworkPolicyManager.SUBSCRIPTION_OVERRIDE_CONGESTED) {
                     log("Congested subscription override: override=" + override
                             + ", networkTypes=" + Arrays.stream(networkTypes)
@@ -1220,7 +1271,7 @@
                         }
                     }
                     mDataNetworkControllerCallbacks.forEach(cb -> cb.invokeFromExecutor(
-                            () -> cb.onSubscriptionPlanOverride()));
+                            cb::onSubscriptionPlanOverride));
                 } else {
                     loge("Unknown override mask: " + overrideMask);
                 }
@@ -1488,7 +1539,8 @@
      * @return List of the reasons why internet data is not allowed. An empty list if internet
      * is allowed.
      */
-    public @NonNull List<DataDisallowedReason> getInternetDataDisallowedReasons() {
+    @NonNull
+    public List<DataDisallowedReason> getInternetDataDisallowedReasons() {
         TelephonyNetworkRequest internetRequest = new TelephonyNetworkRequest(
                 new NetworkRequest.Builder()
                         .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
@@ -1506,7 +1558,8 @@
      * @param reason The reason for evaluation.
      * @return The data evaluation result.
      */
-    private @NonNull DataEvaluation evaluateNetworkRequest(
+    @NonNull
+    private DataEvaluation evaluateNetworkRequest(
             @NonNull TelephonyNetworkRequest networkRequest, DataEvaluationReason reason) {
         DataEvaluation evaluation = new DataEvaluation(reason);
         int transport = mAccessNetworksManager.getPreferredTransportByNetworkCapability(
@@ -1724,7 +1777,7 @@
         networkRequest.setEvaluation(evaluation);
         // EXTERNAL_QUERY generates too many log spam.
         if (reason != DataEvaluationReason.EXTERNAL_QUERY) {
-            log(evaluation.toString() + ", network type="
+            log(evaluation + ", network type="
                     + TelephonyManager.getNetworkTypeName(getDataNetworkType(transport))
                     + ", reg state="
                     + NetworkRegistrationInfo.registrationStateToString(
@@ -1798,7 +1851,8 @@
      * @return The grouped unsatisfied network requests. The network requests that have the same
      * network capabilities is grouped into one {@link NetworkRequestList}.
      */
-    private @NonNull List<NetworkRequestList> getGroupedUnsatisfiedNetworkRequests() {
+    @NonNull
+    private List<NetworkRequestList> getGroupedUnsatisfiedNetworkRequests() {
         NetworkRequestList networkRequestList = new NetworkRequestList();
         for (TelephonyNetworkRequest networkRequest : mAllNetworkRequestList) {
             if (networkRequest.getState() == TelephonyNetworkRequest.REQUEST_STATE_UNSATISFIED) {
@@ -1819,8 +1873,7 @@
         log("Re-evaluating " + networkRequestLists.stream().mapToInt(List::size).sum()
                 + " unsatisfied network requests in " + networkRequestLists.size()
                 + " groups, " + networkRequestLists.stream().map(
-                        requestList -> DataUtils.networkCapabilitiesToString(
-                                requestList.get(0).getCapabilities()))
+                        NetworkRequestList::toStringSimplified)
                 .collect(Collectors.joining(", ")) + " due to " + reason);
 
         // Second, see if any existing network can satisfy those network requests.
@@ -1853,7 +1906,8 @@
      *
      * @return The data evaluation result.
      */
-    private @NonNull DataEvaluation evaluateDataNetwork(@NonNull DataNetwork dataNetwork,
+    @NonNull
+    private DataEvaluation evaluateDataNetwork(@NonNull DataNetwork dataNetwork,
             @NonNull DataEvaluationReason reason) {
         DataEvaluation evaluation = new DataEvaluation(reason);
         // Bypass all checks for emergency data network.
@@ -2094,35 +2148,30 @@
      */
     private boolean canConnectivityTransportSatisfyNetworkRequest(
             @NonNull TelephonyNetworkRequest networkRequest, @TransportType int transport) {
+        // Check if this is a IWLAN network request.
+        if (transport == AccessNetworkConstants.TRANSPORT_TYPE_WLAN) {
+            // If the request would result in bringing up network on IWLAN, then no
+            // need to check if the device is using satellite network.
+            return true;
+        }
+
         // When the device is on satellite, only restricted network request can request network.
         if (mServiceState.isUsingNonTerrestrialNetwork()
-                && networkRequest.getNativeNetworkRequest().hasCapability(
+                && networkRequest.hasCapability(
                         NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED)) {
             return false;
         }
 
         // If the network request does not specify cellular or satellite, then it can be
         // satisfied when the device is either on cellular ot satellite.
-        if (!networkRequest.getNativeNetworkRequest().hasTransport(
-                NetworkCapabilities.TRANSPORT_CELLULAR)
-                && !networkRequest.getNativeNetworkRequest().hasTransport(
-                        NetworkCapabilities.TRANSPORT_SATELLITE)) {
-            return true;
-        }
-
-        // Check if this is a IWLAN network request.
-        if (networkRequest.getNativeNetworkRequest().hasTransport(
-                NetworkCapabilities.TRANSPORT_CELLULAR)
-                && transport == AccessNetworkConstants.TRANSPORT_TYPE_WLAN) {
-            // If the cellular request would result in bringing up network on IWLAN, then no
-            // need to check if the device is using satellite network.
+        if (!networkRequest.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)
+                && !networkRequest.hasTransport(NetworkCapabilities.TRANSPORT_SATELLITE)) {
             return true;
         }
 
         // As a short term solution, allowing some networks to be always marked as cellular
         // transport if certain capabilities are in the network request.
-        if (networkRequest.getNativeNetworkRequest().hasTransport(
-                NetworkCapabilities.TRANSPORT_CELLULAR) && Arrays.stream(
+        if (networkRequest.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) && Arrays.stream(
                         networkRequest.getCapabilities())
                 .anyMatch(mDataConfigManager.getForcedCellularTransportCapabilities()::contains)) {
             return true;
@@ -2132,11 +2181,9 @@
         // the network is satellite, then the request must specify satellite transport and
         // restricted.
         return (mServiceState.isUsingNonTerrestrialNetwork()
-                && networkRequest.getNativeNetworkRequest().hasTransport(
-                        NetworkCapabilities.TRANSPORT_SATELLITE))
+                && networkRequest.hasTransport(NetworkCapabilities.TRANSPORT_SATELLITE))
                 || (!mServiceState.isUsingNonTerrestrialNetwork()
-                        && networkRequest.getNativeNetworkRequest().hasTransport(
-                        NetworkCapabilities.TRANSPORT_CELLULAR));
+                        && networkRequest.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR));
     }
 
     /**
@@ -2199,7 +2246,8 @@
      *
      * @see CarrierConfigManager#KEY_IWLAN_HANDOVER_POLICY_STRING_ARRAY
      */
-    private @NonNull DataEvaluation evaluateDataNetworkHandover(@NonNull DataNetwork dataNetwork) {
+    @NonNull
+    private DataEvaluation evaluateDataNetworkHandover(@NonNull DataNetwork dataNetwork) {
         DataEvaluation dataEvaluation = new DataEvaluation(DataEvaluationReason.DATA_HANDOVER);
         if (!dataNetwork.isConnecting() && !dataNetwork.isConnected()) {
             dataEvaluation.addDataDisallowedReason(DataDisallowedReason.ILLEGAL_STATE);
@@ -2257,10 +2305,7 @@
                     sourceNetworkType);
             NetworkRegistrationInfo nri = mServiceState.getNetworkRegistrationInfo(
                     NetworkRegistrationInfo.DOMAIN_PS, AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
-            boolean isWwanInService = false;
-            if (nri != null && nri.isInService()) {
-                isWwanInService = true;
-            }
+            boolean isWwanInService = nri != null && nri.isInService();
             // If WWAN is inService, use the real roaming state reported by modem instead of
             // using the overridden roaming state, otherwise get last known roaming state stored
             // in data network.
@@ -2322,7 +2367,8 @@
      * {@link #evaluateDataNetwork(DataNetwork, DataEvaluationReason)}.
      * @return The tear down reason.
      */
-    private static @TearDownReason int getTearDownReason(@NonNull DataEvaluation dataEvaluation) {
+    @TearDownReason
+    private static int getTearDownReason(@NonNull DataEvaluation dataEvaluation) {
         if (dataEvaluation.containsDisallowedReasons()) {
             switch (dataEvaluation.getDataDisallowedReasons().get(0)) {
                 case DATA_DISABLED:
@@ -2523,14 +2569,14 @@
         RegistrationManager.RegistrationCallback callback =
                 new RegistrationManager.RegistrationCallback() {
                     @Override
-                    public void onRegistered(ImsRegistrationAttributes attributes) {
+                    public void onRegistered(@NonNull ImsRegistrationAttributes attributes) {
                         log("IMS " + DataUtils.imsFeatureToString(imsFeature)
                                 + " registered. Attributes=" + attributes);
                         mRegisteredImsFeatures.add(imsFeature);
                     }
 
                     @Override
-                    public void onUnregistered(ImsReasonInfo info) {
+                    public void onUnregistered(@NonNull ImsReasonInfo info) {
                         log("IMS " + DataUtils.imsFeatureToString(imsFeature)
                                 + " deregistered. Info=" + info);
                         mRegisteredImsFeatures.remove(imsFeature);
@@ -2738,8 +2784,8 @@
      * @param dataProfile The data profile.
      * @return The network requests list.
      */
-    private @NonNull NetworkRequestList findSatisfiableNetworkRequests(
-            @NonNull DataProfile dataProfile) {
+    @NonNull
+    private NetworkRequestList findSatisfiableNetworkRequests(@NonNull DataProfile dataProfile) {
         return new NetworkRequestList(mAllNetworkRequestList.stream()
                 .filter(request -> request.getState()
                         == TelephonyNetworkRequest.REQUEST_STATE_UNSATISFIED)
@@ -3038,8 +3084,18 @@
             List<NetworkRequestList> groupRequestLists = getGroupedUnsatisfiedNetworkRequests();
             dataSetupRetryEntry.networkRequestList.stream()
                     .filter(request -> groupRequestLists.stream()
-                            .anyMatch(groupRequestList -> groupRequestList
-                                    .get(request.getCapabilities()) != null))
+                            .anyMatch(groupRequestList -> {
+                                // The unsatisfied request has all the requested capabilities.
+                                if (groupRequestList.get(request.getCapabilities()) == null) {
+                                    return false;
+                                }
+                                TelephonyNetworkRequest leading = groupRequestList.getFirst();
+                                // The unsatisfied request covers all the requested transports.
+                                return leading.getTransportTypes().length == 0
+                                        || request.getTransportTypes().length == 0
+                                        || Arrays.stream(request.getTransportTypes())
+                                        .allMatch(leading::hasTransport);
+                            }))
                     .forEach(requestList::add);
         }
         if (requestList.isEmpty()) {
@@ -3679,17 +3735,13 @@
         DataSpecificRegistrationInfo newDsri = newNri.getDataSpecificInfo();
 
         if (newDsri == null) return false;
-        if ((oldDsri == null || oldDsri.getVopsSupportInfo() == null
+        // If previously VoPS was supported (or does not exist), and now the network reports
+        // VoPS not supported, we should evaluate existing data networks to see if they need
+        // to be torn down.
+        return (oldDsri == null || oldDsri.getVopsSupportInfo() == null
                 || oldDsri.getVopsSupportInfo().isVopsSupported())
                 && (newDsri.getVopsSupportInfo() != null && !newDsri.getVopsSupportInfo()
-                .isVopsSupported())) {
-            // If previously VoPS was supported (or does not exist), and now the network reports
-            // VoPS not supported, we should evaluate existing data networks to see if they need
-            // to be torn down.
-            return true;
-        }
-
-        return false;
+                .isVopsSupported());
     }
 
     /**
@@ -3736,17 +3788,13 @@
         DataSpecificRegistrationInfo newDsri = newPsNri.getDataSpecificInfo();
 
         if (oldDsri == null) return false;
-        if ((newDsri == null || newDsri.getVopsSupportInfo() == null
+        // If previously VoPS was not supported, and now the network reports
+        // VoPS supported (or does not report), we should evaluate the unsatisfied network
+        // request to see if the can be satisfied again.
+        return (newDsri == null || newDsri.getVopsSupportInfo() == null
                 || newDsri.getVopsSupportInfo().isVopsSupported())
                 && (oldDsri.getVopsSupportInfo() != null && !oldDsri.getVopsSupportInfo()
-                .isVopsSupported())) {
-            // If previously VoPS was not supported, and now the network reports
-            // VoPS supported (or does not report), we should evaluate the unsatisfied network
-            // request to see if the can be satisfied again.
-            return true;
-        }
-
-        return false;
+                .isVopsSupported());
     }
 
     /**
@@ -3857,28 +3905,32 @@
     /**
      * @return Data config manager instance.
      */
-    public @NonNull DataConfigManager getDataConfigManager() {
+    @NonNull
+    public DataConfigManager getDataConfigManager() {
         return mDataConfigManager;
     }
 
     /**
      * @return Data profile manager instance.
      */
-    public @NonNull DataProfileManager getDataProfileManager() {
+    @NonNull
+    public DataProfileManager getDataProfileManager() {
         return mDataProfileManager;
     }
 
     /**
      * @return Data settings manager instance.
      */
-    public @NonNull DataSettingsManager getDataSettingsManager() {
+    @NonNull
+    public DataSettingsManager getDataSettingsManager() {
         return mDataSettingsManager;
     }
 
     /**
      * @return Data retry manager instance.
      */
-    public @NonNull DataRetryManager getDataRetryManager() {
+    @NonNull
+    public DataRetryManager getDataRetryManager() {
         return mDataRetryManager;
     }
 
@@ -3886,7 +3938,8 @@
      * @return The list of SubscriptionPlans
      */
     @VisibleForTesting
-    public @NonNull List<SubscriptionPlan> getSubscriptionPlans() {
+    @NonNull
+    public List<SubscriptionPlan> getSubscriptionPlans() {
         return mSubscriptionPlans;
     }
 
@@ -3894,7 +3947,9 @@
      * @return The set of network types an unmetered override applies to
      */
     @VisibleForTesting
-    public @NonNull @NetworkType Set<Integer> getUnmeteredOverrideNetworkTypes() {
+    @NonNull
+    @NetworkType
+    public Set<Integer> getUnmeteredOverrideNetworkTypes() {
         return mUnmeteredOverrideNetworkTypes;
     }
 
@@ -3902,7 +3957,9 @@
      * @return The set of network types a congested override applies to
      */
     @VisibleForTesting
-    public @NonNull @NetworkType Set<Integer> getCongestedOverrideNetworkTypes() {
+    @NonNull
+    @NetworkType
+    public Set<Integer> getCongestedOverrideNetworkTypes() {
         return mCongestedOverrideNetworkTypes;
     }
 
@@ -3912,7 +3969,8 @@
      * @param transport The transport.
      * @return The current network type.
      */
-    private @NetworkType int getDataNetworkType(@TransportType int transport) {
+    @NetworkType
+    private int getDataNetworkType(@TransportType int transport) {
         NetworkRegistrationInfo nri = mServiceState.getNetworkRegistrationInfo(
                 NetworkRegistrationInfo.DOMAIN_PS, transport);
         if (nri != null) {
@@ -3928,8 +3986,8 @@
      * @param transport The transport.
      * @return The registration state.
      */
-    private @RegistrationState int getDataRegistrationState(@NonNull ServiceState ss,
-            @TransportType int transport) {
+    @RegistrationState
+    private int getDataRegistrationState(@NonNull ServiceState ss, @TransportType int transport) {
         NetworkRegistrationInfo nri = ss.getNetworkRegistrationInfo(
                 NetworkRegistrationInfo.DOMAIN_PS, transport);
         if (nri != null) {
@@ -3941,7 +3999,8 @@
     /**
      * @return The data activity. Note this is only updated when screen is on.
      */
-    public @DataActivityType int getDataActivity() {
+    @DataActivityType
+    public int getDataActivity() {
         return mDataActivity;
     }
 
@@ -4087,14 +4146,16 @@
      *
      * @return The data network state.
      */
-    public @DataState int getInternetDataNetworkState() {
+    @DataState
+    public int getInternetDataNetworkState() {
         return mInternetDataNetworkState;
     }
 
     /**
      * @return List of bound data service packages name on WWAN and WLAN.
      */
-    public @NonNull List<String> getDataServicePackages() {
+    @NonNull
+    public List<String> getDataServicePackages() {
         List<String> packages = new ArrayList<>();
         for (int i = 0; i < mDataServiceManagers.size(); i++) {
             packages.add(mDataServiceManagers.valueAt(i).getDataServicePackageName());
@@ -4104,8 +4165,8 @@
 
     /**
      * Request network validation.
-     *
-     * Nnetwork validation request is sent to the DataNetwork that matches the network capability
+     * <p>
+     * Network validation request is sent to the DataNetwork that matches the network capability
      * in the list of DataNetwork owned by the DNC.
      *
      * @param capability network capability {@link NetCapability}
diff --git a/src/java/com/android/internal/telephony/data/DataProfileManager.java b/src/java/com/android/internal/telephony/data/DataProfileManager.java
index 2a2a792..c50d50a 100644
--- a/src/java/com/android/internal/telephony/data/DataProfileManager.java
+++ b/src/java/com/android/internal/telephony/data/DataProfileManager.java
@@ -82,43 +82,51 @@
     private final LocalLog mLocalLog = new LocalLog(128);
 
     /** Data network controller. */
-    private final @NonNull DataNetworkController mDataNetworkController;
+    @NonNull
+    private final DataNetworkController mDataNetworkController;
 
     /** Data config manager. */
-    private final @NonNull DataConfigManager mDataConfigManager;
+    @NonNull
+    private final DataConfigManager mDataConfigManager;
 
     /** Cellular data service. */
-    private final @NonNull DataServiceManager mWwanDataServiceManager;
+    @NonNull
+    private final DataServiceManager mWwanDataServiceManager;
 
     /**
      * All data profiles for the current carrier. Note only data profiles loaded from the APN
      * database will be stored here. The on-demand data profiles (generated dynamically, for
      * example, enterprise data profiles with differentiator) are not stored here.
      */
-    private final @NonNull List<DataProfile> mAllDataProfiles = new ArrayList<>();
+    @NonNull
+    private final List<DataProfile> mAllDataProfiles = new ArrayList<>();
 
     /** The data profile used for initial attach. */
-    private @Nullable DataProfile mInitialAttachDataProfile = null;
+    @Nullable
+    private DataProfile mInitialAttachDataProfile = null;
 
     /** The preferred data profile used for internet. */
-    private @Nullable DataProfile mPreferredDataProfile = null;
+    @Nullable
+    private DataProfile mPreferredDataProfile = null;
 
     /** The last data profile that's successful for internet connection by subscription id. */
-    private final @NonNull LruCache<Integer, DataProfile> mLastInternetDataProfiles =
-            new LruCache<>(256);
+    @NonNull
+    private final LruCache<Integer, DataProfile> mLastInternetDataProfiles = new LruCache<>(256);
 
     /** Preferred data profile set id. */
     private int mPreferredDataProfileSetId = Telephony.Carriers.NO_APN_SET_ID;
 
     /** Data profile manager callbacks. */
-    private final @NonNull Set<DataProfileManagerCallback> mDataProfileManagerCallbacks =
-            new ArraySet<>();
+    @NonNull
+    private final Set<DataProfileManagerCallback> mDataProfileManagerCallbacks = new ArraySet<>();
 
     /** SIM state. */
-    private @SimState int mSimState = TelephonyManager.SIM_STATE_UNKNOWN;
+    @SimState
+    private int mSimState = TelephonyManager.SIM_STATE_UNKNOWN;
 
     /** Feature flags controlling which feature is enabled. */
-    private final @NonNull FeatureFlags mFeatureFlags;
+    @NonNull
+    private final FeatureFlags mFeatureFlags;
 
     /**
      * Data profile manager callback. This should be only used by {@link DataNetworkController}.
@@ -477,7 +485,8 @@
      *
      * @return The preferred data profile.
      */
-    private @Nullable DataProfile getPreferredDataProfileFromDb() {
+    @Nullable
+    private DataProfile getPreferredDataProfileFromDb() {
         Cursor cursor = mPhone.getContext().getContentResolver().query(
                 Uri.withAppendedPath(Telephony.Carriers.PREFERRED_APN_URI,
                         String.valueOf(mPhone.getSubId())), null, null, null,
@@ -502,7 +511,8 @@
     /**
      * @return The preferred data profile from carrier config.
      */
-    private @Nullable DataProfile getPreferredDataProfileFromConfig() {
+    @Nullable
+    private DataProfile getPreferredDataProfileFromConfig() {
         // Check if there is configured default preferred data profile.
         String defaultPreferredApn = mDataConfigManager.getDefaultPreferredApn();
         if (!TextUtils.isEmpty(defaultPreferredApn)) {
@@ -586,10 +596,10 @@
 
     /**
      * Update the data profile used for initial attach.
-     *
+     * <p>
      * Note that starting from Android 13 only APNs that supports "IA" type will be used for
      * initial attach. Please update APN configuration file if needed.
-     *
+     * <p>
      * Some carriers might explicitly require that using "user-added" APN for initial
      * attach. In this case, exception can be configured through
      * {@link CarrierConfigManager#KEY_ALLOWED_INITIAL_ATTACH_APN_TYPES_STRING_ARRAY}.
@@ -642,7 +652,8 @@
      * @param apnTypeBitmask APN type
      * @return The APN setting
      */
-    private @NonNull ApnSetting buildDefaultApnSetting(@NonNull String entry,
+    @NonNull
+    private ApnSetting buildDefaultApnSetting(@NonNull String entry,
             @NonNull String apn, @Annotation.ApnType int apnTypeBitmask) {
         return new ApnSetting.Builder()
                 .setEntryName(entry)
@@ -665,7 +676,8 @@
      * 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(
+    @Nullable
+    public DataProfile getDataProfileForNetworkRequest(
             @NonNull TelephonyNetworkRequest networkRequest, @NetworkType int networkType,
             boolean isNtn, boolean isEsimBootstrapProvisioning, boolean ignorePermanentFailure) {
         ApnSetting apnSetting = null;
@@ -736,7 +748,8 @@
      * 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(
+    @Nullable
+    private ApnSetting getApnSettingForNetworkRequest(
             @NonNull TelephonyNetworkRequest networkRequest, @NetworkType int networkType,
             boolean isNtn, boolean isEsimBootStrapProvisioning, boolean ignorePermanentFailure) {
         if (!networkRequest.hasAttribute(
@@ -996,7 +1009,8 @@
      *
      * @return The merged data profile. {@code null} if merging is not possible.
      */
-    private static @Nullable DataProfile mergeDataProfiles(
+    @Nullable
+    private static DataProfile mergeDataProfiles(
             @NonNull DataProfile dp1, @NonNull DataProfile dp2) {
         Objects.requireNonNull(dp1);
         Objects.requireNonNull(dp2);
diff --git a/src/java/com/android/internal/telephony/data/DataRetryManager.java b/src/java/com/android/internal/telephony/data/DataRetryManager.java
index 7454d01..d35e9e8 100644
--- a/src/java/com/android/internal/telephony/data/DataRetryManager.java
+++ b/src/java/com/android/internal/telephony/data/DataRetryManager.java
@@ -150,53 +150,67 @@
     private static final int RESET_REASON_TAC_CHANGED = 6;
 
     /** The phone instance. */
-    private final @NonNull Phone mPhone;
+    @NonNull
+    private final Phone mPhone;
 
     /** Featureflags. */
-    private final @NonNull FeatureFlags mFlags;
+    @NonNull
+    private final FeatureFlags mFlags;
 
     /** The RIL instance. */
-    private final @NonNull CommandsInterface mRil;
+    @NonNull
+    private final CommandsInterface mRil;
 
     /** Logging tag. */
-    private final @NonNull String mLogTag;
+    @NonNull
+    private final String mLogTag;
 
     /** Local log. */
-    private final @NonNull LocalLog mLocalLog = new LocalLog(128);
+    @NonNull
+    private final LocalLog mLocalLog = new LocalLog(128);
 
     /** Alarm Manager used to schedule long set up or handover retries. */
-    private final @NonNull AlarmManager mAlarmManager;
+    @NonNull
+    private final AlarmManager mAlarmManager;
 
     /**
      * The data retry callback. This is only used to notify {@link DataNetworkController} to retry
      * setup data network.
      */
-    private @NonNull Set<DataRetryManagerCallback> mDataRetryManagerCallbacks = new ArraySet<>();
+    @NonNull
+    private final Set<DataRetryManagerCallback> mDataRetryManagerCallbacks = new ArraySet<>();
 
     /** Data service managers. */
-    private @NonNull SparseArray<DataServiceManager> mDataServiceManagers;
+    @NonNull
+    private final SparseArray<DataServiceManager> mDataServiceManagers;
 
     /** Data config manager instance. */
-    private final @NonNull DataConfigManager mDataConfigManager;
+    @NonNull
+    private final DataConfigManager mDataConfigManager;
 
     /** Data profile manager. */
-    private final @NonNull DataProfileManager mDataProfileManager;
+    @NonNull
+    private final DataProfileManager mDataProfileManager;
 
     /** Data setup retry rule list. */
-    private @NonNull List<DataSetupRetryRule> mDataSetupRetryRuleList = new ArrayList<>();
+    @NonNull
+    private List<DataSetupRetryRule> mDataSetupRetryRuleList = new ArrayList<>();
 
     /** Data handover retry rule list. */
-    private @NonNull List<DataHandoverRetryRule> mDataHandoverRetryRuleList = new ArrayList<>();
+    @NonNull
+    private List<DataHandoverRetryRule> mDataHandoverRetryRuleList = new ArrayList<>();
 
     /** Data retry entries. */
-    private final @NonNull List<DataRetryEntry> mDataRetryEntries = new ArrayList<>();
+    @NonNull
+    private final List<DataRetryEntry> mDataRetryEntries = new ArrayList<>();
 
     /**
      * Data throttling entries. Note this only stores throttling requested by networks. We intended
      * not to store frameworks-initiated throttling because they are not explicit/strong throttling
      * requests.
      */
-    private final @NonNull List<DataThrottlingEntry> mDataThrottlingEntries = new ArrayList<>();
+    @NonNull
+    private final List<DataThrottlingEntry> mDataThrottlingEntries = new ArrayList<>();
 
     /**
      * Represent a single data setup/handover throttling reported by networks.
@@ -205,31 +219,37 @@
         /**
          * The data profile that is being throttled for setup/handover retry.
          */
-        public final @NonNull DataProfile dataProfile;
+        @NonNull
+        public final DataProfile dataProfile;
 
         /**
          * The associated network request list when throttling happened. Should be {@code null} when
          * retry type is {@link ThrottleStatus#RETRY_TYPE_HANDOVER}.
          */
-        public final @Nullable NetworkRequestList networkRequestList;
+        @Nullable
+        public final NetworkRequestList networkRequestList;
 
         /**
          * The data network that is being throttled for handover retry. Should be
          * {@code null} when retryType is {@link ThrottleStatus#RETRY_TYPE_NEW_CONNECTION}.
          */
-        public final @Nullable DataNetwork dataNetwork;
+        @Nullable
+        public final DataNetwork dataNetwork;
 
         /** The transport that the data profile has been throttled on. */
-        public final @TransportType int transport;
+        @TransportType
+        public final int transport;
 
         /** The retry type when throttling expires. */
-        public final @RetryType int retryType;
+        @RetryType
+        public final int retryType;
 
         /**
          * The expiration time of data throttling. This is the time retrieved from
          * {@link SystemClock#elapsedRealtime()}.
          */
-        public final @ElapsedRealtimeLong long expirationTimeMillis;
+        @ElapsedRealtimeLong
+        public final long expirationTimeMillis;
 
         /**
          * Constructor.
@@ -257,7 +277,8 @@
         }
 
         @Override
-        public @NonNull String toString() {
+        @NonNull
+        public String toString() {
             return "[DataThrottlingEntry: dataProfile=" + dataProfile + ", request list="
                     + networkRequestList + ", dataNetwork=" + dataNetwork + ", transport="
                     + AccessNetworkConstants.transportTypeToString(transport) + ", expiration time="
@@ -293,13 +314,17 @@
          * capabilities specified here, then retry will happen. Empty set indicates the retry rule
          * is not using network capabilities.
          */
-        protected @NonNull @NetCapability Set<Integer> mNetworkCapabilities = new ArraySet<>();
+        @NonNull
+        @NetCapability
+        protected Set<Integer> mNetworkCapabilities = new ArraySet<>();
 
         /**
          * The fail causes. If data setup failed with certain fail causes, then retry will happen.
          * Empty set indicates the retry rule is not using the fail causes.
          */
-        protected @NonNull @DataFailureCause Set<Integer> mFailCauses = new ArraySet<>();
+        @NonNull
+        @DataFailureCause
+        protected Set<Integer> mFailCauses = new ArraySet<>();
 
         public DataRetryRule(@NonNull String ruleString) {
             if (TextUtils.isEmpty(ruleString)) {
@@ -353,7 +378,8 @@
          * @return The data network setup retry intervals in milliseconds. If this is empty, then
          * {@link #getMaxRetries()} must return 0.
          */
-        public @NonNull List<Long> getRetryIntervalsMillis() {
+        @NonNull
+        public List<Long> getRetryIntervalsMillis() {
             return mRetryIntervalsMillis;
         }
 
@@ -372,43 +398,44 @@
          * happen. Empty set indicates the retry rule is not using the fail causes.
          */
         @VisibleForTesting
-        public @NonNull @DataFailureCause Set<Integer> getFailCauses() {
+        @NonNull
+        @DataFailureCause
+        public Set<Integer> getFailCauses() {
             return mFailCauses;
         }
     }
 
     /**
      * Represent a rule for data setup retry.
-     *
+     * <p>
      * The syntax of the retry rule:
      * 1. Retry based on {@link NetworkCapabilities}. Note that only APN-type network capabilities
      *    are supported. If the capabilities are not specified, then the retry rule only applies
      *    to the current failed APN used in setup data call request.
      * "capabilities=[netCaps1|netCaps2|...], [retry_interval=n1|n2|n3|n4...], [maximum_retries=n]"
-     *
+     * <p>
      * 2. Retry based on {@link DataFailCause}
      * "fail_causes=[cause1|cause2|cause3|..], [retry_interval=n1|n2|n3|n4...], [maximum_retries=n]"
-     *
+     * <p>
      * 3. Retry based on {@link NetworkCapabilities} and {@link DataFailCause}. Note that only
      *    APN-type network capabilities are supported.
      * "capabilities=[netCaps1|netCaps2|...], fail_causes=[cause1|cause2|cause3|...],
      *     [retry_interval=n1|n2|n3|n4...], [maximum_retries=n]"
-     *
+     * <p>
      * 4. Permanent fail causes (no timer-based retry) on the current failed APN. Retry interval
      *    is specified for retrying the next available APN.
      * "permanent_fail_causes=8|27|28|29|30|32|33|35|50|51|111|-5|-6|65537|65538|-3|65543|65547|
      *     2252|2253|2254, retry_interval=2500"
-     *
+     * <p>
      * For example,
      * "capabilities=eims, retry_interval=1000, maximum_retries=20" means if the attached
      * network request is emergency, then retry data network setup every 1 second for up to 20
      * times.
-     *
+     * <p>
      * "capabilities=internet|enterprise|dun|ims|fota, retry_interval=2500|3000|"
      * "5000|10000|15000|20000|40000|60000|120000|240000|600000|1200000|1800000"
      * "1800000, maximum_retries=20" means for those capabilities, retry happens in 2.5s, 3s, 5s,
      * 10s, 15s, 20s, 40s, 1m, 2m, 4m, 10m, 20m, 30m, 30m, 30m, until reaching 20 retries.
-     *
      */
     public static class DataSetupRetryRule extends DataRetryRule {
         private static final String RULE_TAG_PERMANENT_FAIL_CAUSES = "permanent_fail_causes";
@@ -469,7 +496,9 @@
          * capabilities.
          */
         @VisibleForTesting
-        public @NonNull @NetCapability Set<Integer> getNetworkCapabilities() {
+        @NonNull
+        @NetCapability
+        public Set<Integer> getNetworkCapabilities() {
             return mNetworkCapabilities;
         }
 
@@ -510,22 +539,22 @@
 
     /**
      * Represent a handover data network retry rule.
-     *
+     * <p>
      * The syntax of the retry rule:
      * 1. Retry when handover fails.
      * "retry_interval=[n1|n2|n3|...], [maximum_retries=n]"
-     *
+     * <p>
      * For example,
      * "retry_interval=1000|3000|5000, maximum_retries=10" means handover retry will happen in 1s,
      * 3s, 5s, 5s, 5s....up to 10 times.
-     *
+     * <p>
      * 2. Retry when handover fails with certain fail causes.
      * "retry_interval=[n1|n2|n3|...], fail_causes=[cause1|cause2|cause3|...], [maximum_retries=n]
-     *
+     * <p>
      * For example,
      * "retry_interval=1000, maximum_retries=3, fail_causes=5" means handover retry every 1 second
      * for up to 3 times when handover fails with the cause 5.
-     *
+     * <p>
      * "maximum_retries=0, fail_causes=6|10|67" means handover retry should not happen for those
      * causes.
      */
@@ -573,7 +602,8 @@
         public @interface DataRetryState {}
 
         /** The rule used for this data retry. {@code null} if the retry is requested by network. */
-        public final @Nullable DataRetryRule appliedDataRetryRule;
+        @Nullable
+        public final DataRetryRule appliedDataRetryRule;
 
         /** The retry delay in milliseconds. */
         public final long retryDelayMillis;
@@ -582,13 +612,15 @@
          * Retry elapsed time. This is the system elapsed time retrieved from
          * {@link SystemClock#elapsedRealtime()}.
          */
-        public final @ElapsedRealtimeLong long retryElapsedTime;
+        @ElapsedRealtimeLong
+        public final long retryElapsedTime;
 
         /** The retry state. */
         protected int mRetryState = RETRY_STATE_NOT_RETRIED;
 
         /** Timestamp when a state is set. For debugging purposes only. */
-        protected @ElapsedRealtimeLong long mRetryStateTimestamp = 0;
+        @ElapsedRealtimeLong
+        protected long mRetryStateTimestamp;
 
         /**
          * Constructor
@@ -617,7 +649,8 @@
         /**
          * @return Get the retry state.
          */
-        public @DataRetryState int getState() {
+        @DataRetryState
+        public int getState() {
             return mRetryState;
         }
 
@@ -649,7 +682,8 @@
             protected long mRetryDelayMillis = TimeUnit.SECONDS.toMillis(5);
 
             /** The applied data retry rule. */
-            protected @Nullable DataRetryRule mAppliedDataRetryRule;
+            @Nullable
+            protected DataRetryRule mAppliedDataRetryRule;
 
             /**
              * Set the data retry delay.
@@ -657,7 +691,8 @@
              * @param retryDelayMillis The retry delay in milliseconds.
              * @return This builder.
              */
-            public @NonNull T setRetryDelay(long retryDelayMillis) {
+            @NonNull
+            public T setRetryDelay(long retryDelayMillis) {
                 mRetryDelayMillis = retryDelayMillis;
                 return (T) this;
             }
@@ -668,7 +703,8 @@
              * @param dataRetryRule The rule that used for this data retry.
              * @return This builder.
              */
-            public @NonNull T setAppliedRetryRule(@NonNull DataRetryRule dataRetryRule) {
+            @NonNull
+            public T setAppliedRetryRule(@NonNull DataRetryRule dataRetryRule) {
                 mAppliedDataRetryRule = dataRetryRule;
                 return (T) this;
             }
@@ -703,16 +739,20 @@
         public @interface SetupRetryType {}
 
         /** Setup retry type. Could be retry by same data profile or same capability. */
-        public final @SetupRetryType int setupRetryType;
+        @SetupRetryType
+        public final int setupRetryType;
 
         /** The network requests to satisfy when retry happens. */
-        public final @NonNull NetworkRequestList networkRequestList;
+        @NonNull
+        public final NetworkRequestList networkRequestList;
 
         /** The data profile that will be used for retry. */
-        public final @Nullable DataProfile dataProfile;
+        @Nullable
+        public final DataProfile dataProfile;
 
         /** The transport to retry data setup. */
-        public final @TransportType int transport;
+        @TransportType
+        public final int transport;
 
         /**
          * Constructor
@@ -743,11 +783,12 @@
          * @return Retry type in string format.
          */
         private static String retryTypeToString(@SetupRetryType int setupRetryType) {
-            switch (setupRetryType) {
-                case RETRY_TYPE_DATA_PROFILE: return "BY_PROFILE";
-                case RETRY_TYPE_NETWORK_REQUESTS: return "BY_NETWORK_REQUESTS";
-                default: return "Unknown(" + setupRetryType + ")";
-            }
+            return switch (setupRetryType) {
+                case RETRY_TYPE_DATA_PROFILE -> "BY_PROFILE";
+                case RETRY_TYPE_NETWORK_REQUESTS -> "BY_NETWORK_REQUESTS";
+                case RETRY_TYPE_UNKNOWN -> "UNKNOWN";
+                default -> "Unknown(" + setupRetryType + ")";
+            };
         }
 
         @Override
@@ -768,16 +809,20 @@
          */
         public static class Builder<T extends Builder<T>> extends DataRetryEntry.Builder<T> {
             /** Data setup retry type. Could be retry by same data profile or same capabilities. */
-            private @SetupRetryType int mSetupRetryType = RETRY_TYPE_UNKNOWN;
+            @SetupRetryType
+            private int mSetupRetryType = RETRY_TYPE_UNKNOWN;
 
             /** The network requests to satisfy when retry happens. */
-            private @NonNull NetworkRequestList mNetworkRequestList;
+            @NonNull
+            private NetworkRequestList mNetworkRequestList;
 
             /** The data profile that will be used for retry. */
-            private @Nullable DataProfile mDataProfile;
+            @Nullable
+            private DataProfile mDataProfile;
 
             /** The transport to retry data setup. */
-            private @TransportType int mTransport = AccessNetworkConstants.TRANSPORT_TYPE_INVALID;
+            @TransportType
+            private int mTransport = AccessNetworkConstants.TRANSPORT_TYPE_INVALID;
 
             /**
              * Set the data retry type.
@@ -786,7 +831,8 @@
              * capabilities.
              * @return This builder.
              */
-            public @NonNull Builder<T> setSetupRetryType(@SetupRetryType int setupRetryType) {
+            @NonNull
+            public Builder<T> setSetupRetryType(@SetupRetryType int setupRetryType) {
                 mSetupRetryType = setupRetryType;
                 return this;
             }
@@ -797,7 +843,8 @@
              * @param networkRequestList The network requests to satisfy when retry happens.
              * @return This builder.
              */
-            public @NonNull Builder<T> setNetworkRequestList(
+            @NonNull
+            public Builder<T> setNetworkRequestList(
                     @NonNull NetworkRequestList networkRequestList) {
                 mNetworkRequestList = networkRequestList;
                 return this;
@@ -809,7 +856,8 @@
              * @param dataProfile The data profile that will be used for retry.
              * @return This builder.
              */
-            public @NonNull Builder<T> setDataProfile(@NonNull DataProfile dataProfile) {
+            @NonNull
+            public Builder<T> setDataProfile(@NonNull DataProfile dataProfile) {
                 mDataProfile = dataProfile;
                 return this;
             }
@@ -820,7 +868,8 @@
              * @param transport The transport to retry data setup.
              * @return This builder.
              */
-            public @NonNull Builder<T> setTransport(@TransportType int transport) {
+            @NonNull
+            public Builder<T> setTransport(@TransportType int transport) {
                 mTransport = transport;
                 return this;
             }
@@ -830,7 +879,8 @@
              *
              * @return The instance of {@link DataSetupRetryEntry}.
              */
-            public @NonNull DataSetupRetryEntry build() {
+            @NonNull
+            public DataSetupRetryEntry build() {
                 if (mNetworkRequestList == null) {
                     throw new IllegalArgumentException("network request list is not specified.");
                 }
@@ -854,7 +904,8 @@
      */
     public static class DataHandoverRetryEntry extends DataRetryEntry {
         /** The data network to be retried for handover. */
-        public final @NonNull DataNetwork dataNetwork;
+        @NonNull
+        public final DataNetwork dataNetwork;
 
         /**
          * Constructor.
@@ -886,7 +937,8 @@
          */
         public static class Builder<T extends Builder<T>> extends DataRetryEntry.Builder<T> {
             /** The data network to be retried for handover. */
-            public @NonNull DataNetwork mDataNetwork;
+            @NonNull
+            public DataNetwork mDataNetwork;
 
             /**
              * Set the data retry type.
@@ -895,7 +947,8 @@
              *
              * @return This builder.
              */
-            public @NonNull Builder<T> setDataNetwork(@NonNull DataNetwork dataNetwork) {
+            @NonNull
+            public Builder<T> setDataNetwork(@NonNull DataNetwork dataNetwork) {
                 mDataNetwork = dataNetwork;
                 return this;
             }
@@ -905,7 +958,8 @@
              *
              * @return The instance of {@link DataHandoverRetryEntry}.
              */
-            public @NonNull DataHandoverRetryEntry build() {
+            @NonNull
+            public DataHandoverRetryEntry build() {
                 return new DataHandoverRetryEntry(mDataNetwork,
                         (DataHandoverRetryRule) mAppliedDataRetryRule, mRetryDelayMillis);
             }
@@ -1865,7 +1919,8 @@
      * @param reason The reason
      * @return The reason in string format.
      */
-    private static @NonNull String resetReasonToString(int reason) {
+    @NonNull
+    private static String resetReasonToString(int reason) {
         return switch (reason) {
             case RESET_REASON_DATA_PROFILES_CHANGED -> "DATA_PROFILES_CHANGED";
             case RESET_REASON_RADIO_ON -> "RADIO_ON";
diff --git a/src/java/com/android/internal/telephony/data/DataSettingsManager.java b/src/java/com/android/internal/telephony/data/DataSettingsManager.java
index 51e5b7d..36e7e19 100644
--- a/src/java/com/android/internal/telephony/data/DataSettingsManager.java
+++ b/src/java/com/android/internal/telephony/data/DataSettingsManager.java
@@ -91,7 +91,8 @@
     private static final int EVENT_INITIALIZE = 11;
 
     private final Phone mPhone;
-    private final @NonNull FeatureFlags mFeatureFlags;
+    @NonNull
+    private final FeatureFlags mFeatureFlags;
     private final ContentResolver mResolver;
     private final SettingsObserver mSettingsObserver;
     private final String mLogTag;
@@ -100,11 +101,12 @@
     private int mSubId;
 
     /** Data config manager */
-    private final @NonNull DataConfigManager mDataConfigManager;
+    @NonNull
+    private final DataConfigManager mDataConfigManager;
 
     /** Data settings manager callbacks. */
-    private final @NonNull Set<DataSettingsManagerCallback> mDataSettingsManagerCallbacks =
-            new ArraySet<>();
+    @NonNull
+    private final Set<DataSettingsManagerCallback> mDataSettingsManagerCallbacks = new ArraySet<>();
 
     /** Mapping of {@link TelephonyManager.DataEnabledReason} to data enabled values. */
     private final Map<Integer, Boolean> mDataEnabledSettings = new ArrayMap<>();
@@ -718,8 +720,9 @@
      * @param policies New mobile data policies in String format.
      * @return A Set of parsed mobile data policies.
      */
-    public @NonNull @MobileDataPolicy Set<Integer> getMobileDataPolicyEnabled(
-            @NonNull String policies) {
+    @NonNull
+    @MobileDataPolicy
+    public Set<Integer> getMobileDataPolicyEnabled(@NonNull String policies) {
         Set<Integer> mobileDataPolicies = new HashSet<>();
         String[] rulesString = policies.trim().split("\\s*,\\s*");
         for (String rule : rulesString) {
@@ -741,7 +744,8 @@
      * @return Parsed mobile data policy. {@link #INVALID_MOBILE_DATA_POLICY} if string can't be
      * parsed into a mobile data policy.
      */
-    private @MobileDataPolicy int parsePolicyFrom(@NonNull String policy) {
+    @MobileDataPolicy
+    private int parsePolicyFrom(@NonNull String policy) {
         int dataPolicy;
         try {
             // parse as new override policy
@@ -810,20 +814,14 @@
 
     private static String dataEnabledChangedReasonToString(
             @TelephonyManager.DataEnabledChangedReason int reason) {
-        switch (reason) {
-            case TelephonyManager.DATA_ENABLED_REASON_USER:
-                return "USER";
-            case TelephonyManager.DATA_ENABLED_REASON_POLICY:
-                return "POLICY";
-            case TelephonyManager.DATA_ENABLED_REASON_CARRIER:
-                return "CARRIER";
-            case TelephonyManager.DATA_ENABLED_REASON_THERMAL:
-                return "THERMAL";
-            case TelephonyManager.DATA_ENABLED_REASON_OVERRIDE:
-                return "OVERRIDE";
-            default:
-                return "UNKNOWN";
-        }
+        return switch (reason) {
+            case TelephonyManager.DATA_ENABLED_REASON_USER -> "USER";
+            case TelephonyManager.DATA_ENABLED_REASON_POLICY -> "POLICY";
+            case TelephonyManager.DATA_ENABLED_REASON_CARRIER -> "CARRIER";
+            case TelephonyManager.DATA_ENABLED_REASON_THERMAL -> "THERMAL";
+            case TelephonyManager.DATA_ENABLED_REASON_OVERRIDE -> "OVERRIDE";
+            default -> "UNKNOWN";
+        };
     }
 
     @Override
diff --git a/src/java/com/android/internal/telephony/data/DataStallRecoveryManager.java b/src/java/com/android/internal/telephony/data/DataStallRecoveryManager.java
index ec6b40f..b9b60a0 100644
--- a/src/java/com/android/internal/telephony/data/DataStallRecoveryManager.java
+++ b/src/java/com/android/internal/telephony/data/DataStallRecoveryManager.java
@@ -140,24 +140,33 @@
     /** Event for duration milliseconds changed. */
     private static final int EVENT_CONTENT_DSRM_DURATION_MILLIS_CHANGED = 5;
 
-    private final @NonNull Phone mPhone;
-    private final @NonNull String mLogTag;
-    private final @NonNull LocalLog mLocalLog = new LocalLog(128);
-    private final @NonNull FeatureFlags mFeatureFlags;
+    @NonNull
+    private final Phone mPhone;
+    @NonNull
+    private final String mLogTag;
+    @NonNull
+    private final LocalLog mLocalLog = new LocalLog(128);
+    @NonNull
+    private final FeatureFlags mFeatureFlags;
 
     /** Data network controller */
-    private final @NonNull DataNetworkController mDataNetworkController;
+    @NonNull
+    private final DataNetworkController mDataNetworkController;
 
     /** Data config manager */
-    private final @NonNull DataConfigManager mDataConfigManager;
+    @NonNull
+    private final DataConfigManager mDataConfigManager;
 
     /** Cellular data service */
-    private final @NonNull DataServiceManager mWwanDataServiceManager;
+    @NonNull
+    private final DataServiceManager mWwanDataServiceManager;
 
     /** The data stall recovery action. */
-    private @RecoveryAction int mRecoveryAction;
+    @RecoveryAction
+    private int mRecoveryAction;
     /** The elapsed real time of last recovery attempted */
-    private @ElapsedRealtimeLong long mTimeLastRecoveryStartMs;
+    @ElapsedRealtimeLong
+    private long mTimeLastRecoveryStartMs;
     /** Whether current network is good or not */
     private boolean mIsValidNetwork;
     /** Whether data stall recovery is triggered or not */
@@ -168,11 +177,14 @@
     private boolean mLastActionReported;
     /** The real time for data stall start. */
     @VisibleForTesting
-    public @ElapsedRealtimeLong long mDataStallStartMs;
+    @ElapsedRealtimeLong
+    public long mDataStallStartMs;
     /** Last data stall recovery action. */
-    private @RecoveryAction int mLastAction;
+    @RecoveryAction
+    private int mLastAction;
     /** Last radio power state. */
-    private @RadioPowerState int mRadioPowerState;
+    @RadioPowerState
+    private int mRadioPowerState;
     /** Whether the NetworkCheckTimer start. */
     private boolean mNetworkCheckTimerStarted = false;
     /** Whether radio state changed during data stall. */
@@ -186,15 +198,18 @@
     /** Whether internet network that require validation is connected. */
     private boolean mIsInternetNetworkConnected;
     /** The durations for current recovery action */
-    private @ElapsedRealtimeLong long mTimeElapsedOfCurrentAction;
+    @ElapsedRealtimeLong
+    private long mTimeElapsedOfCurrentAction;
     /** Tracks the total number of validation duration a data stall */
     private int mValidationCount;
     /** Tracks the number of validation for current action during a data stall */
     private int mActionValidationCount;
     /** The array for the timers between recovery actions. */
-    private @NonNull long[] mDataStallRecoveryDelayMillisArray;
+    @NonNull
+    private long[] mDataStallRecoveryDelayMillisArray;
     /** The boolean array for the flags. They are used to skip the recovery actions if needed. */
-    private @NonNull boolean[] mSkipRecoveryActionArray;
+    @NonNull
+    private boolean[] mSkipRecoveryActionArray;
 
     /**
      * The content URI for the DSRM recovery actions.
@@ -563,7 +578,7 @@
         if (isValid) {
             if (mFeatureFlags.dsrsDiagnosticsEnabled()) {
                 // Broadcast intent that data stall recovered.
-                broadcastDataStallDetected(getRecoveryAction());
+                broadcastDataStallDetected(mLastAction);
             }
             reset();
         } else if (isRecoveryNeeded(true)) {
@@ -684,7 +699,7 @@
         // Get the information for DSRS state
         final boolean isRecovered = !mDataStalled;
         final int duration = (int) (SystemClock.elapsedRealtime() - mDataStallStartMs);
-        final @RecoveredReason int reason = getRecoveredReason(mIsValidNetwork);
+        @RecoveredReason final int reason = getRecoveredReason(mIsValidNetwork);
         final int durationOfAction = (int) getDurationOfCurrentRecoveryMs();
         if (mFeatureFlags.dsrsDiagnosticsEnabled()) {
             log("mValidationCount=" + mValidationCount
@@ -712,7 +727,7 @@
     private void cleanUpDataNetwork() {
         log("cleanUpDataNetwork: notify clean up data network");
         mDataStallRecoveryManagerCallback.invokeFromExecutor(
-                () -> mDataStallRecoveryManagerCallback.onDataStallReestablishInternet());
+                mDataStallRecoveryManagerCallback::onDataStallReestablishInternet);
     }
 
     /** Recovery Action: RECOVERY_ACTION_RADIO_RESTART */
@@ -817,7 +832,7 @@
     private void setNetworkValidationState(boolean isValid) {
         boolean isLogNeeded = false;
         int timeDuration = 0;
-        int timeDurationOfCurrentAction = 0;
+        int timeDurationOfCurrentAction;
         boolean isFirstDataStall = false;
         boolean isFirstValidationAfterDoRecovery = false;
         @RecoveredReason int reason = getRecoveredReason(isValid);
@@ -891,9 +906,6 @@
             if (mLastAction <= RECOVERY_ACTION_CLEANUP) {
                 ret = RECOVERED_REASON_MODEM;
             }
-            if (mLastAction > RECOVERY_ACTION_CLEANUP) {
-                ret = RECOVERED_REASON_DSRM;
-            }
             if (mIsAirPlaneModeEnableDuringDataStall) {
                 ret = RECOVERED_REASON_USER;
             }
@@ -953,7 +965,8 @@
      * @param reason The recovered reason.
      * @return The recovered reason in string format.
      */
-    private static @NonNull String recoveredReasonToString(@RecoveredReason int reason) {
+    @NonNull
+    private static String recoveredReasonToString(@RecoveredReason int reason) {
         return switch (reason) {
             case RECOVERED_REASON_NONE -> "RECOVERED_REASON_NONE";
             case RECOVERED_REASON_DSRM -> "RECOVERED_REASON_DSRM";
@@ -969,17 +982,14 @@
      * @param state The radio power state
      * @return The radio power state in string format.
      */
-    private static @NonNull String radioPowerStateToString(@RadioPowerState int state) {
-        switch (state) {
-            case TelephonyManager.RADIO_POWER_OFF:
-                return "RADIO_POWER_OFF";
-            case TelephonyManager.RADIO_POWER_ON:
-                return "RADIO_POWER_ON";
-            case TelephonyManager.RADIO_POWER_UNAVAILABLE:
-                return "RADIO_POWER_UNAVAILABLE";
-            default:
-                return "Unknown(" + state + ")";
-        }
+    @NonNull
+    private static String radioPowerStateToString(@RadioPowerState int state) {
+        return switch (state) {
+            case TelephonyManager.RADIO_POWER_OFF -> "RADIO_POWER_OFF";
+            case TelephonyManager.RADIO_POWER_ON -> "RADIO_POWER_ON";
+            case TelephonyManager.RADIO_POWER_UNAVAILABLE -> "RADIO_POWER_UNAVAILABLE";
+            default -> "Unknown(" + state + ")";
+        };
     }
 
     /**
@@ -988,7 +998,8 @@
      * @param action The recovery action
      * @return The recovery action in string format.
      */
-    private static @NonNull String recoveryActionToString(@RecoveryAction int action) {
+    @NonNull
+    private static String recoveryActionToString(@RecoveryAction int action) {
         return switch (action) {
             case RECOVERY_ACTION_GET_DATA_CALL_LIST -> "RECOVERY_ACTION_GET_DATA_CALL_LIST";
             case RECOVERY_ACTION_CLEANUP -> "RECOVERY_ACTION_CLEANUP";
diff --git a/src/java/com/android/internal/telephony/data/DataUtils.java b/src/java/com/android/internal/telephony/data/DataUtils.java
index 49e54e7..8b95913 100644
--- a/src/java/com/android/internal/telephony/data/DataUtils.java
+++ b/src/java/com/android/internal/telephony/data/DataUtils.java
@@ -27,6 +27,7 @@
 import android.telephony.AccessNetworkConstants.AccessNetworkType;
 import android.telephony.AccessNetworkConstants.RadioAccessNetworkType;
 import android.telephony.AccessNetworkConstants.TransportType;
+import android.telephony.Annotation.ConnectivityTransport;
 import android.telephony.Annotation.DataActivityType;
 import android.telephony.Annotation.NetCapability;
 import android.telephony.Annotation.NetworkType;
@@ -69,32 +70,30 @@
      * @param capabilityString The capability in string format
      * @return The network capability. -1 if not found.
      */
-    public static @NetCapability int getNetworkCapabilityFromString(
-            @NonNull String capabilityString) {
-        switch (capabilityString.toUpperCase(Locale.ROOT)) {
-            case "MMS": return NetworkCapabilities.NET_CAPABILITY_MMS;
-            case "SUPL": return NetworkCapabilities.NET_CAPABILITY_SUPL;
-            case "DUN": return NetworkCapabilities.NET_CAPABILITY_DUN;
-            case "FOTA": return NetworkCapabilities.NET_CAPABILITY_FOTA;
-            case "IMS": return NetworkCapabilities.NET_CAPABILITY_IMS;
-            case "CBS": return NetworkCapabilities.NET_CAPABILITY_CBS;
-            case "XCAP": return NetworkCapabilities.NET_CAPABILITY_XCAP;
-            case "EIMS": return NetworkCapabilities.NET_CAPABILITY_EIMS;
-            case "INTERNET": return NetworkCapabilities.NET_CAPABILITY_INTERNET;
-            case "MCX": return NetworkCapabilities.NET_CAPABILITY_MCX;
-            case "VSIM": return NetworkCapabilities.NET_CAPABILITY_VSIM;
-            case "BIP" : return NetworkCapabilities.NET_CAPABILITY_BIP;
-            case "ENTERPRISE": return NetworkCapabilities.NET_CAPABILITY_ENTERPRISE;
-            case "PRIORITIZE_BANDWIDTH":
-                return NetworkCapabilities.NET_CAPABILITY_PRIORITIZE_BANDWIDTH;
-            case "PRIORITIZE_LATENCY":
-                return NetworkCapabilities.NET_CAPABILITY_PRIORITIZE_LATENCY;
-            case "RCS":
-                return NetworkCapabilities.NET_CAPABILITY_RCS;
-            default:
+    @NetCapability
+    public static int getNetworkCapabilityFromString(@NonNull String capabilityString) {
+        return switch (capabilityString.toUpperCase(Locale.ROOT)) {
+            case "MMS" -> NetworkCapabilities.NET_CAPABILITY_MMS;
+            case "SUPL" -> NetworkCapabilities.NET_CAPABILITY_SUPL;
+            case "DUN" -> NetworkCapabilities.NET_CAPABILITY_DUN;
+            case "FOTA" -> NetworkCapabilities.NET_CAPABILITY_FOTA;
+            case "IMS" -> NetworkCapabilities.NET_CAPABILITY_IMS;
+            case "CBS" -> NetworkCapabilities.NET_CAPABILITY_CBS;
+            case "XCAP" -> NetworkCapabilities.NET_CAPABILITY_XCAP;
+            case "EIMS" -> NetworkCapabilities.NET_CAPABILITY_EIMS;
+            case "INTERNET" -> NetworkCapabilities.NET_CAPABILITY_INTERNET;
+            case "MCX" -> NetworkCapabilities.NET_CAPABILITY_MCX;
+            case "VSIM" -> NetworkCapabilities.NET_CAPABILITY_VSIM;
+            case "BIP" -> NetworkCapabilities.NET_CAPABILITY_BIP;
+            case "ENTERPRISE" -> NetworkCapabilities.NET_CAPABILITY_ENTERPRISE;
+            case "PRIORITIZE_BANDWIDTH" -> NetworkCapabilities.NET_CAPABILITY_PRIORITIZE_BANDWIDTH;
+            case "PRIORITIZE_LATENCY" -> NetworkCapabilities.NET_CAPABILITY_PRIORITIZE_LATENCY;
+            case "RCS" -> NetworkCapabilities.NET_CAPABILITY_RCS;
+            default -> {
                 loge("Illegal network capability: " + capabilityString);
-                return -1;
-        }
+                yield -1;
+            }
+        };
     }
 
     /**
@@ -105,7 +104,8 @@
      * @param capabilitiesString capability strings joined by {@code |}
      * @return Set of capabilities
      */
-    public static @NetCapability Set<Integer> getNetworkCapabilitiesFromString(
+    @NetCapability
+    public static Set<Integer> getNetworkCapabilitiesFromString(
             @NonNull String capabilitiesString) {
         // e.g. "IMS|" is not allowed
         if (!capabilitiesString.matches("(\\s*[a-zA-Z_]+\\s*)(\\|\\s*[a-zA-Z_]+\\s*)*")) {
@@ -119,69 +119,107 @@
 
     /**
      * Convert a network capability to string.
-     *
+     * <p>
      * This is for debugging and logging purposes only.
      *
      * @param netCap Network capability.
      * @return Network capability in string format.
      */
-    public static @NonNull String networkCapabilityToString(@NetCapability int netCap) {
-        switch (netCap) {
-            case NetworkCapabilities.NET_CAPABILITY_MMS:                  return "MMS";
-            case NetworkCapabilities.NET_CAPABILITY_SUPL:                 return "SUPL";
-            case NetworkCapabilities.NET_CAPABILITY_DUN:                  return "DUN";
-            case NetworkCapabilities.NET_CAPABILITY_FOTA:                 return "FOTA";
-            case NetworkCapabilities.NET_CAPABILITY_IMS:                  return "IMS";
-            case NetworkCapabilities.NET_CAPABILITY_CBS:                  return "CBS";
-            case NetworkCapabilities.NET_CAPABILITY_WIFI_P2P:             return "WIFI_P2P";
-            case NetworkCapabilities.NET_CAPABILITY_IA:                   return "IA";
-            case NetworkCapabilities.NET_CAPABILITY_RCS:                  return "RCS";
-            case NetworkCapabilities.NET_CAPABILITY_XCAP:                 return "XCAP";
-            case NetworkCapabilities.NET_CAPABILITY_EIMS:                 return "EIMS";
-            case NetworkCapabilities.NET_CAPABILITY_NOT_METERED:          return "NOT_METERED";
-            case NetworkCapabilities.NET_CAPABILITY_INTERNET:             return "INTERNET";
-            case NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED:       return "NOT_RESTRICTED";
-            case NetworkCapabilities.NET_CAPABILITY_TRUSTED:              return "TRUSTED";
-            case NetworkCapabilities.NET_CAPABILITY_NOT_VPN:              return "NOT_VPN";
-            case NetworkCapabilities.NET_CAPABILITY_VALIDATED:            return "VALIDATED";
-            case NetworkCapabilities.NET_CAPABILITY_CAPTIVE_PORTAL:       return "CAPTIVE_PORTAL";
-            case NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING:          return "NOT_ROAMING";
-            case NetworkCapabilities.NET_CAPABILITY_FOREGROUND:           return "FOREGROUND";
-            case NetworkCapabilities.NET_CAPABILITY_NOT_CONGESTED:        return "NOT_CONGESTED";
-            case NetworkCapabilities.NET_CAPABILITY_NOT_SUSPENDED:        return "NOT_SUSPENDED";
-            case NetworkCapabilities.NET_CAPABILITY_OEM_PAID:             return "OEM_PAID";
-            case NetworkCapabilities.NET_CAPABILITY_MCX:                  return "MCX";
-            case NetworkCapabilities.NET_CAPABILITY_PARTIAL_CONNECTIVITY:
-                return "PARTIAL_CONNECTIVITY";
-            case NetworkCapabilities.NET_CAPABILITY_TEMPORARILY_NOT_METERED:
-                return "TEMPORARILY_NOT_METERED";
-            case NetworkCapabilities.NET_CAPABILITY_OEM_PRIVATE:          return "OEM_PRIVATE";
-            case NetworkCapabilities.NET_CAPABILITY_VEHICLE_INTERNAL:     return "VEHICLE_INTERNAL";
-            case NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED:      return "NOT_VCN_MANAGED";
-            case NetworkCapabilities.NET_CAPABILITY_ENTERPRISE:           return "ENTERPRISE";
-            case NetworkCapabilities.NET_CAPABILITY_VSIM:                 return "VSIM";
-            case NetworkCapabilities.NET_CAPABILITY_BIP:                  return "BIP";
-            case NetworkCapabilities.NET_CAPABILITY_HEAD_UNIT:            return "HEAD_UNIT";
-            case NetworkCapabilities.NET_CAPABILITY_MMTEL:                return "MMTEL";
-            case NetworkCapabilities.NET_CAPABILITY_PRIORITIZE_LATENCY:
-                return "PRIORITIZE_LATENCY";
-            case NetworkCapabilities.NET_CAPABILITY_PRIORITIZE_BANDWIDTH:
-                return "PRIORITIZE_BANDWIDTH";
-            default:
+    @NonNull
+    public static String networkCapabilityToString(@NetCapability int netCap) {
+        return switch (netCap) {
+            case NetworkCapabilities.NET_CAPABILITY_MMS -> "MMS";
+            case NetworkCapabilities.NET_CAPABILITY_SUPL -> "SUPL";
+            case NetworkCapabilities.NET_CAPABILITY_DUN -> "DUN";
+            case NetworkCapabilities.NET_CAPABILITY_FOTA -> "FOTA";
+            case NetworkCapabilities.NET_CAPABILITY_IMS -> "IMS";
+            case NetworkCapabilities.NET_CAPABILITY_CBS -> "CBS";
+            case NetworkCapabilities.NET_CAPABILITY_WIFI_P2P -> "WIFI_P2P";
+            case NetworkCapabilities.NET_CAPABILITY_IA -> "IA";
+            case NetworkCapabilities.NET_CAPABILITY_RCS -> "RCS";
+            case NetworkCapabilities.NET_CAPABILITY_XCAP -> "XCAP";
+            case NetworkCapabilities.NET_CAPABILITY_EIMS -> "EIMS";
+            case NetworkCapabilities.NET_CAPABILITY_NOT_METERED -> "NOT_METERED";
+            case NetworkCapabilities.NET_CAPABILITY_INTERNET -> "INTERNET";
+            case NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED -> "NOT_RESTRICTED";
+            case NetworkCapabilities.NET_CAPABILITY_TRUSTED -> "TRUSTED";
+            case NetworkCapabilities.NET_CAPABILITY_NOT_VPN -> "NOT_VPN";
+            case NetworkCapabilities.NET_CAPABILITY_VALIDATED -> "VALIDATED";
+            case NetworkCapabilities.NET_CAPABILITY_CAPTIVE_PORTAL -> "CAPTIVE_PORTAL";
+            case NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING -> "NOT_ROAMING";
+            case NetworkCapabilities.NET_CAPABILITY_FOREGROUND -> "FOREGROUND";
+            case NetworkCapabilities.NET_CAPABILITY_NOT_CONGESTED -> "NOT_CONGESTED";
+            case NetworkCapabilities.NET_CAPABILITY_NOT_SUSPENDED -> "NOT_SUSPENDED";
+            case NetworkCapabilities.NET_CAPABILITY_OEM_PAID -> "OEM_PAID";
+            case NetworkCapabilities.NET_CAPABILITY_MCX -> "MCX";
+            case NetworkCapabilities.NET_CAPABILITY_PARTIAL_CONNECTIVITY -> "PARTIAL_CONNECTIVITY";
+            case NetworkCapabilities.NET_CAPABILITY_TEMPORARILY_NOT_METERED ->
+                    "TEMPORARILY_NOT_METERED";
+            case NetworkCapabilities.NET_CAPABILITY_OEM_PRIVATE -> "OEM_PRIVATE";
+            case NetworkCapabilities.NET_CAPABILITY_VEHICLE_INTERNAL -> "VEHICLE_INTERNAL";
+            case NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED -> "NOT_VCN_MANAGED";
+            case NetworkCapabilities.NET_CAPABILITY_ENTERPRISE -> "ENTERPRISE";
+            case NetworkCapabilities.NET_CAPABILITY_VSIM -> "VSIM";
+            case NetworkCapabilities.NET_CAPABILITY_BIP -> "BIP";
+            case NetworkCapabilities.NET_CAPABILITY_HEAD_UNIT -> "HEAD_UNIT";
+            case NetworkCapabilities.NET_CAPABILITY_MMTEL -> "MMTEL";
+            case NetworkCapabilities.NET_CAPABILITY_PRIORITIZE_LATENCY -> "PRIORITIZE_LATENCY";
+            case NetworkCapabilities.NET_CAPABILITY_PRIORITIZE_BANDWIDTH -> "PRIORITIZE_BANDWIDTH";
+            default -> {
                 loge("Unknown network capability(" + netCap + ")");
-                return "Unknown(" + netCap + ")";
-        }
+                yield "Unknown(" + netCap + ")";
+            }
+        };
+    }
+
+    /**
+     * Concat an array of {@link NetworkCapabilities.Transport} in string format.
+     *
+     * @param transports an array of connectivity transports
+     * @return a string of the array of transports.
+     */
+    @NonNull
+    public static String connectivityTransportsToString(
+            @NonNull @ConnectivityTransport int[] transports) {
+        return Arrays.stream(transports).mapToObj(DataUtils::connectivityTransportToString)
+                .collect(Collectors.joining("|"));
+    }
+
+    /**
+     * Convert a {@link NetworkCapabilities.Transport} to a string.
+     *
+     * @param transport the connectivity transport
+     * @return the transport in string
+     */
+    @NonNull
+    public static String connectivityTransportToString(
+            @ConnectivityTransport int transport) {
+        return switch (transport) {
+            case NetworkCapabilities.TRANSPORT_CELLULAR -> "CELLULAR";
+            case NetworkCapabilities.TRANSPORT_WIFI -> "WIFI";
+            case NetworkCapabilities.TRANSPORT_BLUETOOTH -> "BLUETOOTH";
+            case NetworkCapabilities.TRANSPORT_ETHERNET -> "ETHERNET";
+            case NetworkCapabilities.TRANSPORT_VPN -> "VPN";
+            case NetworkCapabilities.TRANSPORT_WIFI_AWARE -> "WIFI_AWARE";
+            case NetworkCapabilities.TRANSPORT_LOWPAN -> "LOWPAN";
+            case NetworkCapabilities.TRANSPORT_TEST -> "TEST";
+            case NetworkCapabilities.TRANSPORT_USB -> "USB";
+            case NetworkCapabilities.TRANSPORT_THREAD -> "THREAD";
+            case NetworkCapabilities.TRANSPORT_SATELLITE -> "SATELLITE";
+            default -> "Unknown(" + transport + ")";
+        };
     }
 
     /**
      * Convert network capabilities to string.
-     *
+     * <p>
      * This is for debugging and logging purposes only.
      *
      * @param netCaps Network capabilities.
      * @return Network capabilities in string format.
      */
-    public static @NonNull String networkCapabilitiesToString(
+    @NonNull
+    public static String networkCapabilitiesToString(
             @NetCapability @Nullable Collection<Integer> netCaps) {
         if (netCaps == null || netCaps.isEmpty()) return "";
         return "[" + netCaps.stream()
@@ -191,13 +229,14 @@
 
     /**
      * Convert network capabilities to string.
-     *
+     * <p>
      * This is for debugging and logging purposes only.
      *
      * @param netCaps Network capabilities.
      * @return Network capabilities in string format.
      */
-    public static @NonNull String networkCapabilitiesToString(@NetCapability int[] netCaps) {
+    @NonNull
+    public static String networkCapabilitiesToString(@NetCapability int[] netCaps) {
         if (netCaps == null) return "";
         return "[" + Arrays.stream(netCaps)
                 .mapToObj(DataUtils::networkCapabilityToString)
@@ -210,14 +249,16 @@
      * @param status The validation status.
      * @return The validation status in string format.
      */
-    public static @NonNull String validationStatusToString(@ValidationStatus int status) {
-        switch (status) {
-            case NetworkAgent.VALIDATION_STATUS_VALID: return "VALID";
-            case NetworkAgent.VALIDATION_STATUS_NOT_VALID: return "INVALID";
-            default:
+    @NonNull
+    public static String validationStatusToString(@ValidationStatus int status) {
+        return switch (status) {
+            case NetworkAgent.VALIDATION_STATUS_VALID -> "VALID";
+            case NetworkAgent.VALIDATION_STATUS_NOT_VALID -> "INVALID";
+            default -> {
                 loge("Unknown validation status(" + status + ")");
-                return "UNKNOWN(" + status + ")";
-        }
+                yield "UNKNOWN(" + status + ")";
+            }
+        };
     }
 
     /**
@@ -226,41 +267,26 @@
      * @param networkCapability Network capability.
      * @return APN type.
      */
-    public static @ApnType int networkCapabilityToApnType(@NetCapability int networkCapability) {
-        switch (networkCapability) {
-            case NetworkCapabilities.NET_CAPABILITY_MMS:
-                return ApnSetting.TYPE_MMS;
-            case NetworkCapabilities.NET_CAPABILITY_SUPL:
-                return ApnSetting.TYPE_SUPL;
-            case NetworkCapabilities.NET_CAPABILITY_DUN:
-                return ApnSetting.TYPE_DUN;
-            case NetworkCapabilities.NET_CAPABILITY_FOTA:
-                return ApnSetting.TYPE_FOTA;
-            case NetworkCapabilities.NET_CAPABILITY_IMS:
-                return ApnSetting.TYPE_IMS;
-            case NetworkCapabilities.NET_CAPABILITY_CBS:
-                return ApnSetting.TYPE_CBS;
-            case NetworkCapabilities.NET_CAPABILITY_XCAP:
-                return ApnSetting.TYPE_XCAP;
-            case NetworkCapabilities.NET_CAPABILITY_EIMS:
-                return ApnSetting.TYPE_EMERGENCY;
-            case NetworkCapabilities.NET_CAPABILITY_INTERNET:
-                return ApnSetting.TYPE_DEFAULT;
-            case NetworkCapabilities.NET_CAPABILITY_MCX:
-                return ApnSetting.TYPE_MCX;
-            case NetworkCapabilities.NET_CAPABILITY_IA:
-                return ApnSetting.TYPE_IA;
-            case NetworkCapabilities.NET_CAPABILITY_ENTERPRISE:
-                return ApnSetting.TYPE_ENTERPRISE;
-            case NetworkCapabilities.NET_CAPABILITY_VSIM:
-                return ApnSetting.TYPE_VSIM;
-            case NetworkCapabilities.NET_CAPABILITY_BIP:
-                return ApnSetting.TYPE_BIP;
-            case NetworkCapabilities.NET_CAPABILITY_RCS:
-                return ApnSetting.TYPE_RCS;
-            default:
-                return ApnSetting.TYPE_NONE;
-        }
+    @ApnType
+    public static int networkCapabilityToApnType(@NetCapability int networkCapability) {
+        return switch (networkCapability) {
+            case NetworkCapabilities.NET_CAPABILITY_MMS -> ApnSetting.TYPE_MMS;
+            case NetworkCapabilities.NET_CAPABILITY_SUPL -> ApnSetting.TYPE_SUPL;
+            case NetworkCapabilities.NET_CAPABILITY_DUN -> ApnSetting.TYPE_DUN;
+            case NetworkCapabilities.NET_CAPABILITY_FOTA -> ApnSetting.TYPE_FOTA;
+            case NetworkCapabilities.NET_CAPABILITY_IMS -> ApnSetting.TYPE_IMS;
+            case NetworkCapabilities.NET_CAPABILITY_CBS -> ApnSetting.TYPE_CBS;
+            case NetworkCapabilities.NET_CAPABILITY_XCAP -> ApnSetting.TYPE_XCAP;
+            case NetworkCapabilities.NET_CAPABILITY_EIMS -> ApnSetting.TYPE_EMERGENCY;
+            case NetworkCapabilities.NET_CAPABILITY_INTERNET -> ApnSetting.TYPE_DEFAULT;
+            case NetworkCapabilities.NET_CAPABILITY_MCX -> ApnSetting.TYPE_MCX;
+            case NetworkCapabilities.NET_CAPABILITY_IA -> ApnSetting.TYPE_IA;
+            case NetworkCapabilities.NET_CAPABILITY_ENTERPRISE -> ApnSetting.TYPE_ENTERPRISE;
+            case NetworkCapabilities.NET_CAPABILITY_VSIM -> ApnSetting.TYPE_VSIM;
+            case NetworkCapabilities.NET_CAPABILITY_BIP -> ApnSetting.TYPE_BIP;
+            case NetworkCapabilities.NET_CAPABILITY_RCS -> ApnSetting.TYPE_RCS;
+            default -> ApnSetting.TYPE_NONE;
+        };
     }
 
     /**
@@ -269,41 +295,26 @@
      * @param apnType APN type.
      * @return Network capability.
      */
-    public static @NetCapability int apnTypeToNetworkCapability(@ApnType int apnType) {
-        switch (apnType) {
-            case ApnSetting.TYPE_MMS:
-                return NetworkCapabilities.NET_CAPABILITY_MMS;
-            case ApnSetting.TYPE_SUPL:
-                return NetworkCapabilities.NET_CAPABILITY_SUPL;
-            case ApnSetting.TYPE_DUN:
-                return NetworkCapabilities.NET_CAPABILITY_DUN;
-            case ApnSetting.TYPE_FOTA:
-                return NetworkCapabilities.NET_CAPABILITY_FOTA;
-            case ApnSetting.TYPE_IMS:
-                return NetworkCapabilities.NET_CAPABILITY_IMS;
-            case ApnSetting.TYPE_CBS:
-                return NetworkCapabilities.NET_CAPABILITY_CBS;
-            case ApnSetting.TYPE_XCAP:
-                return NetworkCapabilities.NET_CAPABILITY_XCAP;
-            case ApnSetting.TYPE_EMERGENCY:
-                return NetworkCapabilities.NET_CAPABILITY_EIMS;
-            case ApnSetting.TYPE_DEFAULT:
-                return NetworkCapabilities.NET_CAPABILITY_INTERNET;
-            case ApnSetting.TYPE_MCX:
-                return NetworkCapabilities.NET_CAPABILITY_MCX;
-            case ApnSetting.TYPE_IA:
-                return NetworkCapabilities.NET_CAPABILITY_IA;
-            case ApnSetting.TYPE_BIP:
-                return NetworkCapabilities.NET_CAPABILITY_BIP;
-            case ApnSetting.TYPE_VSIM:
-                return NetworkCapabilities.NET_CAPABILITY_VSIM;
-            case ApnSetting.TYPE_ENTERPRISE:
-                return NetworkCapabilities.NET_CAPABILITY_ENTERPRISE;
-            case ApnSetting.TYPE_RCS:
-                return NetworkCapabilities.NET_CAPABILITY_RCS;
-            default:
-                return -1;
-        }
+    @NetCapability
+    public static int apnTypeToNetworkCapability(@ApnType int apnType) {
+        return switch (apnType) {
+            case ApnSetting.TYPE_MMS -> NetworkCapabilities.NET_CAPABILITY_MMS;
+            case ApnSetting.TYPE_SUPL -> NetworkCapabilities.NET_CAPABILITY_SUPL;
+            case ApnSetting.TYPE_DUN -> NetworkCapabilities.NET_CAPABILITY_DUN;
+            case ApnSetting.TYPE_FOTA -> NetworkCapabilities.NET_CAPABILITY_FOTA;
+            case ApnSetting.TYPE_IMS -> NetworkCapabilities.NET_CAPABILITY_IMS;
+            case ApnSetting.TYPE_CBS -> NetworkCapabilities.NET_CAPABILITY_CBS;
+            case ApnSetting.TYPE_XCAP -> NetworkCapabilities.NET_CAPABILITY_XCAP;
+            case ApnSetting.TYPE_EMERGENCY -> NetworkCapabilities.NET_CAPABILITY_EIMS;
+            case ApnSetting.TYPE_DEFAULT -> NetworkCapabilities.NET_CAPABILITY_INTERNET;
+            case ApnSetting.TYPE_MCX -> NetworkCapabilities.NET_CAPABILITY_MCX;
+            case ApnSetting.TYPE_IA -> NetworkCapabilities.NET_CAPABILITY_IA;
+            case ApnSetting.TYPE_BIP -> NetworkCapabilities.NET_CAPABILITY_BIP;
+            case ApnSetting.TYPE_VSIM -> NetworkCapabilities.NET_CAPABILITY_VSIM;
+            case ApnSetting.TYPE_ENTERPRISE -> NetworkCapabilities.NET_CAPABILITY_ENTERPRISE;
+            case ApnSetting.TYPE_RCS -> NetworkCapabilities.NET_CAPABILITY_RCS;
+            default -> -1;
+        };
     }
 
     /**
@@ -312,37 +323,26 @@
      * @param networkType The network type.
      * @return The access network type.
      */
-    public static @RadioAccessNetworkType int networkTypeToAccessNetworkType(
-            @NetworkType int networkType) {
-        switch (networkType) {
-            case TelephonyManager.NETWORK_TYPE_GPRS:
-            case TelephonyManager.NETWORK_TYPE_EDGE:
-            case TelephonyManager.NETWORK_TYPE_GSM:
-                return AccessNetworkType.GERAN;
-            case TelephonyManager.NETWORK_TYPE_UMTS:
-            case TelephonyManager.NETWORK_TYPE_HSDPA:
-            case TelephonyManager.NETWORK_TYPE_HSPAP:
-            case TelephonyManager.NETWORK_TYPE_HSUPA:
-            case TelephonyManager.NETWORK_TYPE_HSPA:
-            case TelephonyManager.NETWORK_TYPE_TD_SCDMA:
-                return AccessNetworkType.UTRAN;
-            case TelephonyManager.NETWORK_TYPE_CDMA:
-            case TelephonyManager.NETWORK_TYPE_EVDO_0:
-            case TelephonyManager.NETWORK_TYPE_EVDO_A:
-            case TelephonyManager.NETWORK_TYPE_EVDO_B:
-            case TelephonyManager.NETWORK_TYPE_1xRTT:
-            case TelephonyManager.NETWORK_TYPE_EHRPD:
-                return AccessNetworkType.CDMA2000;
-            case TelephonyManager.NETWORK_TYPE_LTE:
-            case TelephonyManager.NETWORK_TYPE_LTE_CA:
-                return AccessNetworkType.EUTRAN;
-            case TelephonyManager.NETWORK_TYPE_IWLAN:
-                return AccessNetworkType.IWLAN;
-            case TelephonyManager.NETWORK_TYPE_NR:
-                return AccessNetworkType.NGRAN;
-            default:
-                return AccessNetworkType.UNKNOWN;
-        }
+    @RadioAccessNetworkType
+    public static int networkTypeToAccessNetworkType(@NetworkType int networkType) {
+        return switch (networkType) {
+            case TelephonyManager.NETWORK_TYPE_GPRS, TelephonyManager.NETWORK_TYPE_EDGE,
+                    TelephonyManager.NETWORK_TYPE_GSM ->
+                    AccessNetworkType.GERAN;
+            case TelephonyManager.NETWORK_TYPE_UMTS, TelephonyManager.NETWORK_TYPE_HSDPA,
+                    TelephonyManager.NETWORK_TYPE_HSPAP, TelephonyManager.NETWORK_TYPE_HSUPA,
+                    TelephonyManager.NETWORK_TYPE_HSPA, TelephonyManager.NETWORK_TYPE_TD_SCDMA ->
+                    AccessNetworkType.UTRAN;
+            case TelephonyManager.NETWORK_TYPE_CDMA, TelephonyManager.NETWORK_TYPE_EVDO_0,
+                    TelephonyManager.NETWORK_TYPE_EVDO_A, TelephonyManager.NETWORK_TYPE_EVDO_B,
+                    TelephonyManager.NETWORK_TYPE_1xRTT, TelephonyManager.NETWORK_TYPE_EHRPD ->
+                    AccessNetworkType.CDMA2000;
+            case TelephonyManager.NETWORK_TYPE_LTE, TelephonyManager.NETWORK_TYPE_LTE_CA ->
+                    AccessNetworkType.EUTRAN;
+            case TelephonyManager.NETWORK_TYPE_IWLAN -> AccessNetworkType.IWLAN;
+            case TelephonyManager.NETWORK_TYPE_NR -> AccessNetworkType.NGRAN;
+            default -> AccessNetworkType.UNKNOWN;
+        };
     }
 
     /**
@@ -351,7 +351,8 @@
      * @param elapsedTime The elapsed time retrieved from {@link SystemClock#elapsedRealtime()}.
      * @return The string format time.
      */
-    public static @NonNull String elapsedTimeToString(@ElapsedRealtimeLong long elapsedTime) {
+    @NonNull
+    public static String elapsedTimeToString(@ElapsedRealtimeLong long elapsedTime) {
         return (elapsedTime != 0) ? systemTimeToString(System.currentTimeMillis()
                 - SystemClock.elapsedRealtime() + elapsedTime) : "never";
     }
@@ -362,7 +363,8 @@
      * @param systemTime The system time retrieved from {@link System#currentTimeMillis()}.
      * @return The string format time.
      */
-    public static @NonNull String systemTimeToString(@CurrentTimeMillisLong long systemTime) {
+    @NonNull
+    public static String systemTimeToString(@CurrentTimeMillisLong long systemTime) {
         return (systemTime != 0) ? TIME_FORMAT.format(systemTime) : "never";
     }
 
@@ -372,14 +374,16 @@
      * @param imsFeature IMS feature.
      * @return IMS feature in string format.
      */
-    public static @NonNull String imsFeatureToString(@ImsFeature.FeatureType int imsFeature) {
-        switch (imsFeature) {
-            case ImsFeature.FEATURE_MMTEL: return "MMTEL";
-            case ImsFeature.FEATURE_RCS: return "RCS";
-            default:
+    @NonNull
+    public static String imsFeatureToString(@ImsFeature.FeatureType int imsFeature) {
+        return switch (imsFeature) {
+            case ImsFeature.FEATURE_MMTEL -> "MMTEL";
+            case ImsFeature.FEATURE_RCS -> "RCS";
+            default -> {
                 loge("Unknown IMS feature(" + imsFeature + ")");
-                return "Unknown(" + imsFeature + ")";
-        }
+                yield "Unknown(" + imsFeature + ")";
+            }
+        };
     }
 
     /**
@@ -390,7 +394,8 @@
      *
      * @return The network requests after grouping.
      */
-    public static @NonNull List<NetworkRequestList> getGroupedNetworkRequestList(
+    @NonNull
+    public static List<NetworkRequestList> getGroupedNetworkRequestList(
             @NonNull NetworkRequestList networkRequestList, @NonNull FeatureFlags featureFlags) {
         List<NetworkRequestList> requests = new ArrayList<>();
         if (featureFlags.satelliteInternet()) {
@@ -406,8 +411,7 @@
                                 Arrays.stream(networkRequest.getNativeNetworkRequest()
                                                 .getEnterpriseIds())
                                         .boxed().collect(Collectors.toSet()),
-                                Arrays.stream(networkRequest.getNativeNetworkRequest()
-                                                .getTransportTypes())
+                                Arrays.stream(networkRequest.getTransportTypes())
                                         .boxed().collect(Collectors.toSet())
                                 ),
                         v -> new NetworkRequestList()).add(networkRequest);
@@ -454,41 +458,31 @@
      * @param sourceTransport The source transport.
      * @return The target transport.
      */
-    public static @TransportType int getTargetTransport(@TransportType int sourceTransport) {
+    @TransportType
+    public static int getTargetTransport(@TransportType int sourceTransport) {
         return sourceTransport == AccessNetworkConstants.TRANSPORT_TYPE_WWAN
                 ? AccessNetworkConstants.TRANSPORT_TYPE_WLAN
                 : AccessNetworkConstants.TRANSPORT_TYPE_WWAN;
     }
 
     /**
-     * Get the source transport from target transport. This is only used for handover between
-     * IWLAN and cellular scenario.
-     *
-     * @param targetTransport The target transport.
-     * @return The source transport.
-     */
-    public static @TransportType int getSourceTransport(@TransportType int targetTransport) {
-        return targetTransport == AccessNetworkConstants.TRANSPORT_TYPE_WWAN
-                ? AccessNetworkConstants.TRANSPORT_TYPE_WLAN
-                : AccessNetworkConstants.TRANSPORT_TYPE_WWAN;
-    }
-
-    /**
      * Convert link status to string.
      *
      * @param linkStatus The link status.
      * @return The link status in string format.
      */
-    public static @NonNull String linkStatusToString(@LinkStatus int linkStatus) {
-        switch (linkStatus) {
-            case DataCallResponse.LINK_STATUS_UNKNOWN: return "UNKNOWN";
-            case DataCallResponse.LINK_STATUS_INACTIVE: return "INACTIVE";
-            case DataCallResponse.LINK_STATUS_ACTIVE: return "ACTIVE";
-            case DataCallResponse.LINK_STATUS_DORMANT: return "DORMANT";
-            default:
+    @NonNull
+    public static String linkStatusToString(@LinkStatus int linkStatus) {
+        return switch (linkStatus) {
+            case DataCallResponse.LINK_STATUS_UNKNOWN -> "UNKNOWN";
+            case DataCallResponse.LINK_STATUS_INACTIVE -> "INACTIVE";
+            case DataCallResponse.LINK_STATUS_ACTIVE -> "ACTIVE";
+            case DataCallResponse.LINK_STATUS_DORMANT -> "DORMANT";
+            default -> {
                 loge("Unknown link status(" + linkStatus + ")");
-                return "UNKNOWN(" + linkStatus + ")";
-        }
+                yield "UNKNOWN(" + linkStatus + ")";
+            }
+        };
     }
 
     /**
@@ -498,17 +492,12 @@
      * @return {@code true} if the access network type is valid.
      */
     public static boolean isValidAccessNetwork(@RadioAccessNetworkType int accessNetworkType) {
-        switch (accessNetworkType) {
-            case AccessNetworkType.GERAN:
-            case AccessNetworkType.UTRAN:
-            case AccessNetworkType.EUTRAN:
-            case AccessNetworkType.CDMA2000:
-            case AccessNetworkType.IWLAN:
-            case AccessNetworkType.NGRAN:
-                return true;
-            default:
-                return false;
-        }
+        return switch (accessNetworkType) {
+            case AccessNetworkType.GERAN, AccessNetworkType.UTRAN, AccessNetworkType.EUTRAN,
+                    AccessNetworkType.CDMA2000, AccessNetworkType.IWLAN, AccessNetworkType.NGRAN ->
+                    true;
+            default -> false;
+        };
     }
 
     /**
@@ -517,17 +506,19 @@
      * @param dataActivity The data activity.
      * @return The data activity in string format.
      */
-    public static @NonNull String dataActivityToString(@DataActivityType int dataActivity) {
-        switch (dataActivity) {
-            case TelephonyManager.DATA_ACTIVITY_NONE: return "NONE";
-            case TelephonyManager.DATA_ACTIVITY_IN: return "IN";
-            case TelephonyManager.DATA_ACTIVITY_OUT: return "OUT";
-            case TelephonyManager.DATA_ACTIVITY_INOUT: return "INOUT";
-            case TelephonyManager.DATA_ACTIVITY_DORMANT: return "DORMANT";
-            default:
+    @NonNull
+    public static String dataActivityToString(@DataActivityType int dataActivity) {
+        return switch (dataActivity) {
+            case TelephonyManager.DATA_ACTIVITY_NONE -> "NONE";
+            case TelephonyManager.DATA_ACTIVITY_IN -> "IN";
+            case TelephonyManager.DATA_ACTIVITY_OUT -> "OUT";
+            case TelephonyManager.DATA_ACTIVITY_INOUT -> "INOUT";
+            case TelephonyManager.DATA_ACTIVITY_DORMANT -> "DORMANT";
+            default -> {
                 loge("Unknown data activity(" + dataActivity + ")");
-                return "UNKNOWN(" + dataActivity + ")";
-        }
+                yield "UNKNOWN(" + dataActivity + ")";
+            }
+        };
     }
 
     private static void loge(String msg) {
diff --git a/src/java/com/android/internal/telephony/data/KeepaliveStatus.java b/src/java/com/android/internal/telephony/data/KeepaliveStatus.java
index 818de96..7b6c38d 100644
--- a/src/java/com/android/internal/telephony/data/KeepaliveStatus.java
+++ b/src/java/com/android/internal/telephony/data/KeepaliveStatus.java
@@ -23,7 +23,7 @@
 /**
  * This class serves to pass around the parameters of Keepalive session
  * status within the telephony framework.
- *
+ * <p>
  * {@hide}
  */
 public class KeepaliveStatus implements Parcelable {
@@ -54,7 +54,8 @@
      * A status code indicating whether this Keepalive session is
      * active, inactive, or pending activation
      */
-    public final @KeepaliveStatusCode int statusCode;
+    @KeepaliveStatusCode
+    public final int statusCode;
 
     /** An error code indicating a lower layer failure, if any */
     public final int errorCode;
@@ -98,7 +99,7 @@
     }
 
     public static final Parcelable.Creator<KeepaliveStatus> CREATOR =
-            new Parcelable.Creator<KeepaliveStatus>() {
+            new Parcelable.Creator<>() {
                 @Override
                 public KeepaliveStatus createFromParcel(Parcel source) {
                     return new KeepaliveStatus(source);
diff --git a/src/java/com/android/internal/telephony/data/KeepaliveTracker.java b/src/java/com/android/internal/telephony/data/KeepaliveTracker.java
index 0a01339..f221779 100644
--- a/src/java/com/android/internal/telephony/data/KeepaliveTracker.java
+++ b/src/java/com/android/internal/telephony/data/KeepaliveTracker.java
@@ -56,19 +56,24 @@
     private static final int EVENT_UNREGISTER_FOR_KEEPALIVE_STATUS = 5;
 
     /** The phone instance. */
-    private final @NonNull Phone mPhone;
+    @NonNull
+    private final Phone mPhone;
 
     /** The parent data network. */
-    private final @NonNull DataNetwork mDataNetwork;
+    @NonNull
+    private final DataNetwork mDataNetwork;
 
     /** The associated network agent. */
-    private final @NonNull TelephonyNetworkAgent mNetworkAgent;
+    @NonNull
+    private final TelephonyNetworkAgent mNetworkAgent;
 
     /** The log tag. */
-    private final @NonNull String mLogTag;
+    @NonNull
+    private final String mLogTag;
 
     /** The keepalive records. */
-    private final @NonNull SparseArray<KeepaliveRecord> mKeepalives = new SparseArray<>();
+    @NonNull
+    private final SparseArray<KeepaliveRecord> mKeepalives = new SparseArray<>();
 
     /**
      * Keepalive session record
@@ -78,7 +83,8 @@
         public int slotIndex;
 
         /** The current status. */
-        public @KeepaliveStatusCode int currentStatus;
+        @KeepaliveStatusCode
+        public int currentStatus;
 
         /**
          * Constructor
diff --git a/src/java/com/android/internal/telephony/data/PhoneSwitcher.java b/src/java/com/android/internal/telephony/data/PhoneSwitcher.java
index b7aa251..27b4331 100644
--- a/src/java/com/android/internal/telephony/data/PhoneSwitcher.java
+++ b/src/java/com/android/internal/telephony/data/PhoneSwitcher.java
@@ -53,7 +53,6 @@
 import android.os.RegistrantList;
 import android.os.RemoteException;
 import android.telephony.CarrierConfigManager;
-import android.telephony.PhoneCapability;
 import android.telephony.PhoneStateListener;
 import android.telephony.SubscriptionInfo;
 import android.telephony.SubscriptionManager;
@@ -183,10 +182,12 @@
         }
     }
 
-    private final @NonNull NetworkRequestList mNetworkRequestList = new NetworkRequestList();
+    @NonNull
+    private final NetworkRequestList mNetworkRequestList = new NetworkRequestList();
     protected final RegistrantList mActivePhoneRegistrants;
     private final SubscriptionManagerService mSubscriptionManagerService;
-    private final @NonNull FeatureFlags mFlags;
+    @NonNull
+    private final FeatureFlags mFlags;
     protected final Context mContext;
     private final LocalLog mLocalLog;
     protected PhoneState[] mPhoneStates;
@@ -310,7 +311,7 @@
     private static final int MAX_LOCAL_LOG_LINES = 256;
 
     // Default timeout value of network validation in millisecond.
-    private final static int DEFAULT_VALIDATION_EXPIRATION_TIME = 2000;
+    private static final int DEFAULT_VALIDATION_EXPIRATION_TIME = 2000;
 
     /** Controller that tracks {@link TelephonyManager#MOBILE_DATA_POLICY_AUTO_DATA_SWITCH} */
     @NonNull private final AutoDataSwitchController mAutoDataSwitchController;
@@ -318,21 +319,23 @@
     @NonNull private final AutoDataSwitchController.AutoDataSwitchControllerCallback
             mAutoDataSwitchCallback;
 
-    private ConnectivityManager mConnectivityManager;
+    private final ConnectivityManager mConnectivityManager;
     private int mImsRegistrationTech = REGISTRATION_TECH_NONE;
     @VisibleForTesting
     public final SparseIntArray mImsRegistrationRadioTechMap = new SparseIntArray();
-    private List<Set<CommandException.Error>> mCurrentDdsSwitchFailure;
+    @NonNull
+    private final List<Set<CommandException.Error>> mCurrentDdsSwitchFailure;
 
     /** Data settings manager callback. Key is the phone id. */
-    private final @NonNull Map<Integer, DataSettingsManagerCallback> mDataSettingsManagerCallbacks =
+    @NonNull
+    private final Map<Integer, DataSettingsManagerCallback> mDataSettingsManagerCallbacks =
             new ArrayMap<>();
 
     private class DefaultNetworkCallback extends ConnectivityManager.NetworkCallback {
         public int mExpectedSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
         public int mSwitchReason = TelephonyEvent.DataSwitch.Reason.DATA_SWITCH_REASON_UNKNOWN;
         @Override
-        public void onCapabilitiesChanged(Network network,
+        public void onCapabilitiesChanged(@NonNull Network network,
                 NetworkCapabilities networkCapabilities) {
             if (networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)) {
                 if (SubscriptionManager.isValidSubscriptionId(mExpectedSubId)
@@ -350,15 +353,15 @@
         }
 
         @Override
-        public void onLost(Network network) {
+        public void onLost(@NonNull Network network) {
             mAutoDataSwitchController.updateDefaultNetworkCapabilities(null);
         }
     }
 
-    private RegistrationManager.RegistrationCallback mRegistrationCallback =
+    private final RegistrationManager.RegistrationCallback mRegistrationCallback =
             new RegistrationManager.RegistrationCallback() {
         @Override
-        public void onRegistered(ImsRegistrationAttributes attributes) {
+        public void onRegistered(@NonNull ImsRegistrationAttributes attributes) {
             int imsRegistrationTech = attributes.getRegistrationTechnology();
             if (imsRegistrationTech != mImsRegistrationTech) {
                 mImsRegistrationTech = imsRegistrationTech;
@@ -367,7 +370,7 @@
         }
 
         @Override
-        public void onUnregistered(ImsReasonInfo info) {
+        public void onUnregistered(@NonNull ImsReasonInfo info) {
             if (mImsRegistrationTech != REGISTRATION_TECH_NONE) {
                 mImsRegistrationTech = REGISTRATION_TECH_NONE;
                 sendMessage(obtainMessage(EVENT_IMS_RADIO_TECH_CHANGED));
@@ -402,14 +405,8 @@
 
     @VisibleForTesting
     public ImsRegisterCallback mImsRegisterCallback =
-            (context, phoneId, cb, executor)-> {
-                try {
-                    ImsManager.getInstance(context, phoneId)
-                            .addRegistrationCallback(cb, executor);
-                } catch (ImsException e) {
-                    throw e;
-                }
-            };
+            (context, phoneId, cb, executor)-> ImsManager.getInstance(context, phoneId)
+                    .addRegistrationCallback(cb, executor);
 
     /**
      * Method to get singleton instance.
@@ -497,7 +494,7 @@
         mRadioConfig = RadioConfig.getInstance();
         mValidator = CellularNetworkValidator.getInstance();
 
-        mCurrentDdsSwitchFailure = new ArrayList<Set<CommandException.Error>>();
+        mCurrentDdsSwitchFailure = new ArrayList<>();
         IntentFilter filter = new IntentFilter();
         filter.addAction(TelephonyManager.ACTION_SIM_APPLICATION_STATE_CHANGED);
         mContext.registerReceiver(mSimStateIntentReceiver, filter);
@@ -545,7 +542,7 @@
                     registerForImsRadioTechChange(context, phoneId);
                 }
             }
-            Set<CommandException.Error> ddsFailure = new HashSet<CommandException.Error>();
+            Set<CommandException.Error> ddsFailure = new HashSet<>();
             mCurrentDdsSwitchFailure.add(ddsFailure);
         }
 
@@ -652,7 +649,7 @@
         }
     };
 
-    private BroadcastReceiver mSimStateIntentReceiver = new BroadcastReceiver() {
+    private final BroadcastReceiver mSimStateIntentReceiver = new BroadcastReceiver() {
         @Override
         public void onReceive(Context context, Intent intent) {
             String action = intent.getAction();
@@ -874,10 +871,8 @@
                             mEmergencyOverride.mOverrideCompleteFuture.complete(false);
                         }
                     }
-                    mEmergencyOverride = req;
-                } else {
-                    mEmergencyOverride = req;
                 }
+                mEmergencyOverride = req;
 
                 logl("new emergency override - " + mEmergencyOverride);
                 // a new request has been created, remove any previous override complete scheduled.
@@ -960,13 +955,9 @@
 
         mImsRegistrationRadioTechMap.put(phoneId, tech);
 
-        if (subId == INVALID_SUBSCRIPTION_ID) {
-            // Need to update the cached IMS registration tech but no need to do any of the
-            // following. When the SIM removed, REGISTRATION_STATE_NOT_REGISTERED is notified.
-            return false;
-        }
-
-        return true;
+        // Need to update the cached IMS registration tech but no need to do any of the
+        // following. When the SIM removed, REGISTRATION_STATE_NOT_REGISTERED is notified.
+        return subId != INVALID_SUBSCRIPTION_ID;
     }
 
     private synchronized void onMultiSimConfigChanged(int activeModemCount) {
@@ -1023,7 +1014,7 @@
             phone.getDataSettingsManager().registerCallback(
                     mDataSettingsManagerCallbacks.get(phone.getPhoneId()));
 
-            Set<CommandException.Error> ddsFailure = new HashSet<CommandException.Error>();
+            Set<CommandException.Error> ddsFailure = new HashSet<>();
             mCurrentDdsSwitchFailure.add(ddsFailure);
 
             if (!mFlags.changeMethodOfObtainingImsRegistrationRadioTech()) {
@@ -1072,7 +1063,7 @@
         }
 
         @Override
-        protected void needNetworkFor(NetworkRequest networkRequest) {
+        protected void needNetworkFor(@NonNull NetworkRequest networkRequest) {
             if (VDBG) log("needNetworkFor " + networkRequest);
             Message msg = mPhoneSwitcher.obtainMessage(EVENT_REQUEST_NETWORK);
             msg.obj = networkRequest;
@@ -1080,7 +1071,7 @@
         }
 
         @Override
-        protected void releaseNetworkFor(NetworkRequest networkRequest) {
+        protected void releaseNetworkFor(@NonNull NetworkRequest networkRequest) {
             if (VDBG) log("releaseNetworkFor " + networkRequest);
             Message msg = mPhoneSwitcher.obtainMessage(EVENT_RELEASE_NETWORK);
             msg.obj = networkRequest;
@@ -1157,7 +1148,7 @@
     protected static final boolean REQUESTS_UNCHANGED = false;
     /**
      * Re-evaluate things. Do nothing if nothing's changed.
-     *
+     * <p>
      * Otherwise, go through the requests in priority order adding their phone until we've added up
      * to the max allowed.  Then go through shutting down phones that aren't in the active phone
      * list. Finally, activate all phones in the active phone list.
@@ -1251,13 +1242,11 @@
                 }
                 sendRilCommands(mPreferredDataPhoneId);
             } else {
-                List<Integer> newActivePhones = new ArrayList<Integer>();
+                List<Integer> newActivePhones = new ArrayList<>();
 
-                /**
-                 * If all phones can have PS attached, activate all.
-                 * Otherwise, choose to activate phones according to requests. And
-                 * if list is not full, add mPreferredDataPhoneId.
-                 */
+                // If all phones can have PS attached, activate all.
+                // Otherwise, choose to activate phones according to requests. And
+                // if list is not full, add mPreferredDataPhoneId.
                 if (mMaxDataAttachModemCount == mActiveModemCount) {
                     for (int i = 0; i < mMaxDataAttachModemCount; i++) {
                         newActivePhones.add(i);
@@ -1345,7 +1334,7 @@
 
     /**
      * Switch the Default data for the context of an outgoing emergency call.
-     *
+     * <p>
      * In some cases, we need to try to switch the Default Data subscription before placing the
      * emergency call on DSDS devices. This includes the following situation:
      * - The modem does not support processing GNSS SUPL requests on the non-default data
@@ -1391,16 +1380,6 @@
         }
     }
 
-    private void onPhoneCapabilityChangedInternal(PhoneCapability capability) {
-        int newMaxDataAttachModemCount = TelephonyManager.getDefault()
-                .getNumberOfModemsWithSimultaneousDataConnections();
-        if (mMaxDataAttachModemCount != newMaxDataAttachModemCount) {
-            mMaxDataAttachModemCount = newMaxDataAttachModemCount;
-            logl("Max active phones changed to " + mMaxDataAttachModemCount);
-            onEvaluate(REQUESTS_UNCHANGED, "phoneCfgChanged");
-        }
-    }
-
     private int phoneIdForRequest(TelephonyNetworkRequest networkRequest) {
         NetworkRequest netRequest = networkRequest.getNativeNetworkRequest();
         int subId = getSubIdFromNetworkSpecifier(netRequest.getNetworkSpecifier());
@@ -1777,7 +1756,7 @@
 
     /**
      * Notify PhoneSwitcher to try to switch data to an opportunistic subscription.
-     *
+     * <p>
      * Set opportunistic data subscription. It's an indication to switch Internet data to this
      * subscription. It has to be an active subscription, and PhoneSwitcher will try to validate
      * it first if needed. If subId is DEFAULT_SUBSCRIPTION_ID, it means we are un-setting
@@ -1856,20 +1835,16 @@
      * @param reason The switch reason.
      * @return The switch reason in string format.
      */
-    private static @NonNull String switchReasonToString(int reason) {
-        switch(reason) {
-            case TelephonyEvent.DataSwitch.Reason.DATA_SWITCH_REASON_UNKNOWN:
-                return "UNKNOWN";
-            case TelephonyEvent.DataSwitch.Reason.DATA_SWITCH_REASON_MANUAL:
-                return "MANUAL";
-            case TelephonyEvent.DataSwitch.Reason.DATA_SWITCH_REASON_IN_CALL:
-                return "IN_CALL";
-            case TelephonyEvent.DataSwitch.Reason.DATA_SWITCH_REASON_CBRS:
-                return "CBRS";
-            case TelephonyEvent.DataSwitch.Reason.DATA_SWITCH_REASON_AUTO:
-                return "AUTO";
-            default: return "UNKNOWN(" + reason + ")";
-        }
+    @NonNull
+    private static String switchReasonToString(int reason) {
+        return switch (reason) {
+            case DataSwitch.Reason.DATA_SWITCH_REASON_UNKNOWN -> "UNKNOWN";
+            case DataSwitch.Reason.DATA_SWITCH_REASON_MANUAL -> "MANUAL";
+            case DataSwitch.Reason.DATA_SWITCH_REASON_IN_CALL -> "IN_CALL";
+            case DataSwitch.Reason.DATA_SWITCH_REASON_CBRS -> "CBRS";
+            case DataSwitch.Reason.DATA_SWITCH_REASON_AUTO -> "AUTO";
+            default -> "UNKNOWN(" + reason + ")";
+        };
     }
 
     /**
@@ -1878,16 +1853,14 @@
      * @param state The switching state.
      * @return The switching state in string format.
      */
-    private static @NonNull String switchStateToString(int state) {
-        switch(state) {
-            case TelephonyEvent.EventState.EVENT_STATE_UNKNOWN:
-                return "UNKNOWN";
-            case TelephonyEvent.EventState.EVENT_STATE_START:
-                return "START";
-            case TelephonyEvent.EventState.EVENT_STATE_END:
-                return "END";
-            default: return "UNKNOWN(" + state + ")";
-        }
+    @NonNull
+    private static String switchStateToString(int state) {
+        return switch (state) {
+            case TelephonyEvent.EventState.EVENT_STATE_UNKNOWN -> "UNKNOWN";
+            case TelephonyEvent.EventState.EVENT_STATE_START -> "START";
+            case TelephonyEvent.EventState.EVENT_STATE_END -> "END";
+            default -> "UNKNOWN(" + state + ")";
+        };
     }
 
     /**
diff --git a/src/java/com/android/internal/telephony/data/QosCallbackTracker.java b/src/java/com/android/internal/telephony/data/QosCallbackTracker.java
index ebddbad..a1ac379 100644
--- a/src/java/com/android/internal/telephony/data/QosCallbackTracker.java
+++ b/src/java/com/android/internal/telephony/data/QosCallbackTracker.java
@@ -63,7 +63,8 @@
     private final RcsStats mRcsStats;
 
     // We perform an exact match on the address
-    private final @NonNull Map<Integer, IFilter> mCallbacksToFilter;
+    @NonNull
+    private final Map<Integer, IFilter> mCallbacksToFilter;
 
     private final int mPhoneId;
 
@@ -143,11 +144,6 @@
                                     }
                                 });
                     }
-
-                    @Override
-                    public void onQosCallbackUnregistered(int qosCallbackId) {
-
-                    }
                 });
     }
 
@@ -259,7 +255,6 @@
                         // The filter matches which means it was previously available, and now is
                         // lost
                         if (doFiltersMatch(existingSession, filter)) {
-                            bearerState = DEDICATED_BEARER_EVENT_STATE_DELETED;
                             sendSessionLost(callbackId, existingSession);
                             notifyMetricDedicatedBearerEvent(existingSession, bearerState, true);
                             sessionsReportedToMetric.add(sessionId);
@@ -285,13 +280,13 @@
         });
     }
 
-    private boolean doFiltersMatch(final @NonNull QosBearerSession qosBearerSession,
-            final @NonNull IFilter filter) {
+    private boolean doFiltersMatch(@NonNull final QosBearerSession qosBearerSession,
+                                   @NonNull final IFilter filter) {
         return getMatchingQosBearerFilter(qosBearerSession, filter) != null;
     }
 
-    private boolean matchesByLocalAddress(final @NonNull QosBearerFilter sessionFilter,
-            final @NonNull IFilter filter) {
+    private boolean matchesByLocalAddress(@NonNull final QosBearerFilter sessionFilter,
+                                          @NonNull final IFilter filter) {
         int portStart;
         int portEnd;
         if (sessionFilter.getLocalPortRange() == null) {
@@ -320,7 +315,7 @@
     }
 
     private boolean matchesByRemoteAddress(@NonNull QosBearerFilter sessionFilter,
-            final @NonNull IFilter filter) {
+                                           @NonNull final IFilter filter) {
         int portStart;
         int portEnd;
         boolean result = false;
@@ -350,8 +345,8 @@
     }
 
     private boolean matchesByProtocol(@NonNull QosBearerFilter sessionFilter,
-            final @NonNull IFilter filter, boolean hasMatchedFilter) {
-        boolean result = false;
+                                      @NonNull final IFilter filter, boolean hasMatchedFilter) {
+        boolean result;
         int protocol = sessionFilter.getProtocol();
         if (protocol == QosBearerFilter.QOS_PROTOCOL_TCP
                 || protocol == QosBearerFilter.QOS_PROTOCOL_UDP) {
@@ -371,8 +366,9 @@
                 ? sessionFilter : qosFilter;
     }
 
-    private @Nullable QosBearerFilter getMatchingQosBearerFilter(
-            @NonNull QosBearerSession qosBearerSession, final @NonNull IFilter filter) {
+    @Nullable
+    private QosBearerFilter getMatchingQosBearerFilter(
+            @NonNull QosBearerSession qosBearerSession, @NonNull final IFilter filter) {
         QosBearerFilter qosFilter = null;
 
         for (final QosBearerFilter sessionFilter : qosBearerSession.getQosBearerFilterList()) {
@@ -410,11 +406,11 @@
         return qosFilter;
     }
 
-    private void sendSessionAvailable(final int callbackId, final @NonNull QosBearerSession session,
-            @NonNull IFilter filter) {
+    private void sendSessionAvailable(final int callbackId, @NonNull final QosBearerSession session,
+                                      @NonNull IFilter filter) {
         QosBearerFilter qosBearerFilter = getMatchingQosBearerFilter(session, filter);
         List<InetSocketAddress> remoteAddresses = new ArrayList<>();
-        if (qosBearerFilter.getRemoteAddresses().size() > 0
+        if (qosBearerFilter != null && !qosBearerFilter.getRemoteAddresses().isEmpty()
                 && qosBearerFilter.getRemotePortRange() != null) {
             remoteAddresses.add(
                     new InetSocketAddress(qosBearerFilter.getRemoteAddresses().get(0).getAddress(),
@@ -459,17 +455,16 @@
     }
 
     private void notifyMetricDedicatedBearerListenerAdded(final int callbackId,
-            final @NonNull QosBearerSession session) {
+                                                          @NonNull final QosBearerSession session) {
 
-        final int slotId = mPhoneId;
         final int rat = getRatInfoFromSessionInfo(session);
         final int qci = getQCIFromSessionInfo(session);
 
-        mRcsStats.onImsDedicatedBearerListenerAdded(callbackId, slotId, rat, qci);
+        mRcsStats.onImsDedicatedBearerListenerAdded(callbackId, mPhoneId, rat, qci);
     }
 
     private void notifyMetricDedicatedBearerListenerBearerUpdateSession(
-            final int callbackId, final @NonNull QosBearerSession session) {
+            final int callbackId, @NonNull final QosBearerSession session) {
         mRcsStats.onImsDedicatedBearerListenerUpdateSession(callbackId, mPhoneId,
                 getRatInfoFromSessionInfo(session), getQCIFromSessionInfo(session), true);
     }
@@ -522,13 +517,12 @@
 
     private void notifyMetricDedicatedBearerEvent(final QosBearerSession session,
             final int bearerState, final boolean hasListener) {
-        final int slotId = mPhoneId;
         int ratAtEnd = getRatInfoFromSessionInfo(session);
         int qci = getQCIFromSessionInfo(session);
         boolean localConnectionInfoReceived = doesLocalConnectionInfoExist(session);
         boolean remoteConnectionInfoReceived = doesRemoteConnectionInfoExist(session);
 
-        mRcsStats.onImsDedicatedBearerEvent(slotId, ratAtEnd, qci, bearerState,
+        mRcsStats.onImsDedicatedBearerEvent(mPhoneId, ratAtEnd, qci, bearerState,
                 localConnectionInfoReceived, remoteConnectionInfoReceived, hasListener);
     }
 
diff --git a/src/java/com/android/internal/telephony/data/TelephonyNetworkAgent.java b/src/java/com/android/internal/telephony/data/TelephonyNetworkAgent.java
index d90724e..5a81f19 100644
--- a/src/java/com/android/internal/telephony/data/TelephonyNetworkAgent.java
+++ b/src/java/com/android/internal/telephony/data/TelephonyNetworkAgent.java
@@ -70,7 +70,8 @@
      * The callbacks that are used to pass information to {@link DataNetwork} and
      * {@link QosCallbackTracker}.
      */
-    private final @NonNull Set<TelephonyNetworkAgentCallback> mTelephonyNetworkAgentCallbacks =
+    @NonNull
+    private final Set<TelephonyNetworkAgentCallback> mTelephonyNetworkAgentCallbacks =
             new ArraySet<>();
 
     /**
@@ -110,7 +111,7 @@
 
         /**
          * Called when a qos callback is registered with a filter.
-         *
+         * <p>
          * Any QoS events that are sent with the same callback id after this method is called are a
          * no-op.
          *
@@ -267,7 +268,7 @@
      * @param filter the filter being registered
      */
     @Override
-    public void onQosCallbackRegistered(final int qosCallbackId, final @NonNull QosFilter filter) {
+    public void onQosCallbackRegistered(final int qosCallbackId, @NonNull final QosFilter filter) {
         if (mAbandoned) {
             log("The agent is already abandoned. Ignored onQosCallbackRegistered.");
             return;
@@ -278,7 +279,7 @@
 
     /**
      * Called when a qos callback is registered with a filter.
-     *
+     * <p>
      * Any QoS events that are sent with the same callback id after this method is called are a
      * no-op.
      *
diff --git a/src/java/com/android/internal/telephony/data/TelephonyNetworkFactory.java b/src/java/com/android/internal/telephony/data/TelephonyNetworkFactory.java
index a16cee6..ca34ca7 100644
--- a/src/java/com/android/internal/telephony/data/TelephonyNetworkFactory.java
+++ b/src/java/com/android/internal/telephony/data/TelephonyNetworkFactory.java
@@ -265,13 +265,13 @@
     }
 
     @Override
-    public void needNetworkFor(NetworkRequest networkRequest) {
+    public void needNetworkFor(@NonNull NetworkRequest networkRequest) {
         Message msg = mInternalHandler.obtainMessage(EVENT_NETWORK_REQUEST);
         msg.obj = networkRequest;
         msg.sendToTarget();
     }
 
-    private void onNeedNetworkFor(Message msg) {
+    private void onNeedNetworkFor(@NonNull Message msg) {
         TelephonyNetworkRequest networkRequest =
                 new TelephonyNetworkRequest((NetworkRequest) msg.obj, mPhone, mFlags);
         boolean shouldApply = mPhoneSwitcher.shouldApplyNetworkRequest(
diff --git a/src/java/com/android/internal/telephony/data/TelephonyNetworkRequest.java b/src/java/com/android/internal/telephony/data/TelephonyNetworkRequest.java
index b059100..117eb36 100644
--- a/src/java/com/android/internal/telephony/data/TelephonyNetworkRequest.java
+++ b/src/java/com/android/internal/telephony/data/TelephonyNetworkRequest.java
@@ -24,6 +24,7 @@
 import android.net.NetworkRequest;
 import android.net.NetworkSpecifier;
 import android.os.SystemClock;
+import android.telephony.Annotation.ConnectivityTransport;
 import android.telephony.Annotation.NetCapability;
 import android.telephony.data.ApnSetting;
 import android.telephony.data.DataProfile;
@@ -137,19 +138,22 @@
     );
 
     /** The phone instance. */
-    private final @NonNull Phone mPhone;
+    @NonNull
+    private final Phone mPhone;
 
     /**
      * Native network request from the clients. See {@link NetworkRequest};
      */
-    private final @NonNull NetworkRequest mNativeNetworkRequest;
+    @NonNull
+    private final NetworkRequest mNativeNetworkRequest;
 
     /**
      * The attributes of the network capabilities in this network request. This describes how this
      * network request can be translated to different fields in {@link DataProfile} or perform
      * special actions in telephony.
      */
-    private final @NetCapabilityAttribute int mCapabilitiesAttributes;
+    @NetCapabilityAttribute
+    private final int mCapabilitiesAttributes;
 
     /**
      * Priority of the network request. The network request has higher priority will be satisfied
@@ -160,13 +164,15 @@
     /**
      * Data config manager for retrieving data config.
      */
-    private final @NonNull DataConfigManager mDataConfigManager;
+    @NonNull
+    private final DataConfigManager mDataConfigManager;
 
     /**
      * The attached data network. Note that the data network could be in any state. {@code null}
      * indicates this network request is not satisfied.
      */
-    private @Nullable DataNetwork mAttachedDataNetwork;
+    @Nullable
+    private DataNetwork mAttachedDataNetwork;
 
     /**
      * The state of the network request.
@@ -175,16 +181,20 @@
      * @see #REQUEST_STATE_SATISFIED
      */
     // This is not a boolean because there might be more states in the future.
-    private @RequestState int mState;
+    @RequestState
+    private int mState;
 
     /** The timestamp when this network request enters telephony. */
-    private final @ElapsedRealtimeLong long mCreatedTimeMillis;
+    @ElapsedRealtimeLong
+    private final long mCreatedTimeMillis;
 
     /** The data evaluation result. */
-    private @Nullable DataEvaluation mEvaluation;
+    @Nullable
+    private DataEvaluation mEvaluation;
 
     /** Feature flag. */
-    private final @NonNull FeatureFlags mFeatureFlags;
+    @NonNull
+    private final FeatureFlags mFeatureFlags;
 
     /**
      * Constructor
@@ -219,14 +229,17 @@
     /**
      * @see NetworkRequest#getNetworkSpecifier()
      */
-    public @Nullable NetworkSpecifier getNetworkSpecifier() {
+    @Nullable
+    public NetworkSpecifier getNetworkSpecifier() {
         return mNativeNetworkRequest.getNetworkSpecifier();
     }
 
     /**
      * @see NetworkRequest#getCapabilities()
      */
-    public @NonNull @NetCapability int[] getCapabilities() {
+    @NonNull
+    @NetCapability
+    public int[] getCapabilities() {
         return mNativeNetworkRequest.getCapabilities();
     }
 
@@ -238,6 +251,23 @@
     }
 
     /**
+     * @see NetworkRequest#getTransportTypes()
+     */
+    @NonNull
+    @ConnectivityTransport
+    public int[] getTransportTypes() {
+        return mNativeNetworkRequest.getTransportTypes();
+    }
+
+    /**
+     * @return {@code true} if the request can be served on the specified transport.
+     * @see NetworkRequest#hasTransport
+     */
+    public boolean hasTransport(@ConnectivityTransport int transport) {
+        return mNativeNetworkRequest.hasTransport(transport);
+    }
+
+    /**
      * @see NetworkRequest#canBeSatisfiedBy(NetworkCapabilities)
      */
     public boolean canBeSatisfiedBy(@Nullable NetworkCapabilities nc) {
@@ -354,7 +384,8 @@
      * @return The highest priority APN type based network capability from this network request. -1
      * if there is no APN type capabilities in this network request.
      */
-    public @NetCapability int getApnTypeNetworkCapability() {
+    @NetCapability
+    public int getApnTypeNetworkCapability() {
         if (!hasAttribute(CAPABILITY_ATTRIBUTE_APN_SETTING)) return -1;
         return Arrays.stream(getCapabilities()).boxed()
                 .filter(cap -> DataUtils.networkCapabilityToApnType(cap) != ApnSetting.TYPE_NONE)
@@ -364,7 +395,8 @@
     /**
      * @return The native network request.
      */
-    public @NonNull NetworkRequest getNativeNetworkRequest() {
+    @NonNull
+    public NetworkRequest getNativeNetworkRequest() {
         return mNativeNetworkRequest;
     }
 
@@ -373,7 +405,7 @@
      *
      * @param dataNetwork The data network.
      */
-    public void setAttachedNetwork(@NonNull DataNetwork dataNetwork) {
+    public void setAttachedNetwork(@Nullable DataNetwork dataNetwork) {
         mAttachedDataNetwork = dataNetwork;
     }
 
@@ -381,7 +413,8 @@
      * @return The attached network. {@code null} indicates the request is not attached to any
      * network (i.e. the request is unsatisfied).
      */
-    public @Nullable DataNetwork getAttachedNetwork() {
+    @Nullable
+    public DataNetwork getAttachedNetwork() {
         return mAttachedDataNetwork;
     }
 
@@ -397,7 +430,8 @@
     /**
      * @return The state of the network request.
      */
-    public @RequestState int getState() {
+    @RequestState
+    public int getState() {
         return mState;
     }
 
@@ -440,7 +474,8 @@
      * @return Os/App id. {@code null} if the request does not have traffic descriptor based network
      * capabilities.
      */
-    public @Nullable OsAppId getOsAppId() {
+    @Nullable
+    public OsAppId getOsAppId() {
         if (!hasAttribute(CAPABILITY_ATTRIBUTE_TRAFFIC_DESCRIPTOR_OS_APP_ID)) return null;
 
         // We do not support multiple network capabilities translated to Os/App id at this time.
@@ -471,18 +506,19 @@
      * @param state The request state.
      * @return The request state in string format.
      */
-    private static @NonNull String requestStateToString(
+    @NonNull
+    private static String requestStateToString(
             @TelephonyNetworkRequest.RequestState int state) {
-        switch (state) {
-            case TelephonyNetworkRequest.REQUEST_STATE_UNSATISFIED: return "UNSATISFIED";
-            case TelephonyNetworkRequest.REQUEST_STATE_SATISFIED: return "SATISFIED";
-            default: return "UNKNOWN(" + state + ")";
-        }
+        return switch (state) {
+            case TelephonyNetworkRequest.REQUEST_STATE_UNSATISFIED -> "UNSATISFIED";
+            case TelephonyNetworkRequest.REQUEST_STATE_SATISFIED -> "SATISFIED";
+            default -> "UNKNOWN(" + state + ")";
+        };
     }
 
     @Override
     public String toString() {
-        return "[" + mNativeNetworkRequest.toString() + ", mPriority=" + mPriority
+        return "[" + mNativeNetworkRequest + ", mPriority=" + mPriority
                 + ", state=" + requestStateToString(mState)
                 + ", mAttachedDataNetwork=" + (mAttachedDataNetwork != null
                 ? mAttachedDataNetwork.name() : null) + ", isMetered=" + isMeteredRequest()
diff --git a/src/java/com/android/internal/telephony/satellite/DatagramController.java b/src/java/com/android/internal/telephony/satellite/DatagramController.java
index 2f18796..8271187 100644
--- a/src/java/com/android/internal/telephony/satellite/DatagramController.java
+++ b/src/java/com/android/internal/telephony/satellite/DatagramController.java
@@ -105,6 +105,7 @@
     private long mDatagramWaitTimeForConnectedState;
     private long mModemImageSwitchingDuration;
     private boolean mWaitForDeviceAlignmentInDemoDatagram;
+    private long mDatagramWaitTimeForConnectedStateForLastMessage;
     @GuardedBy("mLock")
     @SatelliteManager.SatelliteModemState
     private int mSatelltieModemState = SatelliteManager.SATELLITE_MODEM_STATE_UNKNOWN;
@@ -161,6 +162,8 @@
         mModemImageSwitchingDuration = getSatelliteModemImageSwitchingDurationMillis();
         mWaitForDeviceAlignmentInDemoDatagram =
                 getWaitForDeviceAlignmentInDemoDatagramFromResources();
+        mDatagramWaitTimeForConnectedStateForLastMessage =
+                getDatagramWaitForConnectedStateForLastMessageTimeoutMillis();
         mDemoModeDatagramList = new ArrayList<>();
     }
 
@@ -447,13 +450,17 @@
     }
 
     @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
-    public long getDatagramWaitTimeForConnectedState() {
+    public long getDatagramWaitTimeForConnectedState(boolean isLastSosMessage) {
         synchronized (mLock) {
+            long timeout = isLastSosMessage ? mDatagramWaitTimeForConnectedStateForLastMessage :
+                    mDatagramWaitTimeForConnectedState;
+            logd("getDatagramWaitTimeForConnectedState: isLastSosMessage=" + isLastSosMessage
+                    + ", timeout=" + timeout + ", modemState=" + mSatelltieModemState);
             if (mSatelltieModemState == SATELLITE_MODEM_STATE_OFF
                     || mSatelltieModemState == SATELLITE_MODEM_STATE_IDLE) {
-                return (mDatagramWaitTimeForConnectedState + mModemImageSwitchingDuration);
+                return (timeout + mModemImageSwitchingDuration);
             }
-            return mDatagramWaitTimeForConnectedState;
+            return timeout;
         }
     }
 
@@ -553,6 +560,11 @@
                 R.integer.config_satellite_modem_image_switching_duration_millis);
     }
 
+    private long getDatagramWaitForConnectedStateForLastMessageTimeoutMillis() {
+        return mContext.getResources().getInteger(
+                R.integer.config_datagram_wait_for_connected_state_for_last_message_timeout_millis);
+    }
+
     /**
      * This API can be used by only CTS to override the cached value for the device overlay config
      * value : config_send_satellite_datagram_to_modem_in_demo_mode, which determines whether
diff --git a/src/java/com/android/internal/telephony/satellite/DatagramDispatcher.java b/src/java/com/android/internal/telephony/satellite/DatagramDispatcher.java
index f764b2b..3984a5f 100644
--- a/src/java/com/android/internal/telephony/satellite/DatagramDispatcher.java
+++ b/src/java/com/android/internal/telephony/satellite/DatagramDispatcher.java
@@ -104,6 +104,7 @@
             mPendingNonEmergencyDatagramsMap = new LinkedHashMap<>();
 
     private long mWaitTimeForDatagramSendingResponse;
+    private long mWaitTimeForDatagramSendingForLastMessageResponse;
     @SatelliteManager.DatagramType
     private int mLastSendRequestDatagramType = DATAGRAM_TYPE_UNKNOWN;
 
@@ -142,6 +143,8 @@
             mSendingDatagramInProgress = false;
         }
         mWaitTimeForDatagramSendingResponse = getWaitForDatagramSendingResponseTimeoutMillis();
+        mWaitTimeForDatagramSendingForLastMessageResponse =
+                getWaitForDatagramSendingResponseForLastMessageTimeoutMillis();
     }
 
     private static final class DatagramDispatcherHandlerRequest {
@@ -680,7 +683,8 @@
         }
         sendMessageDelayed(obtainMessage(
                         EVENT_DATAGRAM_WAIT_FOR_CONNECTED_STATE_TIMED_OUT, datagramArgs),
-                mDatagramController.getDatagramWaitTimeForConnectedState());
+                mDatagramController.getDatagramWaitTimeForConnectedState(
+                        SatelliteServiceUtils.isLastSosMessage(datagramArgs.datagramType)));
     }
 
     private void stopDatagramWaitForConnectedStateTimer() {
@@ -709,9 +713,13 @@
             logd("WaitForDatagramSendingResponseTimer was already started");
             return;
         }
+        long waitTime = SatelliteServiceUtils.isLastSosMessage(argument.datagramType)
+                ? mWaitTimeForDatagramSendingForLastMessageResponse
+                : mWaitTimeForDatagramSendingResponse;
+        logd("startWaitForDatagramSendingResponseTimer: datagramType=" + argument.datagramType
+                + ", waitTime=" + waitTime);
         sendMessageDelayed(obtainMessage(
-                EVENT_WAIT_FOR_DATAGRAM_SENDING_RESPONSE_TIMED_OUT, argument),
-                mWaitTimeForDatagramSendingResponse);
+                EVENT_WAIT_FOR_DATAGRAM_SENDING_RESPONSE_TIMED_OUT, argument), waitTime);
     }
 
     private void stopWaitForDatagramSendingResponseTimer() {
@@ -760,6 +768,11 @@
                 R.integer.config_wait_for_datagram_sending_response_timeout_millis);
     }
 
+    private long getWaitForDatagramSendingResponseForLastMessageTimeoutMillis() {
+        return mContext.getResources().getInteger(R.integer
+                .config_wait_for_datagram_sending_response_for_last_message_timeout_millis);
+    }
+
     private boolean shouldProcessEventSendSatelliteDatagramDone(
             @NonNull SendSatelliteDatagramArgument argument) {
         synchronized (mLock) {
diff --git a/src/java/com/android/internal/telephony/satellite/DatagramReceiver.java b/src/java/com/android/internal/telephony/satellite/DatagramReceiver.java
index f1f0fde..21e4318 100644
--- a/src/java/com/android/internal/telephony/satellite/DatagramReceiver.java
+++ b/src/java/com/android/internal/telephony/satellite/DatagramReceiver.java
@@ -818,7 +818,7 @@
         }
         sendMessageDelayed(obtainMessage(
                         EVENT_DATAGRAM_WAIT_FOR_CONNECTED_STATE_TIMED_OUT),
-                mDatagramController.getDatagramWaitTimeForConnectedState());
+                mDatagramController.getDatagramWaitTimeForConnectedState(false));
     }
 
     private void stopDatagramWaitForConnectedStateTimer() {
diff --git a/src/java/com/android/internal/telephony/satellite/SatelliteController.java b/src/java/com/android/internal/telephony/satellite/SatelliteController.java
index 819f919..aaad18b 100644
--- a/src/java/com/android/internal/telephony/satellite/SatelliteController.java
+++ b/src/java/com/android/internal/telephony/satellite/SatelliteController.java
@@ -155,6 +155,7 @@
     private static final boolean DEBUG = !"user".equals(Build.TYPE);
     /** File used to store shared preferences related to satellite. */
     public static final String SATELLITE_SHARED_PREF = "satellite_shared_pref";
+    public static final String SATELLITE_SUBSCRIPTION_ID = "satellite_subscription_id";
     /** Value to pass for the setting key SATELLITE_MODE_ENABLED, enabled = 1, disabled = 0 */
     public static final int SATELLITE_MODE_ENABLED_TRUE = 1;
     public static final int SATELLITE_MODE_ENABLED_FALSE = 0;
@@ -220,7 +221,8 @@
     @NonNull private static SatelliteController sInstance;
     @NonNull private final Context mContext;
     @NonNull private final SatelliteModemInterface mSatelliteModemInterface;
-    @NonNull private SatelliteSessionController mSatelliteSessionController;
+    @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE)
+    @NonNull protected SatelliteSessionController mSatelliteSessionController;
     @NonNull private final PointingAppController mPointingAppController;
     @NonNull private final DatagramController mDatagramController;
     @NonNull private final ControllerMetricsStats mControllerMetricsStats;
@@ -273,6 +275,8 @@
             new AtomicBoolean(false);
     private final AtomicBoolean mIsModemEnabledReportingNtnSignalStrength =
             new AtomicBoolean(false);
+    private final AtomicBoolean mLatestRequestedStateForNtnSignalStrengthReport =
+            new AtomicBoolean(false);
     private final AtomicBoolean mRegisteredForSatelliteSupportedStateChanged =
             new AtomicBoolean(false);
     /**
@@ -1013,6 +1017,7 @@
                         }
                     }
                     // Request Ntn signal strength report when satellite enabled or disabled done.
+                    mLatestRequestedStateForNtnSignalStrengthReport.set(argument.enableSatellite);
                     updateNtnSignalStrengthReporting(argument.enableSatellite);
                 } else {
                     synchronized (mSatelliteEnabledRequestLock) {
@@ -1373,6 +1378,13 @@
                                 + shouldReport);
                 if (errorCode == SATELLITE_RESULT_SUCCESS) {
                     mIsModemEnabledReportingNtnSignalStrength.set(shouldReport);
+                    if (mLatestRequestedStateForNtnSignalStrengthReport.get()
+                            != mIsModemEnabledReportingNtnSignalStrength.get()) {
+                        logd("mLatestRequestedStateForNtnSignalStrengthReport does not match with "
+                                + "mIsModemEnabledReportingNtnSignalStrength");
+                        updateNtnSignalStrengthReporting(
+                                mLatestRequestedStateForNtnSignalStrengthReport.get());
+                    }
                 } else {
                     loge(((boolean) request.argument ? "startSendingNtnSignalStrength"
                             : "stopSendingNtnSignalStrength") + "returns " + errorCode);
@@ -1644,6 +1656,7 @@
                 /* We have already successfully queried the satellite modem. */
                 Bundle bundle = new Bundle();
                 bundle.putBoolean(SatelliteManager.KEY_SATELLITE_SUPPORTED, mIsSatelliteSupported);
+                bundle.putInt(SATELLITE_SUBSCRIPTION_ID, subId);
                 result.send(SATELLITE_RESULT_SUCCESS, bundle);
                 return;
             }
@@ -3251,6 +3264,9 @@
         }
         mSatelliteSessionController = SatelliteSessionController.make(
                 mContext, getLooper(), supported);
+        logd("create a new SatelliteSessionController due to isSatelliteSupported state has "
+                + "changed to " + supported);
+
         if (supported) {
             registerForSatelliteProvisionStateChanged();
             registerForPendingDatagramCount();
@@ -3512,6 +3528,10 @@
                 }
             }
             mIsSatelliteSupported = supported;
+            mSatelliteSessionController = SatelliteSessionController.make(
+                    mContext, getLooper(), supported);
+            logd("create a new SatelliteSessionController due to isSatelliteSupported state has "
+                    + "changed to " + supported);
         }
 
         List<ISatelliteSupportedStateCallback> deadCallersList = new ArrayList<>();
@@ -4463,6 +4483,7 @@
             return;
         }
 
+        mLatestRequestedStateForNtnSignalStrengthReport.set(shouldReport);
         if (mIsModemEnabledReportingNtnSignalStrength.get() == shouldReport) {
             logd("handleCmdUpdateNtnSignalStrengthReporting: ignore request. "
                     + "mIsModemEnabledReportingNtnSignalStrength="
diff --git a/src/java/com/android/internal/telephony/satellite/SatelliteModemInterface.java b/src/java/com/android/internal/telephony/satellite/SatelliteModemInterface.java
index 58260d1..8a26fd2 100644
--- a/src/java/com/android/internal/telephony/satellite/SatelliteModemInterface.java
+++ b/src/java/com/android/internal/telephony/satellite/SatelliteModemInterface.java
@@ -66,6 +66,8 @@
     @NonNull private static SatelliteModemInterface sInstance;
     @NonNull private final Context mContext;
     @NonNull private final DemoSimulator mDemoSimulator;
+    @NonNull private final SatelliteListener mVendorListener;
+    @NonNull private final SatelliteListener mDemoListener;
     @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE)
     @NonNull protected final ExponentialBackoff mExponentialBackoff;
     @NonNull private final Object mLock = new Object();
@@ -237,6 +239,8 @@
             SatelliteController satelliteController, @NonNull Looper looper) {
         mContext = context;
         mDemoSimulator = DemoSimulator.make(context, satelliteController);
+        mVendorListener = new SatelliteListener(false);
+        mDemoListener = new SatelliteListener(true);
         mIsSatelliteServiceSupported = getSatelliteServiceSupport();
         mSatelliteController = satelliteController;
         mExponentialBackoff = new ExponentialBackoff(REBIND_INITIAL_DELAY, REBIND_MAXIMUM_DELAY,
@@ -349,11 +353,8 @@
             mSatelliteService = ISatellite.Stub.asInterface(service);
             mExponentialBackoff.stop();
             try {
-                SatelliteListener vendorListener = new SatelliteListener(false);
-                mSatelliteService.setSatelliteListener(vendorListener);
-
-                SatelliteListener demoListener = new SatelliteListener(true);
-                mDemoSimulator.setSatelliteListener(demoListener);
+                mSatelliteService.setSatelliteListener(mVendorListener);
+                mDemoSimulator.setSatelliteListener(mDemoListener);
             } catch (RemoteException e) {
                 // TODO: Retry setSatelliteListener
                 logd("setSatelliteListener: RemoteException " + e);
diff --git a/src/java/com/android/internal/telephony/satellite/SatelliteServiceUtils.java b/src/java/com/android/internal/telephony/satellite/SatelliteServiceUtils.java
index 67b2586..d33fd73 100644
--- a/src/java/com/android/internal/telephony/satellite/SatelliteServiceUtils.java
+++ b/src/java/com/android/internal/telephony/satellite/SatelliteServiceUtils.java
@@ -347,7 +347,9 @@
     }
 
     /**
-     *
+     * Check if the datagramType is the sos message (DATAGRAM_TYPE_SOS_MESSAGE,
+     * DATAGRAM_TYPE_LAST_SOS_MESSAGE_STILL_NEED_HELP,
+     * DATAGRAM_TYPE_LAST_SOS_MESSAGE_NO_HELP_NEEDED) or not
      */
     public static boolean isSosMessage(int datagramType) {
         return datagramType == SatelliteManager.DATAGRAM_TYPE_SOS_MESSAGE
@@ -356,6 +358,16 @@
     }
 
     /**
+     * Check if the datagramType is the last sos message
+     * (DATAGRAM_TYPE_LAST_SOS_MESSAGE_STILL_NEED_HELP or
+     * DATAGRAM_TYPE_LAST_SOS_MESSAGE_NO_HELP_NEEDED) or not
+     */
+    public static boolean isLastSosMessage(int datagramType) {
+        return datagramType == SatelliteManager.DATAGRAM_TYPE_LAST_SOS_MESSAGE_STILL_NEED_HELP
+                || datagramType == SatelliteManager.DATAGRAM_TYPE_LAST_SOS_MESSAGE_NO_HELP_NEEDED;
+    }
+
+    /**
      * Return phone associated with phoneId 0.
      *
      * @return phone associated with phoneId 0 or {@code null} if it doesn't exist.
diff --git a/src/java/com/android/internal/telephony/satellite/SatelliteSessionController.java b/src/java/com/android/internal/telephony/satellite/SatelliteSessionController.java
index dc0cf47..dcf9bb0 100644
--- a/src/java/com/android/internal/telephony/satellite/SatelliteSessionController.java
+++ b/src/java/com/android/internal/telephony/satellite/SatelliteSessionController.java
@@ -39,7 +39,6 @@
 import android.os.Message;
 import android.os.RemoteException;
 import android.os.SystemProperties;
-import android.telephony.Rlog;
 import android.telephony.satellite.ISatelliteModemStateCallback;
 import android.telephony.satellite.SatelliteManager;
 import android.telephony.satellite.stub.ISatelliteGateway;
@@ -163,15 +162,9 @@
      */
     public static SatelliteSessionController make(
             @NonNull Context context, @NonNull Looper looper, boolean isSatelliteSupported) {
-        if (sInstance == null) {
+        if (sInstance == null || isSatelliteSupported != sInstance.mIsSatelliteSupported) {
             sInstance = new SatelliteSessionController(context, looper, isSatelliteSupported,
                     SatelliteModemInterface.getInstance());
-        } else {
-            if (isSatelliteSupported != sInstance.mIsSatelliteSupported) {
-                Rlog.e(TAG, "New satellite support state " + isSatelliteSupported
-                        + " is different from existing state " + sInstance.mIsSatelliteSupported
-                        + ". Ignore the new state.");
-            }
         }
         return sInstance;
     }
diff --git a/src/java/com/android/internal/telephony/subscription/SubscriptionManagerService.java b/src/java/com/android/internal/telephony/subscription/SubscriptionManagerService.java
index 5d653c7..0e98a9e 100644
--- a/src/java/com/android/internal/telephony/subscription/SubscriptionManagerService.java
+++ b/src/java/com/android/internal/telephony/subscription/SubscriptionManagerService.java
@@ -1452,6 +1452,11 @@
             if (mSlotIndexToSubId.containsKey(phoneId)) {
                 markSubscriptionsInactive(phoneId);
             }
+
+            if (Flags.clearCachedImsPhoneNumberWhenDeviceLostImsRegistration()) {
+                // Clear the cached Ims phone number
+                setNumberFromIms(getSubId(phoneId), new String(""));
+            }
         } else if (simState == TelephonyManager.SIM_STATE_NOT_READY) {
             // Check if this is the final state. Only update the subscription if NOT_READY is a
             // final state.
@@ -1464,6 +1469,11 @@
             } else {
                 logl("updateSubscription: UICC app disabled on slot " + phoneId);
                 markSubscriptionsInactive(phoneId);
+
+                if (Flags.clearCachedImsPhoneNumberWhenDeviceLostImsRegistration()) {
+                    // Clear the cached Ims phone number
+                    setNumberFromIms(getSubId(phoneId), new String(""));
+                }
             }
         } else {
             String iccId = getIccId(phoneId);
@@ -1572,12 +1582,6 @@
                         loge("updateSubscription: ICC card is not available.");
                     }
 
-                    if (Flags.clearCachedImsPhoneNumberWhenDeviceLostImsRegistration()) {
-                        // Clear the cached Ims phone number
-                        // before proceeding with Ims Registration
-                        setNumberFromIms(subId, new String(""));
-                    }
-
                     // Attempt to restore SIM specific settings when SIM is loaded.
                     Bundle result = mContext.getContentResolver().call(
                             SubscriptionManager.SIM_INFO_BACKUP_AND_RESTORE_CONTENT_URI,
diff --git a/tests/telephonytests/src/com/android/internal/telephony/data/DataNetworkControllerTest.java b/tests/telephonytests/src/com/android/internal/telephony/data/DataNetworkControllerTest.java
index 78fee33..f418523 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/data/DataNetworkControllerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/data/DataNetworkControllerTest.java
@@ -139,6 +139,8 @@
 import java.util.Set;
 import java.util.concurrent.Executor;
 
+import javax.annotation.Nullable;
+
 @RunWith(AndroidTestingRunner.class)
 @TestableLooper.RunWithLooper
 public class DataNetworkControllerTest extends TelephonyTest {
@@ -1130,18 +1132,23 @@
     }
 
     private @NonNull TelephonyNetworkRequest createNetworkRequest(Integer... capabilities) {
-        return createNetworkRequest(false, capabilities);
+        return createNetworkRequest(null, capabilities);
     }
 
-    private @NonNull TelephonyNetworkRequest createNetworkRequest(boolean restricted,
+    private @NonNull TelephonyNetworkRequest createNetworkRequest(@Nullable Boolean restricted,
                                                                   Integer... capabilities) {
         NetworkCapabilities netCaps = new NetworkCapabilities();
         for (int networkCapability : capabilities) {
             netCaps.addCapability(networkCapability);
         }
 
-        if (restricted) {
-            netCaps.removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED);
+        if (restricted != null) {
+            if (restricted) {
+                netCaps.removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED);
+            }
+        } else {
+            // Data Network uses the same to define its own capabilities.
+            netCaps.maybeMarkCapabilitiesRestricted();
         }
 
         NetworkRequest nativeNetworkRequest = new NetworkRequest(netCaps,
@@ -1733,6 +1740,14 @@
         verify(mMockedDataNetworkControllerCallback, never())
                 .onConnectedInternetDataNetworksChanged(any());
 
+        // However, WLAN network setup shouldn't be affected
+        doReturn(AccessNetworkConstants.TRANSPORT_TYPE_WLAN).when(mAccessNetworksManager)
+                .getPreferredTransportByNetworkCapability(anyInt());
+        mDataNetworkControllerUT.obtainMessage(5 /*EVENT_REEVALUATE_UNSATISFIED_NETWORK_REQUESTS*/,
+                DataEvaluation.DataEvaluationReason.PREFERRED_TRANSPORT_CHANGED).sendToTarget();
+        processAllMessages();
+        verify(mMockedDataNetworkControllerCallback).onConnectedInternetDataNetworksChanged(any());
+
         mIsNonTerrestrialNetwork = false;
     }
 
@@ -3311,12 +3326,20 @@
                 NetworkCapabilities.NET_CAPABILITY_IMS);
         TelephonyNetworkRequest secondTnr = createNetworkRequest(
                 NetworkCapabilities.NET_CAPABILITY_IMS);
+        TelephonyNetworkRequest thirdTnr = new TelephonyNetworkRequest(
+                new NetworkRequest((new NetworkCapabilities.Builder())
+                        .addCapability(NetworkCapabilities.NET_CAPABILITY_IMS)
+                        .addTransportType(NetworkCapabilities.TRANSPORT_SATELLITE)
+                        .build(),
+                        ConnectivityManager.TYPE_MOBILE, ++mNetworkRequestId,
+                        NetworkRequest.Type.REQUEST), mPhone, mFeatureFlags);
 
         mDataNetworkControllerUT.addNetworkRequest(firstTnr);
         processAllMessages();
 
         mDataNetworkControllerUT.removeNetworkRequest(firstTnr);
         mDataNetworkControllerUT.addNetworkRequest(secondTnr);
+        mDataNetworkControllerUT.addNetworkRequest(thirdTnr);
         processAllFutureMessages();
 
         verify(mMockedWwanDataServiceManager, times(1)).setupDataCall(anyInt(),
@@ -4181,6 +4204,7 @@
 
         NetworkCapabilities netCaps = new NetworkCapabilities();
         netCaps.addCapability(NetworkCapabilities.NET_CAPABILITY_IMS);
+        netCaps.maybeMarkCapabilitiesRestricted();
         netCaps.setRequestorPackageName(FAKE_MMTEL_PACKAGE);
 
         NetworkRequest nativeNetworkRequest = new NetworkRequest(netCaps,
@@ -4233,6 +4257,7 @@
         // setup emergency data network.
         NetworkCapabilities netCaps = new NetworkCapabilities();
         netCaps.addCapability(NetworkCapabilities.NET_CAPABILITY_EIMS);
+        netCaps.maybeMarkCapabilitiesRestricted();
         netCaps.setRequestorPackageName(FAKE_MMTEL_PACKAGE);
 
         NetworkRequest nativeNetworkRequest = new NetworkRequest(netCaps,
@@ -5093,7 +5118,8 @@
         serviceStateChanged(TelephonyManager.NETWORK_TYPE_LTE,
                 NetworkRegistrationInfo.REGISTRATION_STATE_HOME);
         mDataNetworkControllerUT.addNetworkRequest(
-                createNetworkRequest(NetworkCapabilities.NET_CAPABILITY_INTERNET));
+                createNetworkRequest(true/*restricted*/,
+                        NetworkCapabilities.NET_CAPABILITY_INTERNET));
         processAllMessages();
         verifyConnectedNetworkHasDataProfile(mEsimBootstrapDataProfile);
 
@@ -5104,13 +5130,6 @@
                 .get(AccessNetworkConstants.TRANSPORT_TYPE_WWAN), 2);
         processAllMessages();
         verifyConnectedNetworkHasDataProfile(mEsimBootstrapImsProfile);
-
-        serviceStateChanged(TelephonyManager.NETWORK_TYPE_LTE,
-                NetworkRegistrationInfo.REGISTRATION_STATE_HOME);
-        mDataNetworkControllerUT.addNetworkRequest(
-                createNetworkRequest(NetworkCapabilities.NET_CAPABILITY_RCS));
-        processAllMessages();
-        verifyNoConnectedNetworkHasCapability(NetworkCapabilities.NET_CAPABILITY_RCS);
     }
 
     @Test
@@ -5149,7 +5168,7 @@
         serviceStateChanged(TelephonyManager.NETWORK_TYPE_LTE,
                 NetworkRegistrationInfo.REGISTRATION_STATE_HOME);
         mDataNetworkControllerUT.addNetworkRequest(
-                createNetworkRequest(NetworkCapabilities.NET_CAPABILITY_INTERNET));
+                createNetworkRequest(true, NetworkCapabilities.NET_CAPABILITY_INTERNET));
         processAllMessages();
         // With allowed data limit unlimited, connection is allowed
         verifyConnectedNetworkHasDataProfile(mEsimBootstrapDataProfile);
diff --git a/tests/telephonytests/src/com/android/internal/telephony/satellite/DatagramDispatcherTest.java b/tests/telephonytests/src/com/android/internal/telephony/satellite/DatagramDispatcherTest.java
index 4896671..dba288e 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/satellite/DatagramDispatcherTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/satellite/DatagramDispatcherTest.java
@@ -98,6 +98,12 @@
     private static final long TEST_DATAGRAM_WAIT_FOR_CONNECTED_STATE_TIMEOUT_MILLIS =
             TimeUnit.SECONDS.toMillis(60);
     private static final Long TIMEOUT_DATAGRAM_DELAY_IN_DEMO_MODE = TimeUnit.SECONDS.toMillis(10);
+    private static final long
+            TEST_DATAGRAM_WAIT_FOR_CONNECTED_STATE_FOR_LAST_MESSAGE_TIMEOUT_MILLIS =
+            TimeUnit.SECONDS.toMillis(60);
+    private static final int
+            TEST_WAIT_FOR_DATAGRAM_SENDING_RESPONSE_FOR_LAST_MESSAGE_TIMEOUT_MILLIS =
+            (int) TimeUnit.SECONDS.toMillis(60);
 
     private TestDatagramDispatcher mDatagramDispatcherUT;
 
@@ -188,8 +194,11 @@
             clearInvocations(mMockSatelliteModemInterface);
             doReturn(true).when(mMockDatagramController)
                     .needsWaitingForSatelliteConnected(eq(datagramType));
-            when(mMockDatagramController.getDatagramWaitTimeForConnectedState())
+            when(mMockDatagramController.getDatagramWaitTimeForConnectedState(eq(false)))
                     .thenReturn(TEST_DATAGRAM_WAIT_FOR_CONNECTED_STATE_TIMEOUT_MILLIS);
+            when(mMockDatagramController.getDatagramWaitTimeForConnectedState(eq(true)))
+                    .thenReturn(
+                            TEST_DATAGRAM_WAIT_FOR_CONNECTED_STATE_FOR_LAST_MESSAGE_TIMEOUT_MILLIS);
             mResultListener.clear();
 
             mDatagramDispatcherUT.sendSatelliteDatagram(SUB_ID, datagramType, mDatagram,
@@ -201,7 +210,8 @@
                     eq(SatelliteManager.SATELLITE_DATAGRAM_TRANSFER_STATE_WAITING_TO_CONNECT),
                     eq(1),
                     eq(SATELLITE_RESULT_SUCCESS));
-            mInOrder.verify(mMockDatagramController).getDatagramWaitTimeForConnectedState();
+            mInOrder.verify(mMockDatagramController).getDatagramWaitTimeForConnectedState(
+                    eq(SatelliteServiceUtils.isLastSosMessage(datagramType)));
             verifyZeroInteractions(mMockSatelliteModemInterface);
             assertTrue(mDatagramDispatcherUT.isDatagramWaitForConnectedStateTimerStarted());
 
@@ -247,7 +257,8 @@
             verifyZeroInteractions(mMockSatelliteModemInterface);
             mInOrder.verify(mMockDatagramController)
                     .needsWaitingForSatelliteConnected(eq(datagramType));
-            mInOrder.verify(mMockDatagramController).getDatagramWaitTimeForConnectedState();
+            mInOrder.verify(mMockDatagramController).getDatagramWaitTimeForConnectedState(
+                    eq(SatelliteServiceUtils.isLastSosMessage(datagramType)));
             assertTrue(mDatagramDispatcherUT.isDatagramWaitForConnectedStateTimerStarted());
 
             moveTimeForward(TEST_DATAGRAM_WAIT_FOR_CONNECTED_STATE_TIMEOUT_MILLIS);
@@ -287,7 +298,8 @@
             verifyZeroInteractions(mMockSatelliteModemInterface);
             mInOrder.verify(mMockDatagramController)
                     .needsWaitingForSatelliteConnected(eq(datagramType));
-            mInOrder.verify(mMockDatagramController).getDatagramWaitTimeForConnectedState();
+            mInOrder.verify(mMockDatagramController).getDatagramWaitTimeForConnectedState(
+                    eq(SatelliteServiceUtils.isLastSosMessage(datagramType)));
             assertTrue(mDatagramDispatcherUT.isDatagramWaitForConnectedStateTimerStarted());
             assertEquals(0, mResultListener.size());
 
@@ -305,86 +317,102 @@
 
     @Test
     public void testSendSatelliteDatagram_timeout() throws  Exception {
-        doAnswer(invocation -> {
-            Message message = (Message) invocation.getArguments()[3];
-
-            mDatagramDispatcherUT.obtainMessage(2 /*EVENT_SEND_SATELLITE_DATAGRAM_DONE*/,
-                            new AsyncResult(message.obj, null, null))
-                    .sendToTarget();
-
-            // DatagramDispatcher should ignore the second EVENT_SEND_SATELLITE_DATAGRAM_DONE
-            mDatagramDispatcherUT.obtainMessage(2 /*EVENT_SEND_SATELLITE_DATAGRAM_DONE*/,
-                            new AsyncResult(message.obj, null, null))
-                    .sendToTarget();
-
-            return null;
-        }).when(mMockSatelliteModemInterface).sendSatelliteDatagram(any(SatelliteDatagram.class),
-                anyBoolean(), anyBoolean(), any(Message.class));
-        doReturn(false).when(mMockDatagramController)
-                .needsWaitingForSatelliteConnected(eq(DATAGRAM_TYPE1));
-        when(mMockDatagramController.getDatagramWaitTimeForConnectedState())
+        when(mMockDatagramController.getDatagramWaitTimeForConnectedState(eq(false)))
                 .thenReturn(TEST_DATAGRAM_WAIT_FOR_CONNECTED_STATE_TIMEOUT_MILLIS);
+        when(mMockDatagramController.getDatagramWaitTimeForConnectedState(eq(true)))
+                .thenReturn(TEST_DATAGRAM_WAIT_FOR_CONNECTED_STATE_FOR_LAST_MESSAGE_TIMEOUT_MILLIS);
         mContextFixture.putIntResource(
                 R.integer.config_wait_for_datagram_sending_response_timeout_millis,
                 TEST_WAIT_FOR_DATAGRAM_SENDING_RESPONSE_TIMEOUT_MILLIS);
+        mContextFixture.putIntResource(
+                R.integer.config_wait_for_datagram_sending_response_for_last_message_timeout_millis,
+                TEST_WAIT_FOR_DATAGRAM_SENDING_RESPONSE_FOR_LAST_MESSAGE_TIMEOUT_MILLIS);
         mResultListener.clear();
+        int[] sosDatagramTypes = {DATAGRAM_TYPE1, DATAGRAM_TYPE4, DATAGRAM_TYPE5};
+        for (int datagramType : sosDatagramTypes) {
+            doAnswer(invocation -> {
+                Message message = (Message) invocation.getArguments()[3];
 
-        mDatagramDispatcherUT.sendSatelliteDatagram(SUB_ID, DATAGRAM_TYPE1, mDatagram,
-                true, mResultListener::offer);
-        processAllMessages();
-        mInOrder.verify(mMockDatagramController)
-                .needsWaitingForSatelliteConnected(eq(DATAGRAM_TYPE1));
-        mInOrder.verify(mMockDatagramController).isPollingInIdleState();
-        mInOrder.verify(mMockDatagramController)
-                .updateSendStatus(eq(SUB_ID), eq(DATAGRAM_TYPE1),
-                        eq(SatelliteManager.SATELLITE_DATAGRAM_TRANSFER_STATE_SENDING), eq(1),
-                        eq(SATELLITE_RESULT_SUCCESS));
-        mInOrder.verify(mMockDatagramController)
-                .updateSendStatus(eq(SUB_ID), eq(DATAGRAM_TYPE1),
-                        eq(SatelliteManager.SATELLITE_DATAGRAM_TRANSFER_STATE_SEND_SUCCESS), eq(0),
-                        eq(SATELLITE_RESULT_SUCCESS));
-        mInOrder.verify(mMockDatagramController)
-                .updateSendStatus(eq(SUB_ID), eq(DATAGRAM_TYPE1),
-                        eq(SatelliteManager.SATELLITE_DATAGRAM_TRANSFER_STATE_IDLE), eq(0),
-                        eq(SATELLITE_RESULT_SUCCESS));
-        verifyNoMoreInteractions(mMockDatagramController);
-        verify(mMockSatelliteModemInterface, times(1)).sendSatelliteDatagram(
-                any(SatelliteDatagram.class), anyBoolean(), anyBoolean(), any(Message.class));
-        assertThat(mResultListener.peek()).isEqualTo(SATELLITE_RESULT_SUCCESS);
-        verify(mMockSessionMetricsStats, times(1)).addCountOfSuccessfulOutgoingDatagram();
-        clearInvocations(mMockSatelliteModemInterface);
-        clearInvocations(mMockDatagramController);
-        clearInvocations(mMockSessionMetricsStats);
-        mResultListener.clear();
+                mDatagramDispatcherUT.obtainMessage(2 /*EVENT_SEND_SATELLITE_DATAGRAM_DONE*/,
+                                new AsyncResult(message.obj, null, null))
+                        .sendToTarget();
 
-        // No response for the send request from modem
-        doNothing().when(mMockSatelliteModemInterface).sendSatelliteDatagram(
-                any(SatelliteDatagram.class), anyBoolean(), anyBoolean(), any(Message.class));
+                // DatagramDispatcher should ignore the second EVENT_SEND_SATELLITE_DATAGRAM_DONE
+                mDatagramDispatcherUT.obtainMessage(2 /*EVENT_SEND_SATELLITE_DATAGRAM_DONE*/,
+                                new AsyncResult(message.obj, null, null))
+                        .sendToTarget();
 
-        mDatagramDispatcherUT.sendSatelliteDatagram(SUB_ID, DATAGRAM_TYPE1, mDatagram,
-                true, mResultListener::offer);
-        processAllMessages();
-        mInOrder.verify(mMockDatagramController)
-                .needsWaitingForSatelliteConnected(eq(DATAGRAM_TYPE1));
-        mInOrder.verify(mMockDatagramController).isPollingInIdleState();
-        mInOrder.verify(mMockDatagramController)
-                .updateSendStatus(eq(SUB_ID), eq(DATAGRAM_TYPE1),
-                        eq(SatelliteManager.SATELLITE_DATAGRAM_TRANSFER_STATE_SENDING), eq(1),
-                        eq(SATELLITE_RESULT_SUCCESS));
-        mInOrder.verify(mMockDatagramController)
-                .updateSendStatus(eq(SUB_ID), eq(DATAGRAM_TYPE1),
-                        eq(SatelliteManager.SATELLITE_DATAGRAM_TRANSFER_STATE_SEND_FAILED), eq(1),
-                        eq(SATELLITE_RESULT_MODEM_TIMEOUT));
-        mInOrder.verify(mMockDatagramController)
-                .updateSendStatus(eq(SUB_ID), eq(DATAGRAM_TYPE1),
-                        eq(SatelliteManager.SATELLITE_DATAGRAM_TRANSFER_STATE_IDLE), eq(0),
-                        eq(SATELLITE_RESULT_SUCCESS));
-        verifyNoMoreInteractions(mMockDatagramController);
-        verify(mMockSatelliteModemInterface, times(1)).sendSatelliteDatagram(
-                any(SatelliteDatagram.class), anyBoolean(), anyBoolean(), any(Message.class));
-        verify(mMockSatelliteModemInterface).abortSendingSatelliteDatagrams(any(Message.class));
-        assertThat(mResultListener.peek()).isEqualTo(SATELLITE_RESULT_MODEM_TIMEOUT);
-        verify(mMockSessionMetricsStats, times(1)).addCountOfFailedOutgoingDatagram();
+                return null;
+            }).when(mMockSatelliteModemInterface).sendSatelliteDatagram(
+                    any(SatelliteDatagram.class),
+                    anyBoolean(), anyBoolean(), any(Message.class));
+            doReturn(false).when(mMockDatagramController)
+                    .needsWaitingForSatelliteConnected(eq(datagramType));
+
+            mDatagramDispatcherUT.sendSatelliteDatagram(SUB_ID, datagramType, mDatagram,
+                    true, mResultListener::offer);
+            processAllMessages();
+            mInOrder.verify(mMockDatagramController)
+                    .needsWaitingForSatelliteConnected(eq(datagramType));
+            mInOrder.verify(mMockDatagramController).isPollingInIdleState();
+            mInOrder.verify(mMockDatagramController)
+                    .updateSendStatus(eq(SUB_ID), eq(datagramType),
+                            eq(SatelliteManager.SATELLITE_DATAGRAM_TRANSFER_STATE_SENDING), eq(1),
+                            eq(SATELLITE_RESULT_SUCCESS));
+            mInOrder.verify(mMockDatagramController)
+                    .updateSendStatus(eq(SUB_ID), eq(datagramType),
+                            eq(SatelliteManager.SATELLITE_DATAGRAM_TRANSFER_STATE_SEND_SUCCESS),
+                            eq(0),
+                            eq(SATELLITE_RESULT_SUCCESS));
+            mInOrder.verify(mMockDatagramController)
+                    .updateSendStatus(eq(SUB_ID), eq(datagramType),
+                            eq(SatelliteManager.SATELLITE_DATAGRAM_TRANSFER_STATE_IDLE), eq(0),
+                            eq(SATELLITE_RESULT_SUCCESS));
+            verifyNoMoreInteractions(mMockDatagramController);
+            verify(mMockSatelliteModemInterface, times(1)).sendSatelliteDatagram(
+                    any(SatelliteDatagram.class), anyBoolean(), anyBoolean(), any(Message.class));
+            assertThat(mResultListener.peek()).isEqualTo(SATELLITE_RESULT_SUCCESS);
+            verify(mMockSessionMetricsStats, times(1)).addCountOfSuccessfulOutgoingDatagram();
+            clearInvocations(mMockSatelliteModemInterface);
+            clearInvocations(mMockDatagramController);
+            clearInvocations(mMockSessionMetricsStats);
+            mResultListener.clear();
+
+            // No response for the send request from modem
+            doNothing().when(mMockSatelliteModemInterface).sendSatelliteDatagram(
+                    any(SatelliteDatagram.class), anyBoolean(), anyBoolean(), any(Message.class));
+
+            mDatagramDispatcherUT.sendSatelliteDatagram(SUB_ID, datagramType, mDatagram,
+                    true, mResultListener::offer);
+            processAllMessages();
+            mInOrder.verify(mMockDatagramController)
+                    .needsWaitingForSatelliteConnected(eq(datagramType));
+            mInOrder.verify(mMockDatagramController).isPollingInIdleState();
+            mInOrder.verify(mMockDatagramController)
+                    .updateSendStatus(eq(SUB_ID), eq(datagramType),
+                            eq(SatelliteManager.SATELLITE_DATAGRAM_TRANSFER_STATE_SENDING), eq(1),
+                            eq(SATELLITE_RESULT_SUCCESS));
+            mInOrder.verify(mMockDatagramController)
+                    .updateSendStatus(eq(SUB_ID), eq(datagramType),
+                            eq(SatelliteManager.SATELLITE_DATAGRAM_TRANSFER_STATE_SEND_FAILED),
+                            eq(1),
+                            eq(SATELLITE_RESULT_MODEM_TIMEOUT));
+            mInOrder.verify(mMockDatagramController)
+                    .updateSendStatus(eq(SUB_ID), eq(datagramType),
+                            eq(SatelliteManager.SATELLITE_DATAGRAM_TRANSFER_STATE_IDLE), eq(0),
+                            eq(SATELLITE_RESULT_SUCCESS));
+            verifyNoMoreInteractions(mMockDatagramController);
+            verify(mMockSatelliteModemInterface, times(1)).sendSatelliteDatagram(
+                    any(SatelliteDatagram.class), anyBoolean(), anyBoolean(), any(Message.class));
+            verify(mMockSatelliteModemInterface).abortSendingSatelliteDatagrams(any(Message.class));
+            assertThat(mResultListener.peek()).isEqualTo(SATELLITE_RESULT_MODEM_TIMEOUT);
+            verify(mMockSessionMetricsStats, times(1)).addCountOfFailedOutgoingDatagram();
+
+            clearInvocations(mMockSatelliteModemInterface);
+            clearInvocations(mMockDatagramController);
+            clearInvocations(mMockSessionMetricsStats);
+            mResultListener.clear();
+        }
     }
 
     @Test
@@ -629,87 +657,96 @@
     }
 
     @Test
-    public void testSendSatelliteDatagramToModemInDemoMode()
-            throws Exception {
+    public void testSendSatelliteDatagramToModemInDemoMode() throws Exception {
         when(mFeatureFlags.oemEnabledSatelliteFlag()).thenReturn(true);
 
-        doAnswer(invocation -> {
-            Message message = (Message) invocation.getArguments()[3];
-            mDatagramDispatcherUT.obtainMessage(2 /*EVENT_SEND_SATELLITE_DATAGRAM_DONE*/,
-                            new AsyncResult(message.obj, null, null))
-                    .sendToTarget();
-            return null;
-        }).when(mMockSatelliteModemInterface).sendSatelliteDatagram(any(SatelliteDatagram.class),
-                anyBoolean(), anyBoolean(), any(Message.class));
         mDatagramDispatcherUT.setDemoMode(true);
         mDatagramDispatcherUT.setDeviceAlignedWithSatellite(true);
-        mIntegerConsumerSemaphore.drainPermits();
 
-        // Test when overlay config config_send_satellite_datagram_to_modem_in_demo_mode is true
-        mDatagramDispatcherUT.setShouldSendDatagramToModemInDemoMode(null);
-        mContextFixture.putBooleanResource(mConfigSendSatelliteDatagramToModemInDemoMode, true);
-        mDatagramDispatcherUT.sendSatelliteDatagram(SUB_ID, DATAGRAM_TYPE1, mDatagram,
-                true, mIntegerConsumer);
-        processAllMessages();
-        moveTimeForward(TIMEOUT_DATAGRAM_DELAY_IN_DEMO_MODE);
-        processAllMessages();
-        waitForIntegerConsumerResult(1);
-        assertEquals(SATELLITE_RESULT_SUCCESS,
-                (int) mIntegerConsumerResult.get(0));
-        mIntegerConsumerResult.clear();
-        verify(mMockSatelliteModemInterface, times(1)).sendSatelliteDatagram(
-                any(SatelliteDatagram.class), anyBoolean(), anyBoolean(), any(Message.class));
+        int[] sosDatagramTypes = {DATAGRAM_TYPE1, DATAGRAM_TYPE4, DATAGRAM_TYPE5};
+        for (int datagramType : sosDatagramTypes) {
+            mIntegerConsumerSemaphore.drainPermits();
+            mIntegerConsumerResult.clear();
+            clearInvocations(mMockDatagramController);
+            clearInvocations(mMockSatelliteModemInterface);
+            clearInvocations(mMockSessionMetricsStats);
+            doAnswer(invocation -> {
+                Message message = (Message) invocation.getArguments()[3];
+                mDatagramDispatcherUT.obtainMessage(2 /*EVENT_SEND_SATELLITE_DATAGRAM_DONE*/,
+                                new AsyncResult(message.obj, null, null))
+                        .sendToTarget();
+                return null;
+            }).when(mMockSatelliteModemInterface).sendSatelliteDatagram(
+                    any(SatelliteDatagram.class),
+                    anyBoolean(), anyBoolean(), any(Message.class));
 
-        moveTimeForward(TIMEOUT_DATAGRAM_DELAY_IN_DEMO_MODE);
-        processAllMessages();
-        verify(mMockDatagramController).pushDemoModeDatagram(
-                anyInt(), any(SatelliteDatagram.class));
-        verify(mMockDatagramController).pollPendingSatelliteDatagrams(anyInt(), any());
-        verify(mMockSessionMetricsStats, times(1)).addCountOfSuccessfulOutgoingDatagram();
+            // Test when overlay config config_send_satellite_datagram_to_modem_in_demo_mode is true
+            mDatagramDispatcherUT.setShouldSendDatagramToModemInDemoMode(null);
+            mContextFixture.putBooleanResource(mConfigSendSatelliteDatagramToModemInDemoMode, true);
+            mDatagramDispatcherUT.sendSatelliteDatagram(SUB_ID, datagramType, mDatagram,
+                    true, mIntegerConsumer);
+            processAllMessages();
+            moveTimeForward(TIMEOUT_DATAGRAM_DELAY_IN_DEMO_MODE);
+            processAllMessages();
+            waitForIntegerConsumerResult(1);
+            assertEquals(SATELLITE_RESULT_SUCCESS, (int) mIntegerConsumerResult.get(0));
+            mIntegerConsumerResult.clear();
+            verify(mMockSatelliteModemInterface, times(1)).sendSatelliteDatagram(
+                    any(SatelliteDatagram.class), anyBoolean(), anyBoolean(), any(Message.class));
 
-        // Test when overlay config config_send_satellite_datagram_to_modem_in_demo_mode is false
-        reset(mMockSatelliteModemInterface);
-        mDatagramDispatcherUT.setShouldSendDatagramToModemInDemoMode(null);
-        mContextFixture.putBooleanResource(mConfigSendSatelliteDatagramToModemInDemoMode, false);
-        mDatagramDispatcherUT.sendSatelliteDatagram(SUB_ID, DATAGRAM_TYPE1, mDatagram,
-                true, mIntegerConsumer);
-        processAllMessages();
-        moveTimeForward(TIMEOUT_DATAGRAM_DELAY_IN_DEMO_MODE);
-        processAllMessages();
+            moveTimeForward(TIMEOUT_DATAGRAM_DELAY_IN_DEMO_MODE);
+            processAllMessages();
+            verify(mMockDatagramController).pushDemoModeDatagram(
+                    anyInt(), any(SatelliteDatagram.class));
+            verify(mMockDatagramController).pollPendingSatelliteDatagrams(anyInt(), any());
+            verify(mMockSessionMetricsStats, times(1)).addCountOfSuccessfulOutgoingDatagram();
 
-        waitForIntegerConsumerResult(1);
-        assertEquals(SATELLITE_RESULT_SUCCESS,
-                (int) mIntegerConsumerResult.get(0));
-        mIntegerConsumerResult.clear();
-        verify(mMockSatelliteModemInterface, never()).sendSatelliteDatagram(
-                any(SatelliteDatagram.class), anyBoolean(), anyBoolean(), any(Message.class));
+            // Test when overlay config config_send_satellite_datagram_to_modem_in_demo_mode is
+            // false
+            reset(mMockSatelliteModemInterface);
+            mDatagramDispatcherUT.setShouldSendDatagramToModemInDemoMode(null);
+            mContextFixture.putBooleanResource(mConfigSendSatelliteDatagramToModemInDemoMode,
+                    false);
+            mDatagramDispatcherUT.sendSatelliteDatagram(SUB_ID, datagramType, mDatagram,
+                    true, mIntegerConsumer);
+            processAllMessages();
+            moveTimeForward(TIMEOUT_DATAGRAM_DELAY_IN_DEMO_MODE);
+            processAllMessages();
 
-        moveTimeForward(TIMEOUT_DATAGRAM_DELAY_IN_DEMO_MODE);
-        processAllMessages();
-        verify(mMockDatagramController, times(2)).pushDemoModeDatagram(
-                anyInt(), any(SatelliteDatagram.class));
-        verify(mMockDatagramController, times(2)).pollPendingSatelliteDatagrams(anyInt(), any());
+            waitForIntegerConsumerResult(1);
+            assertEquals(SATELLITE_RESULT_SUCCESS, (int) mIntegerConsumerResult.get(0));
+            mIntegerConsumerResult.clear();
+            verify(mMockSatelliteModemInterface, never()).sendSatelliteDatagram(
+                    any(SatelliteDatagram.class), anyBoolean(), anyBoolean(), any(Message.class));
 
-        // Send datagram one more time
-        reset(mMockSatelliteModemInterface);
-        mDatagramDispatcherUT.sendSatelliteDatagram(SUB_ID, DATAGRAM_TYPE1, mDatagram,
-                true, mIntegerConsumer);
-        processAllMessages();
-        moveTimeForward(TIMEOUT_DATAGRAM_DELAY_IN_DEMO_MODE);
-        processAllMessages();
+            moveTimeForward(TIMEOUT_DATAGRAM_DELAY_IN_DEMO_MODE);
+            processAllMessages();
+            verify(mMockDatagramController, times(2)).pushDemoModeDatagram(
+                    anyInt(), any(SatelliteDatagram.class));
+            verify(mMockDatagramController, times(2)).pollPendingSatelliteDatagrams(anyInt(),
+                    any());
 
-        waitForIntegerConsumerResult(1);
-        assertEquals(SATELLITE_RESULT_SUCCESS,
-                (int) mIntegerConsumerResult.get(0));
-        mIntegerConsumerResult.clear();
-        verify(mMockSatelliteModemInterface, never()).sendSatelliteDatagram(
-                any(SatelliteDatagram.class), anyBoolean(), anyBoolean(), any(Message.class));
+            // Send datagram one more time
+            reset(mMockSatelliteModemInterface);
+            mDatagramDispatcherUT.sendSatelliteDatagram(SUB_ID, datagramType, mDatagram,
+                    true, mIntegerConsumer);
+            processAllMessages();
+            moveTimeForward(TIMEOUT_DATAGRAM_DELAY_IN_DEMO_MODE);
+            processAllMessages();
 
-        moveTimeForward(TIMEOUT_DATAGRAM_DELAY_IN_DEMO_MODE);
-        processAllMessages();
-        verify(mMockDatagramController, times(3)).pushDemoModeDatagram(
-                anyInt(), any(SatelliteDatagram.class));
-        verify(mMockDatagramController, times(3)).pollPendingSatelliteDatagrams(anyInt(), any());
+            waitForIntegerConsumerResult(1);
+            assertEquals(SATELLITE_RESULT_SUCCESS, (int) mIntegerConsumerResult.get(0));
+            mIntegerConsumerResult.clear();
+            verify(mMockSatelliteModemInterface, never()).sendSatelliteDatagram(
+                    any(SatelliteDatagram.class), anyBoolean(), anyBoolean(), any(Message.class));
+
+            moveTimeForward(TIMEOUT_DATAGRAM_DELAY_IN_DEMO_MODE);
+            processAllMessages();
+            verify(mMockDatagramController, times(3)).pushDemoModeDatagram(
+                    anyInt(), any(SatelliteDatagram.class));
+            verify(mMockDatagramController, times(3)).pollPendingSatelliteDatagrams(anyInt(),
+                    any());
+        }
 
         mDatagramDispatcherUT.setDemoMode(false);
         mDatagramDispatcherUT.setDeviceAlignedWithSatellite(false);
diff --git a/tests/telephonytests/src/com/android/internal/telephony/satellite/DatagramReceiverTest.java b/tests/telephonytests/src/com/android/internal/telephony/satellite/DatagramReceiverTest.java
index 79d3657..4d3acb4 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/satellite/DatagramReceiverTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/satellite/DatagramReceiverTest.java
@@ -25,6 +25,7 @@
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyBoolean;
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.anyInt;
 import static org.mockito.Mockito.clearInvocations;
@@ -170,7 +171,7 @@
         }).when(mMockSatelliteModemInterface).pollPendingSatelliteDatagrams(any(Message.class));
         doReturn(true).when(mMockDatagramController)
                 .needsWaitingForSatelliteConnected(eq(SatelliteManager.DATAGRAM_TYPE_UNKNOWN));
-        when(mMockDatagramController.getDatagramWaitTimeForConnectedState())
+        when(mMockDatagramController.getDatagramWaitTimeForConnectedState(anyBoolean()))
                 .thenReturn(TEST_DATAGRAM_WAIT_FOR_CONNECTED_STATE_TIMEOUT_MILLIS);
         mResultListener.clear();
 
@@ -181,7 +182,7 @@
         mInOrder.verify(mMockDatagramController).updateReceiveStatus(eq(SUB_ID),
                 eq(SatelliteManager.SATELLITE_DATAGRAM_TRANSFER_STATE_WAITING_TO_CONNECT), eq(0),
                 eq(SatelliteManager.SATELLITE_RESULT_SUCCESS));
-        mInOrder.verify(mMockDatagramController).getDatagramWaitTimeForConnectedState();
+        mInOrder.verify(mMockDatagramController).getDatagramWaitTimeForConnectedState(eq(false));
         verifyZeroInteractions(mMockSatelliteModemInterface);
         assertTrue(mDatagramReceiverUT.isDatagramWaitForConnectedStateTimerStarted());
 
@@ -210,7 +211,7 @@
         processAllMessages();
         mInOrder.verify(mMockDatagramController)
                 .needsWaitingForSatelliteConnected(eq(SatelliteManager.DATAGRAM_TYPE_UNKNOWN));
-        mInOrder.verify(mMockDatagramController).getDatagramWaitTimeForConnectedState();
+        mInOrder.verify(mMockDatagramController).getDatagramWaitTimeForConnectedState(eq(false));
         verifyZeroInteractions(mMockSatelliteModemInterface);
         assertTrue(mDatagramReceiverUT.isDatagramWaitForConnectedStateTimerStarted());
 
diff --git a/tests/telephonytests/src/com/android/internal/telephony/satellite/SatelliteControllerTest.java b/tests/telephonytests/src/com/android/internal/telephony/satellite/SatelliteControllerTest.java
index 1484b47..f8656bf 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/satellite/SatelliteControllerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/satellite/SatelliteControllerTest.java
@@ -202,6 +202,7 @@
     @Mock private TelephonyConfigUpdateInstallReceiver mMockTelephonyConfigUpdateInstallReceiver;
     @Mock private SatelliteConfigParser mMockConfigParser;
     @Mock private SatelliteConfig mMockConfig;
+    @Mock private DemoSimulator mMockDemoSimulator;
 
     private Semaphore mIIntegerConsumerSemaphore = new Semaphore(0);
     private IIntegerConsumer mIIntegerConsumer = new IIntegerConsumer.Stub() {
@@ -475,6 +476,7 @@
         replaceInstance(PhoneFactory.class, "sPhones", null, new Phone[]{mPhone, mPhone2});
         replaceInstance(TelephonyConfigUpdateInstallReceiver.class, "sReceiverAdaptorInstance",
                 null, mMockTelephonyConfigUpdateInstallReceiver);
+        replaceInstance(DemoSimulator.class, "sInstance", null, mMockDemoSimulator);
 
         mServiceState2 = Mockito.mock(ServiceState.class);
         when(mPhone.getServiceState()).thenReturn(mServiceState);
@@ -785,6 +787,7 @@
         setUpResponseForRequestSatelliteEnabled(true, false, false, SATELLITE_RESULT_SUCCESS);
         mSatelliteControllerUT.requestSatelliteEnabled(SUB_ID, true, false, false,
                 mIIntegerConsumer);
+        mSatelliteControllerUT.setSatelliteSessionController(mMockSatelliteSessionController);
         processAllMessages();
         assertTrue(waitForIIntegerConsumerResult(1));
         assertEquals(SATELLITE_RESULT_SUCCESS, (long) mIIntegerConsumerResults.get(0));
@@ -1304,6 +1307,7 @@
                 .registerForSatelliteModemStateChanged(callback);
 
         resetSatelliteControllerUTToSupportedAndProvisionedState();
+        mSatelliteControllerUT.setSatelliteSessionController(mMockSatelliteSessionController);
 
         errorCode = mSatelliteControllerUT.registerForSatelliteModemStateChanged(
                 SUB_ID, callback);
@@ -1324,7 +1328,7 @@
                 .unregisterForSatelliteModemStateChanged(callback);
 
         resetSatelliteControllerUTToSupportedAndProvisionedState();
-
+        mSatelliteControllerUT.setSatelliteSessionController(mMockSatelliteSessionController);
         mSatelliteControllerUT.unregisterForModemStateChanged(SUB_ID, callback);
         verify(mMockSatelliteSessionController).unregisterForSatelliteModemStateChanged(callback);
     }
@@ -2250,6 +2254,7 @@
                 SATELLITE_MODEM_STATE_CONNECTED);
 
         resetSatelliteControllerUTToSupportedAndProvisionedState();
+        mSatelliteControllerUT.setSatelliteSessionController(mMockSatelliteSessionController);
         clearInvocations(mMockSatelliteSessionController);
         clearInvocations(mMockDatagramController);
         sendSatelliteModemStateChangedEvent(SATELLITE_MODEM_STATE_UNAVAILABLE, null);
@@ -4502,5 +4507,9 @@
         protected long getElapsedRealtime() {
             return elapsedRealtime;
         }
+
+        void setSatelliteSessionController(SatelliteSessionController satelliteSessionController) {
+            mSatelliteSessionController = satelliteSessionController;
+        }
     }
 }