Merge "Remove requestIsSatelliteCommunicationAllowedForCurrentLocation from vendor implementation" into 24D1-dev am: da4964f5fe

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/opt/telephony/+/26619385

Change-Id: Ibf2732be36fac772135ec2f4ce704e656a9be614
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
diff --git a/flags/calling.aconfig b/flags/calling.aconfig
index e67ebc6..bdd0844 100644
--- a/flags/calling.aconfig
+++ b/flags/calling.aconfig
@@ -1,12 +1,16 @@
 package: "com.android.internal.telephony.flags"
 
+# OWNER=breadley TARGET=24Q3
 flag {
   name: "simultaneous_calling_indications"
+  is_exported: true
   namespace: "telephony"
   description: "APIs that are used to notify simultaneous calling changes to other applications."
   bug: "297446980"
+  is_exported: true
 }
 
+# OWNER=yomna TARGET=24Q3
 flag {
   name: "show_call_fail_notification_for_2g_toggle"
   namespace: "telephony"
diff --git a/flags/data.aconfig b/flags/data.aconfig
index 6334803..fbd8508 100644
--- a/flags/data.aconfig
+++ b/flags/data.aconfig
@@ -1,5 +1,6 @@
 package: "com.android.internal.telephony.flags"
 
+# OWNER=linggm TARGET=24Q3
 flag {
   name: "auto_data_switch_allow_roaming"
   namespace: "telephony"
@@ -10,6 +11,7 @@
   }
 }
 
+# OWNER=linggm TARGET=24Q3
 flag {
   name: "auto_data_switch_rat_ss"
   namespace: "telephony"
@@ -17,6 +19,7 @@
   bug:"260928808"
 }
 
+# OWNER=linggm TARGET=24Q2
 flag {
   name: "use_alarm_callback"
   namespace: "telephony"
@@ -24,6 +27,7 @@
   bug: "311476875"
 }
 
+# OWNER=linggm TARGET=24Q2
 flag {
   name: "refine_preferred_data_profile_selection"
   namespace: "telephony"
@@ -31,6 +35,7 @@
   bug: "311476883"
 }
 
+# OWNER=linggm TARGET=24Q2
 flag {
   name: "unthrottle_check_transport"
   namespace: "telephony"
@@ -38,6 +43,7 @@
   bug: "303922311"
 }
 
+# OWNER=linggm TARGET=24Q1
 flag {
   name: "relax_ho_teardown"
   namespace: "telephony"
@@ -45,6 +51,7 @@
   bug: "270895912"
 }
 
+# OWNER=linggm TARGET=24Q2
 flag {
   name: "allow_mmtel_in_non_vops"
   namespace: "telephony"
@@ -52,6 +59,7 @@
   bug: "241198464"
 }
 
+# OWNER=jackyu TARGET=24Q2
 flag {
   name: "metered_embb_urlcc"
   namespace: "telephony"
@@ -59,27 +67,34 @@
   bug: "301310451"
   }
 
+# OWNER=sarahchin TARGET=24Q3
 flag {
   name: "slicing_additional_error_codes"
+  is_exported: true
   namespace: "telephony"
   description: "Support additional slicing error codes and functionality."
   bug: "307378699"
 }
 
+# OWNER=nagendranb TARGET=24Q3
 flag {
   name: "apn_setting_field_support_flag"
+  is_exported: true
   namespace: "telephony"
   description: "Expose apn setting supporting field"
   bug: "307038091"
 }
 
+# OWNER=sangyun TARGET=24Q3
 flag {
   name: "network_validation"
+  is_exported: true
   namespace: "telephony"
   description: "Request network validation for data networks and response status."
   bug:"286171724"
 }
 
+# OWNER=nagendranb TARGET=24Q2
 flag {
  name: "notify_data_activity_changed_with_slot"
   namespace: "telephony"
@@ -87,6 +102,7 @@
   bug: "309896936"
 }
 
+# OWNER=qingqi TARGET=24Q3
 flag {
   name: "vonr_enabled_metric"
   namespace: "telephony"
@@ -94,6 +110,7 @@
   bug:"288449751"
 }
 
+# OWNER=willycwhu TARGET=24Q2
 flag {
   name: "ignore_existing_networks_for_internet_allowed_checking"
   namespace: "telephony"
@@ -101,6 +118,7 @@
   bug: "284420611"
 }
 
+# OWNER=apsankar TARGET=24Q3
 flag {
   name: "data_call_session_stats_captures_cross_sim_calling"
   namespace: "telephony"
@@ -108,6 +126,7 @@
   bug: "313956117"
 }
 
+# OWNER=jackyu TARGET=24Q2
 flag {
   name: "force_iwlan_mms"
   namespace: "telephony"
@@ -115,6 +134,7 @@
   bug: "316211526"
 }
 
+# OWNER=sewook TARGET=24Q3
 flag {
   name: "reconnect_qualified_network"
   namespace: "telephony"
@@ -122,6 +142,7 @@
   bug: "319520561"
 }
 
+# OWNER=jackyu TARGET=24Q3
 flag {
   name: "dsrs_diagnostics_enabled"
   namespace: "telephony"
diff --git a/flags/domainselection.aconfig b/flags/domainselection.aconfig
index 2e1dfc8..3bf5898 100644
--- a/flags/domainselection.aconfig
+++ b/flags/domainselection.aconfig
@@ -1,5 +1,6 @@
 package: "com.android.internal.telephony.flags"
 
+# OWNER=forestchoi TARGET=24Q3
 flag {
     name: "ap_domain_selection_enabled"
     namespace: "telephony"
@@ -7,6 +8,7 @@
     bug:"258112541"
 }
 
+# OWNER=forestchoi TARGET=24Q3
 flag {
     name: "use_aosp_domain_selection_service"
     namespace: "telephony"
@@ -14,13 +16,16 @@
     bug:"258112541"
 }
 
+# OWNER=forestchoi TARGET=24Q3
 flag {
     name: "use_oem_domain_selection_service"
+    is_exported: true
     namespace: "telephony"
     description: "This flag controls OEMs' domain selection service supported."
     bug:"258112541"
 }
 
+# OWNER=forestchoi TARGET=24Q3
 flag {
     name: "domain_selection_metrics_enabled"
     namespace: "telephony"
diff --git a/flags/ims.aconfig b/flags/ims.aconfig
index d09259e..4dbd8aa 100644
--- a/flags/ims.aconfig
+++ b/flags/ims.aconfig
@@ -1,5 +1,6 @@
 package: "com.android.internal.telephony.flags"
 
+# OWNER=hyosunkim TARGET=24Q2
 flag {
     name: "conference_hold_unhold_changed_to_send_message"
     namespace: "telephony"
@@ -7,6 +8,7 @@
     bug:"288002989"
 }
 
+# OWNER=joonhunshin TARGET=24Q2
 flag {
     name: "ignore_already_terminated_incoming_call_before_registering_listener"
     namespace: "telephony"
@@ -14,6 +16,7 @@
     bug:"289461637"
 }
 
+# OWNER=joonhunshin TARGET=24Q2
 flag {
     name: "clear_cached_ims_phone_number_when_device_lost_ims_registration"
     namespace: "telephony"
@@ -21,6 +24,7 @@
     bug:"288002989"
 }
 
+# OWNER=sangyun TARGET=24Q2
 flag {
     name: "update_ims_service_by_gathering_provisioning_changes"
     namespace: "telephony"
@@ -28,13 +32,16 @@
     bug:"302281114"
 }
 
+# OWNER=shmun TARGET=24Q3
 flag {
     name: "add_rat_related_suggested_action_to_ims_registration"
+    is_exported: true
     namespace: "telephony"
     description: "This flag is for adding suggested actions related to RAT to ims registration"
     bug:"290573256"
 }
 
+# OWNER=joonhunshin TARGET=24Q3
 flag {
     name: "terminate_active_video_call_when_accepting_second_video_call_as_audio_only"
     namespace: "telephony"
@@ -42,13 +49,16 @@
     bug:"309548300"
 }
 
+# OWNER=sewookseo TARGET=24Q3
 flag {
     name: "emergency_registration_state"
+    is_exported: true
     namespace: "telephony"
     description: "This flag is created to notify emergency registration state changed."
     bug:"312101946"
 }
 
+# OWNER=apsankar TARGET=24Q3
 flag {
     name: "call_extra_for_non_hold_supported_carriers"
     namespace: "telephony"
@@ -56,9 +66,29 @@
     bug:"315993953"
 }
 
+# OWNER=joonhunshin TARGET=24Q3
 flag {
     name: "update_roaming_state_to_set_wfc_mode"
     namespace: "telephony"
     description: "This flag updates roaming state to set wfc mode"
     bug:"317298331"
 }
+
+# OWNER=joonhunshin TARGET=24Q3
+flag {
+    name: "enable_sip_subscribe_retry"
+    namespace: "telephony"
+    description: "This flag controls whether framework supports SIP subscribe retry or not"
+    bug:"297023230"
+}
+
+# OWNER=joonhunshin TARGET=24Q3
+flag {
+    name: "answer_audio_only_when_answering_via_mmi_code"
+    namespace: "telephony"
+    description: "This flag changes the media type when answering incoming call via MMI code"
+    bug:"286499659"
+    metadata {
+        purpose: PURPOSE_BUGFIX
+    }
+}
diff --git a/flags/iwlan.aconfig b/flags/iwlan.aconfig
index 0dc9f8d..702e3f1 100644
--- a/flags/iwlan.aconfig
+++ b/flags/iwlan.aconfig
@@ -1,13 +1,18 @@
 package: "com.android.internal.telephony.flags"
 
+# OWNER=jmunikrishna TARGET=24Q3
 flag {
     name: "enable_aead_algorithms"
+    is_exported: true
     namespace: "telephony"
     description: "Add AEAD algorithms AES-GCM-8, AES-GCM-12 and AES-GCM-16 to IWLAN"
     bug:"306119890"
 }
+
+# OWNER=jmunikrishna TARGET=24Q3
 flag {
     name: "enable_multiple_sa_proposals"
+    is_exported: true
     namespace: "telephony"
     description: "Add multiple proposals of cipher suites in IKE SA and Child SA"
     bug:"287296642"
diff --git a/flags/messaging.aconfig b/flags/messaging.aconfig
index 1ba89ba..57cfdb4 100644
--- a/flags/messaging.aconfig
+++ b/flags/messaging.aconfig
@@ -1,5 +1,6 @@
 package: "com.android.internal.telephony.flags"
 
+# OWNER=linggm TARGET=24Q1
 flag {
   name: "reject_bad_sub_id_interaction"
   namespace: "telephony"
@@ -7,6 +8,7 @@
   bug: "294125411"
 }
 
+# OWNER=hwangoo TARGET=24Q2
 flag {
   name: "sms_domain_selection_enabled"
   namespace: "telephony"
@@ -14,8 +16,10 @@
   bug: "262804071"
 }
 
+# OWNER=tnd TARGET=24Q3
 flag {
   name: "mms_disabled_error"
+  is_exported: true
   namespace: "telephony"
   description: "This flag controls the support of the new MMS error code MMS_ERROR_MMS_DISABLED."
   bug: "305062594"
diff --git a/flags/misc.aconfig b/flags/misc.aconfig
index aabceca..f5e9f6f 100644
--- a/flags/misc.aconfig
+++ b/flags/misc.aconfig
@@ -1,5 +1,6 @@
 package: "com.android.internal.telephony.flags"
 
+# OWNER=tjstuart TARGET=24Q3
 flag {
   name: "do_not_override_precise_label"
   namespace: "telephony"
@@ -8,6 +9,7 @@
   is_fixed_read_only: true
 }
 
+# OWNER=tnd TARGET=24Q1
 flag {
   name: "log_mms_sms_database_access_info"
   namespace: "telephony"
@@ -15,6 +17,7 @@
   bug: "275225402"
 }
 
+# OWNER=tjstuart TARGET=24Q3
 flag {
   name: "stop_spamming_emergency_notification"
   namespace: "telephony"
@@ -22,13 +25,16 @@
   bug: "275225402"
 }
 
+# OWNER=avinashmp TARGET=24Q3
 flag {
   name: "enable_wps_check_api_flag"
+  is_exported: true
   namespace: "telephony"
   description: "Enable system api isWpsCallNumber. Its an utility api to check if the dialed number is for Wireless Priority Service call."
   bug: "304272356"
 }
 
+# OWNER=grantmenke TARGET=24Q3
 flag {
   name: "ensure_access_to_call_settings_is_restricted"
   namespace: "telephony"
@@ -36,6 +42,7 @@
   bug: "309655251"
 }
 
+# OWNER=sangyun TARGET=24Q2
 flag {
   name: "reorganize_roaming_notification"
   namespace: "telephony"
@@ -43,6 +50,7 @@
   bug: "310594087"
 }
 
+# OWNER=sangyun TARGET=24Q2
 flag {
   name: "dismiss_network_selection_notification_on_sim_disable"
   namespace: "telephony"
@@ -50,6 +58,7 @@
   bug: "310594186"
 }
 
+# OWNER=nagendranb TARGET=24Q3
 flag {
   name: "enable_telephony_analytics"
   namespace: "telephony"
@@ -57,20 +66,25 @@
   bug: "309896524"
 }
 
+# OWNER=rambowang TARGET=24Q3
 flag {
   name: "show_call_id_and_call_waiting_in_additional_settings_menu"
+  is_exported: true
   namespace: "telephony"
   description: "Expose carrier config KEY_ADDITIONAL_SETTINGS_CALLER_ID_VISIBILITY_BOOL and KEY_ADDITIONAL_SETTINGS_CALL_WAITING_VISIBILITY_BOOL."
   bug: "310264981"
 }
 
+# OWNER=rambowang TARGET=24Q3
 flag {
     name: "reset_mobile_network_settings"
+    is_exported: true
     namespace: "telephony"
     description: "Allows applications to launch Reset Mobile Network Settings page in Settings app."
     bug:"271921464"
 }
 
+# OWNER=rambowang TARGET=24Q3
 flag {
     name: "fix_crash_on_getting_config_when_phone_is_gone"
     namespace: "telephony"
@@ -81,6 +95,7 @@
     }
 }
 
+# OWNER=rambowang TARGET=24Q3
 flag {
     name: "add_anomaly_when_notify_config_changed_with_invalid_phone"
     namespace: "telephony"
@@ -90,3 +105,14 @@
         purpose: PURPOSE_BUGFIX
     }
 }
+
+# OWNER=rambowang TARGET=24Q3
+flag {
+    name: "hide_preinstalled_carrier_app_at_most_once"
+    namespace: "telephony"
+    description: "Fix bug when preloaded carrier app is uninstalled and lose provisioning data"
+    bug:"158028151"
+    metadata {
+        purpose: PURPOSE_BUGFIX
+    }
+}
diff --git a/flags/network.aconfig b/flags/network.aconfig
index ab917f0..7587be9 100644
--- a/flags/network.aconfig
+++ b/flags/network.aconfig
@@ -1,5 +1,6 @@
 package: "com.android.internal.telephony.flags"
 
+# OWNER=nharold TARGET=24Q1
 flag {
     name: "enable_carrier_config_n1_control_attempt2"
     namespace: "telephony"
@@ -11,20 +12,25 @@
     }
 }
 
+# OWNER=sarahchin TARGET=24Q1
 flag {
   name: "hide_roaming_icon"
+  is_exported: true
   namespace: "telephony"
   description: "Allow carriers to hide the roaming (R) icon when roaming."
   bug: "301467052"
 }
 
+# OWNER=cukie TARGET=24Q3
 flag {
   name: "enable_identifier_disclosure_transparency"
+  is_exported: true
   namespace: "telephony"
   description: "Guards APIs for enabling and disabling identifier disclosure transparency"
   bug: "276752426"
 }
 
+# OWNER=cukie TARGET=24Q3
 flag {
   name: "enable_identifier_disclosure_transparency_unsol_events"
   namespace: "telephony"
@@ -32,13 +38,16 @@
   bug: "276752426"
 }
 
+# OWNER=cukie TARGET=24Q3
 flag {
   name: "enable_modem_cipher_transparency"
+  is_exported: true
   namespace: "telephony"
   description: "Guards APIs for enabling and disabling modem cipher transparency."
   bug: "283336425"
 }
 
+# OWNER=cukie TARGET=24Q3
 flag {
   name: "enable_modem_cipher_transparency_unsol_events"
   namespace: "telephony"
@@ -46,13 +55,16 @@
   bug: "283336425"
 }
 
+# OWNER=songferngwang TARGET=24Q3
 flag {
   name: "hide_prefer_3g_item"
+  is_exported: true
   namespace: "telephony"
   description: "Used in the Preferred Network Types menu to determine if the 3G option is displayed."
   bug: "310639009"
 }
 
+# OWNER=sarahchin TARGET=24Q2
 flag {
   name: "support_nr_sa_rrc_idle"
   namespace: "telephony"
@@ -60,8 +72,10 @@
   bug: "298233308"
 }
 
+# OWNER=nharold TARGET=24Q3
 flag {
   name: "network_registration_info_reject_cause"
+  is_exported: true
   namespace: "telephony"
   description: "Elevate NRI#getRejectCause from System to Public"
   bug: "239730435"
diff --git a/flags/satellite.aconfig b/flags/satellite.aconfig
index e640e6e..d9f1498 100644
--- a/flags/satellite.aconfig
+++ b/flags/satellite.aconfig
@@ -1,15 +1,27 @@
 package: "com.android.internal.telephony.flags"
 
+# OWNER=amallampati TARGET=24Q3
 flag {
     name: "oem_enabled_satellite_flag"
+    is_exported: true
     namespace: "telephony"
     description: "This flag controls satellite communication supported by OEMs."
     bug:"291811962"
 }
 
+# OWNER=amallampati TARGET=24Q3
 flag {
     name: "carrier_enabled_satellite_flag"
+    is_exported: true
     namespace: "telephony"
     description: "This flag controls satellite communication supported by carriers."
     bug:"296437388"
+}
+
+# OWNER=nagendranb TARGET=24Q3
+flag {
+    name: "satellite_internet"
+    namespace: "telephony"
+    description: "This flag enables satellite internet support."
+    bug:"326972202"
 }
\ No newline at end of file
diff --git a/flags/subscription.aconfig b/flags/subscription.aconfig
index cebedd5..5bc5340 100644
--- a/flags/subscription.aconfig
+++ b/flags/subscription.aconfig
@@ -1,26 +1,33 @@
 package: "com.android.internal.telephony.flags"
 
+# OWNER=linggm TARGET=24Q3
 flag {
   name: "work_profile_api_split"
+  is_exported: true
   namespace: "telephony"
   description: "To support separation between personal and work from TelephonyManager and SubscriptionManager API perspective."
   bug: "296076674"
 }
 
+# OWNER=linggm TARGET=24Q3
 flag {
   name: "enforce_subscription_user_filter"
+  is_exported: true
   namespace: "telephony"
   description: "Enabled flag means subscriptions enforce filtering result base on calling user handle. It marks the telephony completion of user filtering."
   bug: "296076674"
 }
 
+# OWNER=rambowang TARGET=24Q3
 flag {
   name: "data_only_cellular_service"
+  is_exported: true
   namespace: "telephony"
   description: "Supports customized cellular service capabilities per subscription."
   bug: "296097429"
 }
 
+# OWNER=rambowang TARGET=24Q3
 flag {
   name: "data_only_service_allow_emergency_call_only"
   namespace: "telephony"
@@ -28,15 +35,19 @@
   bug: "296097429"
 }
 
+# OWNER=hhshin TARGET=24Q3
 flag {
   name: "support_psim_to_esim_conversion"
+  is_exported: true
   namespace: "telephony"
   description: "Support the psim to esim conversion."
   bug: "315073761"
 }
 
+# OWNER=bookatz TARGET=24Q3
 flag {
   name: "subscription_user_association_query"
+  is_exported: true
   namespace: "telephony"
   description: "Supports querying if a subscription is associated with the caller"
   bug: "325045841"
diff --git a/flags/telephony.aconfig b/flags/telephony.aconfig
index 9ef70b1..91e8cf3 100644
--- a/flags/telephony.aconfig
+++ b/flags/telephony.aconfig
@@ -1,5 +1,6 @@
 package: "com.android.internal.telephony.flags"
 
+# OWNER=joonhunshin TARGET=24Q3
 flag {
     name: "enforce_telephony_feature_mapping"
     namespace: "telephony"
@@ -7,6 +8,7 @@
     bug:"297989574"
 }
 
+# OWNER=joonhunshin TARGET=24Q3
 flag {
     name: "enforce_telephony_feature_mapping_for_public_apis"
     namespace: "telephony"
@@ -14,6 +16,7 @@
     bug:"297989574"
 }
 
+# OWNER=stevestatia TARGET=24Q3
 flag {
     name: "prevent_system_server_and_phone_deadlock"
     namespace: "telephony"
@@ -21,6 +24,7 @@
     bug: "315973270"
 }
 
+# OWNER=joonhunshin TARGET=24Q3
 flag {
     name: "prevent_invocation_repeat_of_ril_call_when_device_does_not_support_voice"
     namespace: "telephony"
@@ -28,6 +32,7 @@
     bug: "290833783"
 }
 
+# OWNER=jackyu TARGET=24Q3
 flag {
     name: "minimal_telephony_cdm_check"
     namespace: "telephony"
@@ -35,9 +40,18 @@
     bug: "310710841"
 }
 
+# OWNER=jackyu TARGET=24Q3
 flag {
     name: "minimal_telephony_managers_conditional_on_features"
     namespace: "telephony"
     description: "This flag enables checking for telephony features before initializing corresponding managers"
     bug: "310710841"
 }
+
+# OWNER=joonhunshin TARGET=24Q3
+flag {
+    name: "set_no_reply_timer_for_cfnry"
+    namespace: "telephony"
+    description: "This flag supports setting the no reply timer for CFNRy based on carrier config"
+    bug:"314732435"
+}
diff --git a/flags/uicc.aconfig b/flags/uicc.aconfig
index c1b860f..6576c87 100644
--- a/flags/uicc.aconfig
+++ b/flags/uicc.aconfig
@@ -1,31 +1,42 @@
 package: "com.android.internal.telephony.flags"
 
+# OWNER=jayachandranc TARGET=24Q3
 flag {
     name: "esim_bootstrap_provisioning_flag"
     namespace: "telephony"
     description: "This flag controls eSIM Bootstrap provisioning feature support."
     bug:"298567545"
 }
+
+# OWNER=arunvoddu TARGET=24Q3
 flag {
     name: "imsi_key_retry_download_on_phone_unlock"
     namespace: "telephony"
     description: "This flag controls to download the IMSI encryption keys after user unlocks the phone."
     bug:"303780982"
 }
+
+# OWNER=arunvoddu TARGET=24Q3
 flag {
     name: "carrier_restriction_status"
+    is_exported: true
     namespace: "telephony"
     description: "This flag controls the visibility of the getCarrierRestrictionStatus in carrierRestrictionRules class."
     bug:"313553044"
 }
+
+# OWNER=arunvoddu TARGET=24Q3
 flag {
     name: "carrier_restriction_rules_enhancement"
     namespace: "telephony"
     description: "This flag controls the new enhancements to the existing carrier restrictions rules"
     bug:"317226653"
 }
+
+# OWNER=rafahs TARGET=24Q3
 flag {
     name: "esim_available_memory"
+    is_exported: true
     namespace: "telephony"
     description: "This flag controls eSIM available memory feature."
     bug:"318348580"
diff --git a/src/java/com/android/internal/telephony/CarrierInfoManager.java b/src/java/com/android/internal/telephony/CarrierInfoManager.java
index 863db93..8364c0a 100644
--- a/src/java/com/android/internal/telephony/CarrierInfoManager.java
+++ b/src/java/com/android/internal/telephony/CarrierInfoManager.java
@@ -33,6 +33,7 @@
 import android.util.Log;
 import android.util.Pair;
 
+import com.android.internal.telephony.flags.Flags;
 import com.android.internal.telephony.metrics.TelephonyMetrics;
 
 import java.security.PublicKey;
@@ -297,7 +298,12 @@
         final TelephonyManager telephonyManager = context.getSystemService(TelephonyManager.class)
                 .createForSubscriptionId(subId);
         int carrierId = telephonyManager.getSimCarrierId();
-        deleteCarrierInfoForImsiEncryption(context, subId, carrierId);
+        if (Flags.imsiKeyRetryDownloadOnPhoneUnlock()) {
+            String simOperator = telephonyManager.getSimOperator();
+            deleteCarrierInfoForImsiEncryption(context, subId, carrierId, simOperator);
+        } else {
+            deleteCarrierInfoForImsiEncryption(context, subId, carrierId);
+        }
         Intent resetIntent = new Intent(TelephonyIntents.ACTION_CARRIER_CERTIFICATE_DOWNLOAD);
         SubscriptionManager.putPhoneIdAndSubIdExtra(resetIntent, mPhoneId);
         context.sendBroadcastAsUser(resetIntent, UserHandle.ALL);
@@ -312,13 +318,29 @@
      */
     public static void deleteCarrierInfoForImsiEncryption(Context context, int subId,
             int carrierId) {
+        deleteCarrierInfoForImsiEncryption(context, subId, carrierId, null);
+    }
+
+    /**
+     * Deletes all the keys for a given Carrier from the device keystore.
+     * @param context Context
+     * @param subId SubscriptionId
+     * @param carrierId delete the key which matches the carrierId
+     * @param simOperator delete the key which matches the MCCMNC
+     *
+     */
+    public static void deleteCarrierInfoForImsiEncryption(Context context, int subId,
+            int carrierId, String simOperator) {
         Log.i(LOG_TAG, "deleting carrier key from db for subId=" + subId);
         String mcc = "";
         String mnc = "";
 
-        final TelephonyManager telephonyManager = context.getSystemService(TelephonyManager.class)
-                .createForSubscriptionId(subId);
-        String simOperator = telephonyManager.getSimOperator();
+        if (TextUtils.isEmpty(simOperator)) {
+            final TelephonyManager telephonyManager = context.getSystemService(
+                            TelephonyManager.class)
+                    .createForSubscriptionId(subId);
+            simOperator = telephonyManager.getSimOperator();
+        }
         if (!TextUtils.isEmpty(simOperator)) {
             mcc = simOperator.substring(0, 3);
             mnc = simOperator.substring(3);
diff --git a/src/java/com/android/internal/telephony/CarrierKeyDownloadManager.java b/src/java/com/android/internal/telephony/CarrierKeyDownloadManager.java
index 9143f21..10a3a32 100644
--- a/src/java/com/android/internal/telephony/CarrierKeyDownloadManager.java
+++ b/src/java/com/android/internal/telephony/CarrierKeyDownloadManager.java
@@ -18,6 +18,7 @@
 
 import static java.nio.charset.StandardCharsets.UTF_8;
 
+import android.annotation.NonNull;
 import android.app.AlarmManager;
 import android.app.DownloadManager;
 import android.app.KeyguardManager;
@@ -27,6 +28,8 @@
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.database.Cursor;
+import android.net.ConnectivityManager;
+import android.net.Network;
 import android.net.Uri;
 import android.os.Handler;
 import android.os.Message;
@@ -34,19 +37,22 @@
 import android.os.UserManager;
 import android.telephony.CarrierConfigManager;
 import android.telephony.ImsiEncryptionInfo;
+import android.telephony.SubscriptionInfo;
 import android.telephony.SubscriptionManager;
 import android.telephony.TelephonyManager;
 import android.text.TextUtils;
 import android.util.Log;
 import android.util.Pair;
 
+
 import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.telephony.flags.FeatureFlags;
+import com.android.internal.telephony.flags.Flags;
 
 import org.json.JSONArray;
 import org.json.JSONException;
 import org.json.JSONObject;
 
+
 import java.io.BufferedReader;
 import java.io.ByteArrayInputStream;
 import java.io.FileInputStream;
@@ -57,6 +63,7 @@
 import java.security.cert.CertificateFactory;
 import java.security.cert.X509Certificate;
 import java.util.Date;
+import java.util.List;
 import java.util.Random;
 import java.util.zip.GZIPInputStream;
 import java.util.zip.ZipException;
@@ -99,6 +106,8 @@
 
     private static final int EVENT_ALARM_OR_CONFIG_CHANGE = 0;
     private static final int EVENT_DOWNLOAD_COMPLETE = 1;
+    private static final int EVENT_NETWORK_AVAILABLE = 2;
+    private static final int EVENT_SCREEN_UNLOCKED = 3;
 
 
     private static final int[] CARRIER_KEY_TYPES = {TelephonyManager.KEY_TYPE_EPDG,
@@ -111,47 +120,77 @@
     private boolean mAllowedOverMeteredNetwork = false;
     private boolean mDeleteOldKeyAfterDownload = false;
     private boolean mIsRequiredToHandleUnlock;
-    private TelephonyManager mTelephonyManager;
+    private final TelephonyManager mTelephonyManager;
     private UserManager mUserManager;
-
     @VisibleForTesting
-    public String mMccMncForDownload;
-    public int mCarrierId;
+    public String mMccMncForDownload = "";
+    public int mCarrierId = TelephonyManager.UNKNOWN_CARRIER_ID;
     @VisibleForTesting
     public long mDownloadId;
-    private final FeatureFlags mFeatureFlags;
+    private DefaultNetworkCallback mDefaultNetworkCallback;
+    private ConnectivityManager mConnectivityManager;
+    private KeyguardManager mKeyguardManager;
 
-    public CarrierKeyDownloadManager(Phone phone, FeatureFlags featureFlags) {
+    public CarrierKeyDownloadManager(Phone phone) {
         mPhone = phone;
-        mFeatureFlags = featureFlags;
         mContext = phone.getContext();
         IntentFilter filter = new IntentFilter();
         filter.addAction(INTENT_KEY_RENEWAL_ALARM_PREFIX);
         filter.addAction(TelephonyIntents.ACTION_CARRIER_CERTIFICATE_DOWNLOAD);
-        filter.addAction(Intent.ACTION_USER_PRESENT);
+        if (Flags.imsiKeyRetryDownloadOnPhoneUnlock()) {
+            filter.addAction(Intent.ACTION_USER_UNLOCKED);
+        }
         mContext.registerReceiver(mBroadcastReceiver, filter, null, phone);
         mDownloadManager = (DownloadManager) mContext.getSystemService(Context.DOWNLOAD_SERVICE);
         mTelephonyManager = mContext.getSystemService(TelephonyManager.class)
                 .createForSubscriptionId(mPhone.getSubId());
-        mUserManager = mContext.getSystemService(UserManager.class);
+        if (Flags.imsiKeyRetryDownloadOnPhoneUnlock()) {
+            mKeyguardManager = mContext.getSystemService(KeyguardManager.class);
+        } else {
+            mUserManager = mContext.getSystemService(UserManager.class);
+        }
         CarrierConfigManager carrierConfigManager = mContext.getSystemService(
                 CarrierConfigManager.class);
         // Callback which directly handle config change should be executed on handler thread
         carrierConfigManager.registerCarrierConfigChangeListener(this::post,
                 (slotIndex, subId, carrierId, specificCarrierId) -> {
-                    boolean isUserUnlocked = mUserManager.isUserUnlocked();
-
-                    if (isUserUnlocked && slotIndex == mPhone.getPhoneId()) {
-                        Log.d(LOG_TAG, "Carrier Config changed: slotIndex=" + slotIndex);
-                        handleAlarmOrConfigChange();
+                    if (Flags.imsiKeyRetryDownloadOnPhoneUnlock()) {
+                        logd("CarrierConfig changed slotIndex = " + slotIndex + " subId = " + subId
+                                + " CarrierId = " + carrierId + " phoneId = "
+                                + mPhone.getPhoneId());
+                        // Below checks are necessary to optimise the logic.
+                        if ((slotIndex == mPhone.getPhoneId()) && (carrierId > 0
+                                || !TextUtils.isEmpty(
+                                mMccMncForDownload))) {
+                            mCarrierId = carrierId;
+                            updateSimOperator();
+                            // If device is screen locked do not proceed to handle
+                            // EVENT_ALARM_OR_CONFIG_CHANGE
+                            if (mKeyguardManager.isDeviceLocked()) {
+                                logd("Device is Locked");
+                                mIsRequiredToHandleUnlock = true;
+                            } else {
+                                logd("Carrier Config changed: slotIndex=" + slotIndex);
+                                sendEmptyMessage(EVENT_ALARM_OR_CONFIG_CHANGE);
+                            }
+                        }
                     } else {
-                        Log.d(LOG_TAG, "User is locked");
-                        mContext.registerReceiver(mUserUnlockedReceiver, new IntentFilter(
-                                Intent.ACTION_USER_UNLOCKED));
+                        boolean isUserUnlocked = mUserManager.isUserUnlocked();
+
+                        if (isUserUnlocked && slotIndex == mPhone.getPhoneId()) {
+                            Log.d(LOG_TAG, "Carrier Config changed: slotIndex=" + slotIndex);
+                            handleAlarmOrConfigChange();
+                        } else {
+                            Log.d(LOG_TAG, "User is locked");
+                            mContext.registerReceiver(mUserUnlockedReceiver, new IntentFilter(
+                                    Intent.ACTION_USER_UNLOCKED));
+                        }
                     }
                 });
+        mConnectivityManager = mContext.getSystemService(ConnectivityManager.class);
     }
 
+    // TODO remove this method upon imsiKeyRetryDownloadOnPhoneUnlock enabled.
     private final BroadcastReceiver mUserUnlockedReceiver = new BroadcastReceiver() {
         @Override
         public void onReceive(Context context, Intent intent) {
@@ -167,7 +206,7 @@
         public void onReceive(Context context, Intent intent) {
             String action = intent.getAction();
             if (action.equals(DownloadManager.ACTION_DOWNLOAD_COMPLETE)) {
-                Log.d(LOG_TAG, "Download Complete");
+                logd("Download Complete");
                 sendMessage(obtainMessage(EVENT_DOWNLOAD_COMPLETE,
                         intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, 0)));
             }
@@ -180,27 +219,36 @@
             String action = intent.getAction();
             int slotIndex = SubscriptionManager.getSlotIndex(mPhone.getSubId());
             int phoneId = mPhone.getPhoneId();
-            if (action.equals(INTENT_KEY_RENEWAL_ALARM_PREFIX)) {
-                int slotIndexExtra = intent.getIntExtra(SubscriptionManager.EXTRA_SLOT_INDEX, -1);
-                if (slotIndexExtra == slotIndex) {
-                    Log.d(LOG_TAG, "Handling key renewal alarm: " + action);
-                    sendEmptyMessage(EVENT_ALARM_OR_CONFIG_CHANGE);
+            switch (action) {
+                case INTENT_KEY_RENEWAL_ALARM_PREFIX -> {
+                    int slotIndexExtra = intent.getIntExtra(SubscriptionManager.EXTRA_SLOT_INDEX,
+                            -1);
+                    if (slotIndexExtra == slotIndex) {
+                        logd("Handling key renewal alarm: " + action);
+                        if (Flags.imsiKeyRetryDownloadOnPhoneUnlock()) {
+                            updateSimOperator();
+                        }
+                        sendEmptyMessage(EVENT_ALARM_OR_CONFIG_CHANGE);
+                    }
                 }
-            } else if (action.equals(TelephonyIntents.ACTION_CARRIER_CERTIFICATE_DOWNLOAD)) {
-                if (phoneId == intent.getIntExtra(PhoneConstants.PHONE_KEY,
-                        SubscriptionManager.INVALID_SIM_SLOT_INDEX)) {
-                    Log.d(LOG_TAG, "Handling reset intent: " + action);
-                    sendEmptyMessage(EVENT_ALARM_OR_CONFIG_CHANGE);
+                case TelephonyIntents.ACTION_CARRIER_CERTIFICATE_DOWNLOAD -> {
+                    if (phoneId == intent.getIntExtra(PhoneConstants.PHONE_KEY,
+                            SubscriptionManager.INVALID_SIM_SLOT_INDEX)) {
+                        logd("Handling reset intent: " + action);
+                        sendEmptyMessage(EVENT_ALARM_OR_CONFIG_CHANGE);
+                    }
                 }
-            }  else if (action.equals(Intent.ACTION_USER_PRESENT)) {
-                // The Carrier key download fails when SIM is inserted while device is locked
-                // hence adding a retry logic when device is unlocked.
-                Log.d(LOG_TAG,
-                        "device unlocked, isRequiredToHandleUnlock = " + mIsRequiredToHandleUnlock
-                                + ", slotIndex = " + slotIndex);
-                if (mIsRequiredToHandleUnlock) {
-                    mIsRequiredToHandleUnlock = false;
-                    sendEmptyMessage(EVENT_ALARM_OR_CONFIG_CHANGE);
+                case Intent.ACTION_USER_UNLOCKED -> {
+                    // The Carrier key download fails when SIM is inserted while device is locked
+                    // hence adding a retry logic when device is unlocked.
+                    logd("device fully unlocked, isRequiredToHandleUnlock = "
+                            + mIsRequiredToHandleUnlock
+                            + ", slotIndex = " + slotIndex + "  hasActiveDataNetwork = " + (
+                            mConnectivityManager.getActiveNetwork() != null));
+                    if (mIsRequiredToHandleUnlock) {
+                        mIsRequiredToHandleUnlock = false;
+                        sendEmptyMessage(EVENT_SCREEN_UNLOCKED);
+                    }
                 }
             }
         }
@@ -209,76 +257,124 @@
     @Override
     public void handleMessage (Message msg) {
         switch (msg.what) {
-            case EVENT_ALARM_OR_CONFIG_CHANGE:
-                handleAlarmOrConfigChange();
-                break;
-            case EVENT_DOWNLOAD_COMPLETE:
+            case EVENT_ALARM_OR_CONFIG_CHANGE, EVENT_NETWORK_AVAILABLE, EVENT_SCREEN_UNLOCKED ->
+                    handleAlarmOrConfigChange();
+            case EVENT_DOWNLOAD_COMPLETE -> {
                 long carrierKeyDownloadIdentifier = (long) msg.obj;
-                String currentMccMnc = getSimOperator();
-                int carrierId = getSimCarrierId();
+                String currentMccMnc = Flags.imsiKeyRetryDownloadOnPhoneUnlock()
+                        ? mTelephonyManager.getSimOperator(mPhone.getSubId()) : getSimOperator();
+                int carrierId = Flags.imsiKeyRetryDownloadOnPhoneUnlock()
+                        ? mTelephonyManager.getSimCarrierId() : getSimCarrierId();
                 if (isValidDownload(currentMccMnc, carrierKeyDownloadIdentifier, carrierId)) {
                     onDownloadComplete(carrierKeyDownloadIdentifier, currentMccMnc, carrierId);
-                    onPostDownloadProcessing(carrierKeyDownloadIdentifier);
+                    onPostDownloadProcessing();
                 }
-                break;
+            }
         }
     }
 
-    private void onPostDownloadProcessing(long carrierKeyDownloadIdentifier) {
+    private void onPostDownloadProcessing() {
         resetRenewalAlarm();
-        cleanupDownloadInfo();
-
+        if(Flags.imsiKeyRetryDownloadOnPhoneUnlock()) {
+            mDownloadId = -1;
+        } else {
+            cleanupDownloadInfo();
+        }
         // unregister from DOWNLOAD_COMPLETE
         mContext.unregisterReceiver(mDownloadReceiver);
     }
 
     private void handleAlarmOrConfigChange() {
-        if (carrierUsesKeys()) {
-            if (areCarrierKeysAbsentOrExpiring()) {
-                boolean downloadStartedSuccessfully = downloadKey();
-                // if the download was attempted, but not started successfully, and if carriers uses
-                // keys, we'll still want to renew the alarms, and try downloading the key a day
-                // later.
-                if (!downloadStartedSuccessfully) {
-                    // If download fails due to the device lock, we will reattempt once the device
-                    // is unlocked.
-                    if (mFeatureFlags.imsiKeyRetryDownloadOnPhoneUnlock()) {
-                        KeyguardManager keyguardManager = mContext.getSystemService(
-                                KeyguardManager.class);
-                        if (keyguardManager.isKeyguardSecure()) {
-                            Log.e(LOG_TAG, "Key download failed in device lock state");
-                            mIsRequiredToHandleUnlock = true;
+        if (Flags.imsiKeyRetryDownloadOnPhoneUnlock()) {
+            if (carrierUsesKeys()) {
+                if (areCarrierKeysAbsentOrExpiring()) {
+                    boolean hasActiveDataNetwork =
+                            (mConnectivityManager.getActiveNetwork() != null);
+                    boolean downloadStartedSuccessfully = hasActiveDataNetwork && downloadKey();
+                    // if the download was attempted, but not started successfully, and if
+                    // carriers uses keys, we'll still want to renew the alarms, and try
+                    // downloading the key a day later.
+                    int slotIndex = SubscriptionManager.getSlotIndex(mPhone.getSubId());
+                    if (downloadStartedSuccessfully) {
+                        unregisterDefaultNetworkCb(slotIndex);
+                    } else {
+                        // If download fails due to the device lock, we will reattempt once the
+                        // device is unlocked.
+                        mIsRequiredToHandleUnlock = mKeyguardManager.isDeviceLocked();
+                        loge("hasActiveDataConnection = " + hasActiveDataNetwork
+                                + "    isDeviceLocked = " + mIsRequiredToHandleUnlock);
+                        if (!hasActiveDataNetwork) {
+                            registerDefaultNetworkCb(slotIndex);
                         }
+                        resetRenewalAlarm();
                     }
-                    resetRenewalAlarm();
                 }
+                logd("handleAlarmOrConfigChange :: areCarrierKeysAbsentOrExpiring returned false");
             } else {
-                return;
+                cleanupRenewalAlarms();
+                if (!isOtherSlotHasCarrier()) {
+                    // delete any existing alarms.
+                    mPhone.deleteCarrierInfoForImsiEncryption(getSimCarrierId(), getSimOperator());
+                }
+                cleanupDownloadInfo();
             }
         } else {
-            // delete any existing alarms.
-            cleanupRenewalAlarms();
-            mPhone.deleteCarrierInfoForImsiEncryption(getSimCarrierId());
-
+            if (carrierUsesKeys()) {
+                if (areCarrierKeysAbsentOrExpiring()) {
+                    boolean downloadStartedSuccessfully = downloadKey();
+                    // if the download was attempted, but not started successfully, and if
+                    // carriers uses keys, we'll still want to renew the alarms, and try
+                    // downloading the key a day later.
+                    if (!downloadStartedSuccessfully) {
+                        resetRenewalAlarm();
+                    }
+                }
+            } else {
+                // delete any existing alarms.
+                cleanupRenewalAlarms();
+                mPhone.deleteCarrierInfoForImsiEncryption(getSimCarrierId());
+            }
         }
     }
 
+    private boolean isOtherSlotHasCarrier() {
+        SubscriptionManager subscriptionManager = mPhone.getContext().getSystemService(
+                SubscriptionManager.class);
+        List<SubscriptionInfo> subscriptionInfoList =
+                subscriptionManager.getActiveSubscriptionInfoList();
+        loge("handleAlarmOrConfigChange ActiveSubscriptionInfoList = " + (
+                (subscriptionInfoList != null) ? subscriptionInfoList.size() : null));
+        for (SubscriptionInfo subInfo : subscriptionInfoList) {
+            if (mPhone.getSubId() != subInfo.getSubscriptionId()
+                    && subInfo.getCarrierId() == mPhone.getCarrierId()) {
+                // We do not proceed to remove the Key from the DB as another slot contains
+                // same operator sim which is in active state.
+                loge("handleAlarmOrConfigChange same operator sim in another slot");
+                return true;
+            }
+        }
+        return false;
+    }
+
     private void cleanupDownloadInfo() {
-        Log.d(LOG_TAG, "Cleaning up download info");
+        logd("Cleaning up download info");
         mDownloadId = -1;
-        mMccMncForDownload = null;
+        if (Flags.imsiKeyRetryDownloadOnPhoneUnlock()) {
+            mMccMncForDownload = "";
+        } else {
+            mMccMncForDownload = null;
+        }
         mCarrierId = TelephonyManager.UNKNOWN_CARRIER_ID;
     }
 
     private void cleanupRenewalAlarms() {
-        Log.d(LOG_TAG, "Cleaning up existing renewal alarms");
+        logd("Cleaning up existing renewal alarms");
         int slotIndex = SubscriptionManager.getSlotIndex(mPhone.getSubId());
         Intent intent = new Intent(INTENT_KEY_RENEWAL_ALARM_PREFIX);
         intent.putExtra(SubscriptionManager.EXTRA_SLOT_INDEX, slotIndex);
         PendingIntent carrierKeyDownloadIntent = PendingIntent.getBroadcast(mContext, 0, intent,
                 PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE);
-        AlarmManager alarmManager =
-                (AlarmManager) mContext.getSystemService(mContext.ALARM_SERVICE);
+        AlarmManager alarmManager =mContext.getSystemService(AlarmManager.class);
         alarmManager.cancel(carrierKeyDownloadIntent);
     }
 
@@ -331,7 +427,7 @@
         cleanupRenewalAlarms();
         int slotIndex = SubscriptionManager.getSlotIndex(mPhone.getSubId());
         long minExpirationDate = getExpirationDate();
-        Log.d(LOG_TAG, "minExpirationDate: " + new Date(minExpirationDate));
+        logd("minExpirationDate: " + new Date(minExpirationDate));
         final AlarmManager alarmManager = (AlarmManager) mContext.getSystemService(
                 Context.ALARM_SERVICE);
         Intent intent = new Intent(INTENT_KEY_RENEWAL_ALARM_PREFIX);
@@ -339,16 +435,35 @@
         PendingIntent carrierKeyDownloadIntent = PendingIntent.getBroadcast(mContext, 0, intent,
                 PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE);
         alarmManager.set(AlarmManager.RTC_WAKEUP, minExpirationDate, carrierKeyDownloadIntent);
-        Log.d(LOG_TAG, "setRenewalAlarm: action=" + intent.getAction() + " time="
+        logd("setRenewalAlarm: action=" + intent.getAction() + " time="
                 + new Date(minExpirationDate));
     }
 
     /**
+     * Read the store the sim operetor value and update the value in case of change in the sim
+     * operetor.
+     */
+    public void updateSimOperator() {
+        if (Flags.imsiKeyRetryDownloadOnPhoneUnlock()) {
+            String simOperator = mPhone.getOperatorNumeric();
+            if (!TextUtils.isEmpty(simOperator) && !simOperator.equals(mMccMncForDownload)) {
+                mMccMncForDownload = simOperator;
+                logd("updateSimOperator, Initialized mMccMncForDownload = " + mMccMncForDownload);
+            }
+        }
+    }
+
+    /**
      * Returns the sim operator.
      **/
     @VisibleForTesting
     public String getSimOperator() {
-        return mTelephonyManager.getSimOperator(mPhone.getSubId());
+        if (Flags.imsiKeyRetryDownloadOnPhoneUnlock()) {
+            updateSimOperator();
+            return mMccMncForDownload;
+        } else {
+            return mTelephonyManager.getSimOperator(mPhone.getSubId());
+        }
     }
 
     /**
@@ -356,7 +471,11 @@
      **/
     @VisibleForTesting
     public int getSimCarrierId() {
-        return mTelephonyManager.getSimCarrierId();
+        if (Flags.imsiKeyRetryDownloadOnPhoneUnlock()) {
+            return (mCarrierId > 0) ? mCarrierId : mPhone.getCarrierId();
+        } else {
+            return mTelephonyManager.getSimCarrierId();
+        }
     }
 
     /**
@@ -367,7 +486,7 @@
     @VisibleForTesting
     public boolean isValidDownload(String currentMccMnc, long currentDownloadId, int carrierId) {
         if (currentDownloadId != mDownloadId) {
-            Log.e(LOG_TAG, "download ID=" + currentDownloadId
+            loge( "download ID=" + currentDownloadId
                     + " for completed download does not match stored id=" + mDownloadId);
             return false;
         }
@@ -375,12 +494,12 @@
         if (TextUtils.isEmpty(currentMccMnc) || TextUtils.isEmpty(mMccMncForDownload)
                 || !TextUtils.equals(currentMccMnc, mMccMncForDownload)
                 || mCarrierId != carrierId) {
-            Log.e(LOG_TAG, "currentMccMnc=" + currentMccMnc + " storedMccMnc =" + mMccMncForDownload
+            loge( "currentMccMnc=" + currentMccMnc + " storedMccMnc =" + mMccMncForDownload
                     + "currentCarrierId = " + carrierId + "  storedCarrierId = " + mCarrierId);
             return false;
         }
 
-        Log.d(LOG_TAG, "Matched MccMnc =  " + currentMccMnc + ", carrierId = " + carrierId
+        logd("Matched MccMnc =  " + currentMccMnc + ", carrierId = " + carrierId
                 + ", downloadId: " + currentDownloadId);
         return true;
     }
@@ -390,7 +509,7 @@
      **/
     private void onDownloadComplete(long carrierKeyDownloadIdentifier, String mccMnc,
             int carrierId) {
-        Log.d(LOG_TAG, "onDownloadComplete: " + carrierKeyDownloadIdentifier);
+        logd("onDownloadComplete: " + carrierKeyDownloadIdentifier);
         String jsonStr;
         DownloadManager.Query query = new DownloadManager.Query();
         query.setFilterById(carrierKeyDownloadIdentifier);
@@ -405,22 +524,21 @@
                 try {
                     jsonStr = convertToString(mDownloadManager, carrierKeyDownloadIdentifier);
                     if (TextUtils.isEmpty(jsonStr)) {
-                        Log.d(LOG_TAG, "fallback to no gzip");
+                        logd("fallback to no gzip");
                         jsonStr = convertToStringNoGZip(mDownloadManager,
                                 carrierKeyDownloadIdentifier);
                     }
                     parseJsonAndPersistKey(jsonStr, mccMnc, carrierId);
                 } catch (Exception e) {
-                    Log.e(LOG_TAG, "Error in download:" + carrierKeyDownloadIdentifier
+                    loge( "Error in download:" + carrierKeyDownloadIdentifier
                             + ". " + e);
                 } finally {
                     mDownloadManager.remove(carrierKeyDownloadIdentifier);
                 }
             }
-            Log.d(LOG_TAG, "Completed downloading keys");
+            logd("Completed downloading keys");
         }
         cursor.close();
-        return;
     }
 
     /**
@@ -442,7 +560,7 @@
                     CarrierConfigManager.IMSI_KEY_DOWNLOAD_URL_STRING,
                     CarrierConfigManager.KEY_ALLOW_METERED_NETWORK_FOR_CERT_DOWNLOAD_BOOL);
         } catch (RuntimeException e) {
-            Log.e(LOG_TAG, "CarrierConfigLoader is not available.");
+            loge( "CarrierConfigLoader is not available.");
         }
         if (b == null || b.isEmpty()) {
             return false;
@@ -452,10 +570,10 @@
         mURL = b.getString(CarrierConfigManager.IMSI_KEY_DOWNLOAD_URL_STRING);
         mAllowedOverMeteredNetwork = b.getBoolean(
                 CarrierConfigManager.KEY_ALLOW_METERED_NETWORK_FOR_CERT_DOWNLOAD_BOOL);
+
         if (mKeyAvailability == 0 || TextUtils.isEmpty(mURL)) {
-            Log.d(LOG_TAG,
-                    "Carrier not enabled or invalid values. mKeyAvailability=" + mKeyAvailability
-                            + " mURL=" + mURL);
+            logd("Carrier not enabled or invalid values. mKeyAvailability=" + mKeyAvailability
+                    + " mURL=" + mURL);
             return false;
         }
         for (int key_type : CARRIER_KEY_TYPES) {
@@ -469,7 +587,7 @@
     private static String convertToStringNoGZip(DownloadManager downloadManager, long downloadId) {
         StringBuilder sb = new StringBuilder();
         try (InputStream source = new FileInputStream(
-                    downloadManager.openDownloadedFile(downloadId).getFileDescriptor())) {
+                downloadManager.openDownloadedFile(downloadId).getFileDescriptor())) {
             // If the carrier does not have the data gzipped, fallback to assuming it is not zipped.
             // parseJsonAndPersistKey may still fail if the data is malformed, so we won't be
             // persisting random bogus strings thinking it's the cert
@@ -488,8 +606,8 @@
 
     private static String convertToString(DownloadManager downloadManager, long downloadId) {
         try (InputStream source = new FileInputStream(
-                    downloadManager.openDownloadedFile(downloadId).getFileDescriptor());
-                    InputStream gzipIs = new GZIPInputStream(source)) {
+                downloadManager.openDownloadedFile(downloadId).getFileDescriptor());
+             InputStream gzipIs = new GZIPInputStream(source)) {
             BufferedReader reader = new BufferedReader(new InputStreamReader(gzipIs, UTF_8));
             StringBuilder sb = new StringBuilder();
 
@@ -523,7 +641,7 @@
     public void parseJsonAndPersistKey(String jsonStr, String mccMnc, int carrierId) {
         if (TextUtils.isEmpty(jsonStr) || TextUtils.isEmpty(mccMnc)
                 || carrierId == TelephonyManager.UNKNOWN_CARRIER_ID) {
-            Log.e(LOG_TAG, "jsonStr or mcc, mnc: is empty or carrierId is UNKNOWN_CARRIER_ID");
+            loge( "jsonStr or mcc, mnc: is empty or carrierId is UNKNOWN_CARRIER_ID");
             return;
         }
         try {
@@ -548,22 +666,28 @@
                     if (typeString.equals(JSON_TYPE_VALUE_EPDG)) {
                         type = TelephonyManager.KEY_TYPE_EPDG;
                     } else if (!typeString.equals(JSON_TYPE_VALUE_WLAN)) {
-                        Log.e(LOG_TAG, "Invalid key-type specified: " + typeString);
+                        loge( "Invalid key-type specified: " + typeString);
                     }
                 }
                 String identifier = key.getString(JSON_IDENTIFIER);
                 Pair<PublicKey, Long> keyInfo =
                         getKeyInformation(cleanCertString(cert).getBytes());
                 if (mDeleteOldKeyAfterDownload) {
-                    mPhone.deleteCarrierInfoForImsiEncryption(TelephonyManager.UNKNOWN_CARRIER_ID);
+                    if (Flags.imsiKeyRetryDownloadOnPhoneUnlock()) {
+                        mPhone.deleteCarrierInfoForImsiEncryption(
+                                TelephonyManager.UNKNOWN_CARRIER_ID, null);
+                    } else {
+                        mPhone.deleteCarrierInfoForImsiEncryption(
+                                TelephonyManager.UNKNOWN_CARRIER_ID);
+                    }
                     mDeleteOldKeyAfterDownload = false;
                 }
                 savePublicKey(keyInfo.first, type, identifier, keyInfo.second, mcc, mnc, carrierId);
             }
         } catch (final JSONException e) {
-            Log.e(LOG_TAG, "Json parsing error: " + e.getMessage());
+            loge( "Json parsing error: " + e.getMessage());
         } catch (final Exception e) {
-            Log.e(LOG_TAG, "Exception getting certificate: " + e);
+            loge( "Exception getting certificate: " + e);
         }
     }
 
@@ -584,7 +708,7 @@
     public static boolean isKeyEnabled(int keyType, int keyAvailability) {
         // since keytype has values of 1, 2.... we need to subtract 1 from the keytype.
         int returnValue = (keyAvailability >> (keyType - 1)) & 1;
-        return (returnValue == 1) ? true : false;
+        return returnValue == 1;
     }
 
     /**
@@ -603,31 +727,42 @@
             ImsiEncryptionInfo imsiEncryptionInfo =
                     mPhone.getCarrierInfoForImsiEncryption(key_type, false);
             if (imsiEncryptionInfo == null) {
-                Log.d(LOG_TAG, "Key not found for: " + key_type);
+                logd("Key not found for: " + key_type);
                 return true;
             } else if (imsiEncryptionInfo.getCarrierId() == TelephonyManager.UNKNOWN_CARRIER_ID) {
-                Log.d(LOG_TAG, "carrier key is unknown carrier, so prefer to reDownload");
+                logd("carrier key is unknown carrier, so prefer to reDownload");
                 mDeleteOldKeyAfterDownload = true;
                 return true;
             }
             Date imsiDate = imsiEncryptionInfo.getExpirationTime();
             long timeToExpire = imsiDate.getTime() - System.currentTimeMillis();
-            return (timeToExpire < START_RENEWAL_WINDOW_DAYS * DAY_IN_MILLIS) ? true : false;
+            return timeToExpire < START_RENEWAL_WINDOW_DAYS * DAY_IN_MILLIS;
         }
         return false;
     }
 
     private boolean downloadKey() {
-        Log.d(LOG_TAG, "starting download from: " + mURL);
-        String mccMnc = getSimOperator();
-        int carrierId = getSimCarrierId();
-        if (!TextUtils.isEmpty(mccMnc) || carrierId != TelephonyManager.UNKNOWN_CARRIER_ID) {
-            Log.d(LOG_TAG, "downloading key for mccmnc : " + mccMnc + ", carrierId : "
-                    + carrierId);
+        logd("starting download from: " + mURL);
+        String mccMnc = null;
+        int carrierId = -1;
+        if (Flags.imsiKeyRetryDownloadOnPhoneUnlock()) {
+            if (TextUtils.isEmpty(mMccMncForDownload)
+                    || mCarrierId == TelephonyManager.UNKNOWN_CARRIER_ID) {
+                loge("mccmnc or carrierId is UnKnown");
+                return false;
+            }
         } else {
-            Log.e(LOG_TAG, "mccmnc or carrierId is UnKnown");
-            return false;
+            mccMnc = getSimOperator();
+            carrierId = getSimCarrierId();
+            if (!TextUtils.isEmpty(mccMnc) || carrierId != TelephonyManager.UNKNOWN_CARRIER_ID) {
+                Log.d(LOG_TAG, "downloading key for mccmnc : " + mccMnc + ", carrierId : "
+                        + carrierId);
+            } else {
+                Log.e(LOG_TAG, "mccmnc or carrierId is UnKnown");
+                return false;
+            }
         }
+
         try {
             // register the broadcast receiver to listen for download complete
             IntentFilter filter = new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE);
@@ -641,15 +776,16 @@
             request.setAllowedOverMetered(mAllowedOverMeteredNetwork);
             request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_HIDDEN);
             request.addRequestHeader("Accept-Encoding", "gzip");
-            Long carrierKeyDownloadRequestId = mDownloadManager.enqueue(request);
-
-            Log.d(LOG_TAG, "saving values mccmnc: " + mccMnc + ", downloadId: "
-                    + carrierKeyDownloadRequestId + ", carrierId: " + carrierId);
-            mMccMncForDownload = mccMnc;
-            mCarrierId = carrierId;
+            long carrierKeyDownloadRequestId = mDownloadManager.enqueue(request);
+            if (!Flags.imsiKeyRetryDownloadOnPhoneUnlock()) {
+                mMccMncForDownload = mccMnc;
+                mCarrierId = carrierId;
+            }
             mDownloadId = carrierKeyDownloadRequestId;
+            logd("saving values mccmnc: " + mMccMncForDownload + ", downloadId: "
+                    + carrierKeyDownloadRequestId + ", carrierId: " + mCarrierId);
         } catch (Exception e) {
-            Log.e(LOG_TAG, "exception trying to download key from url: " + mURL + ", Exception = "
+            loge( "exception trying to download key from url: " + mURL + ",  Exception = "
                     + e.getMessage());
             return false;
         }
@@ -667,7 +803,7 @@
         CertificateFactory cf = CertificateFactory.getInstance("X.509");
         X509Certificate cert = (X509Certificate) cf.generateCertificate(inStream);
         Pair<PublicKey, Long> keyInformation =
-                new Pair(cert.getPublicKey(), cert.getNotAfter().getTime());
+                new Pair<>(cert.getPublicKey(), cert.getNotAfter().getTime());
         return keyInformation;
     }
 
@@ -699,4 +835,59 @@
                 cert.indexOf(CERT_BEGIN_STRING),
                 cert.indexOf(CERT_END_STRING) + CERT_END_STRING.length());
     }
+
+    /**
+     * Registering the callback to listen on data connection availability.
+     *
+     * @param slotId Sim slotIndex that tries to download the key.
+     */
+    private void registerDefaultNetworkCb(int slotId) {
+        logd("RegisterDefaultNetworkCb for slotId = " + slotId);
+        if (mDefaultNetworkCallback == null
+                && slotId != SubscriptionManager.INVALID_SIM_SLOT_INDEX) {
+            mDefaultNetworkCallback = new DefaultNetworkCallback(slotId);
+            mConnectivityManager.registerDefaultNetworkCallback(mDefaultNetworkCallback, this);
+        }
+    }
+
+    /**
+     * Unregister the data connection monitor listener.
+     */
+    private void unregisterDefaultNetworkCb(int slotId) {
+        logd("unregisterDefaultNetworkCb for slotId = " + slotId);
+        if (mDefaultNetworkCallback != null) {
+            mConnectivityManager.unregisterNetworkCallback(mDefaultNetworkCallback);
+            mDefaultNetworkCallback = null;
+        }
+    }
+
+    final class DefaultNetworkCallback extends ConnectivityManager.NetworkCallback {
+        final int mSlotIndex;
+
+        public DefaultNetworkCallback(int slotId) {
+            mSlotIndex = slotId;
+        }
+
+        /** Called when the framework connects and has declared a new network ready for use. */
+        @Override
+        public void onAvailable(@NonNull Network network) {
+            logd("Data network connected, slotId = " + mSlotIndex);
+            if (mConnectivityManager.getActiveNetwork() != null && SubscriptionManager.getSlotIndex(
+                    mPhone.getSubId()) == mSlotIndex) {
+                mIsRequiredToHandleUnlock = false;
+                unregisterDefaultNetworkCb(mSlotIndex);
+                sendEmptyMessage(EVENT_NETWORK_AVAILABLE);
+            }
+        }
+    }
+
+    private void loge(String logStr) {
+        String TAG = LOG_TAG + " [" + mPhone.getPhoneId() + "]";
+        Log.e(TAG, logStr);
+    }
+
+    private void logd(String logStr) {
+        String TAG = LOG_TAG + " [" + mPhone.getPhoneId() + "]";
+        Log.d(TAG, logStr);
+    }
 }
diff --git a/src/java/com/android/internal/telephony/GsmCdmaPhone.java b/src/java/com/android/internal/telephony/GsmCdmaPhone.java
index db0fb2d..eeba86b 100644
--- a/src/java/com/android/internal/telephony/GsmCdmaPhone.java
+++ b/src/java/com/android/internal/telephony/GsmCdmaPhone.java
@@ -539,7 +539,7 @@
         mContext.registerReceiver(mBroadcastReceiver, filter,
                 android.Manifest.permission.MODIFY_PHONE_STATE, null, Context.RECEIVER_EXPORTED);
 
-        mCDM = new CarrierKeyDownloadManager(this, mFeatureFlags);
+        mCDM = new CarrierKeyDownloadManager(this);
         mCIM = new CarrierInfoManager();
 
         mCi.registerForImeiMappingChanged(this, EVENT_IMEI_MAPPING_CHANGED, null);
@@ -2124,8 +2124,13 @@
 
     @Override
     public void deleteCarrierInfoForImsiEncryption(int carrierId) {
+        CarrierInfoManager.deleteCarrierInfoForImsiEncryption(mContext, getSubId(), carrierId);
+    }
+
+    @Override
+    public void deleteCarrierInfoForImsiEncryption(int carrierId, String simOperator) {
         CarrierInfoManager.deleteCarrierInfoForImsiEncryption(mContext, getSubId(),
-                carrierId);
+                carrierId, simOperator);
     }
 
     @Override
@@ -2298,6 +2303,11 @@
     }
 
     @Override
+    protected void onSetNetworkSelectionModeCompleted() {
+        mSST.pollState();
+    }
+
+    @Override
     public String getCdmaPrlVersion() {
         return mSST.getPrlVersion();
     }
@@ -3669,6 +3679,7 @@
             case EVENT_SUBSCRIPTIONS_CHANGED:
                 logd("EVENT_SUBSCRIPTIONS_CHANGED");
                 updateUsageSetting();
+                updateNullCipherNotifier();
                 break;
             case EVENT_SET_NULL_CIPHER_AND_INTEGRITY_DONE:
                 logd("EVENT_SET_NULL_CIPHER_AND_INTEGRITY_DONE");
@@ -3769,7 +3780,8 @@
                         && mNullCipherNotifier != null) {
                     ar = (AsyncResult) msg.obj;
                     SecurityAlgorithmUpdate update = (SecurityAlgorithmUpdate) ar.result;
-                    mNullCipherNotifier.onSecurityAlgorithmUpdate(mContext, getSubId(), update);
+                    mNullCipherNotifier.onSecurityAlgorithmUpdate(mContext, getPhoneId(),
+                            getSubId(), update);
                 }
                 break;
 
@@ -5444,6 +5456,25 @@
                 obtainMessage(EVENT_SET_SECURITY_ALGORITHMS_UPDATED_ENABLED_DONE));
     }
 
+    /**
+     * Update the phoneId -> subId mapping of the null cipher notifier.
+     */
+    @VisibleForTesting
+    public void updateNullCipherNotifier() {
+        if (!mFeatureFlags.enableModemCipherTransparencyUnsolEvents()) {
+            return;
+        }
+
+        SubscriptionInfoInternal subInfo = mSubscriptionManagerService
+                .getSubscriptionInfoInternal(getSubId());
+        boolean active = false;
+        if (subInfo != null) {
+            active = subInfo.isActive();
+        }
+        mNullCipherNotifier.setSubscriptionMapping(mContext, getPhoneId(),
+                active ? subInfo.getSubscriptionId() : -1);
+    }
+
     @Override
     public boolean isNullCipherAndIntegritySupported() {
         return mIsNullCipherAndIntegritySupported;
diff --git a/src/java/com/android/internal/telephony/MultiSimSettingController.java b/src/java/com/android/internal/telephony/MultiSimSettingController.java
index aaeba23..a5f433b 100644
--- a/src/java/com/android/internal/telephony/MultiSimSettingController.java
+++ b/src/java/com/android/internal/telephony/MultiSimSettingController.java
@@ -17,6 +17,7 @@
 package com.android.internal.telephony;
 
 import static android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID;
+import static android.telephony.SubscriptionManager.PROFILE_CLASS_PROVISIONING;
 import static android.telephony.TelephonyManager.ACTION_PRIMARY_SUBSCRIPTION_LIST_CHANGED;
 import static android.telephony.TelephonyManager.EXTRA_DEFAULT_SUBSCRIPTION_SELECT_TYPE;
 import static android.telephony.TelephonyManager.EXTRA_DEFAULT_SUBSCRIPTION_SELECT_TYPE_ALL;
@@ -632,7 +633,9 @@
             if (hasData()) mSubscriptionManagerService.setDefaultDataSubId(subId);
             if (hasCalling()) mSubscriptionManagerService.setDefaultVoiceSubId(subId);
             if (hasMessaging()) mSubscriptionManagerService.setDefaultSmsSubId(subId);
-            sendDefaultSubConfirmedNotification(subId);
+            if (!mSubscriptionManagerService.isEsimBootStrapProvisioningActivated()) {
+                sendDefaultSubConfirmedNotification(subId);
+            }
             return;
         }
 
@@ -685,7 +688,9 @@
         // Update mPrimarySubList. Opportunistic subscriptions can't be default
         // data / voice / sms subscription.
         List<Integer> prevPrimarySubList = mPrimarySubList;
-        mPrimarySubList = activeSubList.stream().filter(info -> !info.isOpportunistic())
+        mPrimarySubList = activeSubList.stream()
+                .filter(info -> !info.isOpportunistic())
+                .filter(info -> info.getProfileClass() != PROFILE_CLASS_PROVISIONING)
                 .map(info -> info.getSubscriptionId())
                 .collect(Collectors.toList());
 
@@ -751,6 +756,12 @@
 
     private void sendSubChangeNotificationIfNeeded(int change, boolean dataSelected,
             boolean voiceSelected, boolean smsSelected) {
+
+        if (mSubscriptionManagerService.isEsimBootStrapProvisioningActivated()) {
+            log("esim bootstrap activation in progress, skip notification");
+            return;
+        }
+
         @TelephonyManager.DefaultSubscriptionSelectType
         int simSelectDialogType = getSimSelectDialogType(
                 change, dataSelected, voiceSelected, smsSelected);
diff --git a/src/java/com/android/internal/telephony/Phone.java b/src/java/com/android/internal/telephony/Phone.java
index c088406..6858533 100644
--- a/src/java/com/android/internal/telephony/Phone.java
+++ b/src/java/com/android/internal/telephony/Phone.java
@@ -779,6 +779,7 @@
             case EVENT_SET_NETWORK_MANUAL_COMPLETE:
             case EVENT_SET_NETWORK_AUTOMATIC_COMPLETE:
                 handleSetSelectNetwork((AsyncResult) msg.obj);
+                onSetNetworkSelectionModeCompleted();
                 return;
         }
 
@@ -1536,6 +1537,12 @@
     }
 
     /**
+     * Called when setting network selection mode is complete.
+     */
+    protected void onSetNetworkSelectionModeCompleted() {
+    }
+
+    /**
      * Query the radio for the current network selection mode.
      *
      * Return values:
@@ -4018,6 +4025,15 @@
         return;
     }
 
+    /**
+     * Deletes all the keys for a given Carrier from the device keystore.
+     * @param carrierId : the carrier ID which needs to be matched in the delete query
+     * @param simOperator : MccMnc which needs to be matched in the delete query.
+     */
+    public void deleteCarrierInfoForImsiEncryption(int carrierId, String simOperator) {
+
+    }
+
     public int getCarrierId() {
         return TelephonyManager.UNKNOWN_CARRIER_ID;
     }
diff --git a/src/java/com/android/internal/telephony/data/AccessNetworksManager.java b/src/java/com/android/internal/telephony/data/AccessNetworksManager.java
index 3d3fbe9..e573db9 100644
--- a/src/java/com/android/internal/telephony/data/AccessNetworksManager.java
+++ b/src/java/com/android/internal/telephony/data/AccessNetworksManager.java
@@ -346,9 +346,9 @@
         }
 
         @Override
-        public void onReconnectQualifedNetworkType(int apnTypes, int qualifiedNetworkType) {
+        public void onReconnectQualifiedNetworkType(int apnTypes, int qualifiedNetworkType) {
             if (mFeatureFlags.reconnectQualifiedNetwork()) {
-                log("onReconnectQualifedNetworkType: apnTypes = ["
+                log("onReconnectQualifiedNetworkType: apnTypes = ["
                         + ApnSetting.getApnTypesStringFromBitmask(apnTypes)
                         + "], networks = [" + AccessNetworkType.toString(qualifiedNetworkType)
                         + "]");
diff --git a/src/java/com/android/internal/telephony/data/DataConfigManager.java b/src/java/com/android/internal/telephony/data/DataConfigManager.java
index 0e06dad..6ad89ce 100644
--- a/src/java/com/android/internal/telephony/data/DataConfigManager.java
+++ b/src/java/com/android/internal/telephony/data/DataConfigManager.java
@@ -1436,6 +1436,18 @@
     }
 
     /**
+     * @return The capabilities that network will be forced to mark as cellular transport.
+     */
+    public @NetCapability Set<Integer> getForcedCellularTransportCapabilities() {
+        String[] forcedCellularTransportCapabilities = mResources.getStringArray(
+                com.android.internal.R.array.config_force_cellular_transport_capabilities);
+
+        return Arrays.stream(forcedCellularTransportCapabilities)
+                .map(DataUtils::getNetworkCapabilityFromString)
+                .collect(Collectors.toSet());
+    }
+
+    /**
      * Log debug messages.
      * @param s debug messages
      */
@@ -1543,6 +1555,9 @@
         pw.println("isTetheringProfileDisabledForRoaming="
                 + isTetheringProfileDisabledForRoaming());
         pw.println("allowClearInitialAttachDataProfile=" + allowClearInitialAttachDataProfile());
+        pw.println("forcedCellularTransportCapabilities=" + getForcedCellularTransportCapabilities()
+                .stream().map(DataUtils::networkCapabilityToString)
+                .collect(Collectors.joining(",")));
         pw.decreaseIndent();
     }
 }
diff --git a/src/java/com/android/internal/telephony/data/DataEvaluation.java b/src/java/com/android/internal/telephony/data/DataEvaluation.java
index 3d10e9c..a54884f 100644
--- a/src/java/com/android/internal/telephony/data/DataEvaluation.java
+++ b/src/java/com/android/internal/telephony/data/DataEvaluation.java
@@ -346,7 +346,9 @@
         /** Handover max retry stopped but network is not on the preferred transport. */
         HANDOVER_RETRY_STOPPED(true),
         /** BootStrap sim data limit reached. */
-        DATA_LIMIT_REACHED(true);
+        DATA_LIMIT_REACHED(true),
+        /** Data network connectivity transport not allowed. */
+        DATA_NETWORK_TRANSPORT_NOT_ALLOWED(true);
 
         private final boolean mIsHardReason;
 
diff --git a/src/java/com/android/internal/telephony/data/DataNetwork.java b/src/java/com/android/internal/telephony/data/DataNetwork.java
index 0dbbc5c..bd98403 100644
--- a/src/java/com/android/internal/telephony/data/DataNetwork.java
+++ b/src/java/com/android/internal/telephony/data/DataNetwork.java
@@ -314,6 +314,7 @@
                     TEAR_DOWN_REASON_ONLY_ALLOWED_SINGLE_NETWORK,
                     TEAR_DOWN_REASON_PREFERRED_DATA_SWITCHED,
                     TEAR_DOWN_REASON_DATA_LIMIT_REACHED,
+                    TEAR_DOWN_REASON_DATA_NETWORK_TRANSPORT_NOT_ALLOWED,
             })
     public @interface TearDownReason {}
 
@@ -413,6 +414,9 @@
     /** Data network tear down due to bootstrap sim data limit reached. */
     public static final int TEAR_DOWN_REASON_DATA_LIMIT_REACHED = 31;
 
+    /** Data network tear down due to current data network transport mismatch. */
+    public static final int TEAR_DOWN_REASON_DATA_NETWORK_TRANSPORT_NOT_ALLOWED = 32;
+
     //********************************************************************************************//
     // WHENEVER ADD A NEW TEAR DOWN REASON, PLEASE UPDATE DataDeactivateReasonEnum in enums.proto //
     //********************************************************************************************//
@@ -698,6 +702,11 @@
      */
     private boolean mLastKnownRoamingState;
 
+    /**
+     * The non-terrestrial status
+     */
+    private final boolean mIsSatellite;
+
     /** The reason that why setting up this data network is allowed. */
     private @NonNull DataAllowedReason mDataAllowedReason;
 
@@ -988,6 +997,8 @@
         mTransport = transport;
         mLastKnownDataNetworkType = getDataNetworkType();
         mLastKnownRoamingState = mPhone.getServiceState().getDataRoamingFromRegistration();
+        mIsSatellite = mPhone.getServiceState().isUsingNonTerrestrialNetwork()
+                && transport == AccessNetworkConstants.TRANSPORT_TYPE_WWAN;
         mDataAllowedReason = dataAllowedReason;
         dataProfile.setLastSetupTimestamp(SystemClock.elapsedRealtime());
         mAttachedNetworkRequestList.addAll(networkRequestList);
@@ -2214,11 +2225,32 @@
     }
 
     /**
+     * @return {@code true} if this is a satellite data network.
+     */
+    public boolean isSatellite() {
+        return mIsSatellite;
+    }
+
+    /**
      * Update the network capabilities.
      */
     private void updateNetworkCapabilities() {
-        final NetworkCapabilities.Builder builder = new NetworkCapabilities.Builder()
-                .addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR);
+        final NetworkCapabilities.Builder builder = new NetworkCapabilities.Builder();
+
+        if (mFlags.satelliteInternet() && mIsSatellite
+                && mDataConfigManager.getForcedCellularTransportCapabilities().stream()
+                .noneMatch(this::hasNetworkCapabilityInNetworkRequests)) {
+            // TODO: b/328622096 remove the try/catch
+            try {
+                builder.addTransportType(NetworkCapabilities.TRANSPORT_SATELLITE);
+            } catch (IllegalArgumentException exception) {
+                loge("TRANSPORT_SATELLITE is not supported.");
+                builder.addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR);
+            }
+        } else {
+            builder.addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR);
+        }
+
         boolean roaming = mPhone.getServiceState().getDataRoaming();
 
         builder.setNetworkSpecifier(new TelephonyNetworkSpecifier.Builder()
@@ -2385,6 +2417,11 @@
             builder.removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED);
         }
 
+        // mark the network as restricted when service state is non-terrestrial(satellite network)
+        if (mFlags.satelliteInternet() && mIsSatellite) {
+            builder.removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED);
+        }
+
         // Check if the feature force MMS on IWLAN is enabled. When the feature is enabled, MMS
         // will be attempted on IWLAN if possible, even if existing cellular networks already
         // supports IWLAN.
@@ -2401,7 +2438,7 @@
                 DataProfile dataProfile = mDataNetworkController.getDataProfileManager()
                         .getDataProfileForNetworkRequest(new TelephonyNetworkRequest(
                                 new NetworkRequest.Builder().addCapability(
-                                NetworkCapabilities.NET_CAPABILITY_MMS).build(), mPhone),
+                                NetworkCapabilities.NET_CAPABILITY_MMS).build(), mPhone, mFlags),
                         TelephonyManager.NETWORK_TYPE_IWLAN, false, false, false);
                 // If we find another data data profile that can support MMS on IWLAN, then remove
                 // the MMS capability from this cellular network. This will allow IWLAN to be
@@ -3790,6 +3827,8 @@
                 return "TEAR_DOWN_REASON_PREFERRED_DATA_SWITCHED";
             case TEAR_DOWN_REASON_DATA_LIMIT_REACHED:
                 return "TEAR_DOWN_REASON_DATA_LIMIT_REACHED";
+            case TEAR_DOWN_REASON_DATA_NETWORK_TRANSPORT_NOT_ALLOWED:
+                return "TEAR_DOWN_REASON_DATA_NETWORK_TRANSPORT_NOT_ALLOWED";
             default:
                 return "UNKNOWN(" + reason + ")";
         }
diff --git a/src/java/com/android/internal/telephony/data/DataNetworkController.java b/src/java/com/android/internal/telephony/data/DataNetworkController.java
index 70d3b23..b4aa1f0 100644
--- a/src/java/com/android/internal/telephony/data/DataNetworkController.java
+++ b/src/java/com/android/internal/telephony/data/DataNetworkController.java
@@ -1454,8 +1454,7 @@
         TelephonyNetworkRequest internetRequest = new TelephonyNetworkRequest(
                 new NetworkRequest.Builder()
                         .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
-                        .addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR)
-                        .build(), mPhone);
+                        .build(), mPhone, mFeatureFlags);
         // If we don't skip checking existing network, then we should check If one of the
         // existing networks can satisfy the internet request, then internet is allowed.
         if ((!mFeatureFlags.ignoreExistingNetworksForInternetAllowedChecking()
@@ -1514,8 +1513,7 @@
         TelephonyNetworkRequest internetRequest = new TelephonyNetworkRequest(
                 new NetworkRequest.Builder()
                         .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
-                        .addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR)
-                        .build(), mPhone);
+                        .build(), mPhone, mFeatureFlags);
         DataEvaluation evaluation = evaluateNetworkRequest(internetRequest,
                 DataEvaluationReason.EXTERNAL_QUERY);
         return evaluation.getDataDisallowedReasons();
@@ -1535,6 +1533,13 @@
         int transport = mAccessNetworksManager.getPreferredTransportByNetworkCapability(
                 networkRequest.getApnTypeNetworkCapability());
 
+        // Check if the request can be satisfied by cellular network or satellite network.
+        if (mFeatureFlags.satelliteInternet()
+                && !canConnectivityTransportSatisfyNetworkRequest(networkRequest, transport)) {
+            evaluation.addDataDisallowedReason(
+                    DataDisallowedReason.DATA_NETWORK_TRANSPORT_NOT_ALLOWED);
+        }
+
         // Bypass all checks for emergency network request.
         if (networkRequest.hasCapability(NetworkCapabilities.NET_CAPABILITY_EIMS)) {
             DataProfile emergencyProfile = mDataProfileManager.getDataProfileForNetworkRequest(
@@ -1549,14 +1554,13 @@
                 evaluation.addDataDisallowedReason(DataDisallowedReason.DATA_THROTTLED);
                 log("Emergency network request is throttled by the previous setup data "
                             + "call response.");
-                log(evaluation.toString());
-                networkRequest.setEvaluation(evaluation);
-                return evaluation;
             }
 
-            evaluation.addDataAllowedReason(DataAllowedReason.EMERGENCY_REQUEST);
-            if (emergencyProfile != null) {
-                evaluation.setCandidateDataProfile(emergencyProfile);
+            if (!evaluation.containsDisallowedReasons()) {
+                evaluation.addDataAllowedReason(DataAllowedReason.EMERGENCY_REQUEST);
+                if (emergencyProfile != null) {
+                    evaluation.setCandidateDataProfile(emergencyProfile);
+                }
             }
             networkRequest.setEvaluation(evaluation);
             log(evaluation.toString());
@@ -1645,11 +1649,6 @@
             evaluation.addDataDisallowedReason(DataDisallowedReason.CDMA_EMERGENCY_CALLBACK_MODE);
         }
 
-        // Check whether data is disallowed while using satellite
-        if (isDataDisallowedDueToSatellite(networkRequest.getCapabilities())) {
-            evaluation.addDataDisallowedReason(DataDisallowedReason.SERVICE_OPTION_NOT_SUPPORTED);
-        }
-
         // Check if only one data network is allowed.
         if (isOnlySingleDataNetworkAllowed(transport)
                 && !hasCapabilityExemptsFromSinglePdnRule(networkRequest.getCapabilities())) {
@@ -1822,7 +1821,7 @@
                 networkRequestList.add(networkRequest);
             }
         }
-        return DataUtils.getGroupedNetworkRequestList(networkRequestList);
+        return DataUtils.getGroupedNetworkRequestList(networkRequestList, mFeatureFlags);
     }
 
     /**
@@ -1891,10 +1890,26 @@
             evaluation.addDataDisallowedReason(DataDisallowedReason.CDMA_EMERGENCY_CALLBACK_MODE);
         }
 
-        // Check whether data is disallowed while using satellite
-        if (isDataDisallowedDueToSatellite(dataNetwork.getNetworkCapabilities()
-                .getCapabilities())) {
-            evaluation.addDataDisallowedReason(DataDisallowedReason.SERVICE_OPTION_NOT_SUPPORTED);
+        // If the network is satellite, then the network must be restricted.
+        if (mFeatureFlags.satelliteInternet()) {
+            // The IWLAN data network should remain intact even when satellite is connected.
+            if (dataNetwork.getTransport() != AccessNetworkConstants.TRANSPORT_TYPE_WLAN) {
+                // On satellite, every data network needs to be restricted.
+                if (mServiceState.isUsingNonTerrestrialNetwork()
+                        && dataNetwork.getNetworkCapabilities()
+                        .hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED)) {
+                    evaluation.addDataDisallowedReason(
+                            DataDisallowedReason.DATA_NETWORK_TRANSPORT_NOT_ALLOWED);
+                }
+
+                // Check if the transport is compatible with the network
+                if (mServiceState.isUsingNonTerrestrialNetwork() != dataNetwork.isSatellite()) {
+                    // Since we don't support satellite/cellular network handover, we should always
+                    // tear down the network when transport changes.
+                    evaluation.addDataDisallowedReason(
+                            DataDisallowedReason.DATA_NETWORK_TRANSPORT_NOT_ALLOWED);
+                }
+            }
         }
 
         // Check whether data limit reached for bootstrap sim, else re-evaluate based on the timer
@@ -2082,6 +2097,65 @@
     }
 
     /**
+     * Check if the transport from connectivity service can satisfy the network request. Note the
+     * transport here is connectivity service's transport (Wifi, cellular, satellite, etc..), not
+     * the widely used {@link AccessNetworkConstants#TRANSPORT_TYPE_WLAN WLAN},
+     * {@link AccessNetworkConstants#TRANSPORT_TYPE_WWAN WWAN} transport in telephony.
+     *
+     * @param networkRequest Network request
+     * @param transport The preferred transport type for the request. The transport here is
+     * WWAN/WLAN.
+     * @return {@code true} if the connectivity transport can satisfy the network request, otherwise
+     * {@code false}.
+     */
+    private boolean canConnectivityTransportSatisfyNetworkRequest(
+            @NonNull TelephonyNetworkRequest networkRequest, @TransportType int transport) {
+        // When the device is on satellite, only restricted network request can request network.
+        if (mServiceState.isUsingNonTerrestrialNetwork()
+                && networkRequest.getNativeNetworkRequest().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.
+            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(
+                        networkRequest.getCapabilities())
+                .anyMatch(mDataConfigManager.getForcedCellularTransportCapabilities()::contains)) {
+            return true;
+        }
+
+        // If the network is cellular, then the request must specify cellular transport. Or if the
+        // the network is satellite, then the request must specify satellite transport and
+        // restricted.
+        return (mServiceState.isUsingNonTerrestrialNetwork()
+                && networkRequest.getNativeNetworkRequest().hasTransport(
+                        NetworkCapabilities.TRANSPORT_SATELLITE))
+                || (!mServiceState.isUsingNonTerrestrialNetwork()
+                        && networkRequest.getNativeNetworkRequest().hasTransport(
+                        NetworkCapabilities.TRANSPORT_CELLULAR));
+    }
+
+    /**
      * tethering and enterprise capabilities are not respected as restricted requests. For a request
      * with these capabilities, any soft disallowed reasons are honored.
      * @param networkRequest The network request to evaluate.
@@ -2300,6 +2374,8 @@
                     return DataNetwork.TEAR_DOWN_REASON_HANDOVER_FAILED;
                 case DATA_LIMIT_REACHED:
                     return DataNetwork.TEAR_DOWN_REASON_DATA_LIMIT_REACHED;
+                case DATA_NETWORK_TRANSPORT_NOT_ALLOWED:
+                    return DataNetwork.TEAR_DOWN_REASON_DATA_NETWORK_TRANSPORT_NOT_ALLOWED;
             }
         }
         return DataNetwork.TEAR_DOWN_REASON_NONE;
@@ -3590,7 +3666,7 @@
             return true;
         }
 
-        if (!oldNri.isNonTerrestrialNetwork() && newNri.isNonTerrestrialNetwork()) {
+        if (oldNri.isNonTerrestrialNetwork() != newNri.isNonTerrestrialNetwork()) {
             return true;
         }
 
@@ -3647,7 +3723,7 @@
             return true;
         }
 
-        if (oldSS.isUsingNonTerrestrialNetwork() && !newSS.isUsingNonTerrestrialNetwork()) {
+        if (oldSS.isUsingNonTerrestrialNetwork() != newSS.isUsingNonTerrestrialNetwork()) {
             return true;
         }
 
@@ -4023,41 +4099,6 @@
     }
 
     /**
-     * Check whether data is disallowed while using satellite
-     * @param capabilities An array of the NetworkCapabilities to be checked
-     * @return {@code true} if the capabilities contain any capability that are restricted
-     * while using satellite else {@code false}
-     */
-    private boolean isDataDisallowedDueToSatellite(@NetCapability int[] capabilities) {
-        if (!mFeatureFlags.carrierEnabledSatelliteFlag()) {
-            return false;
-        }
-
-        if (!mServiceState.isUsingNonTerrestrialNetwork()) {
-            // Device is not connected to satellite
-            return false;
-        }
-
-        Set<Integer> restrictedCapabilities = Set.of(NetworkCapabilities.NET_CAPABILITY_INTERNET);
-        if (Arrays.stream(capabilities).noneMatch(restrictedCapabilities::contains)) {
-            // Only internet data disallowed while using satellite
-            return false;
-        }
-
-        for (NetworkRegistrationInfo nri : mServiceState.getNetworkRegistrationInfoList()) {
-            if (nri.isNonTerrestrialNetwork()
-                    && nri.getAvailableServices().contains(
-                            NetworkRegistrationInfo.SERVICE_TYPE_DATA)) {
-                // Data is supported while using satellite
-                return false;
-            }
-        }
-
-        // Data is disallowed while using satellite
-        return true;
-    }
-
-    /**
      * Request network validation.
      *
      * Nnetwork validation request is sent to the DataNetwork that matches the network capability
diff --git a/src/java/com/android/internal/telephony/data/DataProfileManager.java b/src/java/com/android/internal/telephony/data/DataProfileManager.java
index 51fc71b..0da220b 100644
--- a/src/java/com/android/internal/telephony/data/DataProfileManager.java
+++ b/src/java/com/android/internal/telephony/data/DataProfileManager.java
@@ -899,7 +899,7 @@
         TelephonyNetworkRequest networkRequest = new TelephonyNetworkRequest(
                 new NetworkRequest.Builder()
                         .addCapability(NetworkCapabilities.NET_CAPABILITY_DUN)
-                        .build(), mPhone);
+                        .build(), mPhone, mFeatureFlags);
         return getDataProfileForNetworkRequest(networkRequest, networkType,
                 mPhone.getServiceState().isUsingNonTerrestrialNetwork(),
                 mDataNetworkController.isEsimBootStrapProvisioningActivated(),
diff --git a/src/java/com/android/internal/telephony/data/DataRetryManager.java b/src/java/com/android/internal/telephony/data/DataRetryManager.java
index 5933463..1fdc182 100644
--- a/src/java/com/android/internal/telephony/data/DataRetryManager.java
+++ b/src/java/com/android/internal/telephony/data/DataRetryManager.java
@@ -1192,7 +1192,7 @@
 
         boolean retryScheduled = false;
         List<NetworkRequestList> groupedNetworkRequestLists =
-                DataUtils.getGroupedNetworkRequestList(requestList);
+                DataUtils.getGroupedNetworkRequestList(requestList, mFlags);
         for (DataSetupRetryRule retryRule : mDataSetupRetryRuleList) {
             if (retryRule.isPermanentFailCauseRule() && retryRule.getFailCauses().contains(cause)) {
                 if (dataProfile.getApnSetting() != null) {
diff --git a/src/java/com/android/internal/telephony/data/DataUtils.java b/src/java/com/android/internal/telephony/data/DataUtils.java
index 0dda7b5..cca6deb 100644
--- a/src/java/com/android/internal/telephony/data/DataUtils.java
+++ b/src/java/com/android/internal/telephony/data/DataUtils.java
@@ -41,6 +41,7 @@
 import android.util.ArrayMap;
 
 import com.android.internal.telephony.data.DataNetworkController.NetworkRequestList;
+import com.android.internal.telephony.flags.FeatureFlags;
 import com.android.telephony.Rlog;
 
 import java.text.SimpleDateFormat;
@@ -406,35 +407,59 @@
      * Group the network requests into several list that contains the same network capabilities.
      *
      * @param networkRequestList The provided network requests.
+     * @param featureFlags The feature flag.
+     *
      * @return The network requests after grouping.
      */
     public static @NonNull List<NetworkRequestList> getGroupedNetworkRequestList(
-            @NonNull NetworkRequestList networkRequestList) {
-        // Key is the capabilities set.
-        Map<Set<Integer>, NetworkRequestList> requestsMap = new ArrayMap<>();
-        for (TelephonyNetworkRequest networkRequest : networkRequestList) {
-            requestsMap.computeIfAbsent(Arrays.stream(networkRequest.getCapabilities())
-                            .boxed().collect(Collectors.toSet()),
-                    v -> new NetworkRequestList()).add(networkRequest);
-        }
+            @NonNull NetworkRequestList networkRequestList, @NonNull FeatureFlags featureFlags) {
         List<NetworkRequestList> requests = new ArrayList<>();
-        // Create separate groups for enterprise requests with different enterprise IDs.
-        for (NetworkRequestList requestList : requestsMap.values()) {
-            List<TelephonyNetworkRequest> enterpriseRequests = requestList.stream()
-                    .filter(request ->
-                            request.hasCapability(NetworkCapabilities.NET_CAPABILITY_ENTERPRISE))
-                    .collect(Collectors.toList());
-            if (enterpriseRequests.isEmpty()) {
-                requests.add(requestList);
-                continue;
+        if (featureFlags.satelliteInternet()) {
+            record NetworkCapabilitiesKey(Set<Integer> caps, Set<Integer> enterpriseIds,
+                                          Set<Integer> transportTypes) { }
+
+            // Key is the combination of capabilities, enterprise ids, and transport types.
+            Map<NetworkCapabilitiesKey, NetworkRequestList> requestsMap = new ArrayMap<>();
+            for (TelephonyNetworkRequest networkRequest : networkRequestList) {
+                requestsMap.computeIfAbsent(new NetworkCapabilitiesKey(
+                                Arrays.stream(networkRequest.getCapabilities())
+                                        .boxed().collect(Collectors.toSet()),
+                                Arrays.stream(networkRequest.getNativeNetworkRequest()
+                                                .getEnterpriseIds())
+                                        .boxed().collect(Collectors.toSet()),
+                                Arrays.stream(networkRequest.getNativeNetworkRequest()
+                                                .getTransportTypes())
+                                        .boxed().collect(Collectors.toSet())
+                                ),
+                        v -> new NetworkRequestList()).add(networkRequest);
             }
-            // Key is the enterprise ID
-            Map<Integer, NetworkRequestList> enterpriseRequestsMap = new ArrayMap<>();
-            for (TelephonyNetworkRequest request : enterpriseRequests) {
-                enterpriseRequestsMap.computeIfAbsent(request.getCapabilityDifferentiator(),
-                        v -> new NetworkRequestList()).add(request);
+            requests.addAll(requestsMap.values());
+        } else {
+            // Key is the capabilities set.
+            Map<Set<Integer>, NetworkRequestList> requestsMap = new ArrayMap<>();
+            for (TelephonyNetworkRequest networkRequest : networkRequestList) {
+                requestsMap.computeIfAbsent(Arrays.stream(networkRequest.getCapabilities())
+                                .boxed().collect(Collectors.toSet()),
+                        v -> new NetworkRequestList()).add(networkRequest);
             }
-            requests.addAll(enterpriseRequestsMap.values());
+            // Create separate groups for enterprise requests with different enterprise IDs.
+            for (NetworkRequestList requestList : requestsMap.values()) {
+                List<TelephonyNetworkRequest> enterpriseRequests = requestList.stream()
+                        .filter(request -> request.hasCapability(
+                                NetworkCapabilities.NET_CAPABILITY_ENTERPRISE))
+                        .toList();
+                if (enterpriseRequests.isEmpty()) {
+                    requests.add(requestList);
+                    continue;
+                }
+                // Key is the enterprise ID
+                Map<Integer, NetworkRequestList> enterpriseRequestsMap = new ArrayMap<>();
+                for (TelephonyNetworkRequest request : enterpriseRequests) {
+                    enterpriseRequestsMap.computeIfAbsent(request.getCapabilityDifferentiator(),
+                            v -> new NetworkRequestList()).add(request);
+                }
+                requests.addAll(enterpriseRequestsMap.values());
+            }
         }
         // Sort the requests so the network request list with higher priority will be at the front.
         return requests.stream()
diff --git a/src/java/com/android/internal/telephony/data/PhoneSwitcher.java b/src/java/com/android/internal/telephony/data/PhoneSwitcher.java
index 8dc8098..5c1d0e1 100644
--- a/src/java/com/android/internal/telephony/data/PhoneSwitcher.java
+++ b/src/java/com/android/internal/telephony/data/PhoneSwitcher.java
@@ -16,7 +16,6 @@
 
 package com.android.internal.telephony.data;
 
-import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
 import static android.telephony.CarrierConfigManager.KEY_DATA_SWITCH_VALIDATION_TIMEOUT_LONG;
 import static android.telephony.SubscriptionManager.DEFAULT_PHONE_INDEX;
 import static android.telephony.SubscriptionManager.DEFAULT_SUBSCRIPTION_ID;
@@ -334,7 +333,7 @@
         @Override
         public void onCapabilitiesChanged(Network network,
                 NetworkCapabilities networkCapabilities) {
-            if (networkCapabilities.hasTransport(TRANSPORT_CELLULAR)) {
+            if (networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)) {
                 if (SubscriptionManager.isValidSubscriptionId(mExpectedSubId)
                         && mExpectedSubId == getSubIdFromNetworkSpecifier(
                         networkCapabilities.getNetworkSpecifier())) {
@@ -569,7 +568,7 @@
         mConnectivityManager.registerDefaultNetworkCallback(mDefaultNetworkCallback, this);
 
         final NetworkCapabilities.Builder builder = new NetworkCapabilities.Builder()
-                .addTransportType(TRANSPORT_CELLULAR)
+                .addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR)
                 .addCapability(NetworkCapabilities.NET_CAPABILITY_MMS)
                 .addCapability(NetworkCapabilities.NET_CAPABILITY_SUPL)
                 .addCapability(NetworkCapabilities.NET_CAPABILITY_DUN)
@@ -594,6 +593,15 @@
                 .addEnterpriseId(NetworkCapabilities.NET_ENTERPRISE_ID_5)
                 .setNetworkSpecifier(new MatchAllNetworkSpecifier());
 
+        if (mFlags.satelliteInternet()) {
+            // TODO: b/328622096 remove the try/catch
+            try {
+                builder.addTransportType(NetworkCapabilities.TRANSPORT_SATELLITE);
+            } catch (IllegalArgumentException exception) {
+                loge("TRANSPORT_SATELLITE is not supported.");
+            }
+        }
+
         NetworkFactory networkFactory = new PhoneSwitcherNetworkRequestListener(looper, context,
                 builder.build(), this);
         // we want to see all requests
@@ -987,7 +995,7 @@
 
     private void onRequestNetwork(NetworkRequest networkRequest) {
         TelephonyNetworkRequest telephonyNetworkRequest = new TelephonyNetworkRequest(
-                networkRequest, PhoneFactory.getDefaultPhone());
+                networkRequest, PhoneFactory.getDefaultPhone(), mFlags);
         if (!mNetworkRequestList.contains(telephonyNetworkRequest)) {
             mNetworkRequestList.add(telephonyNetworkRequest);
             onEvaluate(REQUESTS_CHANGED, "netRequest");
@@ -996,7 +1004,7 @@
 
     private void onReleaseNetwork(NetworkRequest networkRequest) {
         TelephonyNetworkRequest telephonyNetworkRequest = new TelephonyNetworkRequest(
-                networkRequest, PhoneFactory.getDefaultPhone());
+                networkRequest, PhoneFactory.getDefaultPhone(), mFlags);
         if (mNetworkRequestList.remove(telephonyNetworkRequest)) {
             onEvaluate(REQUESTS_CHANGED, "netReleased");
             collectReleaseNetworkMetrics(networkRequest);
@@ -1554,6 +1562,9 @@
         mPendingSwitchSubId = INVALID_SUBSCRIPTION_ID;
 
         if (subIdToValidate == mPreferredDataSubId.get()) {
+            if (subId == SubscriptionManager.DEFAULT_SUBSCRIPTION_ID) {
+                mAutoSelectedDataSubId = SubscriptionManager.DEFAULT_SUBSCRIPTION_ID;
+            }
             sendSetOpptCallbackHelper(callback, SET_OPPORTUNISTIC_SUB_SUCCESS);
             return;
         }
diff --git a/src/java/com/android/internal/telephony/data/TelephonyNetworkFactory.java b/src/java/com/android/internal/telephony/data/TelephonyNetworkFactory.java
index 377c219..877d7b8 100644
--- a/src/java/com/android/internal/telephony/data/TelephonyNetworkFactory.java
+++ b/src/java/com/android/internal/telephony/data/TelephonyNetworkFactory.java
@@ -163,6 +163,16 @@
                 .addEnterpriseId(NetworkCapabilities.NET_ENTERPRISE_ID_5)
                 .setNetworkSpecifier(new TelephonyNetworkSpecifier.Builder()
                 .setSubscriptionId(subscriptionId).build());
+
+        if (mFlags.satelliteInternet()) {
+            // TODO: b/328622096 remove the try/catch
+            try {
+                builder.addTransportType(NetworkCapabilities.TRANSPORT_SATELLITE);
+            } catch (IllegalArgumentException exception) {
+                log("TRANSPORT_SATELLITE is not supported.");
+            }
+        }
+
         return builder.build();
     }
 
@@ -263,7 +273,7 @@
 
     private void onNeedNetworkFor(Message msg) {
         TelephonyNetworkRequest networkRequest =
-                new TelephonyNetworkRequest((NetworkRequest) msg.obj, mPhone);
+                new TelephonyNetworkRequest((NetworkRequest) msg.obj, mPhone, mFlags);
         boolean shouldApply = mPhoneSwitcher.shouldApplyNetworkRequest(
                 networkRequest, mPhone.getPhoneId());
 
@@ -289,7 +299,7 @@
 
     private void onReleaseNetworkFor(Message msg) {
         TelephonyNetworkRequest networkRequest =
-                new TelephonyNetworkRequest((NetworkRequest) msg.obj, mPhone);
+                new TelephonyNetworkRequest((NetworkRequest) msg.obj, mPhone, mFlags);
         boolean applied = mNetworkRequests.get(networkRequest)
                 != AccessNetworkConstants.TRANSPORT_TYPE_INVALID;
 
diff --git a/src/java/com/android/internal/telephony/data/TelephonyNetworkRequest.java b/src/java/com/android/internal/telephony/data/TelephonyNetworkRequest.java
index 2668302..b059100 100644
--- a/src/java/com/android/internal/telephony/data/TelephonyNetworkRequest.java
+++ b/src/java/com/android/internal/telephony/data/TelephonyNetworkRequest.java
@@ -31,6 +31,7 @@
 import android.telephony.data.TrafficDescriptor.OsAppId;
 
 import com.android.internal.telephony.Phone;
+import com.android.internal.telephony.flags.FeatureFlags;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
@@ -182,15 +183,21 @@
     /** The data evaluation result. */
     private @Nullable DataEvaluation mEvaluation;
 
+    /** Feature flag. */
+    private final @NonNull FeatureFlags mFeatureFlags;
+
     /**
      * Constructor
      *
      * @param request The native network request from the clients.
      * @param phone The phone instance
+     * @param featureFlags The feature flag
      */
-    public TelephonyNetworkRequest(NetworkRequest request, Phone phone) {
+    public TelephonyNetworkRequest(@NonNull NetworkRequest request, @NonNull Phone phone,
+                                   @NonNull FeatureFlags featureFlags) {
         mPhone = phone;
         mNativeNetworkRequest = request;
+        mFeatureFlags = featureFlags;
 
         int capabilitiesAttributes = CAPABILITY_ATTRIBUTE_NONE;
         for (int networkCapability : mNativeNetworkRequest.getCapabilities()) {
@@ -274,6 +281,31 @@
         if ((hasAttribute(CAPABILITY_ATTRIBUTE_APN_SETTING)
                 || hasAttribute(CAPABILITY_ATTRIBUTE_TRAFFIC_DESCRIPTOR_DNN))
                 && dataProfile.getApnSetting() != null) {
+            if (mFeatureFlags.satelliteInternet()) {
+                if (mNativeNetworkRequest.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)
+                        && !mNativeNetworkRequest.hasTransport(
+                                NetworkCapabilities.TRANSPORT_SATELLITE)) {
+                    if (Arrays.stream(getCapabilities()).noneMatch(mDataConfigManager
+                            .getForcedCellularTransportCapabilities()::contains)) {
+                        // If the request is explicitly for the cellular, then the data profile
+                        // needs to support cellular.
+                        if (!dataProfile.getApnSetting().isForInfrastructure(
+                                ApnSetting.INFRASTRUCTURE_CELLULAR)) {
+                            return false;
+                        }
+                    }
+                } else if (mNativeNetworkRequest.hasTransport(
+                        NetworkCapabilities.TRANSPORT_SATELLITE)
+                        && !mNativeNetworkRequest.hasTransport(
+                                NetworkCapabilities.TRANSPORT_CELLULAR)) {
+                    // If the request is explicitly for the satellite, then the data profile needs
+                    // to support satellite.
+                    if (!dataProfile.getApnSetting().isForInfrastructure(
+                            ApnSetting.INFRASTRUCTURE_SATELLITE)) {
+                        return false;
+                    }
+                }
+            }
             // Fallback to the legacy APN type matching.
             List<Integer> apnTypes = Arrays.stream(getCapabilities()).boxed()
                     .map(DataUtils::networkCapabilityToApnType)
diff --git a/src/java/com/android/internal/telephony/imsphone/ImsPhone.java b/src/java/com/android/internal/telephony/imsphone/ImsPhone.java
index a6bb1d6..5366ebb 100644
--- a/src/java/com/android/internal/telephony/imsphone/ImsPhone.java
+++ b/src/java/com/android/internal/telephony/imsphone/ImsPhone.java
@@ -75,6 +75,7 @@
 import android.os.UserHandle;
 import android.preference.PreferenceManager;
 import android.sysprop.TelephonyProperties;
+import android.telecom.VideoProfile;
 import android.telephony.AccessNetworkConstants;
 import android.telephony.CarrierConfigManager;
 import android.telephony.NetworkRegistrationInfo;
@@ -802,7 +803,11 @@
             try {
                 if (getRingingCall().getState() != ImsPhoneCall.State.IDLE) {
                     if (DBG) logd("MmiCode 2: accept ringing call");
-                    mCT.acceptCall(ImsCallProfile.CALL_TYPE_VOICE);
+                    if (mFeatureFlags.answerAudioOnlyWhenAnsweringViaMmiCode()) {
+                        mCT.acceptCall(VideoProfile.STATE_AUDIO_ONLY);
+                    } else {
+                        mCT.acceptCall(ImsCallProfile.CALL_TYPE_VOICE);
+                    }
                 } else if (getBackgroundCall().getState() == ImsPhoneCall.State.HOLDING) {
                     // If there's an active ongoing call as well, hold it and the background one
                     // should automatically unhold. Otherwise just unhold the background call.
diff --git a/src/java/com/android/internal/telephony/metrics/DeviceStateHelper.java b/src/java/com/android/internal/telephony/metrics/DeviceStateHelper.java
index 29729c8..9ab52fb 100644
--- a/src/java/com/android/internal/telephony/metrics/DeviceStateHelper.java
+++ b/src/java/com/android/internal/telephony/metrics/DeviceStateHelper.java
@@ -41,7 +41,7 @@
                 .registerCallback(
                         new HandlerExecutor(new Handler(mHandlerThread.getLooper())),
                         state -> {
-                            updateFoldState(state);
+                            updateFoldState(state.getIdentifier());
                         });
     }
 
diff --git a/src/java/com/android/internal/telephony/metrics/MetricsCollector.java b/src/java/com/android/internal/telephony/metrics/MetricsCollector.java
index 456b91b..d7f07c5 100644
--- a/src/java/com/android/internal/telephony/metrics/MetricsCollector.java
+++ b/src/java/com/android/internal/telephony/metrics/MetricsCollector.java
@@ -138,14 +138,6 @@
     private static final long MIN_COOLDOWN_MILLIS =
             DBG ? 10L * MILLIS_PER_SECOND : 23L * MILLIS_PER_HOUR;
 
-    /**
-     * Sets atom pull cool down to 4 minutes for userdebug build.
-     *
-     * <p>Applies to certain atoms: CellularServiceState.
-     */
-    private static final long CELL_SERVICE_MIN_COOLDOWN_MILLIS =
-            DBG ? 10L * MILLIS_PER_SECOND :
-                    IS_DEBUGGABLE ? 4L * MILLIS_PER_MINUTE : 23L * MILLIS_PER_HOUR;
 
     /**
      * Buckets with less than these many calls will be dropped.
@@ -166,6 +158,13 @@
     private static final long CELL_SERVICE_DURATION_BUCKET_MILLIS =
             DBG || IS_DEBUGGABLE ? 2L * MILLIS_PER_SECOND : 5L * MILLIS_PER_MINUTE;
 
+    /**
+     * Sets atom pull cool down to 4 minutes for userdebug build, 5 hours for user build.
+     *
+     * <p>Applies to certain atoms: CellularServiceState, DataCallSession,
+     * ImsRegistrationTermination.
+     */
+    private final long mPowerCorrelatedMinCooldownMillis;
     private final PersistAtomsStorage mStorage;
     private final DeviceStateHelper mDeviceStateHelper;
     private final StatsManager mStatsManager;
@@ -234,6 +233,9 @@
 
         mAirplaneModeStats = new AirplaneModeStats(context);
         mDefaultNetworkMonitor = new DefaultNetworkMonitor(context, featureFlags);
+        mPowerCorrelatedMinCooldownMillis = DBG ? 10L * MILLIS_PER_SECOND :
+                IS_DEBUGGABLE ? 4L * MILLIS_PER_MINUTE : (long) context.getResources().getInteger(
+                com.android.internal.R.integer.config_metrics_pull_cooldown_millis);
     }
 
     /**
@@ -516,7 +518,8 @@
     private int pullDataCallSession(List<StatsEvent> data) {
         // Include ongoing data call segments
         concludeDataCallSessionStats();
-        DataCallSession[] dataCallSessions = mStorage.getDataCallSessions(MIN_COOLDOWN_MILLIS);
+        DataCallSession[] dataCallSessions = mStorage.getDataCallSessions(
+                mPowerCorrelatedMinCooldownMillis);
         if (dataCallSessions != null) {
             Arrays.stream(dataCallSessions)
                     .forEach(dataCall -> data.add(buildStatsEvent(dataCall)));
@@ -544,8 +547,8 @@
     private int pullCellularServiceState(List<StatsEvent> data) {
         // Include the latest durations
         concludeServiceStateStats();
-        CellularServiceState[] persistAtoms =
-                mStorage.getCellularServiceStates(CELL_SERVICE_MIN_COOLDOWN_MILLIS);
+        CellularServiceState[] persistAtoms = mStorage.getCellularServiceStates(
+                mPowerCorrelatedMinCooldownMillis);
         if (persistAtoms != null) {
             // list is already shuffled when instances were inserted
             Arrays.stream(persistAtoms)
@@ -573,8 +576,8 @@
     }
 
     private int pullImsRegistrationTermination(List<StatsEvent> data) {
-        ImsRegistrationTermination[] persistAtoms =
-                mStorage.getImsRegistrationTerminations(MIN_COOLDOWN_MILLIS);
+        ImsRegistrationTermination[] persistAtoms = mStorage.getImsRegistrationTerminations(
+                mPowerCorrelatedMinCooldownMillis);
         if (persistAtoms != null) {
             // list is already shuffled when instances were inserted
             Arrays.stream(persistAtoms)
diff --git a/src/java/com/android/internal/telephony/satellite/SatelliteController.java b/src/java/com/android/internal/telephony/satellite/SatelliteController.java
index 88682bf..287f839 100644
--- a/src/java/com/android/internal/telephony/satellite/SatelliteController.java
+++ b/src/java/com/android/internal/telephony/satellite/SatelliteController.java
@@ -2463,6 +2463,12 @@
             logd("getSatellitePlmnsForCarrier: carrierEnabledSatelliteFlag is disabled");
             return new ArrayList<>();
         }
+
+        if (!isSatelliteSupportedViaCarrier(subId)) {
+            logd("Satellite for carrier is not supported.");
+            return new ArrayList<>();
+        }
+
         synchronized (mSupportedSatelliteServicesLock) {
             return mMergedPlmnListPerCarrier.get(subId, new ArrayList<>()).stream().toList();
         }
diff --git a/src/java/com/android/internal/telephony/security/CellularNetworkSecuritySafetySource.java b/src/java/com/android/internal/telephony/security/CellularNetworkSecuritySafetySource.java
index 34f26e3..605b197 100644
--- a/src/java/com/android/internal/telephony/security/CellularNetworkSecuritySafetySource.java
+++ b/src/java/com/android/internal/telephony/security/CellularNetworkSecuritySafetySource.java
@@ -25,6 +25,8 @@
 import android.app.PendingIntent;
 import android.content.Context;
 import android.content.Intent;
+import android.content.res.Resources;
+import android.net.Uri;
 import android.safetycenter.SafetyCenterManager;
 import android.safetycenter.SafetyEvent;
 import android.safetycenter.SafetySourceData;
@@ -62,10 +64,6 @@
 
     private static final Intent CELLULAR_NETWORK_SECURITY_SETTINGS_INTENT =
             new Intent("android.settings.CELLULAR_NETWORK_SECURITY");
-    // TODO(b/321999913): direct to a help page URL e.g.
-    //                    new Intent(Intent.ACTION_VIEW, Uri.parse("https://..."));
-    private static final Intent LEARN_MORE_INTENT = new Intent();
-
     static final int NULL_CIPHER_STATE_ENCRYPTED = 0;
     static final int NULL_CIPHER_STATE_NOTIFY_ENCRYPTED = 1;
     static final int NULL_CIPHER_STATE_NOTIFY_NON_ENCRYPTED = 2;
@@ -123,6 +121,13 @@
     }
 
     /**
+     * Clears issue state for the identified subscription
+     */
+    public synchronized  void clearNullCipherState(Context context, int subId) {
+        mNullCipherStates.remove(subId);
+        updateSafetyCenter(context);
+    }
+    /**
      * Enables or disables the identifier disclosure issue and clears any current issues if the
      * enable state is changed.
      */
@@ -216,7 +221,8 @@
                 builder = new SafetySourceIssue.Builder(
                         NULL_CIPHER_ISSUE_NON_ENCRYPTED_ID + "_" + subId,
                         context.getString(
-                            R.string.scNullCipherIssueNonEncryptedTitle, subInfo.getDisplayName()),
+                                R.string.scNullCipherIssueNonEncryptedTitle,
+                                subInfo.getDisplayName()),
                         context.getString(R.string.scNullCipherIssueNonEncryptedSummary),
                         SEVERITY_LEVEL_RECOMMENDATION,
                         NULL_CIPHER_ISSUE_NON_ENCRYPTED_ID);
@@ -225,7 +231,7 @@
                 builder = new SafetySourceIssue.Builder(
                         NULL_CIPHER_ISSUE_NON_ENCRYPTED_ID + "_" + subId,
                         context.getString(
-                            R.string.scNullCipherIssueEncryptedTitle, subInfo.getDisplayName()),
+                                R.string.scNullCipherIssueEncryptedTitle, subInfo.getDisplayName()),
                         context.getString(R.string.scNullCipherIssueEncryptedSummary),
                         SEVERITY_LEVEL_INFORMATION,
                         NULL_CIPHER_ISSUE_ENCRYPTED_ID);
@@ -233,26 +239,31 @@
             default:
                 throw new AssertionError();
         }
-
-        return Optional.of(
-                builder
-                    .setNotificationBehavior(SafetySourceIssue.NOTIFICATION_BEHAVIOR_IMMEDIATELY)
-                    .setIssueCategory(SafetySourceIssue.ISSUE_CATEGORY_DEVICE)
-                    .addAction(
+        builder
+                .setNotificationBehavior(
+                        SafetySourceIssue.NOTIFICATION_BEHAVIOR_IMMEDIATELY)
+                .setIssueCategory(SafetySourceIssue.ISSUE_CATEGORY_DEVICE)
+                .addAction(
                         new SafetySourceIssue.Action.Builder(
                                 NULL_CIPHER_ACTION_SETTINGS_ID,
                                 context.getString(R.string.scNullCipherIssueActionSettings),
                                 mSafetyCenterManagerWrapper.getActivityPendingIntent(
                                         context, CELLULAR_NETWORK_SECURITY_SETTINGS_INTENT))
-                            .build())
-                    .addAction(
-                        new SafetySourceIssue.Action.Builder(
-                                NULL_CIPHER_ACTION_LEARN_MORE_ID,
-                                context.getString(R.string.scNullCipherIssueActionLearnMore),
-                                mSafetyCenterManagerWrapper.getActivityPendingIntent(
-                                        context, LEARN_MORE_INTENT))
-                            .build())
-                    .build());
+                                .build());
+
+        Intent learnMoreIntent = getLearnMoreIntent(context);
+        if (learnMoreIntent != null) {
+            builder.addAction(
+                    new SafetySourceIssue.Action.Builder(
+                            NULL_CIPHER_ACTION_LEARN_MORE_ID,
+                            context.getString(
+                                    R.string.scNullCipherIssueActionLearnMore),
+                            mSafetyCenterManagerWrapper.getActivityPendingIntent(
+                                    context, learnMoreIntent))
+                            .build());
+        }
+
+        return Optional.of(builder.build());
     }
 
     /** Builds the identity disclosure issue if it's enabled and there are disclosures to report. */
@@ -264,7 +275,8 @@
 
         SubscriptionInfoInternal subInfo =
                 mSubscriptionManagerService.getSubscriptionInfoInternal(subId);
-        return Optional.of(
+
+        SafetySourceIssue.Builder builder =
                 new SafetySourceIssue.Builder(
                         IDENTIFIER_DISCLOSURE_ISSUE_ID + "_" + subId,
                         context.getString(R.string.scIdentifierDisclosureIssueTitle),
@@ -276,23 +288,51 @@
                                 subInfo.getDisplayName()),
                         SEVERITY_LEVEL_RECOMMENDATION,
                         IDENTIFIER_DISCLOSURE_ISSUE_ID)
-                    .setNotificationBehavior(SafetySourceIssue.NOTIFICATION_BEHAVIOR_IMMEDIATELY)
-                    .setIssueCategory(SafetySourceIssue.ISSUE_CATEGORY_DEVICE)
-                    .addAction(
-                        new SafetySourceIssue.Action.Builder(
-                                NULL_CIPHER_ACTION_SETTINGS_ID,
-                                context.getString(R.string.scNullCipherIssueActionSettings),
-                                mSafetyCenterManagerWrapper.getActivityPendingIntent(
-                                        context, CELLULAR_NETWORK_SECURITY_SETTINGS_INTENT))
-                            .build())
-                    .addAction(
-                        new SafetySourceIssue.Action.Builder(
-                                NULL_CIPHER_ACTION_LEARN_MORE_ID,
-                                context.getString(R.string.scNullCipherIssueActionLearnMore),
-                                mSafetyCenterManagerWrapper.getActivityPendingIntent(
-                                        context, LEARN_MORE_INTENT))
-                            .build())
-                .build());
+                        .setNotificationBehavior(
+                                SafetySourceIssue.NOTIFICATION_BEHAVIOR_IMMEDIATELY)
+                        .setIssueCategory(SafetySourceIssue.ISSUE_CATEGORY_DEVICE)
+                        .addAction(
+                                new SafetySourceIssue.Action.Builder(
+                                        NULL_CIPHER_ACTION_SETTINGS_ID,
+                                        context.getString(
+                                                R.string.scNullCipherIssueActionSettings),
+                                        mSafetyCenterManagerWrapper.getActivityPendingIntent(
+                                                context,
+                                                CELLULAR_NETWORK_SECURITY_SETTINGS_INTENT))
+                                        .build());
+
+        Intent learnMoreIntent = getLearnMoreIntent(context);
+        if (learnMoreIntent != null) {
+            builder.addAction(
+                    new SafetySourceIssue.Action.Builder(
+                            NULL_CIPHER_ACTION_LEARN_MORE_ID,
+                            context.getString(R.string.scNullCipherIssueActionLearnMore),
+                            mSafetyCenterManagerWrapper.getActivityPendingIntent(
+                                    context, learnMoreIntent)).build()
+            );
+        }
+
+        return Optional.of(builder.build());
+    }
+
+    /**
+     * Return Intent for learn more action, or null if resource associated with the Intent
+     * uri is
+     * missing or empty.
+     */
+    private Intent getLearnMoreIntent(Context context) {
+        String learnMoreUri;
+        try {
+            learnMoreUri = context.getString(R.string.scCellularNetworkSecurityLearnMore);
+        } catch (Resources.NotFoundException e) {
+            return null;
+        }
+
+        if (learnMoreUri.isEmpty()) {
+            return null;
+        }
+
+        return new Intent(Intent.ACTION_VIEW, Uri.parse(learnMoreUri));
     }
 
     /** A wrapper around {@link SafetyCenterManager} that can be instrumented in tests. */
@@ -337,7 +377,7 @@
         private IdentifierDisclosure(int count, Instant start, Instant end) {
             mDisclosureCount = count;
             mWindowStart = start;
-            mWindowEnd  = end;
+            mWindowEnd = end;
         }
 
         private int getDisclosureCount() {
diff --git a/src/java/com/android/internal/telephony/security/NullCipherNotifier.java b/src/java/com/android/internal/telephony/security/NullCipherNotifier.java
index 3ece701..e13c5b0 100644
--- a/src/java/com/android/internal/telephony/security/NullCipherNotifier.java
+++ b/src/java/com/android/internal/telephony/security/NullCipherNotifier.java
@@ -56,6 +56,7 @@
 
     private final CellularNetworkSecuritySafetySource mSafetySource;
     private final HashMap<Integer, SubscriptionState> mSubscriptionState = new HashMap<>();
+    private final HashMap<Integer, Integer> mActiveSubscriptions = new HashMap<>();
 
     private final Object mEnabledLock = new Object();
     @GuardedBy("mEnabledLock")
@@ -90,31 +91,78 @@
      * Adds a security algorithm update. If appropriate, this will trigger a user notification.
      */
     public void onSecurityAlgorithmUpdate(
-            Context context, int subId, SecurityAlgorithmUpdate update) {
+            Context context, int phoneId, int subId, SecurityAlgorithmUpdate update) {
         Rlog.d(TAG, "Security algorithm update: subId = " + subId + " " + update);
 
         if (shouldIgnoreUpdate(update)) {
             return;
         }
 
+        if (!isEnabled()) {
+            Rlog.i(TAG, "Ignoring onSecurityAlgorithmUpdate. Notifier is disabled.");
+            return;
+        }
+
         try {
             mSerializedWorkQueue.execute(() -> {
-                SubscriptionState subState = mSubscriptionState.get(subId);
-                if (subState == null) {
-                    subState = new SubscriptionState();
-                    mSubscriptionState.put(subId, subState);
-                }
+                try {
+                    maybeUpdateSubscriptionMapping(context, phoneId, subId);
+                    SubscriptionState subState = mSubscriptionState.get(subId);
+                    if (subState == null) {
+                        subState = new SubscriptionState();
+                        mSubscriptionState.put(subId, subState);
+                    }
 
-                @CellularNetworkSecuritySafetySource.NullCipherState int nullCipherState =
-                        subState.update(update);
-                mSafetySource.setNullCipherState(context, subId, nullCipherState);
+                    @CellularNetworkSecuritySafetySource.NullCipherState int nullCipherState =
+                            subState.update(update);
+                    mSafetySource.setNullCipherState(context, subId, nullCipherState);
+                } catch (Throwable t) {
+                    Rlog.e(TAG, "Failed to execute onSecurityAlgorithmUpdate " + t.getMessage());
+                }
             });
         } catch (RejectedExecutionException e) {
-            Rlog.e(TAG, "Failed to schedule onEnableNotifier: " + e.getMessage());
+            Rlog.e(TAG, "Failed to schedule onSecurityAlgorithmUpdate: " + e.getMessage());
         }
     }
 
     /**
+     * Set or update the current phoneId to subId mapping. When a new subId is mapped to a phoneId,
+     * we update the safety source to clear state of the old subId.
+     */
+    public void setSubscriptionMapping(Context context, int phoneId, int subId) {
+
+        if (!isEnabled()) {
+            Rlog.i(TAG, "Ignoring setSubscriptionMapping. Notifier is disabled.");
+        }
+
+        try {
+            mSerializedWorkQueue.execute(() -> {
+                try {
+                    maybeUpdateSubscriptionMapping(context, phoneId, subId);
+                } catch (Throwable t) {
+                    Rlog.e(TAG, "Failed to update subId mapping. phoneId: " + phoneId + " subId: "
+                            + subId + ". " + t.getMessage());
+                }
+            });
+
+        } catch (RejectedExecutionException e) {
+            Rlog.e(TAG, "Failed to schedule setSubscriptionMapping: " + e.getMessage());
+        }
+    }
+
+    private void maybeUpdateSubscriptionMapping(Context context, int phoneId, int subId) {
+        final Integer oldSubId = mActiveSubscriptions.put(phoneId, subId);
+        if (oldSubId == null || oldSubId == subId) {
+            return;
+        }
+
+        // Our subId was updated for this phone, we should clear this subId's state.
+        mSubscriptionState.remove(oldSubId);
+        mSafetySource.clearNullCipherState(context, oldSubId);
+    }
+
+
+    /**
      * Enables null cipher notification; {@code onSecurityAlgorithmUpdate} will start handling
      * security algorithm updates and send notifications to the user when required.
      */
@@ -285,7 +333,7 @@
     /** The state of security algorithms for a network connection. */
     private static final class ConnectionState {
         private static final ConnectionState UNKNOWN =
-                 new ConnectionState(SECURITY_ALGORITHM_UNKNOWN, SECURITY_ALGORITHM_UNKNOWN);
+                new ConnectionState(SECURITY_ALGORITHM_UNKNOWN, SECURITY_ALGORITHM_UNKNOWN);
 
         private final @SecurityAlgorithm int mEncryption;
         private final @SecurityAlgorithm int mIntegrity;
diff --git a/src/java/com/android/internal/telephony/subscription/SubscriptionManagerService.java b/src/java/com/android/internal/telephony/subscription/SubscriptionManagerService.java
index 8757c97..fcbd9d0 100644
--- a/src/java/com/android/internal/telephony/subscription/SubscriptionManagerService.java
+++ b/src/java/com/android/internal/telephony/subscription/SubscriptionManagerService.java
@@ -4422,6 +4422,43 @@
     }
 
     /**
+     * checks whether esim bootstrap is activated for any of the available active subscription info
+     * list.
+     *
+     * @return {@code true} if esim bootstrap is activated for any of the active subscription,
+     * else {@code false}
+     *
+     */
+    public boolean isEsimBootStrapProvisioningActivated() {
+        if (!mFeatureFlags.esimBootstrapProvisioningFlag()) {
+            return false;
+        }
+
+        List<SubscriptionInfo> activeSubInfos =
+                getActiveSubscriptionInfoList(mContext.getOpPackageName(),
+                        mContext.getAttributionTag(), true/*isForAllProfile*/);
+
+        return activeSubInfos.stream().anyMatch(subInfo -> subInfo != null
+                && subInfo.getProfileClass() == SubscriptionManager.PROFILE_CLASS_PROVISIONING);
+    }
+
+    /**
+     * checks whether esim bootstrap is activated for the subscription.
+     *
+     * @return {@code true} if esim bootstrap is activated for sub id else {@code false}
+     *
+     */
+    public boolean isEsimBootStrapProvisioningActiveForSubId(int subId) {
+        if (!mFeatureFlags.esimBootstrapProvisioningFlag()) {
+            return false;
+        }
+
+        SubscriptionInfoInternal subInfo = getSubscriptionInfoInternal(subId);
+        return subInfo != null
+                && subInfo.getProfileClass() == SubscriptionManager.PROFILE_CLASS_PROVISIONING;
+    }
+
+    /**
      * Get the current calling package name.
      * @return the current calling package name
      */
diff --git a/src/java/com/android/internal/telephony/uicc/UiccController.java b/src/java/com/android/internal/telephony/uicc/UiccController.java
index 0459bf6..84e84d9 100644
--- a/src/java/com/android/internal/telephony/uicc/UiccController.java
+++ b/src/java/com/android/internal/telephony/uicc/UiccController.java
@@ -1799,6 +1799,8 @@
         }
         pw.decreaseIndent();
         pw.println();
+        mCarrierServiceBindHelper.dump(fd, pw, args);
+        pw.println();
         pw.println("sLocalLog= ");
         pw.increaseIndent();
         mPinStorage.dump(fd, pw, args);
diff --git a/src/java/com/android/internal/telephony/uicc/UiccProfile.java b/src/java/com/android/internal/telephony/uicc/UiccProfile.java
index 0457971..a22f075 100644
--- a/src/java/com/android/internal/telephony/uicc/UiccProfile.java
+++ b/src/java/com/android/internal/telephony/uicc/UiccProfile.java
@@ -1290,6 +1290,11 @@
             return -1;
         }
 
+        if (mUiccApplications[index] == null) {
+            loge("App index " + index + " is invalid");
+            return -1;
+        }
+
         if (mUiccApplications[index].getType() != expectedAppType
                 && mUiccApplications[index].getType() != altExpectedAppType) {
             loge("App index " + index + " is invalid since it's not "
diff --git a/tests/telephonytests/src/com/android/internal/telephony/CarrierAppUtilsTest.java b/tests/telephonytests/src/com/android/internal/telephony/CarrierAppUtilsTest.java
index 2a66a5f..e06e4fe 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/CarrierAppUtilsTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/CarrierAppUtilsTest.java
@@ -23,6 +23,7 @@
 import android.os.Bundle;
 import android.os.CarrierAssociatedAppEntry;
 import android.os.UserHandle;
+import android.platform.test.flag.junit.SetFlagsRule;
 import android.provider.Settings;
 import android.telephony.TelephonyManager;
 import android.test.mock.MockContentProvider;
@@ -34,9 +35,12 @@
 import androidx.test.filters.SmallTest;
 import androidx.test.runner.AndroidJUnit4;
 
+import com.android.internal.telephony.flags.Flags;
+
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Ignore;
+import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.Mockito;
@@ -59,6 +63,9 @@
     private static final int USER_ID = 12345;
     private static final String CALLING_PACKAGE = "phone";
 
+    @Rule
+    public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
+
     // Mocked classes
     private Context mContext;
     private PackageManager mPackageManager;
@@ -79,6 +86,7 @@
 
     @Before
     public void setUp() throws Exception {
+        mSetFlagsRule.enableFlags(Flags.FLAG_HIDE_PREINSTALLED_CARRIER_APP_AT_MOST_ONCE);
         System.setProperty("dexmaker.dexcache",
                 InstrumentationRegistry.getTargetContext().getCacheDir().getPath());
         Thread.currentThread().setContextClassLoader(getClass().getClassLoader());
@@ -113,6 +121,7 @@
     public void testDisableCarrierAppsUntilPrivileged_EmptyList() {
         CarrierAppUtils.disableCarrierAppsUntilPrivileged(CALLING_PACKAGE, mTelephonyManager,
                 mContentResolver, USER_ID, new ArraySet<>(), ASSOCIATED_APPS, mContext);
+
         Mockito.verifyNoMoreInteractions(mPackageManager, mTelephonyManager);
     }
 
@@ -125,9 +134,11 @@
                         | PackageManager.MATCH_SYSTEM_ONLY)).thenReturn(null);
         ArraySet<String> systemCarrierAppsDisabledUntilUsed = new ArraySet<>();
         systemCarrierAppsDisabledUntilUsed.add("com.example.missing.app");
+
         CarrierAppUtils.disableCarrierAppsUntilPrivileged(CALLING_PACKAGE, mTelephonyManager,
                 mContentResolver, USER_ID, systemCarrierAppsDisabledUntilUsed, ASSOCIATED_APPS,
                 mContext);
+
         Mockito.verify(mPackageManager, Mockito.never()).setSystemAppState(Mockito.anyString(),
                 Mockito.eq(PackageManager.SYSTEM_APP_STATE_HIDDEN_UNTIL_INSTALLED_HIDDEN));
         Mockito.verify(mPackageManager, Mockito.never()).setSystemAppState(Mockito.anyString(),
@@ -147,8 +158,10 @@
                 PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS
                         | PackageManager.MATCH_HIDDEN_UNTIL_INSTALLED_COMPONENTS))
                 .thenReturn(appInfo);
+
         CarrierAppUtils.disableCarrierAppsUntilPrivileged(CALLING_PACKAGE, mTelephonyManager,
                 mContentResolver, USER_ID, CARRIER_APPS, ASSOCIATED_APPS, mContext);
+
         Mockito.verify(mPackageManager, Mockito.never()).setSystemAppState(Mockito.anyString(),
                 Mockito.eq(PackageManager.SYSTEM_APP_STATE_HIDDEN_UNTIL_INSTALLED_HIDDEN));
         Mockito.verify(mPackageManager, Mockito.never()).setSystemAppState(Mockito.anyString(),
@@ -173,15 +186,16 @@
         Mockito.when(mPackageManager
                 .getApplicationEnabledSetting(Mockito.anyString()))
                 .thenReturn(PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER);
-
         Mockito.when(mPackageManager.getApplicationInfo(CARRIER_APP,
                 PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS
                         | PackageManager.MATCH_HIDDEN_UNTIL_INSTALLED_COMPONENTS
                         | PackageManager.MATCH_SYSTEM_ONLY)).thenReturn(appInfo);
         Mockito.when(mTelephonyManager.checkCarrierPrivilegesForPackageAnyPhone(CARRIER_APP))
                 .thenReturn(TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS);
+
         CarrierAppUtils.disableCarrierAppsUntilPrivileged(CALLING_PACKAGE, mTelephonyManager,
                 mContentResolver, USER_ID, CARRIER_APPS, ASSOCIATED_APPS, mContext);
+
         Mockito.verify(mPackageManager).setSystemAppState(CARRIER_APP,
                 PackageManager.SYSTEM_APP_STATE_HIDDEN_UNTIL_INSTALLED_HIDDEN);
         Mockito.verify(mPackageManager, Mockito.never()).setSystemAppState(Mockito.anyString(),
@@ -199,15 +213,16 @@
         Mockito.when(mPackageManager
                 .getApplicationEnabledSetting(Mockito.anyString()))
                 .thenReturn(PackageManager.COMPONENT_ENABLED_STATE_DISABLED);
-
         Mockito.when(mPackageManager.getApplicationInfo(CARRIER_APP,
                 PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS
                         | PackageManager.MATCH_HIDDEN_UNTIL_INSTALLED_COMPONENTS
                         | PackageManager.MATCH_SYSTEM_ONLY)).thenReturn(appInfo);
         Mockito.when(mTelephonyManager.checkCarrierPrivilegesForPackageAnyPhone(CARRIER_APP))
                 .thenReturn(TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS);
+
         CarrierAppUtils.disableCarrierAppsUntilPrivileged(CALLING_PACKAGE, mTelephonyManager,
                 mContentResolver, USER_ID, CARRIER_APPS, ASSOCIATED_APPS, mContext);
+
         Mockito.verify(mPackageManager).setSystemAppState(CARRIER_APP,
                 PackageManager.SYSTEM_APP_STATE_HIDDEN_UNTIL_INSTALLED_HIDDEN);
         Mockito.verify(mPackageManager, Mockito.never()).setSystemAppState(Mockito.anyString(),
@@ -231,8 +246,10 @@
                         | PackageManager.MATCH_SYSTEM_ONLY)).thenReturn(appInfo);
         Mockito.when(mTelephonyManager.checkCarrierPrivilegesForPackageAnyPhone(CARRIER_APP))
                 .thenReturn(TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS);
+
         CarrierAppUtils.disableCarrierAppsUntilPrivileged(CALLING_PACKAGE, mTelephonyManager,
                 mContentResolver, USER_ID, CARRIER_APPS, ASSOCIATED_APPS, mContext);
+
         Mockito.verify(mPackageManager).setSystemAppState(CARRIER_APP,
                 PackageManager.SYSTEM_APP_STATE_HIDDEN_UNTIL_INSTALLED_HIDDEN);
         Mockito.verify(mPackageManager, Mockito.never()).setSystemAppState(Mockito.anyString(),
@@ -255,11 +272,12 @@
         Mockito.when(mPackageManager
                 .getApplicationEnabledSetting(Mockito.anyString()))
                 .thenReturn(PackageManager.COMPONENT_ENABLED_STATE_ENABLED);
-
         Mockito.when(mTelephonyManager.checkCarrierPrivilegesForPackageAnyPhone(CARRIER_APP))
                 .thenReturn(TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS);
+
         CarrierAppUtils.disableCarrierAppsUntilPrivileged(CALLING_PACKAGE, mTelephonyManager,
                 mContentResolver, USER_ID, CARRIER_APPS, ASSOCIATED_APPS, mContext);
+
         Mockito.verify(mPackageManager).setSystemAppState(CARRIER_APP,
                 PackageManager.SYSTEM_APP_STATE_HIDDEN_UNTIL_INSTALLED_HIDDEN);
         Mockito.verify(mPackageManager, Mockito.never()).setSystemAppState(Mockito.anyString(),
@@ -287,8 +305,10 @@
                 .thenReturn(PackageManager.COMPONENT_ENABLED_STATE_DEFAULT);
         Mockito.when(mTelephonyManager.checkCarrierPrivilegesForPackageAnyPhone(CARRIER_APP))
                 .thenReturn(TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS);
+
         CarrierAppUtils.disableCarrierAppsUntilPrivileged(CALLING_PACKAGE, mTelephonyManager,
                 mContentResolver, USER_ID, CARRIER_APPS, ASSOCIATED_APPS, mContext);
+
         Mockito.verify(mPackageManager).setSystemAppState(CARRIER_APP,
                 PackageManager.SYSTEM_APP_STATE_HIDDEN_UNTIL_INSTALLED_HIDDEN);
         Mockito.verify(mPackageManager).setSystemAppState(CARRIER_APP,
@@ -329,8 +349,10 @@
                 .thenReturn(associatedAppInfo);
         Mockito.when(mTelephonyManager.checkCarrierPrivilegesForPackageAnyPhone(CARRIER_APP))
                 .thenReturn(TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS);
+
         CarrierAppUtils.disableCarrierAppsUntilPrivileged(CALLING_PACKAGE, mTelephonyManager,
                 mContentResolver, USER_ID, CARRIER_APPS, ASSOCIATED_APPS, mContext);
+
         Mockito.verify(mPackageManager).setSystemAppState(CARRIER_APP,
                 PackageManager.SYSTEM_APP_STATE_HIDDEN_UNTIL_INSTALLED_HIDDEN);
         Mockito.verify(mPackageManager).setSystemAppState(ASSOCIATED_APP,
@@ -371,8 +393,10 @@
                 .thenReturn(null);
         Mockito.when(mTelephonyManager.checkCarrierPrivilegesForPackageAnyPhone(CARRIER_APP))
                 .thenReturn(TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS);
+
         CarrierAppUtils.disableCarrierAppsUntilPrivileged(CALLING_PACKAGE, mTelephonyManager,
                 mContentResolver, USER_ID, CARRIER_APPS, ASSOCIATED_APPS, mContext);
+
         Mockito.verify(mPackageManager).setSystemAppState(CARRIER_APP,
                 PackageManager.SYSTEM_APP_STATE_HIDDEN_UNTIL_INSTALLED_HIDDEN);
         Mockito.verify(mPackageManager, Mockito.never()).setSystemAppState(ASSOCIATED_APP,
@@ -412,8 +436,10 @@
                 .thenReturn(associatedAppInfo);
         Mockito.when(mTelephonyManager.checkCarrierPrivilegesForPackageAnyPhone(CARRIER_APP))
                 .thenReturn(TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS);
+
         CarrierAppUtils.disableCarrierAppsUntilPrivileged(CALLING_PACKAGE, mTelephonyManager,
                 mContentResolver, USER_ID, CARRIER_APPS, ASSOCIATED_APPS, mContext);
+
         Mockito.verify(mPackageManager).setSystemAppState(CARRIER_APP,
                 PackageManager.SYSTEM_APP_STATE_HIDDEN_UNTIL_INSTALLED_HIDDEN);
         Mockito.verify(mPackageManager).setSystemAppState(ASSOCIATED_APP,
@@ -440,8 +466,10 @@
                 .thenReturn(appInfo);
         Mockito.when(mTelephonyManager.checkCarrierPrivilegesForPackageAnyPhone(CARRIER_APP))
                 .thenReturn(TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS);
+
         CarrierAppUtils.disableCarrierAppsUntilPrivileged(CALLING_PACKAGE, mTelephonyManager,
                 mContentResolver, USER_ID, CARRIER_APPS, ASSOCIATED_APPS, mContext);
+
         Mockito.verify(mPackageManager).setSystemAppState(CARRIER_APP,
                 PackageManager.SYSTEM_APP_STATE_HIDDEN_UNTIL_INSTALLED_HIDDEN);
         Mockito.verify(mPackageManager, Mockito.never()).setSystemAppState(Mockito.anyString(),
@@ -465,9 +493,11 @@
                         | PackageManager.MATCH_HIDDEN_UNTIL_INSTALLED_COMPONENTS
                         | PackageManager.MATCH_SYSTEM_ONLY))
                 .thenReturn(appInfo);
+
         CarrierAppUtils.disableCarrierAppsUntilPrivileged(CALLING_PACKAGE,
                 null /* telephonyManager */, mContentResolver, USER_ID, CARRIER_APPS,
                 ASSOCIATED_APPS, mContext);
+
         Mockito.verify(mPackageManager).setSystemAppState(CARRIER_APP,
                 PackageManager.SYSTEM_APP_STATE_HIDDEN_UNTIL_INSTALLED_HIDDEN);
         Mockito.verify(mPackageManager, Mockito.never()).setSystemAppState(Mockito.anyString(),
@@ -476,7 +506,7 @@
                 Mockito.eq(PackageManager.SYSTEM_APP_STATE_UNINSTALLED));
     }
 
-    /** Configured app has no privileges, and was uninstalled - should do nothing. */
+    /** Configured app has no privileges, and was explicitly disabled - should do nothing. */
     @Test @SmallTest
     public void testDisableCarrierAppsUntilPrivileged_NoPrivileges_Disabled() throws Exception {
         ApplicationInfo appInfo = new ApplicationInfo();
@@ -492,8 +522,10 @@
                 .thenReturn(appInfo);
         Mockito.when(mTelephonyManager.checkCarrierPrivilegesForPackageAnyPhone(CARRIER_APP))
                 .thenReturn(TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS);
+
         CarrierAppUtils.disableCarrierAppsUntilPrivileged(CALLING_PACKAGE, mTelephonyManager,
                 mContentResolver, USER_ID, CARRIER_APPS, ASSOCIATED_APPS, mContext);
+
         Mockito.verify(mPackageManager).setSystemAppState(CARRIER_APP,
                 PackageManager.SYSTEM_APP_STATE_HIDDEN_UNTIL_INSTALLED_HIDDEN);
         Mockito.verify(mPackageManager, Mockito.never()).setSystemAppState(Mockito.anyString(),
@@ -502,7 +534,7 @@
                 Mockito.eq(PackageManager.SYSTEM_APP_STATE_UNINSTALLED));
     }
 
-    /** Telephony is not initialized, and app was uninstalled - should do nothing. */
+    /** Telephony is not initialized, and app was explicitly disabled - should do nothing. */
     @Test @SmallTest
     public void testDisableCarrierAppsUntilPrivileged_NullPrivileges_Disabled() throws Exception {
         ApplicationInfo appInfo = new ApplicationInfo();
@@ -516,9 +548,11 @@
                         | PackageManager.MATCH_HIDDEN_UNTIL_INSTALLED_COMPONENTS
                         | PackageManager.MATCH_SYSTEM_ONLY))
                 .thenReturn(appInfo);
+
         CarrierAppUtils.disableCarrierAppsUntilPrivileged(CALLING_PACKAGE,
                 null /* telephonyManager */, mContentResolver, USER_ID, CARRIER_APPS,
                 ASSOCIATED_APPS, mContext);
+
         Mockito.verify(mPackageManager).setSystemAppState(CARRIER_APP,
                 PackageManager.SYSTEM_APP_STATE_HIDDEN_UNTIL_INSTALLED_HIDDEN);
         Mockito.verify(mPackageManager, Mockito.never()).setSystemAppState(Mockito.anyString(),
@@ -527,7 +561,7 @@
                 Mockito.eq(PackageManager.SYSTEM_APP_STATE_UNINSTALLED));
     }
 
-    /** Configured app has no privileges, and is explicitly installed - should do nothing. */
+    /** Configured app has no privileges, and was explicitly enabled - should do nothing. */
     @Test @SmallTest
     public void testDisableCarrierAppsUntilPrivileged_NoPrivileges_Enabled() throws Exception {
         ApplicationInfo appInfo = new ApplicationInfo();
@@ -543,8 +577,10 @@
                 .thenReturn(appInfo);
         Mockito.when(mTelephonyManager.checkCarrierPrivilegesForPackageAnyPhone(CARRIER_APP))
                 .thenReturn(TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS);
+
         CarrierAppUtils.disableCarrierAppsUntilPrivileged(CALLING_PACKAGE, mTelephonyManager,
                 mContentResolver, USER_ID, CARRIER_APPS, ASSOCIATED_APPS, mContext);
+
         Mockito.verify(mPackageManager).setSystemAppState(CARRIER_APP,
                 PackageManager.SYSTEM_APP_STATE_HIDDEN_UNTIL_INSTALLED_HIDDEN);
         Mockito.verify(mPackageManager, Mockito.never()).setSystemAppState(Mockito.anyString(),
@@ -553,7 +589,7 @@
                 Mockito.eq(PackageManager.SYSTEM_APP_STATE_UNINSTALLED));
     }
 
-    /** Telephony is not initialized, and app is explicitly installed - should do nothing. */
+    /** Telephony is not initialized, and app was explicitly enabled - should do nothing. */
     @Test @SmallTest
     public void testDisableCarrierAppsUntilPrivileged_NullPrivileges_Enabled() throws Exception {
         ApplicationInfo appInfo = new ApplicationInfo();
@@ -567,9 +603,11 @@
                         | PackageManager.MATCH_HIDDEN_UNTIL_INSTALLED_COMPONENTS
                         | PackageManager.MATCH_SYSTEM_ONLY))
                 .thenReturn(appInfo);
+
         CarrierAppUtils.disableCarrierAppsUntilPrivileged(CALLING_PACKAGE,
                 null /* telephonyManager */, mContentResolver, USER_ID, CARRIER_APPS,
                 ASSOCIATED_APPS, mContext);
+
         Mockito.verify(mPackageManager).setSystemAppState(CARRIER_APP,
                 PackageManager.SYSTEM_APP_STATE_HIDDEN_UNTIL_INSTALLED_HIDDEN);
         Mockito.verify(mPackageManager, Mockito.never()).setSystemAppState(Mockito.anyString(),
@@ -578,7 +616,8 @@
                 Mockito.eq(PackageManager.SYSTEM_APP_STATE_UNINSTALLED));
     }
 
-    /** Configured /data app has no privileges - should do nothing. */
+    /** Configured app has been installed as an update in /data and has no privileges
+     *  - should do nothing. */
     @Test @SmallTest
     public void testDisableCarrierAppsUntilPrivileged_NoPrivileges_UpdatedApp() throws Exception {
         ApplicationInfo appInfo = new ApplicationInfo();
@@ -595,8 +634,10 @@
                 .thenReturn(appInfo);
         Mockito.when(mTelephonyManager.checkCarrierPrivilegesForPackageAnyPhone(CARRIER_APP))
                 .thenReturn(TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS);
+
         CarrierAppUtils.disableCarrierAppsUntilPrivileged(CALLING_PACKAGE, mTelephonyManager,
                 mContentResolver, USER_ID, CARRIER_APPS, ASSOCIATED_APPS, mContext);
+
         Mockito.verify(mPackageManager).setSystemAppState(CARRIER_APP,
                 PackageManager.SYSTEM_APP_STATE_HIDDEN_UNTIL_INSTALLED_HIDDEN);
         Mockito.verify(mPackageManager, Mockito.never()).setSystemAppState(Mockito.anyString(),
@@ -620,9 +661,11 @@
                         | PackageManager.MATCH_HIDDEN_UNTIL_INSTALLED_COMPONENTS
                         | PackageManager.MATCH_SYSTEM_ONLY))
                 .thenReturn(appInfo);
+
         CarrierAppUtils.disableCarrierAppsUntilPrivileged(CALLING_PACKAGE,
                 null /* telephonyManager */, mContentResolver, USER_ID, CARRIER_APPS,
                 ASSOCIATED_APPS, mContext);
+
         Mockito.verify(mPackageManager).setSystemAppState(CARRIER_APP,
                 PackageManager.SYSTEM_APP_STATE_HIDDEN_UNTIL_INSTALLED_HIDDEN);
         Mockito.verify(mPackageManager, Mockito.never()).setSystemAppState(Mockito.anyString(),
@@ -632,7 +675,8 @@
     }
 
     /**
-     * Configured app has no privileges, and is in the default state - should uninstalled.
+     * Configured app has no privileges, is in the default state and it was never uninstalled before
+     *  - should uninstalled.
      * Associated app is installed and should not be touched.
      */
     @Test @SmallTest
@@ -660,8 +704,10 @@
                 .thenReturn(associatedAppInfo);
         Mockito.when(mTelephonyManager.checkCarrierPrivilegesForPackageAnyPhone(CARRIER_APP))
                 .thenReturn(TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS);
+
         CarrierAppUtils.disableCarrierAppsUntilPrivileged(CALLING_PACKAGE, mTelephonyManager,
                 mContentResolver, USER_ID, CARRIER_APPS, ASSOCIATED_APPS, mContext);
+
         Mockito.verify(mPackageManager).setSystemAppState(CARRIER_APP,
                 PackageManager.SYSTEM_APP_STATE_HIDDEN_UNTIL_INSTALLED_HIDDEN);
         Mockito.verify(mPackageManager).setSystemAppState(ASSOCIATED_APP,
@@ -675,8 +721,8 @@
     }
 
     /**
-     * Configured app has no privileges, and is in the default state along with associated app -
-     * should uninstall both.
+     * Configured app has no privileges, is in the default state along with associated app and never
+     * unstalled before - should uninstall both.
      */
     @Test @SmallTest
     public void testDisableCarrierAppsUntilPrivileged_NoPrivileges_Associated_Default()
@@ -703,8 +749,10 @@
                 .thenReturn(associatedAppInfo);
         Mockito.when(mTelephonyManager.checkCarrierPrivilegesForPackageAnyPhone(CARRIER_APP))
                 .thenReturn(TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS);
+
         CarrierAppUtils.disableCarrierAppsUntilPrivileged(CALLING_PACKAGE, mTelephonyManager,
                 mContentResolver, USER_ID, CARRIER_APPS, ASSOCIATED_APPS, mContext);
+
         Mockito.verify(mPackageManager).setSystemAppState(CARRIER_APP,
                 PackageManager.SYSTEM_APP_STATE_HIDDEN_UNTIL_INSTALLED_HIDDEN);
         Mockito.verify(mPackageManager).setSystemAppState(ASSOCIATED_APP,
@@ -717,7 +765,7 @@
 
     /**
      * Configured app has no privileges, and is in the default state along with associated app, and
-     * disabling has already occurred - should only uninstall configured app.
+     * disabling has already occurred - should uninstall nothing.
      */
     @Test @SmallTest
     public void testDisableCarrierAppsUntilPrivileged_NoPrivileges_Associated_Default_HandledSdk()
@@ -747,15 +795,17 @@
                 .thenReturn(associatedAppInfo);
         Mockito.when(mTelephonyManager.checkCarrierPrivilegesForPackageAnyPhone(CARRIER_APP))
                 .thenReturn(TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS);
+
         // Different associated app SDK than usual.
         CarrierAppUtils.disableCarrierAppsUntilPrivileged(CALLING_PACKAGE, mTelephonyManager,
                 mContentResolver, USER_ID, CARRIER_APPS,
                 makeAssociatedApp(CARRIER_APP, ASSOCIATED_APP, Build.VERSION.SDK_INT), mContext);
+
         Mockito.verify(mPackageManager).setSystemAppState(CARRIER_APP,
                 PackageManager.SYSTEM_APP_STATE_HIDDEN_UNTIL_INSTALLED_HIDDEN);
         Mockito.verify(mPackageManager).setSystemAppState(ASSOCIATED_APP,
                 PackageManager.SYSTEM_APP_STATE_HIDDEN_UNTIL_INSTALLED_HIDDEN);
-        Mockito.verify(mPackageManager).setSystemAppState(CARRIER_APP,
+        Mockito.verify(mPackageManager, Mockito.never()).setSystemAppState(CARRIER_APP,
                 PackageManager.SYSTEM_APP_STATE_UNINSTALLED);
         Mockito.verify(mPackageManager, Mockito.never()).setSystemAppState(ASSOCIATED_APP,
                 PackageManager.SYSTEM_APP_STATE_INSTALLED);
@@ -765,7 +815,7 @@
 
     /**
      * Configured app has no privileges, and is in the default state along with associated app, and
-     * disabling has already occurred - should only uninstall configured app.
+     * disabling has already occurred - should uninstall nothing.
      */
     @Test @SmallTest
     public void testDCAUP_NoPrivileges_Associated_Default_HandledSdk_AssociatedSdkUnspecified()
@@ -795,14 +845,16 @@
                 .thenReturn(associatedAppInfo);
         Mockito.when(mTelephonyManager.checkCarrierPrivilegesForPackageAnyPhone(CARRIER_APP))
                 .thenReturn(TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS);
+
         // Using SDK_UNSPECIFIED for the associated app's addedInSdk.
         CarrierAppUtils.disableCarrierAppsUntilPrivileged(CALLING_PACKAGE, mTelephonyManager,
                 mContentResolver, USER_ID, CARRIER_APPS, ASSOCIATED_APPS, mContext);
+
         Mockito.verify(mPackageManager).setSystemAppState(CARRIER_APP,
                 PackageManager.SYSTEM_APP_STATE_HIDDEN_UNTIL_INSTALLED_HIDDEN);
         Mockito.verify(mPackageManager).setSystemAppState(ASSOCIATED_APP,
                 PackageManager.SYSTEM_APP_STATE_HIDDEN_UNTIL_INSTALLED_HIDDEN);
-        Mockito.verify(mPackageManager).setSystemAppState(CARRIER_APP,
+        Mockito.verify(mPackageManager, Mockito.never()).setSystemAppState(CARRIER_APP,
                 PackageManager.SYSTEM_APP_STATE_UNINSTALLED);
         Mockito.verify(mPackageManager, Mockito.never()).setSystemAppState(ASSOCIATED_APP,
                 PackageManager.SYSTEM_APP_STATE_INSTALLED);
@@ -812,15 +864,14 @@
 
     /**
      * Configured app has no privileges, and is in the default state along with associated app, and
-     * disabling has not yet occurred on this SDK level - should uninstall both since the associated
-     * app's SDK matches.
+     * disabling has not yet occurred on any SDK level - should uninstall both since disabling never
+     * occurred before and the associated app's SDK matches.
      */
     @Test @SmallTest
     public void testDCAUP_NoPrivileges_Associated_Default_NewSdk_AssociatedSdkCurrent()
             throws Exception {
         Settings.Secure.putIntForUser(
-                mContentResolver, Settings.Secure.CARRIER_APPS_HANDLED,
-                Build.VERSION.SDK_INT - 1, USER_ID);
+                mContentResolver, Settings.Secure.CARRIER_APPS_HANDLED, 0, USER_ID);
         ApplicationInfo appInfo = new ApplicationInfo();
         appInfo.packageName = CARRIER_APP;
         appInfo.flags |= ApplicationInfo.FLAG_SYSTEM | ApplicationInfo.FLAG_INSTALLED;
@@ -843,10 +894,12 @@
                 .thenReturn(associatedAppInfo);
         Mockito.when(mTelephonyManager.checkCarrierPrivilegesForPackageAnyPhone(CARRIER_APP))
                 .thenReturn(TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS);
+
         // Different associated app SDK than usual.
         CarrierAppUtils.disableCarrierAppsUntilPrivileged(CALLING_PACKAGE, mTelephonyManager,
                 mContentResolver, USER_ID, CARRIER_APPS,
                 makeAssociatedApp(CARRIER_APP, ASSOCIATED_APP, Build.VERSION.SDK_INT), mContext);
+
         Mockito.verify(mPackageManager).setSystemAppState(CARRIER_APP,
                 PackageManager.SYSTEM_APP_STATE_HIDDEN_UNTIL_INSTALLED_HIDDEN);
         Mockito.verify(mPackageManager).setSystemAppState(ASSOCIATED_APP,
@@ -861,7 +914,7 @@
 
     /**
      * Configured app has no privileges, and is in the default state along with associated app, and
-     * disabling has not yet occurred on the current SDK - should only uninstall configured app
+     * disabling has not yet occurred on the current SDK - should uninstall nothing
      * since the associated app's SDK isn't specified but we've already run at least once.
      */
     @Test @SmallTest
@@ -892,14 +945,16 @@
                 .thenReturn(associatedAppInfo);
         Mockito.when(mTelephonyManager.checkCarrierPrivilegesForPackageAnyPhone(CARRIER_APP))
                 .thenReturn(TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS);
+
         // Using SDK_UNSPECIFIED for the associated app's addedInSdk.
         CarrierAppUtils.disableCarrierAppsUntilPrivileged(CALLING_PACKAGE, mTelephonyManager,
                 mContentResolver, USER_ID, CARRIER_APPS, ASSOCIATED_APPS, mContext);
+
         Mockito.verify(mPackageManager).setSystemAppState(CARRIER_APP,
                 PackageManager.SYSTEM_APP_STATE_HIDDEN_UNTIL_INSTALLED_HIDDEN);
         Mockito.verify(mPackageManager).setSystemAppState(ASSOCIATED_APP,
                 PackageManager.SYSTEM_APP_STATE_HIDDEN_UNTIL_INSTALLED_HIDDEN);
-        Mockito.verify(mPackageManager).setSystemAppState(CARRIER_APP,
+        Mockito.verify(mPackageManager, Mockito.never()).setSystemAppState(CARRIER_APP,
                 PackageManager.SYSTEM_APP_STATE_UNINSTALLED);
         Mockito.verify(mPackageManager, Mockito.never()).setSystemAppState(ASSOCIATED_APP,
                 PackageManager.SYSTEM_APP_STATE_INSTALLED);
@@ -909,7 +964,7 @@
 
     /**
      * Configured app has no privileges, and is in the default state along with associated app, and
-     * disabling has not yet occurred on the current SDK - should only uninstall configured app
+     * disabling has not yet occurred on the current SDK - should uninstall nothing
      * since the associated app's SDK doesn't match.
      */
     @Test @SmallTest
@@ -940,16 +995,18 @@
                 .thenReturn(associatedAppInfo);
         Mockito.when(mTelephonyManager.checkCarrierPrivilegesForPackageAnyPhone(CARRIER_APP))
                 .thenReturn(TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS);
+
         // Different associated app SDK than usual.
         CarrierAppUtils.disableCarrierAppsUntilPrivileged(CALLING_PACKAGE, mTelephonyManager,
                 mContentResolver, USER_ID, CARRIER_APPS,
                 makeAssociatedApp(CARRIER_APP, ASSOCIATED_APP, Build.VERSION.SDK_INT - 1),
                 mContext);
+
         Mockito.verify(mPackageManager).setSystemAppState(CARRIER_APP,
                 PackageManager.SYSTEM_APP_STATE_HIDDEN_UNTIL_INSTALLED_HIDDEN);
         Mockito.verify(mPackageManager).setSystemAppState(ASSOCIATED_APP,
                 PackageManager.SYSTEM_APP_STATE_HIDDEN_UNTIL_INSTALLED_HIDDEN);
-        Mockito.verify(mPackageManager).setSystemAppState(CARRIER_APP,
+        Mockito.verify(mPackageManager, Mockito.never()).setSystemAppState(CARRIER_APP,
                 PackageManager.SYSTEM_APP_STATE_UNINSTALLED);
         Mockito.verify(mPackageManager, Mockito.never()).setSystemAppState(ASSOCIATED_APP,
                 PackageManager.SYSTEM_APP_STATE_INSTALLED);
@@ -959,8 +1016,8 @@
 
     /**
      * Configured app has no privileges, and is in the default state along with associated app, and
-     * disabling has not yet occurred on this SDK level - should uninstall both since the associated
-     * app's SDK is newer than the last evaluation.
+     * disabling has not yet occurred on this SDK level - should uninstall only associated
+     * app since the associated app's SDK is newer than the last evaluation.
      *
      * While this case is expected to feel somewhat strange, it effectively simulates skipping a
      * whole SDK level in a single OTA. For example, the device is on P. A new associated app is
@@ -996,16 +1053,18 @@
                 .thenReturn(associatedAppInfo);
         Mockito.when(mTelephonyManager.checkCarrierPrivilegesForPackageAnyPhone(CARRIER_APP))
                 .thenReturn(TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS);
+
         // Different associated app SDK than usual.
         CarrierAppUtils.disableCarrierAppsUntilPrivileged(CALLING_PACKAGE, mTelephonyManager,
                 mContentResolver, USER_ID, CARRIER_APPS,
                 makeAssociatedApp(CARRIER_APP, ASSOCIATED_APP, Build.VERSION.SDK_INT - 1),
                 mContext);
+
         Mockito.verify(mPackageManager).setSystemAppState(CARRIER_APP,
                 PackageManager.SYSTEM_APP_STATE_HIDDEN_UNTIL_INSTALLED_HIDDEN);
         Mockito.verify(mPackageManager).setSystemAppState(ASSOCIATED_APP,
                 PackageManager.SYSTEM_APP_STATE_HIDDEN_UNTIL_INSTALLED_HIDDEN);
-        Mockito.verify(mPackageManager).setSystemAppState(CARRIER_APP,
+        Mockito.verify(mPackageManager, Mockito.never()).setSystemAppState(CARRIER_APP,
                 PackageManager.SYSTEM_APP_STATE_UNINSTALLED);
         Mockito.verify(mPackageManager, Mockito.never()).setSystemAppState(ASSOCIATED_APP,
                 PackageManager.SYSTEM_APP_STATE_INSTALLED);
@@ -1043,10 +1102,12 @@
                 .thenReturn(associatedAppInfo);
         Mockito.when(mTelephonyManager.checkCarrierPrivilegesForPackageAnyPhone(CARRIER_APP))
                 .thenReturn(TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS);
+
         // Different associated app SDK than usual.
         CarrierAppUtils.disableCarrierAppsUntilPrivileged(CALLING_PACKAGE, mTelephonyManager,
                 mContentResolver, USER_ID, CARRIER_APPS,
                 makeAssociatedApp(CARRIER_APP, ASSOCIATED_APP, Build.VERSION.SDK_INT), mContext);
+
         Mockito.verify(mPackageManager).setSystemAppState(CARRIER_APP,
                 PackageManager.SYSTEM_APP_STATE_HIDDEN_UNTIL_INSTALLED_HIDDEN);
         Mockito.verify(mPackageManager).setSystemAppState(ASSOCIATED_APP,
@@ -1089,9 +1150,11 @@
                 .thenReturn(associatedAppInfo);
         Mockito.when(mTelephonyManager.checkCarrierPrivilegesForPackageAnyPhone(CARRIER_APP))
                 .thenReturn(TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS);
+
         // Using SDK_UNSPECIFIED for the associated app's addedInSdk.
         CarrierAppUtils.disableCarrierAppsUntilPrivileged(CALLING_PACKAGE, mTelephonyManager,
                 mContentResolver, USER_ID, CARRIER_APPS, ASSOCIATED_APPS, mContext);
+
         Mockito.verify(mPackageManager).setSystemAppState(CARRIER_APP,
                 PackageManager.SYSTEM_APP_STATE_HIDDEN_UNTIL_INSTALLED_HIDDEN);
         Mockito.verify(mPackageManager).setSystemAppState(ASSOCIATED_APP,
@@ -1104,7 +1167,10 @@
                 PackageManager.SYSTEM_APP_STATE_UNINSTALLED);
     }
 
-    /** Telephony is not initialized, and app is in the default state - should uninstall it. */
+    /**
+     * Telephony is not initialized, and app is in the default state and never uninstall before
+     * - should uninstall it.
+     **/
     @Test @SmallTest
     public void testDisableCarrierAppsUntilPrivileged_NullPrivileges_Default() throws Exception {
         ApplicationInfo appInfo = new ApplicationInfo();
@@ -1118,16 +1184,51 @@
                         | PackageManager.MATCH_HIDDEN_UNTIL_INSTALLED_COMPONENTS
                         | PackageManager.MATCH_SYSTEM_ONLY))
                 .thenReturn(appInfo);
+
         CarrierAppUtils.disableCarrierAppsUntilPrivileged(CALLING_PACKAGE,
                 null /* telephonyManager */, mContentResolver, USER_ID, CARRIER_APPS,
                 ASSOCIATED_APPS, mContext);
+
         Mockito.verify(mPackageManager).setSystemAppState(CARRIER_APP,
                 PackageManager.SYSTEM_APP_STATE_HIDDEN_UNTIL_INSTALLED_HIDDEN);
         Mockito.verify(mPackageManager).setSystemAppState(CARRIER_APP,
                 PackageManager.SYSTEM_APP_STATE_UNINSTALLED);
     }
 
-    /** Configured app has no privileges, and is disabled until used or not installed - should do
+    /**
+     * Telephony is not initialized, and app is in the default state but uninstall before
+     * - should not uninstall again.
+     **/
+    @Test @SmallTest
+    public void testDisableCarrierAppsUntilPrivileged_NullPrivileges_Default_alreadyUninstalled()
+            throws Exception {
+        Settings.Secure.putIntForUser(
+                mContentResolver, Settings.Secure.CARRIER_APPS_HANDLED,
+                Build.VERSION.SDK_INT, USER_ID);
+        ApplicationInfo appInfo = new ApplicationInfo();
+        appInfo.packageName = CARRIER_APP;
+        appInfo.flags |= ApplicationInfo.FLAG_SYSTEM | ApplicationInfo.FLAG_INSTALLED;
+        Mockito.when(mPackageManager
+                .getApplicationEnabledSetting(Mockito.anyString()))
+                .thenReturn(PackageManager.COMPONENT_ENABLED_STATE_DEFAULT);
+        Mockito.when(mPackageManager.getApplicationInfo(CARRIER_APP,
+                PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS
+                        | PackageManager.MATCH_HIDDEN_UNTIL_INSTALLED_COMPONENTS
+                        | PackageManager.MATCH_SYSTEM_ONLY))
+                .thenReturn(appInfo);
+
+        CarrierAppUtils.disableCarrierAppsUntilPrivileged(CALLING_PACKAGE,
+                null /* telephonyManager */, mContentResolver, USER_ID, CARRIER_APPS,
+                ASSOCIATED_APPS, mContext);
+
+        Mockito.verify(mPackageManager).setSystemAppState(CARRIER_APP,
+                PackageManager.SYSTEM_APP_STATE_HIDDEN_UNTIL_INSTALLED_HIDDEN);
+        Mockito.verify(mPackageManager, Mockito.never()).setSystemAppState(CARRIER_APP,
+                PackageManager.SYSTEM_APP_STATE_UNINSTALLED);
+    }
+
+    /**
+     * Configured app has no privileges, and is disabled until used or not installed - should do
      *  nothing.
      **/
     @Test @SmallTest
@@ -1146,8 +1247,10 @@
                 .thenReturn(appInfo);
         Mockito.when(mTelephonyManager.checkCarrierPrivilegesForPackageAnyPhone(CARRIER_APP))
                 .thenReturn(TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS);
+
         CarrierAppUtils.disableCarrierAppsUntilPrivileged(CALLING_PACKAGE, mTelephonyManager,
                 mContentResolver, USER_ID, CARRIER_APPS, ASSOCIATED_APPS, mContext);
+
         Mockito.verify(mPackageManager).setSystemAppState(CARRIER_APP,
                 PackageManager.SYSTEM_APP_STATE_HIDDEN_UNTIL_INSTALLED_HIDDEN);
         Mockito.verify(mPackageManager, Mockito.never()).setSystemAppState(Mockito.anyString(),
@@ -1156,8 +1259,9 @@
                 Mockito.eq(PackageManager.SYSTEM_APP_STATE_UNINSTALLED));
     }
 
-    /** Telephony is not initialized, and app is disabled until used or not installed - should do
-     *  nothing.
+    /**
+     * Telephony is not initialized, and app is disabled until used or not installed - should do
+     * nothing.
      **/
     @Test @SmallTest
     public void testDisableCarrierAppsUntilPrivileged_NullPrivileges_DisabledUntilUsed()
@@ -1173,9 +1277,11 @@
                         | PackageManager.MATCH_HIDDEN_UNTIL_INSTALLED_COMPONENTS
                         | PackageManager.MATCH_SYSTEM_ONLY))
                 .thenReturn(appInfo);
+
         CarrierAppUtils.disableCarrierAppsUntilPrivileged(CALLING_PACKAGE,
                 null /* telephonyManager */, mContentResolver, USER_ID, CARRIER_APPS,
                 ASSOCIATED_APPS, mContext);
+
         Mockito.verify(mPackageManager).setSystemAppState(CARRIER_APP,
                 PackageManager.SYSTEM_APP_STATE_HIDDEN_UNTIL_INSTALLED_HIDDEN);
         Mockito.verify(mPackageManager, Mockito.never()).setSystemAppState(Mockito.anyString(),
diff --git a/tests/telephonytests/src/com/android/internal/telephony/CarrierKeyDownloadMgrTest.java b/tests/telephonytests/src/com/android/internal/telephony/CarrierKeyDownloadMgrTest.java
index 07482e0..e60e95b 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/CarrierKeyDownloadMgrTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/CarrierKeyDownloadMgrTest.java
@@ -22,6 +22,7 @@
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyString;
 import static org.mockito.Mockito.anyBoolean;
 import static org.mockito.Mockito.anyInt;
 import static org.mockito.Mockito.times;
@@ -31,6 +32,8 @@
 import android.app.DownloadManager;
 import android.content.Context;
 import android.content.Intent;
+import android.net.ConnectivityManager;
+import android.net.Network;
 import android.os.PersistableBundle;
 import android.telephony.CarrierConfigManager;
 import android.telephony.ImsiEncryptionInfo;
@@ -38,18 +41,18 @@
 import android.telephony.TelephonyManager;
 import android.testing.AndroidTestingRunner;
 import android.testing.TestableLooper;
+import android.text.TextUtils;
 import android.util.Pair;
 
 import androidx.test.filters.SmallTest;
 
-import com.android.internal.telephony.flags.FeatureFlags;
-
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.ArgumentCaptor;
 import org.mockito.ArgumentMatchers;
+import org.mockito.Mock;
 import org.mockito.Mockito;
 
 import java.security.PublicKey;
@@ -91,7 +94,7 @@
                     + "\"public-key\": \"" + CERT + "\"}]}";
 
     private CarrierConfigManager.CarrierConfigChangeListener mCarrierConfigChangeListener;
-    private FeatureFlags mFeatureFlags;
+
     @Before
     public void setUp() throws Exception {
         logd("CarrierActionAgentTest +Setup!");
@@ -99,15 +102,18 @@
         mBundle = mContextFixture.getCarrierConfigBundle();
         when(mCarrierConfigManager.getConfigForSubId(anyInt(), any())).thenReturn(mBundle);
         when(mUserManager.isUserUnlocked()).thenReturn(true);
+        when(mKeyguardManager.isDeviceLocked()).thenReturn(false);
         // Capture listener to emulate the carrier config change notification used later
         ArgumentCaptor<CarrierConfigManager.CarrierConfigChangeListener> listenerArgumentCaptor =
                 ArgumentCaptor.forClass(CarrierConfigManager.CarrierConfigChangeListener.class);
-        mFeatureFlags = Mockito.mock(FeatureFlags.class);
-        mCarrierKeyDM = new CarrierKeyDownloadManager(mPhone, mFeatureFlags);
+        mCarrierKeyDM = new CarrierKeyDownloadManager(mPhone);
         verify(mCarrierConfigManager).registerCarrierConfigChangeListener(any(),
                 listenerArgumentCaptor.capture());
         mCarrierConfigChangeListener = listenerArgumentCaptor.getAllValues().get(0);
-
+        mConnectivityManager = (ConnectivityManager) mPhone.getContext().getSystemService(
+                Context.CONNECTIVITY_SERVICE);
+        Network network = Mockito.mock(Network.class);
+        when(mConnectivityManager.getActiveNetwork()).thenReturn(network);
         processAllMessages();
         logd("CarrierActionAgentTest -Setup!");
     }
@@ -331,8 +337,8 @@
         expectedCal.add(Calendar.DATE, 1);
         String dateExpected = dt.format(expectedCal.getTime());
 
-        when(mTelephonyManager.getSimOperator(anyInt())).thenReturn("310260");
-        when(mTelephonyManager.getSimCarrierId()).thenReturn(1);
+        when(mPhone.getOperatorNumeric()).thenReturn("310260");
+        when(mPhone.getCarrierId()).thenReturn(1);
         Intent mIntent = new Intent(DownloadManager.ACTION_DOWNLOAD_COMPLETE);
         mIntent.putExtra(DownloadManager.EXTRA_DOWNLOAD_ID, downloadId);
         mContext.sendBroadcast(mIntent);
@@ -355,11 +361,11 @@
         bundle.putInt(CarrierConfigManager.IMSI_KEY_AVAILABILITY_INT, 3);
         bundle.putString(CarrierConfigManager.IMSI_KEY_DOWNLOAD_URL_STRING, mURL);
 
-        when(mTelephonyManager.getSimOperator(anyInt())).thenReturn("310260");
-        when(mTelephonyManager.getSimCarrierId()).thenReturn(1);
+        when(mPhone.getOperatorNumeric()).thenReturn("310260");
+        when(mPhone.getCarrierId()).thenReturn(1);
         mCarrierConfigChangeListener.onCarrierConfigChanged(0 /* slotIndex */,
                 SubscriptionManager.INVALID_SUBSCRIPTION_ID,
-                TelephonyManager.UNKNOWN_CARRIER_ID, TelephonyManager.UNKNOWN_CARRIER_ID);
+                1, TelephonyManager.UNKNOWN_CARRIER_ID);
         processAllMessages();
         assertEquals("310260", mCarrierKeyDM.mMccMncForDownload);
         assertEquals(1, mCarrierKeyDM.mCarrierId);
@@ -369,6 +375,7 @@
     @SmallTest
     public void testCarrierConfigChangedWithUserLocked() {
         when(mUserManager.isUserUnlocked()).thenReturn(false);
+        when(mKeyguardManager.isDeviceLocked()).thenReturn(true);
         CarrierConfigManager carrierConfigManager = (CarrierConfigManager)
                 mContext.getSystemService(Context.CARRIER_CONFIG_SERVICE);
         int slotId = mPhone.getPhoneId();
@@ -376,14 +383,14 @@
         bundle.putInt(CarrierConfigManager.IMSI_KEY_AVAILABILITY_INT, 3);
         bundle.putString(CarrierConfigManager.IMSI_KEY_DOWNLOAD_URL_STRING, mURL);
 
-        when(mTelephonyManager.getSimOperator(anyInt())).thenReturn("310260");
-        when(mTelephonyManager.getSimCarrierId()).thenReturn(1);
+        when(mPhone.getOperatorNumeric()).thenReturn("310260");
+        when(mPhone.getCarrierId()).thenReturn(1);
         mCarrierConfigChangeListener.onCarrierConfigChanged(0 /* slotIndex */,
                 SubscriptionManager.INVALID_SUBSCRIPTION_ID,
-                TelephonyManager.UNKNOWN_CARRIER_ID, TelephonyManager.UNKNOWN_CARRIER_ID);
+                1, TelephonyManager.UNKNOWN_CARRIER_ID);
         processAllMessages();
-        assertNull(mCarrierKeyDM.mMccMncForDownload);
-        assertEquals(0, mCarrierKeyDM.mCarrierId);
+        assertEquals("310260", mCarrierKeyDM.mMccMncForDownload);
+        assertEquals(1, mCarrierKeyDM.mCarrierId);
     }
 
     @Test
@@ -391,6 +398,7 @@
     public void testUserLockedAfterCarrierConfigChanged() {
         // User is locked at beginning
         when(mUserManager.isUserUnlocked()).thenReturn(false);
+        when(mKeyguardManager.isDeviceLocked()).thenReturn(true);
         CarrierConfigManager carrierConfigManager = (CarrierConfigManager)
                 mContext.getSystemService(Context.CARRIER_CONFIG_SERVICE);
         int slotId = mPhone.getPhoneId();
@@ -399,17 +407,18 @@
         bundle.putString(CarrierConfigManager.IMSI_KEY_DOWNLOAD_URL_STRING, mURL);
 
         // Carrier config change received
-        when(mTelephonyManager.getSimOperator(anyInt())).thenReturn("310260");
-        when(mTelephonyManager.getSimCarrierId()).thenReturn(1);
+        when(mPhone.getOperatorNumeric()).thenReturn("310260");
+        when(mPhone.getCarrierId()).thenReturn(1);
         mCarrierConfigChangeListener.onCarrierConfigChanged(0 /* slotIndex */,
                 SubscriptionManager.INVALID_SUBSCRIPTION_ID,
-                TelephonyManager.UNKNOWN_CARRIER_ID, TelephonyManager.UNKNOWN_CARRIER_ID);
+                1, TelephonyManager.UNKNOWN_CARRIER_ID);
         processAllMessages();
 
         // User unlocked event received
-        Intent mIntent = new Intent(Intent.ACTION_USER_UNLOCKED);
+        Intent mIntent = new Intent(Intent.ACTION_USER_PRESENT);
         mContext.sendBroadcast(mIntent);
         when(mUserManager.isUserUnlocked()).thenReturn(true);
+        when(mKeyguardManager.isDeviceLocked()).thenReturn(false);
         processAllMessages();
 
         assertEquals("310260", mCarrierKeyDM.mMccMncForDownload);
@@ -432,11 +441,11 @@
 
         mCarrierConfigChangeListener.onCarrierConfigChanged(0 /* slotIndex */,
                 SubscriptionManager.INVALID_SUBSCRIPTION_ID,
-                TelephonyManager.UNKNOWN_CARRIER_ID, TelephonyManager.UNKNOWN_CARRIER_ID);
+                1, TelephonyManager.UNKNOWN_CARRIER_ID);
         processAllMessages();
-        assertNull(mCarrierKeyDM.mMccMncForDownload);
+        assertTrue(TextUtils.isEmpty(mCarrierKeyDM.mMccMncForDownload));
 
-        verify(mPhone).deleteCarrierInfoForImsiEncryption(0);
+        verify(mPhone).deleteCarrierInfoForImsiEncryption(1, "");
     }
 
     /**
@@ -453,8 +462,8 @@
         bundle.putInt(CarrierConfigManager.IMSI_KEY_AVAILABILITY_INT, 3);
         bundle.putString(CarrierConfigManager.IMSI_KEY_DOWNLOAD_URL_STRING, mURL);
 
-        when(mTelephonyManager.getSimOperator(anyInt())).thenReturn("310260");
-        when(mTelephonyManager.getSimCarrierId()).thenReturn(1);
+        when(mPhone.getOperatorNumeric()).thenReturn("310260");
+        when(mPhone.getCarrierId()).thenReturn(1);
         Intent mIntent = new Intent("com.android.internal.telephony.carrier_key_download_alarm");
         mIntent.putExtra(SubscriptionManager.EXTRA_SLOT_INDEX, slotIndex);
         mContext.sendBroadcast(mIntent);
@@ -493,4 +502,4 @@
         assertEquals(CarrierKeyDownloadManager
                 .cleanCertString("Comments before" + CERT + "Comments after"), CERT);
     }
-}
+}
\ No newline at end of file
diff --git a/tests/telephonytests/src/com/android/internal/telephony/GsmCdmaPhoneTest.java b/tests/telephonytests/src/com/android/internal/telephony/GsmCdmaPhoneTest.java
index 614846b..ba08f8b 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/GsmCdmaPhoneTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/GsmCdmaPhoneTest.java
@@ -3019,7 +3019,63 @@
         processAllMessages();
 
         verify(mNullCipherNotifier, times(1))
-                .onSecurityAlgorithmUpdate(eq(mContext), eq(0), eq(update));
+                .onSecurityAlgorithmUpdate(eq(mContext), eq(0), eq(0), eq(update));
+    }
+
+    @Test
+    public void testUpdateNullCipherNotifier_flagDisabled() {
+        when(mFeatureFlags.enableModemCipherTransparencyUnsolEvents()).thenReturn(false);
+        Phone phoneUT = makeNewPhoneUT();
+        phoneUT.sendMessage(
+                mPhoneUT.obtainMessage(
+                        Phone.EVENT_SUBSCRIPTIONS_CHANGED,
+                        new AsyncResult(null, null, null)));
+        processAllMessages();
+
+        verify(mNullCipherNotifier, never()).setSubscriptionMapping(any(), anyInt(), anyInt());
+    }
+
+    @Test
+    public void testUpdateNullCipherNotifier_activeSubscription() {
+        when(mFeatureFlags.enableModemCipherTransparencyUnsolEvents()).thenReturn(true);
+
+        int subId = 10;
+        SubscriptionInfoInternal subInfo = new SubscriptionInfoInternal.Builder().setSimSlotIndex(
+                0).setId(subId).build();
+        when(mSubscriptionManagerService.getSubscriptionInfoInternal(subId)).thenReturn(
+                subInfo);
+        doReturn(subId).when(mSubscriptionManagerService)
+                .getSubId(anyInt());
+        Phone phoneUT = makeNewPhoneUT();
+
+        phoneUT.sendMessage(
+                mPhoneUT.obtainMessage(
+                        Phone.EVENT_SUBSCRIPTIONS_CHANGED,
+                        new AsyncResult(null, null, null)));
+        processAllMessages();
+
+        verify(mNullCipherNotifier, times(1)).setSubscriptionMapping(eq(mContext), eq(0), eq(10));
+    }
+
+    @Test
+    public void testUpdateNullCipherNotifier_inactiveSubscription() {
+        when(mFeatureFlags.enableModemCipherTransparencyUnsolEvents()).thenReturn(true);
+        int subId = 1;
+        SubscriptionInfoInternal subInfo = new SubscriptionInfoInternal.Builder().setSimSlotIndex(
+                -1).setId(subId).build();
+        when(mSubscriptionManagerService.getSubscriptionInfoInternal(subId)).thenReturn(
+                subInfo);
+        doReturn(subId).when(mSubscriptionManagerService)
+                .getSubId(anyInt());
+        Phone phoneUT = makeNewPhoneUT();
+
+        phoneUT.sendMessage(
+                mPhoneUT.obtainMessage(
+                        Phone.EVENT_SUBSCRIPTIONS_CHANGED,
+                        new AsyncResult(null, null, null)));
+        processAllMessages();
+
+        verify(mNullCipherNotifier, times(1)).setSubscriptionMapping(eq(mContext), eq(0), eq(-1));
     }
 
     @Test
diff --git a/tests/telephonytests/src/com/android/internal/telephony/MultiSimSettingControllerTest.java b/tests/telephonytests/src/com/android/internal/telephony/MultiSimSettingControllerTest.java
index a7e9604..d1ab64d 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/MultiSimSettingControllerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/MultiSimSettingControllerTest.java
@@ -1007,4 +1007,57 @@
         // Default data is set to sub1
         verify(mSubscriptionManagerService).syncGroupedSetting(1);
     }
+
+    @Test
+    public void testDailogsAndWarnings_WithBootstrapSim() {
+        doReturn(true).when(mFeatureFlags).esimBootstrapProvisioningFlag();
+
+        // Mark sub 2 as inactive.
+        markSubscriptionInactive(2);
+        mMultiSimSettingControllerUT.notifyAllSubscriptionLoaded();
+        sendCarrierConfigChanged(0, 1);
+        processAllMessages();
+
+        // Sub 1 should be default sub silently.
+        verify(mSubscriptionManagerService).setDefaultDataSubId(1);
+        verify(mSubscriptionManagerService).setDefaultVoiceSubId(1);
+        verify(mSubscriptionManagerService).setDefaultSmsSubId(1);
+        verifyDismissIntentSent();
+
+        // Mark sub 2 bootstrap sim as active in phone[1].
+        doReturn(true).when(mSubscriptionManagerService).isEsimBootStrapProvisioningActivated();
+        setSimSlotIndex(2, 1);
+        clearInvocations(mSubscriptionManagerService);
+        clearInvocations(mContext);
+        mSubInfo[2] = new SubscriptionInfoInternal.Builder().setId(2).setSimSlotIndex(1)
+                .setProfileClass(SubscriptionManager.PROFILE_CLASS_PROVISIONING).build();
+        mMultiSimSettingControllerUT.notifySubscriptionInfoChanged();
+        sendCarrierConfigChanged(1, 2);
+        processAllMessages();
+
+        // Taking out SIM 1.
+        clearInvocations(mSubscriptionManagerService);
+        markSubscriptionInactive(1/*subid*/);
+        mMultiSimSettingControllerUT.notifySubscriptionInfoChanged();
+        sendCarrierConfigChanged(0/*phoneid*/, SubscriptionManager.INVALID_SUBSCRIPTION_ID);
+        processAllMessages();
+
+        // No user selection needed, no intent should be sent for notification
+        verify(mContext, never()).sendBroadcast(any());
+
+        //Insert back sim1 and switch from sub 1 to sub 3 in phone[0].
+        clearInvocations(mSubscriptionManagerService);
+        markSubscriptionInactive(1);
+        setSimSlotIndex(3, 0);
+        mMultiSimSettingControllerUT.notifySubscriptionInfoChanged();
+        sendCarrierConfigChanged(0/*phoneid*/, 3/*subid*/);
+        processAllMessages();
+
+        // Sub 3 should be default sub.
+        verify(mSubscriptionManagerService).setDefaultDataSubId(3);
+        verify(mSubscriptionManagerService).setDefaultVoiceSubId(3);
+        verify(mSubscriptionManagerService).setDefaultSmsSubId(3);
+        verify(mContext, never()).sendBroadcast(any());
+    }
+
 }
diff --git a/tests/telephonytests/src/com/android/internal/telephony/data/AccessNetworksManagerTest.java b/tests/telephonytests/src/com/android/internal/telephony/data/AccessNetworksManagerTest.java
index d1e5066..e45023c 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/data/AccessNetworksManagerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/data/AccessNetworksManagerTest.java
@@ -356,7 +356,7 @@
 
         mAccessNetworksManager.registerCallback(mMockedCallback);
 
-        mQnsCallback.onReconnectQualifedNetworkType(ApnSetting.TYPE_IMS | ApnSetting.TYPE_MMS,
+        mQnsCallback.onReconnectQualifiedNetworkType(ApnSetting.TYPE_IMS | ApnSetting.TYPE_MMS,
                 AccessNetworkType.IWLAN);
         processAllMessages();
 
@@ -381,7 +381,7 @@
     @Test
     public void testCallbackForReconnectQualifiedNetworkTypeWithFlagDisabled() throws Exception {
         when(mFeatureFlags.reconnectQualifiedNetwork()).thenReturn(false);
-        mQnsCallback.onReconnectQualifedNetworkType(ApnSetting.TYPE_IMS | ApnSetting.TYPE_MMS,
+        mQnsCallback.onReconnectQualifiedNetworkType(ApnSetting.TYPE_IMS | ApnSetting.TYPE_MMS,
                 AccessNetworkType.IWLAN);
         processAllMessages();
 
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 9423551..fecadd6 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/data/DataNetworkControllerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/data/DataNetworkControllerTest.java
@@ -182,7 +182,6 @@
     private LinkBandwidthEstimatorCallback mLinkBandwidthEstimatorCallback;
 
     private boolean mIsNonTerrestrialNetwork = false;
-    private ArrayList<Integer> mCarrierSupportedSatelliteServices = new ArrayList<>();
     private FeatureFlags mFeatureFlags;
 
     private final DataProfile mGeneralPurposeDataProfile = new DataProfile.Builder()
@@ -700,7 +699,6 @@
                 .setDomain(NetworkRegistrationInfo.DOMAIN_PS)
                 .setDataSpecificInfo(dsri)
                 .setIsNonTerrestrialNetwork(mIsNonTerrestrialNetwork)
-                .setAvailableServices(mCarrierSupportedSatelliteServices)
                 .setEmergencyOnly(isEmergencyOnly)
                 .build());
 
@@ -710,7 +708,6 @@
                 .setRegistrationState(iwlanRegState)
                 .setDomain(NetworkRegistrationInfo.DOMAIN_PS)
                 .setIsNonTerrestrialNetwork(mIsNonTerrestrialNetwork)
-                .setAvailableServices(mCarrierSupportedSatelliteServices)
                 .setEmergencyOnly(isEmergencyOnly)
                 .build());
 
@@ -854,6 +851,9 @@
                 .config_enable_iwlan_handover_policy, true);
         mContextFixture.putBooleanResource(com.android.internal.R.bool
                 .config_enhanced_iwlan_handover_check, true);
+        mContextFixture.putStringArrayResource(com.android.internal.R.array
+                .config_force_cellular_transport_capabilities,
+                new String[] {"ims", "eims", "xcap"});
     }
 
     @Before
@@ -896,6 +896,8 @@
         doReturn(PhoneConstants.State.IDLE).when(mCT).getState();
         doReturn(new SubscriptionInfoInternal.Builder().setId(1).build())
                 .when(mSubscriptionManagerService).getSubscriptionInfoInternal(anyInt());
+        doReturn(true).when(mFeatureFlags).carrierEnabledSatelliteFlag();
+        doReturn(true).when(mFeatureFlags).satelliteInternet();
 
         List<SubscriptionInfo> infoList = new ArrayList<>();
         infoList.add(mMockSubInfo);
@@ -1136,15 +1138,24 @@
     }
 
     private @NonNull TelephonyNetworkRequest createNetworkRequest(Integer... capabilities) {
+        return createNetworkRequest(false, capabilities);
+    }
+
+    private @NonNull TelephonyNetworkRequest createNetworkRequest(boolean restricted,
+                                                                  Integer... capabilities) {
         NetworkCapabilities netCaps = new NetworkCapabilities();
         for (int networkCapability : capabilities) {
             netCaps.addCapability(networkCapability);
         }
 
+        if (restricted) {
+            netCaps.removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED);
+        }
+
         NetworkRequest nativeNetworkRequest = new NetworkRequest(netCaps,
                 ConnectivityManager.TYPE_MOBILE, ++mNetworkRequestId, NetworkRequest.Type.REQUEST);
 
-        return new TelephonyNetworkRequest(nativeNetworkRequest, mPhone);
+        return new TelephonyNetworkRequest(nativeNetworkRequest, mPhone, mFeatureFlags);
     }
 
     // The purpose of this test is to make sure the network request insertion/removal works as
@@ -1405,7 +1416,7 @@
         netCaps.removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED);
         mDataNetworkControllerUT.addNetworkRequest(new TelephonyNetworkRequest(
                 new NetworkRequest(netCaps, ConnectivityManager.TYPE_MOBILE, ++mNetworkRequestId,
-                        NetworkRequest.Type.REQUEST), mPhone));
+                        NetworkRequest.Type.REQUEST), mPhone, mFeatureFlags));
         processAllMessages();
         verifyConnectedNetworkHasCapabilities(NetworkCapabilities.NET_CAPABILITY_ENTERPRISE);
         List<DataNetwork> dataNetworkList = getDataNetworks();
@@ -1708,72 +1719,123 @@
     }
 
     @Test
-    public void testNonTerrestrialNetworkChangedWithoutDataSupport() throws Exception {
-        when(mFeatureFlags.carrierEnabledSatelliteFlag()).thenReturn(true);
+    public void testIsNetworkRequestSatisfiedByTransportCellularTransportRequest() {
         mIsNonTerrestrialNetwork = true;
-        // Data is not supported while using satellite
-        mCarrierSupportedSatelliteServices.add(NetworkRegistrationInfo.SERVICE_TYPE_VOICE);
+
+        // Data is not supported for cellular transport network request while using satellite
+        // network
         serviceStateChanged(TelephonyManager.NETWORK_TYPE_LTE,
                 NetworkRegistrationInfo.REGISTRATION_STATE_HOME);
 
-        mDataNetworkControllerUT.addNetworkRequest(
-                createNetworkRequest(NetworkCapabilities.NET_CAPABILITY_INTERNET));
+        // Set network request transport as Cellular in satellite network
+        NetworkCapabilities netCaps = new NetworkCapabilities();
+        netCaps.addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR);
+        netCaps.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET);
+        netCaps.removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED);
+        mDataNetworkControllerUT.addNetworkRequest(new TelephonyNetworkRequest(
+                new NetworkRequest(netCaps, ConnectivityManager.TYPE_MOBILE, ++mNetworkRequestId,
+                        NetworkRequest.Type.REQUEST), mPhone, mFeatureFlags));
         processAllMessages();
 
-        // Data with internet capability should not be allowed
-        // when the device is using non-terrestrial network
-        verifyNoConnectedNetworkHasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET);
+        // Verify data is not connected since Network request cannot satisfy by transport
+        verify(mMockedDataNetworkControllerCallback, never())
+                .onConnectedInternetDataNetworksChanged(any());
 
         mIsNonTerrestrialNetwork = false;
-        mCarrierSupportedSatelliteServices.clear();
-        serviceStateChanged(TelephonyManager.NETWORK_TYPE_LTE,
-                NetworkRegistrationInfo.REGISTRATION_STATE_HOME);
-
-        // Verify data is restored.
-        verifyInternetConnected();
     }
 
     @Test
-    public void testNonTerrestrialNetworkWithDataSupport() throws Exception {
-        when(mFeatureFlags.carrierEnabledSatelliteFlag()).thenReturn(true);
-        mIsNonTerrestrialNetwork = true;
-        // Data is supported while using satellite
-        mCarrierSupportedSatelliteServices.add(NetworkRegistrationInfo.SERVICE_TYPE_DATA);
-        serviceStateChanged(TelephonyManager.NETWORK_TYPE_LTE,
-                NetworkRegistrationInfo.REGISTRATION_STATE_HOME);
-
-        mDataNetworkControllerUT.addNetworkRequest(
-                createNetworkRequest(NetworkCapabilities.NET_CAPABILITY_INTERNET));
+    public void testIsNetworkRequestSatisfiedByTransportSatelliteTransportRequest_Terrestrial() {
+        // Set network request transport as satellite in satellite network
+        NetworkCapabilities netCaps = new NetworkCapabilities();
+        netCaps.addTransportType(NetworkCapabilities.TRANSPORT_SATELLITE);
+        netCaps.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET);
+        netCaps.removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED);
+        mDataNetworkControllerUT.addNetworkRequest(new TelephonyNetworkRequest(
+                new NetworkRequest(netCaps, ConnectivityManager.TYPE_MOBILE, ++mNetworkRequestId,
+                        NetworkRequest.Type.REQUEST), mPhone, mFeatureFlags));
         processAllMessages();
 
-        // Verify data is connected.
-        verifyInternetConnected();
+        // Verify data is not supported for satellite transport network request while using cellular
+        verify(mMockedDataNetworkControllerCallback, never())
+                .onConnectedInternetDataNetworksChanged(any());
 
-        mIsNonTerrestrialNetwork = false;
-        mCarrierSupportedSatelliteServices.clear();
     }
 
     @Test
-    public void testNonTerrestrialNetworkWithFlagDisabled() throws Exception {
-        when(mFeatureFlags.carrierEnabledSatelliteFlag()).thenReturn(false);
-
+    public void testIsNetworkRequestSatisfiedByTransportSatelliteTransportRequest() {
         mIsNonTerrestrialNetwork = true;
-        // Data is not supported while using satellite
-        mCarrierSupportedSatelliteServices.add(NetworkRegistrationInfo.SERVICE_TYPE_VOICE);
+
+        // Data is supported for satellite transport network request while using satellite network
         serviceStateChanged(TelephonyManager.NETWORK_TYPE_LTE,
                 NetworkRegistrationInfo.REGISTRATION_STATE_HOME);
 
-        mDataNetworkControllerUT.addNetworkRequest(
-                createNetworkRequest(NetworkCapabilities.NET_CAPABILITY_INTERNET));
+        // Set network request transport as satellite while using satellite network
+        NetworkCapabilities netCaps = new NetworkCapabilities();
+        netCaps.addTransportType(NetworkCapabilities.TRANSPORT_SATELLITE);
+        netCaps.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET);
+        netCaps.removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED);
+        mDataNetworkControllerUT.addNetworkRequest(new TelephonyNetworkRequest(
+                new NetworkRequest(netCaps, ConnectivityManager.TYPE_MOBILE, ++mNetworkRequestId,
+                        NetworkRequest.Type.REQUEST), mPhone, mFeatureFlags));
         processAllMessages();
 
-        // As feature is disabled, data is connected.
-        verifyInternetConnected();
+        // Verify data is connected since Network request satisfy by transport
+        verify(mMockedDataNetworkControllerCallback).onConnectedInternetDataNetworksChanged(any());
 
         mIsNonTerrestrialNetwork = false;
-        mCarrierSupportedSatelliteServices.clear();
     }
 
+    @Test
+    public void testIsNetworkRequestSatisfiedByTransportNoTransportRequest() {
+        mIsNonTerrestrialNetwork = true;
+
+        // Data is supported for no transport network request while using satellite network
+        serviceStateChanged(TelephonyManager.NETWORK_TYPE_LTE,
+                NetworkRegistrationInfo.REGISTRATION_STATE_HOME);
+
+        // Set network request transport as no transport with Internet capability
+        NetworkCapabilities netCaps = new NetworkCapabilities();
+        netCaps.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET);
+        netCaps.removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED);
+        mDataNetworkControllerUT.addNetworkRequest(new TelephonyNetworkRequest(
+                new NetworkRequest(netCaps, ConnectivityManager.TYPE_MOBILE, ++mNetworkRequestId,
+                        NetworkRequest.Type.REQUEST), mPhone, mFeatureFlags));
+        processAllMessages();
+
+        // Verify data is connected since Network request satisfy by transport
+        verify(mMockedDataNetworkControllerCallback).onConnectedInternetDataNetworksChanged(any());
+
+        mIsNonTerrestrialNetwork = false;
+    }
+
+    @Test
+    public void testIsNetworkCapabilitySatelliteAndCellularCapableImsCellularTransportRequest()
+            throws Exception {
+        mIsNonTerrestrialNetwork = true;
+
+        // IMS PDN is supported for cellular network request while using satellite network
+        serviceStateChanged(TelephonyManager.NETWORK_TYPE_LTE,
+                NetworkRegistrationInfo.REGISTRATION_STATE_HOME);
+
+        // Set network request transport as Cellular + IMS
+        NetworkCapabilities netCaps = new NetworkCapabilities();
+        netCaps.addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR);
+        netCaps.addCapability(NetworkCapabilities.NET_CAPABILITY_IMS);
+        netCaps.addCapability(NetworkCapabilities.NET_CAPABILITY_MMTEL);
+        netCaps.removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED);
+        mDataNetworkControllerUT.addNetworkRequest(new TelephonyNetworkRequest(
+                new NetworkRequest(netCaps, ConnectivityManager.TYPE_MOBILE, ++mNetworkRequestId,
+                        NetworkRequest.Type.REQUEST), mPhone, mFeatureFlags));
+        processAllMessages();
+
+        // Verify ims is connected since, cellular network request for ims is allowed while using
+        // satellite network
+        verifyConnectedNetworkHasCapabilities(NetworkCapabilities.NET_CAPABILITY_IMS,
+                NetworkCapabilities.NET_CAPABILITY_MMTEL);
+
+        mIsNonTerrestrialNetwork = false;
+    }
 
     @Test
     public void testRoamingDataChanged() throws Exception {
@@ -3437,7 +3499,7 @@
                 .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
                 .removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED)
                 .build();
-        TelephonyNetworkRequest tnr = new TelephonyNetworkRequest(request, mPhone);
+        TelephonyNetworkRequest tnr = new TelephonyNetworkRequest(request, mPhone, mFeatureFlags);
 
         mDataNetworkControllerUT.addNetworkRequest(tnr);
         processAllMessages();
@@ -3461,7 +3523,7 @@
                 .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
                 .removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED)
                 .build();
-        TelephonyNetworkRequest tnr = new TelephonyNetworkRequest(request, mPhone);
+        TelephonyNetworkRequest tnr = new TelephonyNetworkRequest(request, mPhone, mFeatureFlags);
 
         mDataNetworkControllerUT.addNetworkRequest(tnr);
         processAllMessages();
@@ -3533,7 +3595,7 @@
                 ConnectivityManager.TYPE_MOBILE, ++mNetworkRequestId, NetworkRequest.Type.REQUEST);
 
         mDataNetworkControllerUT.addNetworkRequest(
-                new TelephonyNetworkRequest(nativeNetworkRequest, mPhone));
+                new TelephonyNetworkRequest(nativeNetworkRequest, mPhone, mFeatureFlags));
         processAllMessages();
 
         verifyConnectedNetworkHasCapabilities(NetworkCapabilities.NET_CAPABILITY_DUN);
@@ -3649,7 +3711,7 @@
                 ConnectivityManager.TYPE_MOBILE, ++mNetworkRequestId, NetworkRequest.Type.REQUEST);
 
         mDataNetworkControllerUT.addNetworkRequest(
-                new TelephonyNetworkRequest(nativeNetworkRequest, mPhone));
+                new TelephonyNetworkRequest(nativeNetworkRequest, mPhone, mFeatureFlags));
         processAllMessages();
 
         // Everything should be disconnected.
@@ -3687,7 +3749,7 @@
                 ConnectivityManager.TYPE_MOBILE, ++mNetworkRequestId, NetworkRequest.Type.REQUEST);
 
         mDataNetworkControllerUT.addNetworkRequest(
-                new TelephonyNetworkRequest(nativeNetworkRequest, mPhone));
+                new TelephonyNetworkRequest(nativeNetworkRequest, mPhone, mFeatureFlags));
         processAllMessages();
 
         // Everything should be disconnected.
@@ -3910,7 +3972,7 @@
                 ConnectivityManager.TYPE_MOBILE, ++mNetworkRequestId, NetworkRequest.Type.REQUEST);
 
         mDataNetworkControllerUT.addNetworkRequest(
-                new TelephonyNetworkRequest(nativeNetworkRequest, mPhone));
+                new TelephonyNetworkRequest(nativeNetworkRequest, mPhone, mFeatureFlags));
         processAllMessages();
 
         verifyConnectedNetworkHasDataProfile(mGeneralPurposeDataProfile);
@@ -3934,7 +3996,7 @@
                 ConnectivityManager.TYPE_MOBILE, ++mNetworkRequestId, NetworkRequest.Type.REQUEST);
 
         mDataNetworkControllerUT.addNetworkRequest(
-                new TelephonyNetworkRequest(nativeNetworkRequest, mPhone));
+                new TelephonyNetworkRequest(nativeNetworkRequest, mPhone, mFeatureFlags));
         processAllMessages();
 
         verifyConnectedNetworkHasDataProfile(mGeneralPurposeDataProfile);
@@ -3999,7 +4061,7 @@
         NetworkRequest nativeNetworkRequest = new NetworkRequest(netCaps,
                 ConnectivityManager.TYPE_MOBILE, ++mNetworkRequestId, NetworkRequest.Type.REQUEST);
         TelephonyNetworkRequest networkRequest = new TelephonyNetworkRequest(
-                nativeNetworkRequest, mPhone);
+                nativeNetworkRequest, mPhone, mFeatureFlags);
 
         mDataNetworkControllerUT.addNetworkRequest(networkRequest);
 
@@ -4051,7 +4113,7 @@
         NetworkRequest nativeNetworkRequest = new NetworkRequest(netCaps,
                 ConnectivityManager.TYPE_MOBILE, ++mNetworkRequestId, NetworkRequest.Type.REQUEST);
         TelephonyNetworkRequest networkRequest = new TelephonyNetworkRequest(
-                nativeNetworkRequest, mPhone);
+                nativeNetworkRequest, mPhone, mFeatureFlags);
 
         mDataNetworkControllerUT.addNetworkRequest(networkRequest);
         processAllMessages();
@@ -4693,11 +4755,12 @@
                 ConnectivityManager.TYPE_MOBILE, 0, NetworkRequest.Type.REQUEST);
 
         mDataNetworkControllerUT.addNetworkRequest(new TelephonyNetworkRequest(
-                nativeNetworkRequest, mPhone));
+                nativeNetworkRequest, mPhone, mFeatureFlags));
         processAllMessages();
 
         // Intentionally create a new telephony request with the original native network request.
-        TelephonyNetworkRequest request = new TelephonyNetworkRequest(nativeNetworkRequest, mPhone);
+        TelephonyNetworkRequest request = new TelephonyNetworkRequest(
+                nativeNetworkRequest, mPhone, mFeatureFlags);
 
         mDataNetworkControllerUT.removeNetworkRequest(request);
         processAllFutureMessages();
@@ -4788,7 +4851,7 @@
                 new NetworkRequest.Builder()
                         .addCapability(NetworkCapabilities.NET_CAPABILITY_ENTERPRISE)
                         .removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED)
-                        .build(), mPhone));
+                        .build(), mPhone, mFeatureFlags));
         processAllMessages();
         verifyConnectedNetworkHasCapabilities(NetworkCapabilities.NET_CAPABILITY_ENTERPRISE,
                 NetworkCapabilities.NET_CAPABILITY_PRIORITIZE_LATENCY);
@@ -4797,7 +4860,7 @@
                 new NetworkRequest.Builder()
                         .addCapability(NetworkCapabilities.NET_CAPABILITY_PRIORITIZE_LATENCY)
                         .removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED)
-                        .build(), mPhone));
+                        .build(), mPhone, mFeatureFlags));
         processAllMessages();
         List<DataNetwork> dataNetworkList = getDataNetworks();
         assertThat(dataNetworkList).hasSize(1);
@@ -4867,12 +4930,16 @@
 
     @Test
     public void testNonTerrestrialNetwork() throws Exception {
-        when(mFeatureFlags.carrierEnabledSatelliteFlag()).thenReturn(true);
         mIsNonTerrestrialNetwork = true;
         serviceStateChanged(TelephonyManager.NETWORK_TYPE_LTE,
                 NetworkRegistrationInfo.REGISTRATION_STATE_HOME);
         mDataNetworkControllerUT.addNetworkRequest(
-                createNetworkRequest(NetworkCapabilities.NET_CAPABILITY_RCS));
+                createNetworkRequest(false, NetworkCapabilities.NET_CAPABILITY_RCS));
+        processAllMessages();
+        verifyAllDataDisconnected();
+
+        mDataNetworkControllerUT.addNetworkRequest(
+                createNetworkRequest(true, NetworkCapabilities.NET_CAPABILITY_RCS));
         processAllMessages();
         verifyConnectedNetworkHasDataProfile(mNtnDataProfile);
     }
@@ -5031,8 +5098,7 @@
     }
 
     @Test
-    public void testNtnNetworkOnProvisioningProfileClass_WithFlagEnabled() throws Exception {
-        when(mFeatureFlags.carrierEnabledSatelliteFlag()).thenReturn(true);
+    public void testNtnNetworkOnProvisioningProfileClassWithFlagEnabled() throws Exception {
         when(mFeatureFlags.esimBootstrapProvisioningFlag()).thenReturn(true);
         // Allowed data limit Unlimited
         mContextFixture.putIntResource(com.android.internal.R.integer
@@ -5044,7 +5110,7 @@
         serviceStateChanged(TelephonyManager.NETWORK_TYPE_LTE,
                 NetworkRegistrationInfo.REGISTRATION_STATE_HOME);
         mDataNetworkControllerUT.addNetworkRequest(
-                createNetworkRequest(NetworkCapabilities.NET_CAPABILITY_RCS));
+                createNetworkRequest(true, NetworkCapabilities.NET_CAPABILITY_RCS));
         processAllMessages();
 
         assertThat(mDataNetworkControllerUT.isEsimBootStrapProvisioningActivated()).isTrue();
@@ -5053,8 +5119,7 @@
     }
 
     @Test
-    public void testNonNtnNetworkOnProvisioningProfileClass_WithFlagEnabled() throws Exception {
-        when(mFeatureFlags.carrierEnabledSatelliteFlag()).thenReturn(true);
+    public void testNonNtnNetworkOnProvisioningProfileClassWithFlagEnabled() throws Exception {
         when(mFeatureFlags.esimBootstrapProvisioningFlag()).thenReturn(true);
         doReturn(new SubscriptionInfoInternal.Builder().setId(1)
                 .setProfileClass(SubscriptionManager.PROFILE_CLASS_PROVISIONING).build())
diff --git a/tests/telephonytests/src/com/android/internal/telephony/data/DataNetworkTest.java b/tests/telephonytests/src/com/android/internal/telephony/data/DataNetworkTest.java
index ebfc41a..19502f5 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/data/DataNetworkTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/data/DataNetworkTest.java
@@ -320,13 +320,13 @@
     }
 
     private void serviceStateChanged(@Annotation.NetworkType int networkType,
-            @NetworkRegistrationInfo.RegistrationState int regState) {
-        serviceStateChanged(networkType, regState, null);
+            @NetworkRegistrationInfo.RegistrationState int regState, boolean isNtn) {
+        serviceStateChanged(networkType, regState, null, isNtn);
     }
 
     private void serviceStateChanged(@Annotation.NetworkType int networkType,
             @NetworkRegistrationInfo.RegistrationState int regState,
-            DataSpecificRegistrationInfo dsri) {
+            DataSpecificRegistrationInfo dsri, boolean isNtn) {
         ServiceState ss = new ServiceState();
         ss.addNetworkRegistrationInfo(new NetworkRegistrationInfo.Builder()
                 .setTransportType(AccessNetworkConstants.TRANSPORT_TYPE_WWAN)
@@ -334,6 +334,7 @@
                 .setRegistrationState(regState)
                 .setDomain(NetworkRegistrationInfo.DOMAIN_PS)
                 .setDataSpecificInfo(dsri)
+                .setIsNonTerrestrialNetwork(isNtn)
                 .build());
 
         ss.addNetworkRegistrationInfo(new NetworkRegistrationInfo.Builder()
@@ -410,9 +411,14 @@
         doReturn(FAKE_IMSI).when(mPhone).getSubscriberId();
         doReturn(true).when(mDataNetworkController)
                 .isNetworkRequestExisting(any(TelephonyNetworkRequest.class));
+        doReturn(Set.of(NetworkCapabilities.NET_CAPABILITY_IMS,
+                NetworkCapabilities.NET_CAPABILITY_EIMS, NetworkCapabilities.NET_CAPABILITY_XCAP))
+                .when(mDataConfigManager).getForcedCellularTransportCapabilities();
+        doReturn(true).when(mFeatureFlags).carrierEnabledSatelliteFlag();
+        doReturn(true).when(mFeatureFlags).satelliteInternet();
 
         serviceStateChanged(TelephonyManager.NETWORK_TYPE_LTE,
-                NetworkRegistrationInfo.REGISTRATION_STATE_HOME);
+                NetworkRegistrationInfo.REGISTRATION_STATE_HOME, false/*isNtn*/);
     }
 
     @After
@@ -446,7 +452,7 @@
         NetworkRequestList networkRequestList = new NetworkRequestList();
         networkRequestList.add(new TelephonyNetworkRequest(new NetworkRequest.Builder()
                 .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
-                .build(), mPhone));
+                .build(), mPhone, mFeatureFlags));
 
         setSuccessfulSetupDataResponse(
                 mMockedWwanDataServiceManager, 123, Collections.emptyList(), mDefaultQos);
@@ -551,12 +557,13 @@
                 .build();
         // Out of service
         serviceStateChanged(TelephonyManager.NETWORK_TYPE_LTE,
-                NetworkRegistrationInfo.REGISTRATION_STATE_NOT_REGISTERED_OR_SEARCHING, dsri);
+                NetworkRegistrationInfo.REGISTRATION_STATE_NOT_REGISTERED_OR_SEARCHING, dsri,
+                false/*isNtn*/);
 
         NetworkRequestList networkRequestList = new NetworkRequestList();
         networkRequestList.add(new TelephonyNetworkRequest(new NetworkRequest.Builder()
                 .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
-                .build(), mPhone));
+                .build(), mPhone, mFeatureFlags));
 
         setSuccessfulSetupDataResponse(mMockedWwanDataServiceManager, 123);
 
@@ -597,7 +604,8 @@
                 .build();
         // Out of service
         serviceStateChanged(TelephonyManager.NETWORK_TYPE_LTE,
-                NetworkRegistrationInfo.REGISTRATION_STATE_NOT_REGISTERED_OR_SEARCHING, dsri);
+                NetworkRegistrationInfo.REGISTRATION_STATE_NOT_REGISTERED_OR_SEARCHING, dsri,
+                false/*isNtn*/);
 
         DataCallResponse response = new DataCallResponse.Builder()
                 .setCause(0)
@@ -653,7 +661,7 @@
         NetworkRequestList networkRequestList = new NetworkRequestList();
         networkRequestList.add(new TelephonyNetworkRequest(new NetworkRequest.Builder()
                 .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
-                .build(), mPhone));
+                .build(), mPhone, mFeatureFlags));
         setSuccessfulSetupDataResponse(mMockedWwanDataServiceManager, 123);
 
         mDataNetworkUT = new DataNetwork(mPhone, mFeatureFlags, Looper.myLooper(),
@@ -742,7 +750,7 @@
         NetworkRequestList networkRequestList = new NetworkRequestList();
         networkRequestList.add(new TelephonyNetworkRequest(new NetworkRequest.Builder()
                 .addCapability(NetworkCapabilities.NET_CAPABILITY_ENTERPRISE)
-                .build(), mPhone));
+                .build(), mPhone, mFeatureFlags));
 
         List<TrafficDescriptor> tds = List.of(
                 new TrafficDescriptor(null, new TrafficDescriptor.OsAppId(
@@ -777,7 +785,7 @@
         NetworkRequestList networkRequestList = new NetworkRequestList();
         networkRequestList.add(new TelephonyNetworkRequest(new NetworkRequest.Builder()
                 .addCapability(NetworkCapabilities.NET_CAPABILITY_PRIORITIZE_LATENCY)
-                .build(), mPhone));
+                .build(), mPhone, mFeatureFlags));
 
         List<TrafficDescriptor> tds = List.of(
                 new TrafficDescriptor(null, new TrafficDescriptor.OsAppId(
@@ -810,7 +818,7 @@
         NetworkRequestList networkRequestList = new NetworkRequestList();
         networkRequestList.add(new TelephonyNetworkRequest(new NetworkRequest.Builder()
                 .addCapability(NetworkCapabilities.NET_CAPABILITY_PRIORITIZE_BANDWIDTH)
-                .build(), mPhone));
+                .build(), mPhone, mFeatureFlags));
 
         List<TrafficDescriptor> tds = List.of(
                 new TrafficDescriptor(null, new TrafficDescriptor.OsAppId(
@@ -843,7 +851,7 @@
         NetworkRequestList networkRequestList = new NetworkRequestList();
         networkRequestList.add(new TelephonyNetworkRequest(new NetworkRequest.Builder()
                 .addCapability(NetworkCapabilities.NET_CAPABILITY_CBS)
-                .build(), mPhone));
+                .build(), mPhone, mFeatureFlags));
 
         List<TrafficDescriptor> tds = List.of(
                 new TrafficDescriptor(null, new TrafficDescriptor.OsAppId(
@@ -877,7 +885,7 @@
         NetworkRequestList networkRequestList = new NetworkRequestList();
         networkRequestList.add(new TelephonyNetworkRequest(new NetworkRequest.Builder()
                 .addCapability(NetworkCapabilities.NET_CAPABILITY_CBS)
-                .build(), mPhone));
+                .build(), mPhone, mFeatureFlags));
 
         List<TrafficDescriptor> tds = List.of(
                 new TrafficDescriptor(null, new TrafficDescriptor.OsAppId(
@@ -962,7 +970,7 @@
         NetworkRequestList networkRequestList = new NetworkRequestList();
         networkRequestList.add(new TelephonyNetworkRequest(new NetworkRequest.Builder()
                 .addCapability(NetworkCapabilities.NET_CAPABILITY_IMS)
-                .build(), mPhone));
+                .build(), mPhone, mFeatureFlags));
 
         setSuccessfulSetupDataResponse(mMockedWlanDataServiceManager, 123);
 
@@ -1183,7 +1191,7 @@
         TelephonyNetworkRequest networkRequest = new TelephonyNetworkRequest(
                 new NetworkRequest.Builder()
                 .addCapability(NetworkCapabilities.NET_CAPABILITY_IMS)
-                .build(), mPhone);
+                .build(), mPhone, mFeatureFlags);
         networkRequestList.add(networkRequest);
 
         SimulatedCommands simulatedCommands2 = mock(SimulatedCommands.class);
@@ -1238,7 +1246,7 @@
         NetworkRequestList networkRequestList = new NetworkRequestList();
         networkRequestList.add(new TelephonyNetworkRequest(new NetworkRequest.Builder()
                 .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
-                .build(), mPhone));
+                .build(), mPhone, mFeatureFlags));
 
         setSuccessfulSetupDataResponse(mMockedWwanDataServiceManager, 123);
 
@@ -1335,7 +1343,7 @@
         networkRequestList.add(new TelephonyNetworkRequest(new NetworkRequest.Builder()
                 .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
                 .removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED)
-                .build(), mPhone));
+                .build(), mPhone, mFeatureFlags));
 
         // Data disabled
         doReturn(false).when(mDataSettingsManager).isDataEnabled();
@@ -1371,14 +1379,14 @@
     @Test
     public void testRestrictedNetworkDataRoamingEnabled() throws Exception {
         serviceStateChanged(TelephonyManager.NETWORK_TYPE_LTE,
-                NetworkRegistrationInfo.REGISTRATION_STATE_ROAMING);
+                NetworkRegistrationInfo.REGISTRATION_STATE_ROAMING, false/*isNtn*/);
 
         NetworkRequestList networkRequestList = new NetworkRequestList();
         // Restricted network request
         networkRequestList.add(new TelephonyNetworkRequest(new NetworkRequest.Builder()
                 .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
                 .removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED)
-                .build(), mPhone));
+                .build(), mPhone, mFeatureFlags));
 
         // Data roaming disabled
         doReturn(false).when(mDataSettingsManager).isDataRoamingEnabled();
@@ -1516,7 +1524,7 @@
         NetworkRequestList networkRequestList = new NetworkRequestList();
         networkRequestList.add(new TelephonyNetworkRequest(new NetworkRequest.Builder()
                 .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
-                .build(), mPhone));
+                .build(), mPhone, mFeatureFlags));
         mDataNetworkUT = new DataNetwork(mPhone, mFeatureFlags, Looper.myLooper(),
                 mDataServiceManagers, mInternetDataProfile, networkRequestList,
                 AccessNetworkConstants.TRANSPORT_TYPE_WWAN,
@@ -1620,7 +1628,7 @@
                         LteVopsSupportInfo.LTE_STATUS_SUPPORTED))
                 .build();
         serviceStateChanged(TelephonyManager.NETWORK_TYPE_LTE,
-                NetworkRegistrationInfo.REGISTRATION_STATE_HOME, dsri);
+                NetworkRegistrationInfo.REGISTRATION_STATE_HOME, dsri, false/*isNtn*/);
 
         assertThat(mDataNetworkUT.getNetworkCapabilities().hasCapability(
                 NetworkCapabilities.NET_CAPABILITY_MMTEL)).isTrue();
@@ -1634,7 +1642,7 @@
                 .build();
         logd("Trigger non VoPS");
         serviceStateChanged(TelephonyManager.NETWORK_TYPE_LTE,
-                NetworkRegistrationInfo.REGISTRATION_STATE_HOME, dsri);
+                NetworkRegistrationInfo.REGISTRATION_STATE_HOME, dsri, false/*isNtn*/);
         // MMTEL should not be removed.
         assertThat(mDataNetworkUT.getNetworkCapabilities().hasCapability(
                 NetworkCapabilities.NET_CAPABILITY_MMTEL)).isTrue();
@@ -1651,7 +1659,7 @@
                         LteVopsSupportInfo.LTE_STATUS_SUPPORTED))
                 .build();
         serviceStateChanged(TelephonyManager.NETWORK_TYPE_LTE,
-                NetworkRegistrationInfo.REGISTRATION_STATE_HOME, dsri);
+                NetworkRegistrationInfo.REGISTRATION_STATE_HOME, dsri, false/*isNtn*/);
 
         assertThat(mDataNetworkUT.getNetworkCapabilities().hasCapability(
                 NetworkCapabilities.NET_CAPABILITY_MMTEL)).isTrue();
@@ -1665,7 +1673,7 @@
                 .build();
         logd("Trigger non VoPS");
         serviceStateChanged(TelephonyManager.NETWORK_TYPE_LTE,
-                NetworkRegistrationInfo.REGISTRATION_STATE_HOME, dsri);
+                NetworkRegistrationInfo.REGISTRATION_STATE_HOME, dsri, false/*isNtn*/);
         // MMTEL should be removed to reflect the actual Vops status.
         assertThat(mDataNetworkUT.getNetworkCapabilities().hasCapability(
                 NetworkCapabilities.NET_CAPABILITY_MMTEL)).isFalse();
@@ -1724,7 +1732,7 @@
 
         TelephonyNetworkRequest networkRequest = new TelephonyNetworkRequest(
                 new NetworkRequest.Builder().addCapability(
-                        NetworkCapabilities.NET_CAPABILITY_SUPL).build(), mPhone);
+                        NetworkCapabilities.NET_CAPABILITY_SUPL).build(), mPhone, mFeatureFlags);
         mDataNetworkUT.attachNetworkRequests(new NetworkRequestList(networkRequest));
         processAllMessages();
 
@@ -1747,7 +1755,7 @@
 
         TelephonyNetworkRequest networkRequest = new TelephonyNetworkRequest(
                 new NetworkRequest.Builder().addCapability(
-                        NetworkCapabilities.NET_CAPABILITY_SUPL).build(), mPhone);
+                        NetworkCapabilities.NET_CAPABILITY_SUPL).build(), mPhone, mFeatureFlags);
         mDataNetworkUT.attachNetworkRequests(new NetworkRequestList(networkRequest));
         processAllMessages();
 
@@ -1900,7 +1908,7 @@
         NetworkRequestList networkRequestList = new NetworkRequestList();
         networkRequestList.add(new TelephonyNetworkRequest(new NetworkRequest.Builder()
                 .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
-                .build(), mPhone));
+                .build(), mPhone, mFeatureFlags));
 
         mDataNetworkUT = new DataNetwork(mPhone, mFeatureFlags, Looper.myLooper(),
                 mDataServiceManagers, mInternetDataProfile, networkRequestList,
@@ -2044,7 +2052,7 @@
         NetworkRequestList networkRequestList = new NetworkRequestList();
         networkRequestList.add(new TelephonyNetworkRequest(new NetworkRequest.Builder()
                 .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
-                .build(), mPhone));
+                .build(), mPhone, mFeatureFlags));
         mDataNetworkUT = new DataNetwork(mPhone, mFeatureFlags, Looper.myLooper(),
                 mDataServiceManagers, m5gDataProfile, networkRequestList,
                 AccessNetworkConstants.TRANSPORT_TYPE_WWAN, DataAllowedReason.NORMAL,
@@ -2141,7 +2149,7 @@
         NetworkRequest.Builder builder = new NetworkRequest.Builder()
                 .addCapability(NetworkCapabilities.NET_CAPABILITY_IMS);
         builder.addCapability(NetworkCapabilities.NET_CAPABILITY_MMTEL);
-        networkRequestList.add(new TelephonyNetworkRequest(builder.build(), mPhone));
+        networkRequestList.add(new TelephonyNetworkRequest(builder.build(), mPhone, mFeatureFlags));
         mDataNetworkUT = new DataNetwork(mPhone, mFeatureFlags, Looper.myLooper(),
                 mDataServiceManagers, mImsDataProfile, networkRequestList,
                 AccessNetworkConstants.TRANSPORT_TYPE_WLAN,
@@ -2248,7 +2256,7 @@
         NetworkRequestList networkRequestList = new NetworkRequestList();
         networkRequestList.add(new TelephonyNetworkRequest(new NetworkRequest.Builder()
                 .addCapability(NetworkCapabilities.NET_CAPABILITY_IMS)
-                .build(), mPhone));
+                .build(), mPhone, mFeatureFlags));
         setSuccessfulSetupDataResponse(mMockedWlanDataServiceManager, 123);
         mDataNetworkUT = new DataNetwork(mPhone, mFeatureFlags, Looper.myLooper(),
                 mDataServiceManagers, mImsDataProfile, networkRequestList,
@@ -2264,7 +2272,7 @@
         NetworkRequest.Builder builder = new NetworkRequest.Builder()
                 .addCapability(NetworkCapabilities.NET_CAPABILITY_IMS);
         if (isMmtel) builder.addCapability(NetworkCapabilities.NET_CAPABILITY_MMTEL);
-        networkRequestList.add(new TelephonyNetworkRequest(builder.build(), mPhone));
+        networkRequestList.add(new TelephonyNetworkRequest(builder.build(), mPhone, mFeatureFlags));
 
         setSuccessfulSetupDataResponse(mMockedWwanDataServiceManager, 123);
 
@@ -2277,6 +2285,37 @@
         processAllMessages();
     }
 
+    private void setupNonTerrestrialDataNetwork() {
+        NetworkRequestList networkRequestList = new NetworkRequestList();
+
+        networkRequestList.add(new TelephonyNetworkRequest(new NetworkRequest.Builder()
+                .addTransportType(NetworkCapabilities.TRANSPORT_SATELLITE)
+                .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
+                .removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED)
+                .build(), mPhone, mFeatureFlags));
+        setSuccessfulSetupDataResponse(mMockedWwanDataServiceManager, 123);
+
+        mDataNetworkUT = new DataNetwork(mPhone, mFeatureFlags, Looper.myLooper(),
+                mDataServiceManagers, mInternetDataProfile, networkRequestList,
+                AccessNetworkConstants.TRANSPORT_TYPE_WWAN,
+                DataAllowedReason.NORMAL, mDataNetworkCallback);
+        processAllMessages();
+    }
+
+    private void setupTerrestrialDataNetwork() {
+        NetworkRequestList networkRequestList = new NetworkRequestList();
+        networkRequestList.add(new TelephonyNetworkRequest(new NetworkRequest.Builder()
+                .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
+                .build(), mPhone, mFeatureFlags));
+        setSuccessfulSetupDataResponse(mMockedWwanDataServiceManager, 123);
+
+        mDataNetworkUT = new DataNetwork(mPhone, mFeatureFlags, Looper.myLooper(),
+                mDataServiceManagers, mInternetDataProfile, networkRequestList,
+                AccessNetworkConstants.TRANSPORT_TYPE_WWAN,
+                DataAllowedReason.NORMAL, mDataNetworkCallback);
+        processAllMessages();
+    }
+
     @Test
     public void testMmsCapabilityRemovedWhenMmsPreferredOnIwlan() throws Exception {
         doReturn(true).when(mFeatureFlags).forceIwlanMms();
@@ -2355,4 +2394,104 @@
 
         verify(mDataNetworkCallback).onQosSessionsChanged(newQosSessions);
     }
+
+    @Test
+    public void testIsTransportSatelliteSupportNonImsNonTerrestrialNetwork() throws Exception {
+        // Service state at Non-terrestrial network
+        serviceStateChanged(TelephonyManager.NETWORK_TYPE_LTE,
+                NetworkRegistrationInfo.REGISTRATION_STATE_HOME, true/*isNtn*/);
+
+        // set up data network with transport type satellite + Internet
+        setupNonTerrestrialDataNetwork();
+
+        //Check now transport type for the data network is satellite
+        assertThat(mDataNetworkUT.getNetworkCapabilities()
+                .hasTransport(NetworkCapabilities.TRANSPORT_SATELLITE)).isTrue();
+    }
+
+    @Test
+    public void testIsTransportSatelliteSupportWithImsNonTerrestrialNetwork() throws Exception {
+        // Service state at Non-terrestrial network
+        serviceStateChanged(TelephonyManager.NETWORK_TYPE_LTE,
+                NetworkRegistrationInfo.REGISTRATION_STATE_HOME, true/*isNtn*/);
+
+        // set up data network with transport type satellite + IMS
+        createImsDataNetwork(false/*isMmtel*/);
+
+        //Check transport type for the data network is Cellular for Ims at non-terrestrial network
+        assertThat(mDataNetworkUT.getNetworkCapabilities()
+                .hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)).isTrue();
+    }
+
+    @Test
+    public void testSatelliteTransportSupportedNonImsTerrestrialToNonTerrestrial()
+            throws Exception {
+        // Service state at terrestrial network
+        serviceStateChanged(TelephonyManager.NETWORK_TYPE_LTE,
+                NetworkRegistrationInfo.REGISTRATION_STATE_HOME, false/*isNtn*/);
+
+        // set up data network with transport type cellular + Internet
+        setupTerrestrialDataNetwork();
+        assertThat(mDataNetworkUT.getNetworkCapabilities()
+                .hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)).isTrue();
+
+        // Service State change terrestrial to non-terrestrial
+        serviceStateChanged(TelephonyManager.NETWORK_TYPE_LTE,
+                NetworkRegistrationInfo.REGISTRATION_STATE_HOME, true/*isNtn*/);
+
+        // Make sure transport type for the data network is still Cellular
+        assertThat(mDataNetworkUT.getNetworkCapabilities()
+                .hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)).isTrue();
+        assertThat(mDataNetworkUT.getNetworkCapabilities()
+                .hasTransport(NetworkCapabilities.TRANSPORT_SATELLITE)).isFalse();
+
+        // Disconnect the Data call
+        mDataNetworkUT.sendMessage(19/*EVENT_DEACTIVATE_DATA_NETWORK_RESPONSE*/, 0/*Success*/);
+        processAllMessages();
+
+        // set up data network with transport type satellite + Internet
+        setupNonTerrestrialDataNetwork();
+
+        //Check now transport type for the data network is satellite
+        assertThat(mDataNetworkUT.getNetworkCapabilities()
+                .hasTransport(NetworkCapabilities.TRANSPORT_SATELLITE)).isTrue();
+    }
+
+    @Test
+    public void testSatelliteTransportSupportedNonImsNonTerrestrialToTerrestrial()
+            throws Exception {
+        // Service state at non-terrestrial network
+        serviceStateChanged(TelephonyManager.NETWORK_TYPE_LTE,
+                NetworkRegistrationInfo.REGISTRATION_STATE_HOME, true/*isNtn*/);
+
+        // set up data network with transport type satellite + Internet
+        setupNonTerrestrialDataNetwork();
+
+        //Check now transport type for the data network is satellite
+        assertThat(mDataNetworkUT.getNetworkCapabilities()
+                .hasTransport(NetworkCapabilities.TRANSPORT_SATELLITE)).isTrue();
+
+        // Service State change non-terrestrial to terrestrial
+        serviceStateChanged(TelephonyManager.NETWORK_TYPE_LTE,
+                NetworkRegistrationInfo.REGISTRATION_STATE_HOME, false/*isNtn*/);
+
+        // Make sure transport type for the data network is still satellite
+        assertThat(mDataNetworkUT.getNetworkCapabilities()
+                .hasTransport(NetworkCapabilities.TRANSPORT_SATELLITE)).isTrue();
+
+        // Make sure transport type for the data network is not cellular
+        assertThat(mDataNetworkUT.getNetworkCapabilities()
+                .hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)).isFalse();
+
+        // Disconnect the Data call
+        mDataNetworkUT.sendMessage(19/*EVENT_DEACTIVATE_DATA_NETWORK_RESPONSE*/, 0/*Success*/);
+        processAllMessages();
+
+        // set up data network with transport type cellular + Internet
+        setupTerrestrialDataNetwork();
+
+        //Check now transport type for the data network is cellular
+        assertThat(mDataNetworkUT.getNetworkCapabilities()
+                .hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)).isTrue();
+    }
 }
diff --git a/tests/telephonytests/src/com/android/internal/telephony/data/DataProfileManagerTest.java b/tests/telephonytests/src/com/android/internal/telephony/data/DataProfileManagerTest.java
index 44d207d..3d6b4f4 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/data/DataProfileManagerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/data/DataProfileManagerTest.java
@@ -888,7 +888,7 @@
         NetworkRequest request = new NetworkRequest.Builder()
                 .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
                 .build();
-        TelephonyNetworkRequest tnr = new TelephonyNetworkRequest(request, mPhone);
+        TelephonyNetworkRequest tnr = new TelephonyNetworkRequest(request, mPhone, mFeatureFlags);
         DataProfile dp = mDataProfileManagerUT.getDataProfileForNetworkRequest(tnr,
                 TelephonyManager.NETWORK_TYPE_LTE, false, false, false);
 
@@ -899,7 +899,7 @@
                 .addCapability(NetworkCapabilities.NET_CAPABILITY_MMS)
                 .addCapability(NetworkCapabilities.NET_CAPABILITY_SUPL)
                 .build();
-        tnr = new TelephonyNetworkRequest(request, mPhone);
+        tnr = new TelephonyNetworkRequest(request, mPhone, mFeatureFlags);
         dp = mDataProfileManagerUT.getDataProfileForNetworkRequest(tnr,
                 TelephonyManager.NETWORK_TYPE_LTE, false, false, false);
 
@@ -909,7 +909,7 @@
         request = new NetworkRequest.Builder()
                 .addCapability(NetworkCapabilities.NET_CAPABILITY_IMS)
                 .build();
-        tnr = new TelephonyNetworkRequest(request, mPhone);
+        tnr = new TelephonyNetworkRequest(request, mPhone, mFeatureFlags);
         dp = mDataProfileManagerUT.getDataProfileForNetworkRequest(tnr,
                 TelephonyManager.NETWORK_TYPE_LTE, false, false, false);
         assertThat(dp.canSatisfy(tnr.getCapabilities())).isTrue();
@@ -918,7 +918,7 @@
         request = new NetworkRequest.Builder()
                 .addCapability(NetworkCapabilities.NET_CAPABILITY_DUN)
                 .build();
-        tnr = new TelephonyNetworkRequest(request, mPhone);
+        tnr = new TelephonyNetworkRequest(request, mPhone, mFeatureFlags);
         dp = mDataProfileManagerUT.getDataProfileForNetworkRequest(tnr,
                 TelephonyManager.NETWORK_TYPE_LTE, false, false, false);
         assertThat(dp).isNull();
@@ -931,7 +931,7 @@
         request = new NetworkRequest.Builder()
                 .addCapability(NetworkCapabilities.NET_CAPABILITY_DUN)
                 .build();
-        tnr = new TelephonyNetworkRequest(request, mPhone);
+        tnr = new TelephonyNetworkRequest(request, mPhone, mFeatureFlags);
         dp = mDataProfileManagerUT.getDataProfileForNetworkRequest(tnr,
                 TelephonyManager.NETWORK_TYPE_NR, false, false , false);
         assertThat(dp.canSatisfy(tnr.getCapabilities())).isTrue();
@@ -943,7 +943,7 @@
         NetworkRequest request = new NetworkRequest.Builder()
                 .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
                 .build();
-        TelephonyNetworkRequest tnr = new TelephonyNetworkRequest(request, mPhone);
+        TelephonyNetworkRequest tnr = new TelephonyNetworkRequest(request, mPhone, mFeatureFlags);
         DataProfile dp = mDataProfileManagerUT.getDataProfileForNetworkRequest(tnr,
                 TelephonyManager.NETWORK_TYPE_GSM, false, false, false);
         // Should not find data profile due to RAT incompatible.
@@ -955,7 +955,7 @@
         TelephonyNetworkRequest tnr = new TelephonyNetworkRequest(
                 new NetworkRequest.Builder()
                         .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
-                        .build(), mPhone);
+                        .build(), mPhone, mFeatureFlags);
         DataProfile dataProfile = mDataProfileManagerUT.getDataProfileForNetworkRequest(
                 tnr, TelephonyManager.NETWORK_TYPE_LTE, false, false, false);
         assertThat(dataProfile.getApnSetting().getApnName()).isEqualTo(GENERAL_PURPOSE_APN);
@@ -973,7 +973,7 @@
         TelephonyNetworkRequest tnr = new TelephonyNetworkRequest(
                 new NetworkRequest.Builder()
                         .addCapability(NetworkCapabilities.NET_CAPABILITY_ENTERPRISE)
-                        .build(), mPhone);
+                        .build(), mPhone, mFeatureFlags);
         DataProfile dataProfile = mDataProfileManagerUT.getDataProfileForNetworkRequest(
                 tnr, TelephonyManager.NETWORK_TYPE_LTE, false, false, false);
         assertThat(dataProfile.getApnSetting()).isNull();
@@ -986,7 +986,7 @@
         tnr = new TelephonyNetworkRequest(new NetworkRequest(new NetworkCapabilities()
                 .addCapability(NetworkCapabilities.NET_CAPABILITY_ENTERPRISE)
                 .addEnterpriseId(2), ConnectivityManager.TYPE_NONE,
-                0, NetworkRequest.Type.REQUEST), mPhone);
+                0, NetworkRequest.Type.REQUEST), mPhone, mFeatureFlags);
         dataProfile = mDataProfileManagerUT.getDataProfileForNetworkRequest(
                 tnr, TelephonyManager.NETWORK_TYPE_LTE, false, false, false);
         assertThat(dataProfile.getApnSetting()).isNull();
@@ -1002,7 +1002,7 @@
         TelephonyNetworkRequest tnr = new TelephonyNetworkRequest(
                 new NetworkRequest.Builder()
                         .addCapability(NetworkCapabilities.NET_CAPABILITY_PRIORITIZE_LATENCY)
-                        .build(), mPhone);
+                        .build(), mPhone, mFeatureFlags);
         DataProfile dataProfile = mDataProfileManagerUT.getDataProfileForNetworkRequest(
                 tnr, TelephonyManager.NETWORK_TYPE_LTE, false, false, false);
         assertThat(dataProfile.getApnSetting()).isNull();
@@ -1018,7 +1018,7 @@
         TelephonyNetworkRequest tnr = new TelephonyNetworkRequest(
                 new NetworkRequest.Builder()
                         .addCapability(NetworkCapabilities.NET_CAPABILITY_PRIORITIZE_BANDWIDTH)
-                        .build(), mPhone);
+                        .build(), mPhone, mFeatureFlags);
         DataProfile dataProfile = mDataProfileManagerUT.getDataProfileForNetworkRequest(
                 tnr, TelephonyManager.NETWORK_TYPE_LTE, false, false, false);
         assertThat(dataProfile.getApnSetting()).isNull();
@@ -1036,7 +1036,7 @@
         NetworkRequest request = new NetworkRequest.Builder()
                 .addCapability(NetworkCapabilities.NET_CAPABILITY_RCS)
                 .build();
-        TelephonyNetworkRequest tnr = new TelephonyNetworkRequest(request, mPhone);
+        TelephonyNetworkRequest tnr = new TelephonyNetworkRequest(request, mPhone, mFeatureFlags);
         DataProfile dp = mDataProfileManagerUT.getDataProfileForNetworkRequest(tnr,
                 TelephonyManager.NETWORK_TYPE_LTE, true, false, false);
 
@@ -1050,7 +1050,7 @@
         TelephonyNetworkRequest tnr = new TelephonyNetworkRequest(
                 new NetworkRequest.Builder()
                         .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
-                        .build(), mPhone);
+                        .build(), mPhone, mFeatureFlags);
         DataProfile dataProfile = mDataProfileManagerUT.getDataProfileForNetworkRequest(
                 tnr, TelephonyManager.NETWORK_TYPE_LTE, false, false, false);
         assertThat(dataProfile.getApnSetting().getApnName()).isEqualTo(GENERAL_PURPOSE_APN);
@@ -1090,7 +1090,7 @@
         TelephonyNetworkRequest dunTnr = new TelephonyNetworkRequest(
                 new NetworkRequest.Builder()
                         .addCapability(NetworkCapabilities.NET_CAPABILITY_DUN)
-                        .build(), mPhone);
+                        .build(), mPhone, mFeatureFlags);
         DataProfile dunDataProfile = mDataProfileManagerUT.getDataProfileForNetworkRequest(
                 dunTnr, TelephonyManager.NETWORK_TYPE_LTE, false, false, false);
         DataNetwork dunInternetNetwork = Mockito.mock(DataNetwork.class);
@@ -1189,7 +1189,7 @@
         TelephonyNetworkRequest tnr = new TelephonyNetworkRequest(
                 new NetworkRequest.Builder()
                         .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
-                        .build(), mPhone);
+                        .build(), mPhone, mFeatureFlags);
         DataProfile dataProfile = mDataProfileManagerUT.getDataProfileForNetworkRequest(
                 tnr, TelephonyManager.NETWORK_TYPE_LTE, false, false, false);
         assertThat(dataProfile).isNull();
@@ -1198,7 +1198,7 @@
         tnr = new TelephonyNetworkRequest(
                 new NetworkRequest.Builder()
                         .addCapability(NetworkCapabilities.NET_CAPABILITY_EIMS)
-                        .build(), mPhone);
+                        .build(), mPhone, mFeatureFlags);
         dataProfile = mDataProfileManagerUT.getDataProfileForNetworkRequest(
                 tnr, TelephonyManager.NETWORK_TYPE_LTE, false, false, false);
         assertThat(dataProfile.getApnSetting().getApnName()).isEqualTo("sos");
@@ -1207,7 +1207,7 @@
         tnr = new TelephonyNetworkRequest(
                 new NetworkRequest.Builder()
                         .addCapability(NetworkCapabilities.NET_CAPABILITY_IMS)
-                        .build(), mPhone);
+                        .build(), mPhone, mFeatureFlags);
         dataProfile = mDataProfileManagerUT.getDataProfileForNetworkRequest(
                 tnr, TelephonyManager.NETWORK_TYPE_LTE, false, false, false);
         assertThat(dataProfile).isEqualTo(null);
@@ -1237,7 +1237,7 @@
         TelephonyNetworkRequest tnr = new TelephonyNetworkRequest(
                 new NetworkRequest.Builder()
                         .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
-                        .build(), mPhone);
+                        .build(), mPhone, mFeatureFlags);
         DataProfile dataProfile = mDataProfileManagerUT.getDataProfileForNetworkRequest(
                 tnr, TelephonyManager.NETWORK_TYPE_LTE, false, false, false);
         assertThat(dataProfile).isNull();
@@ -1246,7 +1246,7 @@
         tnr = new TelephonyNetworkRequest(
                 new NetworkRequest.Builder()
                         .addCapability(NetworkCapabilities.NET_CAPABILITY_EIMS)
-                        .build(), mPhone);
+                        .build(), mPhone, mFeatureFlags);
         dataProfile = mDataProfileManagerUT.getDataProfileForNetworkRequest(
                 tnr, TelephonyManager.NETWORK_TYPE_LTE, false, false, false);
         assertThat(dataProfile.getApnSetting().getApnName()).isEqualTo("sos");
@@ -1255,7 +1255,7 @@
         tnr = new TelephonyNetworkRequest(
                 new NetworkRequest.Builder()
                         .addCapability(NetworkCapabilities.NET_CAPABILITY_IMS)
-                        .build(), mPhone);
+                        .build(), mPhone, mFeatureFlags);
         dataProfile = mDataProfileManagerUT.getDataProfileForNetworkRequest(
                 tnr, TelephonyManager.NETWORK_TYPE_LTE, false, false, false);
         assertThat(dataProfile).isEqualTo(null);
@@ -1291,7 +1291,7 @@
         DataProfile dataProfile = mDataProfileManagerUT.getDataProfileForNetworkRequest(
                 new TelephonyNetworkRequest(new NetworkRequest.Builder()
                         .addCapability(NetworkCapabilities.NET_CAPABILITY_IMS)
-                        .build(), mPhone),
+                        .build(), mPhone, mFeatureFlags),
                 TelephonyManager.NETWORK_TYPE_LTE, false, false, false);
         assertThat(dataProfile.getApnSetting().getApnName()).isEqualTo(IMS_APN);
     }
@@ -1301,7 +1301,7 @@
         NetworkRequest request = new NetworkRequest.Builder()
                 .addCapability(NetworkCapabilities.NET_CAPABILITY_FOTA)
                 .build();
-        TelephonyNetworkRequest tnr = new TelephonyNetworkRequest(request, mPhone);
+        TelephonyNetworkRequest tnr = new TelephonyNetworkRequest(request, mPhone, mFeatureFlags);
         // This should get the merged data profile after deduping.
         DataProfile dp = mDataProfileManagerUT.getDataProfileForNetworkRequest(tnr,
                 TelephonyManager.NETWORK_TYPE_LTE, false, false, false);
@@ -1439,7 +1439,7 @@
     public void testDefaultEmergencyDataProfileValid() {
         TelephonyNetworkRequest tnr = new TelephonyNetworkRequest(new NetworkRequest.Builder()
                 .addCapability(NetworkCapabilities.NET_CAPABILITY_EIMS)
-                .build(), mPhone);
+                .build(), mPhone, mFeatureFlags);
         DataProfile dataProfile = mDataProfileManagerUT.getDataProfileForNetworkRequest(
                 tnr, TelephonyManager.NETWORK_TYPE_LTE, false, false, false);
 
@@ -1456,7 +1456,7 @@
         TelephonyNetworkRequest tnr = new TelephonyNetworkRequest(
                 new NetworkRequest.Builder()
                         .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
-                        .build(), mPhone);
+                        .build(), mPhone, mFeatureFlags);
         DataProfile dataProfile = mDataProfileManagerUT.getDataProfileForNetworkRequest(
                 tnr, TelephonyManager.NETWORK_TYPE_LTE, false, false, false);
         assertThat(dataProfile.getApnSetting().getApnName()).isEqualTo(GENERAL_PURPOSE_APN);
@@ -1522,7 +1522,7 @@
         TelephonyNetworkRequest tnr = new TelephonyNetworkRequest(
                 new NetworkRequest.Builder()
                         .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
-                        .build(), mPhone);
+                        .build(), mPhone, mFeatureFlags);
         changeSimStateTo(TelephonyManager.SIM_STATE_LOADED);
         mDataProfileManagerUT.obtainMessage(2 /*EVENT_APN_DATABASE_CHANGED*/).sendToTarget();
         processAllMessages();
@@ -1828,7 +1828,7 @@
         NetworkRequest request = new NetworkRequest.Builder()
                 .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
                 .build();
-        TelephonyNetworkRequest tnr = new TelephonyNetworkRequest(request, mPhone);
+        TelephonyNetworkRequest tnr = new TelephonyNetworkRequest(request, mPhone, mFeatureFlags);
         DataProfile dp = mDataProfileManagerUT.getDataProfileForNetworkRequest(tnr,
                 TelephonyManager.NETWORK_TYPE_LTE, false, false, false);
 
@@ -1852,7 +1852,7 @@
         NetworkRequest request = new NetworkRequest.Builder()
                 .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
                 .build();
-        TelephonyNetworkRequest tnr = new TelephonyNetworkRequest(request, mPhone);
+        TelephonyNetworkRequest tnr = new TelephonyNetworkRequest(request, mPhone, mFeatureFlags);
         DataProfile dp = mDataProfileManagerUT.getDataProfileForNetworkRequest(tnr,
                 TelephonyManager.NETWORK_TYPE_LTE, false, false, false);
 
@@ -1883,7 +1883,7 @@
 
         // Verify the we can get the previously permanent failed data profile again.
         assertThat(mDataProfileManagerUT.getDataProfileForNetworkRequest(
-                new TelephonyNetworkRequest(request, mPhone),
+                new TelephonyNetworkRequest(request, mPhone, mFeatureFlags),
                 TelephonyManager.NETWORK_TYPE_LTE, false, false, false))
                 .isNotNull();
     }
@@ -1902,7 +1902,7 @@
         // flag is enabled at data profile, during esim bootstrap provisioning
         TelephonyNetworkRequest tnr = new TelephonyNetworkRequest(new NetworkRequest.Builder()
                 .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
-                .build(), mPhone);
+                .build(), mPhone, mFeatureFlags);
         DataProfile dataProfile = mDataProfileManagerUT.getDataProfileForNetworkRequest(
                 tnr, TelephonyManager.NETWORK_TYPE_LTE, false, true, false);
         assertThat(dataProfile.getApnSetting().getApnName()).isEqualTo(
@@ -1912,7 +1912,7 @@
         // is enabled at data profile, during esim bootstrap provisioning
         tnr = new TelephonyNetworkRequest(new NetworkRequest.Builder()
                  .addCapability(NetworkCapabilities.NET_CAPABILITY_IMS)
-                 .build(), mPhone);
+                 .build(), mPhone, mFeatureFlags);
         dataProfile  = mDataProfileManagerUT.getDataProfileForNetworkRequest(
                 tnr, TelephonyManager.NETWORK_TYPE_LTE, false, true, false);
         assertThat(dataProfile.getApnSetting().getApnName()).isEqualTo("IMS_APN");
@@ -1921,7 +1921,7 @@
         // is disabled at data profile, during esim bootstrap provisioning
         tnr = new TelephonyNetworkRequest(new NetworkRequest.Builder()
                 .addCapability(NetworkCapabilities.NET_CAPABILITY_MMS)
-                .build(), mPhone);
+                .build(), mPhone, mFeatureFlags);
         dataProfile  = mDataProfileManagerUT.getDataProfileForNetworkRequest(
                 tnr, TelephonyManager.NETWORK_TYPE_LTE, false, true, false);
         assertThat(dataProfile).isEqualTo(null);
@@ -1930,7 +1930,7 @@
         // is disabled at data profile, during esim bootstrap provisioning
         tnr = new TelephonyNetworkRequest(new NetworkRequest.Builder()
                 .addCapability(NetworkCapabilities.NET_CAPABILITY_RCS)
-                .build(), mPhone);
+                .build(), mPhone, mFeatureFlags);
         dataProfile = mDataProfileManagerUT.getDataProfileForNetworkRequest(
                 tnr, TelephonyManager.NETWORK_TYPE_LTE, false, true, false);
         assertThat(dataProfile).isEqualTo(null);
@@ -1950,7 +1950,7 @@
         // type
         TelephonyNetworkRequest tnr = new TelephonyNetworkRequest(new NetworkRequest.Builder()
                 .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
-                .build(), mPhone);
+                .build(), mPhone, mFeatureFlags);
         DataProfile dataProfile = mDataProfileManagerUT.getDataProfileForNetworkRequest(
                 tnr, TelephonyManager.NETWORK_TYPE_LTE, false, true, false);
         assertThat(dataProfile.getApnSetting().getApnName()).isEqualTo(
@@ -1972,7 +1972,7 @@
         // type
         TelephonyNetworkRequest tnr = new TelephonyNetworkRequest(new NetworkRequest.Builder()
                 .addCapability(NetworkCapabilities.NET_CAPABILITY_RCS)
-                .build(), mPhone);
+                .build(), mPhone, mFeatureFlags);
         DataProfile dataProfile = mDataProfileManagerUT.getDataProfileForNetworkRequest(
                 tnr, TelephonyManager.NETWORK_TYPE_LTE, true, true, false);
         assertThat(dataProfile.getApnSetting().getApnName()).isEqualTo(RCS_APN1);
diff --git a/tests/telephonytests/src/com/android/internal/telephony/data/DataRetryManagerTest.java b/tests/telephonytests/src/com/android/internal/telephony/data/DataRetryManagerTest.java
index 2541bd1..c413f83 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/data/DataRetryManagerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/data/DataRetryManagerTest.java
@@ -292,7 +292,7 @@
         NetworkRequest request = new NetworkRequest.Builder()
                 .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
                 .build();
-        TelephonyNetworkRequest tnr = new TelephonyNetworkRequest(request, mPhone);
+        TelephonyNetworkRequest tnr = new TelephonyNetworkRequest(request, mPhone, mFeatureFlags);
         DataNetworkController.NetworkRequestList
                 networkRequestList = new DataNetworkController.NetworkRequestList(tnr);
         mDataRetryManagerUT.evaluateDataSetupRetry(mDataProfile1,
@@ -316,7 +316,7 @@
         NetworkRequest request = new NetworkRequest.Builder()
                 .addCapability(NetworkCapabilities.NET_CAPABILITY_IMS)
                 .build();
-        TelephonyNetworkRequest tnr = new TelephonyNetworkRequest(request, mPhone);
+        TelephonyNetworkRequest tnr = new TelephonyNetworkRequest(request, mPhone, mFeatureFlags);
         DataNetworkController.NetworkRequestList
                 networkRequestList = new DataNetworkController.NetworkRequestList(tnr);
         mDataRetryManagerUT.evaluateDataSetupRetry(mDataProfile3,
@@ -345,7 +345,7 @@
         NetworkRequest request = new NetworkRequest.Builder()
                 .addCapability(NetworkCapabilities.NET_CAPABILITY_IMS)
                 .build();
-        TelephonyNetworkRequest tnr = new TelephonyNetworkRequest(request, mPhone);
+        TelephonyNetworkRequest tnr = new TelephonyNetworkRequest(request, mPhone, mFeatureFlags);
         DataNetworkController.NetworkRequestList
                 networkRequestList = new DataNetworkController.NetworkRequestList(tnr);
         mDataRetryManagerUT.evaluateDataSetupRetry(mDataProfile3,
@@ -432,7 +432,7 @@
         NetworkRequest request = new NetworkRequest.Builder()
                 .addCapability(NetworkCapabilities.NET_CAPABILITY_ENTERPRISE)
                 .build();
-        TelephonyNetworkRequest tnr = new TelephonyNetworkRequest(request, mPhone);
+        TelephonyNetworkRequest tnr = new TelephonyNetworkRequest(request, mPhone, mFeatureFlags);
         DataNetworkController.NetworkRequestList
                 networkRequestList = new DataNetworkController.NetworkRequestList(tnr);
 
@@ -535,7 +535,7 @@
         NetworkRequest request = new NetworkRequest.Builder()
                 .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
                 .build();
-        TelephonyNetworkRequest tnr = new TelephonyNetworkRequest(request, mPhone);
+        TelephonyNetworkRequest tnr = new TelephonyNetworkRequest(request, mPhone, mFeatureFlags);
         DataNetworkController.NetworkRequestList
                 networkRequestList = new DataNetworkController.NetworkRequestList(tnr);
         mDataRetryManagerUT.evaluateDataSetupRetry(mDataProfile1,
@@ -568,7 +568,7 @@
         NetworkRequest request = new NetworkRequest.Builder()
                 .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
                 .build();
-        TelephonyNetworkRequest tnr = new TelephonyNetworkRequest(request, mPhone);
+        TelephonyNetworkRequest tnr = new TelephonyNetworkRequest(request, mPhone, mFeatureFlags);
         DataNetworkController.NetworkRequestList
                 networkRequestList = new DataNetworkController.NetworkRequestList(tnr);
 
@@ -647,7 +647,7 @@
         NetworkRequest request = new NetworkRequest.Builder()
                 .addCapability(NetworkCapabilities.NET_CAPABILITY_IMS)
                 .build();
-        TelephonyNetworkRequest tnr = new TelephonyNetworkRequest(request, mPhone);
+        TelephonyNetworkRequest tnr = new TelephonyNetworkRequest(request, mPhone, mFeatureFlags);
         DataNetworkController.NetworkRequestList
                 networkRequestList = new DataNetworkController.NetworkRequestList(tnr);
 
@@ -709,7 +709,7 @@
         NetworkRequest request = new NetworkRequest.Builder()
                 .addCapability(NetworkCapabilities.NET_CAPABILITY_IMS)
                 .build();
-        TelephonyNetworkRequest tnr = new TelephonyNetworkRequest(request, mPhone);
+        TelephonyNetworkRequest tnr = new TelephonyNetworkRequest(request, mPhone, mFeatureFlags);
         DataNetworkController.NetworkRequestList
                 networkRequestList = new DataNetworkController.NetworkRequestList(tnr);
 
@@ -798,7 +798,7 @@
         NetworkRequest request = new NetworkRequest.Builder()
                 .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
                 .build();
-        TelephonyNetworkRequest tnr = new TelephonyNetworkRequest(request, mPhone);
+        TelephonyNetworkRequest tnr = new TelephonyNetworkRequest(request, mPhone, mFeatureFlags);
         DataNetworkController.NetworkRequestList
                 networkRequestList = new DataNetworkController.NetworkRequestList(tnr);
         mDataRetryManagerUT.evaluateDataSetupRetry(mDataProfile1,
@@ -839,7 +839,7 @@
         NetworkRequest request = new NetworkRequest.Builder()
                 .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
                 .build();
-        TelephonyNetworkRequest tnr = new TelephonyNetworkRequest(request, mPhone);
+        TelephonyNetworkRequest tnr = new TelephonyNetworkRequest(request, mPhone, mFeatureFlags);
         DataNetworkController.NetworkRequestList
                 networkRequestList = new DataNetworkController.NetworkRequestList(tnr);
 
@@ -853,7 +853,7 @@
                 .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
                 .addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED)
                 .addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VPN)
-                .build(), mPhone);
+                .build(), mPhone, mFeatureFlags);
         assertThat(mDataRetryManagerUT.isSimilarNetworkRequestRetryScheduled(tnr,
                 AccessNetworkConstants.TRANSPORT_TYPE_WWAN)).isTrue();
         assertThat(mDataRetryManagerUT.isSimilarNetworkRequestRetryScheduled(tnr,
diff --git a/tests/telephonytests/src/com/android/internal/telephony/data/DataUtilsTest.java b/tests/telephonytests/src/com/android/internal/telephony/data/DataUtilsTest.java
index ea8a7d7..38de618 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/data/DataUtilsTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/data/DataUtilsTest.java
@@ -18,24 +18,32 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
+import static org.mockito.Mockito.doReturn;
+
 import android.net.NetworkCapabilities;
 import android.net.NetworkRequest;
 
 import com.android.internal.telephony.TelephonyTest;
 import com.android.internal.telephony.data.DataNetworkController.NetworkRequestList;
+import com.android.internal.telephony.flags.FeatureFlags;
 
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
+import org.mockito.Mockito;
 
 import java.util.List;
 
 public class DataUtilsTest extends TelephonyTest {
 
+    private FeatureFlags mFeatureFlags;
+
     @Before
     public void setUp() throws Exception {
         logd("DataUtilsTest +Setup!");
         super.setUp(getClass().getSimpleName());
+        mFeatureFlags = Mockito.mock(FeatureFlags.class);
+        doReturn(true).when(mFeatureFlags).satelliteInternet();
         logd("DataUtilsTest -Setup!");
     }
 
@@ -57,10 +65,13 @@
                 NetworkCapabilities.NET_CAPABILITY_ENTERPRISE,
                 NetworkCapabilities.NET_CAPABILITY_ENTERPRISE,
                 NetworkCapabilities.NET_CAPABILITY_ENTERPRISE,
+                NetworkCapabilities.NET_CAPABILITY_IMS,
+                NetworkCapabilities.NET_CAPABILITY_IMS,
         };
 
         int requestId = 0;
         int enterpriseId = 1;
+        int transportType = NetworkCapabilities.TRANSPORT_CELLULAR;
         TelephonyNetworkRequest networkRequest;
         for (int netCap : netCaps) {
             if (netCap == NetworkCapabilities.NET_CAPABILITY_ENTERPRISE) {
@@ -69,24 +80,31 @@
                                 .addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR)
                                 .addCapability(NetworkCapabilities.NET_CAPABILITY_ENTERPRISE)
                                 .addEnterpriseId(enterpriseId).build(), -1, requestId++,
-                        NetworkRequest.Type.REQUEST), mPhone);
+                        NetworkRequest.Type.REQUEST), mPhone, mFeatureFlags);
                 if (enterpriseId == 1) enterpriseId++;
+            } else if (netCap == NetworkCapabilities.NET_CAPABILITY_IMS) {
+                networkRequest = new TelephonyNetworkRequest(new NetworkRequest(
+                        new NetworkCapabilities.Builder()
+                                .addTransportType(transportType)
+                                .addCapability(netCap).build(), -1, requestId++,
+                        NetworkRequest.Type.REQUEST), mPhone, mFeatureFlags);
+                transportType = NetworkCapabilities.TRANSPORT_SATELLITE;
             } else {
                 networkRequest = new TelephonyNetworkRequest(new NetworkRequest(
                         new NetworkCapabilities.Builder()
                                 .addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR)
                                 .addCapability(netCap).build(), -1, requestId++,
-                        NetworkRequest.Type.REQUEST), mPhone);
+                        NetworkRequest.Type.REQUEST), mPhone, mFeatureFlags);
             }
             requestList.add(networkRequest);
         }
 
-        assertThat(requestList).hasSize(8);
+        assertThat(requestList).hasSize(10);
 
         List<NetworkRequestList> requestListList =
-                DataUtils.getGroupedNetworkRequestList(requestList);
+                DataUtils.getGroupedNetworkRequestList(requestList, mFeatureFlags);
 
-        assertThat(requestListList).hasSize(5);
+        assertThat(requestListList).hasSize(7);
         requestList = requestListList.get(0);
         assertThat(requestList).hasSize(1);
         assertThat(requestList.get(0).hasCapability(
@@ -100,26 +118,40 @@
                 NetworkCapabilities.NET_CAPABILITY_MMS)).isTrue();
 
         requestList = requestListList.get(2);
-        assertThat(requestList).hasSize(2);
+        assertThat(requestList).hasSize(1);
         assertThat(requestList.get(0).hasCapability(
-                NetworkCapabilities.NET_CAPABILITY_INTERNET)).isTrue();
-        assertThat(requestList.get(1).hasCapability(
-                NetworkCapabilities.NET_CAPABILITY_INTERNET)).isTrue();
+                NetworkCapabilities.NET_CAPABILITY_IMS)).isTrue();
+        assertThat(requestList.get(0).getNativeNetworkRequest().hasTransport(
+                NetworkCapabilities.TRANSPORT_CELLULAR)).isTrue();
 
         requestList = requestListList.get(3);
         assertThat(requestList).hasSize(1);
         assertThat(requestList.get(0).hasCapability(
-                NetworkCapabilities.NET_CAPABILITY_ENTERPRISE)).isTrue();
-        assertThat(requestList.get(0).getCapabilityDifferentiator() == 1).isTrue();
+                NetworkCapabilities.NET_CAPABILITY_IMS)).isTrue();
+        assertThat(requestList.get(0).getNativeNetworkRequest().hasTransport(
+                NetworkCapabilities.TRANSPORT_SATELLITE)).isTrue();
 
         requestList = requestListList.get(4);
         assertThat(requestList).hasSize(2);
         assertThat(requestList.get(0).hasCapability(
+                NetworkCapabilities.NET_CAPABILITY_INTERNET)).isTrue();
+        assertThat(requestList.get(1).hasCapability(
+                NetworkCapabilities.NET_CAPABILITY_INTERNET)).isTrue();
+
+        requestList = requestListList.get(5);
+        assertThat(requestList).hasSize(1);
+        assertThat(requestList.get(0).hasCapability(
                 NetworkCapabilities.NET_CAPABILITY_ENTERPRISE)).isTrue();
-        assertThat(requestList.get(0).getCapabilityDifferentiator() == 2).isTrue();
+        assertThat(requestList.get(0).getCapabilityDifferentiator()).isEqualTo(1);
+
+        requestList = requestListList.get(6);
+        assertThat(requestList).hasSize(2);
+        assertThat(requestList.get(0).hasCapability(
+                NetworkCapabilities.NET_CAPABILITY_ENTERPRISE)).isTrue();
+        assertThat(requestList.get(0).getCapabilityDifferentiator()).isEqualTo(2);
         assertThat(requestList.get(1).hasCapability(
                 NetworkCapabilities.NET_CAPABILITY_ENTERPRISE)).isTrue();
-        assertThat(requestList.get(1).getCapabilityDifferentiator() == 2).isTrue();
+        assertThat(requestList.get(1).getCapabilityDifferentiator()).isEqualTo(2);
     }
 
     @Test
diff --git a/tests/telephonytests/src/com/android/internal/telephony/data/PhoneSwitcherTest.java b/tests/telephonytests/src/com/android/internal/telephony/data/PhoneSwitcherTest.java
index e011a60..8420acf 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/data/PhoneSwitcherTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/data/PhoneSwitcherTest.java
@@ -221,8 +221,8 @@
         NetworkRequest internetNetworkRequest = addInternetNetworkRequest(null, 50);
 
         assertFalse("phone active after request", mPhoneSwitcherUT
-                .shouldApplyNetworkRequest(
-                        new TelephonyNetworkRequest(internetNetworkRequest, mPhone), 0));
+                .shouldApplyNetworkRequest(new TelephonyNetworkRequest(
+                        internetNetworkRequest, mPhone, mFeatureFlags), 0));
 
         // not registered yet - shouldn't inc
         verify(mActivePhoneSwitchHandler, never()).sendMessageAtTime(any(), anyLong());
@@ -628,9 +628,9 @@
         // Phone 0 (sub 1) should be activated as it has default data sub.
         assertEquals(1, mPhoneSwitcherUT.getActiveDataSubId());
         assertTrue(mPhoneSwitcherUT.shouldApplyNetworkRequest(
-                new TelephonyNetworkRequest(internetRequest, mPhone), 0));
+                new TelephonyNetworkRequest(internetRequest, mPhone, mFeatureFlags), 0));
         assertFalse(mPhoneSwitcherUT.shouldApplyNetworkRequest(
-                new TelephonyNetworkRequest(internetRequest, mPhone), 1));
+                new TelephonyNetworkRequest(internetRequest, mPhone, mFeatureFlags), 1));
 
         // Set sub 2 as preferred sub should make phone 1 activated and phone 0 deactivated.
         mPhoneSwitcherUT.trySetOpportunisticDataSubscription(2, false, null);
@@ -645,9 +645,9 @@
 
         // switch shouldn't occur due to the higher priority event
         assertTrue(mPhoneSwitcherUT.shouldApplyNetworkRequest(
-                new TelephonyNetworkRequest(internetRequest, mPhone), 0));
+                new TelephonyNetworkRequest(internetRequest, mPhone, mFeatureFlags), 0));
         assertFalse(mPhoneSwitcherUT.shouldApplyNetworkRequest(
-                new TelephonyNetworkRequest(internetRequest, mPhone), 1));
+                new TelephonyNetworkRequest(internetRequest, mPhone, mFeatureFlags), 1));
         assertEquals(1, mPhoneSwitcherUT.getActiveDataSubId());
         assertEquals(2, mPhoneSwitcherUT.getAutoSelectedDataSubId());
 
@@ -657,9 +657,9 @@
         assertEquals(2, mPhoneSwitcherUT.getActiveDataSubId());
         assertEquals(2, mPhoneSwitcherUT.getAutoSelectedDataSubId());
         assertTrue(mPhoneSwitcherUT.shouldApplyNetworkRequest(
-                new TelephonyNetworkRequest(internetRequest, mPhone), 1));
+                new TelephonyNetworkRequest(internetRequest, mPhone, mFeatureFlags), 1));
         assertFalse(mPhoneSwitcherUT.shouldApplyNetworkRequest(
-                new TelephonyNetworkRequest(internetRequest, mPhone), 0));
+                new TelephonyNetworkRequest(internetRequest, mPhone, mFeatureFlags), 0));
     }
 
     @Test
@@ -751,13 +751,13 @@
         verify(mMockRadioConfig, never()).setPreferredDataModem(anyInt(), any());
         verify(mActivePhoneSwitchHandler, never()).sendMessageAtTime(any(), anyLong());
         assertTrue(mPhoneSwitcherUT.shouldApplyNetworkRequest(
-                new TelephonyNetworkRequest(internetRequest, mPhone), 0));
+                new TelephonyNetworkRequest(internetRequest, mPhone, mFeatureFlags), 0));
         assertFalse(mPhoneSwitcherUT.shouldApplyNetworkRequest(
-                new TelephonyNetworkRequest(mmsRequest, mPhone), 0));
+                new TelephonyNetworkRequest(mmsRequest, mPhone, mFeatureFlags), 0));
         assertFalse(mPhoneSwitcherUT.shouldApplyNetworkRequest(
-                new TelephonyNetworkRequest(internetRequest, mPhone), 1));
+                new TelephonyNetworkRequest(internetRequest, mPhone, mFeatureFlags), 1));
         assertTrue(mPhoneSwitcherUT.shouldApplyNetworkRequest(
-                new TelephonyNetworkRequest(mmsRequest, mPhone), 1));
+                new TelephonyNetworkRequest(mmsRequest, mPhone, mFeatureFlags), 1));
 
         // Set sub 2 as preferred sub should make phone 1 preferredDataModem
         doReturn(new SubscriptionInfoInternal.Builder(mSubscriptionManagerService
@@ -773,13 +773,13 @@
         processAllMessages();
         verify(mActivePhoneSwitchHandler, times(2)).sendMessageAtTime(any(), anyLong());
         assertFalse(mPhoneSwitcherUT.shouldApplyNetworkRequest(
-                new TelephonyNetworkRequest(internetRequest, mPhone), 0));
+                new TelephonyNetworkRequest(internetRequest, mPhone, mFeatureFlags), 0));
         assertFalse(mPhoneSwitcherUT.shouldApplyNetworkRequest(
-                new TelephonyNetworkRequest(mmsRequest, mPhone), 0));
+                new TelephonyNetworkRequest(mmsRequest, mPhone, mFeatureFlags), 0));
         assertTrue(mPhoneSwitcherUT.shouldApplyNetworkRequest(
-                new TelephonyNetworkRequest(internetRequest, mPhone), 1));
+                new TelephonyNetworkRequest(internetRequest, mPhone, mFeatureFlags), 1));
         assertTrue(mPhoneSwitcherUT.shouldApplyNetworkRequest(
-                new TelephonyNetworkRequest(mmsRequest, mPhone), 1));
+                new TelephonyNetworkRequest(mmsRequest, mPhone, mFeatureFlags), 1));
 
         clearInvocations(mMockRadioConfig);
         clearInvocations(mActivePhoneSwitchHandler);
@@ -796,13 +796,13 @@
         processAllMessages();
         verify(mActivePhoneSwitchHandler, times(2)).sendMessageAtTime(any(), anyLong());
         assertTrue(mPhoneSwitcherUT.shouldApplyNetworkRequest(
-                new TelephonyNetworkRequest(internetRequest, mPhone), 0));
+                new TelephonyNetworkRequest(internetRequest, mPhone, mFeatureFlags), 0));
         assertFalse(mPhoneSwitcherUT.shouldApplyNetworkRequest(
-                new TelephonyNetworkRequest(mmsRequest, mPhone), 0));
+                new TelephonyNetworkRequest(mmsRequest, mPhone, mFeatureFlags), 0));
         assertFalse(mPhoneSwitcherUT.shouldApplyNetworkRequest(
-                new TelephonyNetworkRequest(internetRequest, mPhone), 1));
+                new TelephonyNetworkRequest(internetRequest, mPhone, mFeatureFlags), 1));
         assertTrue(mPhoneSwitcherUT.shouldApplyNetworkRequest(
-                new TelephonyNetworkRequest(mmsRequest, mPhone), 1));
+                new TelephonyNetworkRequest(mmsRequest, mPhone, mFeatureFlags), 1));
 
         // SetDataAllowed should never be triggered.
         verify(mCommandsInterface0, never()).setDataAllowed(anyBoolean(), any());
@@ -1038,9 +1038,9 @@
         setDefaultDataSubId(1);
         NetworkRequest internetRequest = addInternetNetworkRequest(null, 50);
         assertTrue(mPhoneSwitcherUT.shouldApplyNetworkRequest(
-                new TelephonyNetworkRequest(internetRequest, mPhone), 0));
+                new TelephonyNetworkRequest(internetRequest, mPhone, mFeatureFlags), 0));
         assertFalse(mPhoneSwitcherUT.shouldApplyNetworkRequest(
-                new TelephonyNetworkRequest(internetRequest, mPhone), 1));
+                new TelephonyNetworkRequest(internetRequest, mPhone, mFeatureFlags), 1));
         clearInvocations(mMockRadioConfig);
         setAllPhonesInactive();
         // Initialization done.
@@ -1050,18 +1050,18 @@
         notifyPhoneAsInCall(mPhone2);
         verify(mMockRadioConfig, never()).setPreferredDataModem(anyInt(), any());
         assertTrue(mPhoneSwitcherUT.shouldApplyNetworkRequest(
-                new TelephonyNetworkRequest(internetRequest, mPhone), 0));
+                new TelephonyNetworkRequest(internetRequest, mPhone, mFeatureFlags), 0));
         assertFalse(mPhoneSwitcherUT.shouldApplyNetworkRequest(
-                new TelephonyNetworkRequest(internetRequest, mPhone), 1));
+                new TelephonyNetworkRequest(internetRequest, mPhone, mFeatureFlags), 1));
 
         // Phone2 has active call, and data is on. So data switch to it.
         doReturn(true).when(mPhone).isUserDataEnabled();
         notifyDataEnabled(true);
         verify(mMockRadioConfig).setPreferredDataModem(eq(1), any());
         assertTrue(mPhoneSwitcherUT.shouldApplyNetworkRequest(
-                new TelephonyNetworkRequest(internetRequest, mPhone), 1));
+                new TelephonyNetworkRequest(internetRequest, mPhone, mFeatureFlags), 1));
         assertFalse(mPhoneSwitcherUT.shouldApplyNetworkRequest(
-                new TelephonyNetworkRequest(internetRequest, mPhone), 0));
+                new TelephonyNetworkRequest(internetRequest, mPhone, mFeatureFlags), 0));
         clearInvocations(mMockRadioConfig);
 
         // Phone2(nDDS) call ended. But Phone1 having cross-SIM call. Don't switch.
@@ -1070,9 +1070,9 @@
         notifyPhoneAsInactive(mPhone2);
         verify(mMockRadioConfig, never()).setPreferredDataModem(anyInt(), any());
         assertTrue(mPhoneSwitcherUT.shouldApplyNetworkRequest(
-                new TelephonyNetworkRequest(internetRequest, mPhone), 1));
+                new TelephonyNetworkRequest(internetRequest, mPhone, mFeatureFlags), 1));
         assertFalse(mPhoneSwitcherUT.shouldApplyNetworkRequest(
-                new TelephonyNetworkRequest(internetRequest, mPhone), 0));
+                new TelephonyNetworkRequest(internetRequest, mPhone, mFeatureFlags), 0));
 
         // Phone(DDS) call ended.
         // Honor auto data switch's suggestion: if DDS is OOS, auto switch to Phone2(nDDS).
@@ -1083,9 +1083,9 @@
         // verify immediately switch back to DDS upon call ends
         verify(mMockRadioConfig).setPreferredDataModem(eq(0), any());
         assertTrue(mPhoneSwitcherUT.shouldApplyNetworkRequest(
-                new TelephonyNetworkRequest(internetRequest, mPhone), 0));
+                new TelephonyNetworkRequest(internetRequest, mPhone, mFeatureFlags), 0));
         assertFalse(mPhoneSwitcherUT.shouldApplyNetworkRequest(
-                new TelephonyNetworkRequest(internetRequest, mPhone), 1));
+                new TelephonyNetworkRequest(internetRequest, mPhone, mFeatureFlags), 1));
 
         // verify the attempt to do auto data switch to Phone2(nDDS)
         processAllFutureMessages();
@@ -1098,9 +1098,9 @@
         notifyPhoneAsInHoldingCall(mPhone2);
         verify(mMockRadioConfig, never()).setPreferredDataModem(anyInt(), any());
         assertTrue(mPhoneSwitcherUT.shouldApplyNetworkRequest(
-                new TelephonyNetworkRequest(internetRequest, mPhone), 0));
+                new TelephonyNetworkRequest(internetRequest, mPhone, mFeatureFlags), 0));
         assertFalse(mPhoneSwitcherUT.shouldApplyNetworkRequest(
-                new TelephonyNetworkRequest(internetRequest, mPhone), 1));
+                new TelephonyNetworkRequest(internetRequest, mPhone, mFeatureFlags), 1));
     }
 
     @Test
@@ -1115,9 +1115,9 @@
         setDefaultDataSubId(1);
         NetworkRequest internetRequest = addInternetNetworkRequest(null, 50);
         assertTrue(mPhoneSwitcherUT.shouldApplyNetworkRequest(
-                new TelephonyNetworkRequest(internetRequest, mPhone), 0));
+                new TelephonyNetworkRequest(internetRequest, mPhone, mFeatureFlags), 0));
         assertFalse(mPhoneSwitcherUT.shouldApplyNetworkRequest(
-                new TelephonyNetworkRequest(internetRequest, mPhone), 1));
+                new TelephonyNetworkRequest(internetRequest, mPhone, mFeatureFlags), 1));
         clearInvocations(mMockRadioConfig);
         setAllPhonesInactive();
         // Initialization done.
@@ -1127,17 +1127,17 @@
         notifyPhoneAsInCall(mPhone2);
         verify(mMockRadioConfig).setPreferredDataModem(eq(1), any());
         assertFalse(mPhoneSwitcherUT.shouldApplyNetworkRequest(
-                new TelephonyNetworkRequest(internetRequest, mPhone), 0));
+                new TelephonyNetworkRequest(internetRequest, mPhone, mFeatureFlags), 0));
         assertTrue(mPhoneSwitcherUT.shouldApplyNetworkRequest(
-                new TelephonyNetworkRequest(internetRequest, mPhone), 1));
+                new TelephonyNetworkRequest(internetRequest, mPhone, mFeatureFlags), 1));
 
         // During the active call, user turns off data, should immediately switch back to DDS
         notifyDataEnabled(false);
         verify(mMockRadioConfig).setPreferredDataModem(eq(0), any());
         assertTrue(mPhoneSwitcherUT.shouldApplyNetworkRequest(
-                new TelephonyNetworkRequest(internetRequest, mPhone), 0));
+                new TelephonyNetworkRequest(internetRequest, mPhone, mFeatureFlags), 0));
         assertFalse(mPhoneSwitcherUT.shouldApplyNetworkRequest(
-                new TelephonyNetworkRequest(internetRequest, mPhone), 1));
+                new TelephonyNetworkRequest(internetRequest, mPhone, mFeatureFlags), 1));
     }
 
     @Test
@@ -1165,16 +1165,16 @@
         setDefaultDataSubId(1);
         NetworkRequest internetRequest = addInternetNetworkRequest(2, 50);
         assertFalse(mPhoneSwitcherUT.shouldApplyNetworkRequest(
-                new TelephonyNetworkRequest(internetRequest, mPhone), 0));
+                new TelephonyNetworkRequest(internetRequest, mPhone, mFeatureFlags), 0));
         assertFalse(mPhoneSwitcherUT.shouldApplyNetworkRequest(
-                new TelephonyNetworkRequest(internetRequest, mPhone), 1));
+                new TelephonyNetworkRequest(internetRequest, mPhone, mFeatureFlags), 1));
 
         // Restricted network request will should be applied.
         internetRequest = addInternetNetworkRequest(2, 50, true);
         assertFalse(mPhoneSwitcherUT.shouldApplyNetworkRequest(
-                new TelephonyNetworkRequest(internetRequest, mPhone), 0));
+                new TelephonyNetworkRequest(internetRequest, mPhone, mFeatureFlags), 0));
         assertTrue(mPhoneSwitcherUT.shouldApplyNetworkRequest(
-                new TelephonyNetworkRequest(internetRequest, mPhone), 1));
+                new TelephonyNetworkRequest(internetRequest, mPhone, mFeatureFlags), 1));
     }
 
     @Test
@@ -1518,6 +1518,53 @@
     }
 
     @Test
+    public void testSetPreferredDataCallback_voiceCall() throws Exception {
+        doReturn(true).when(mMockRadioConfig).isSetPreferredDataCommandSupported();
+        initialize();
+        setAllPhonesInactive();
+
+        // Phone 0 has sub 1, phone 1 has sub 2.
+        // Sub 1 is default data sub.
+        // Both are active subscriptions are active sub, as they are in both active slots.
+        setSlotIndexToSubId(0, 1);
+        setSlotIndexToSubId(1, 2);
+        setDefaultDataSubId(1);
+        assertEquals(1, mPhoneSwitcherUT.getActiveDataSubId());
+
+        doReturn(new SubscriptionInfoInternal.Builder(mSubscriptionManagerService
+                .getSubscriptionInfoInternal(2)).setOpportunistic(1).build())
+                .when(mSubscriptionManagerService).getSubscriptionInfoInternal(2);
+
+        // First temporarily switched to the opportunistic sub 2
+        mPhoneSwitcherUT.trySetOpportunisticDataSubscription(2, false, mSetOpptDataCallback1);
+        processAllMessages();
+        mPhoneSwitcherUT.mValidationCallback.onNetworkAvailable(null, 2);
+        processAllMessages();
+        verify(mSetOpptDataCallback1).onComplete(SET_OPPORTUNISTIC_SUB_SUCCESS);
+
+        // Voice call led back to default sub 1
+        doReturn(mImsPhone).when(mPhone).getImsPhone();
+        doReturn(true).when(mPhone).isUserDataEnabled();
+        doReturn(true).when(mDataSettingsManager).isDataEnabled();
+        mockImsRegTech(0, REGISTRATION_TECH_LTE);
+        notifyPhoneAsInCall(mPhone);
+
+        assertEquals(1, mPhoneSwitcherUT.getActiveDataSubId());
+        assertEquals(2, mPhoneSwitcherUT.getAutoSelectedDataSubId());
+
+        // CBRS set preferred data back to default during the phone call
+        clearInvocations(mSetOpptDataCallback1);
+        mPhoneSwitcherUT.trySetOpportunisticDataSubscription(SubscriptionManager
+                .DEFAULT_SUBSCRIPTION_ID, false, mSetOpptDataCallback1);
+        processAllMessages();
+
+        verify(mSetOpptDataCallback1).onComplete(SET_OPPORTUNISTIC_SUB_SUCCESS);
+        assertEquals(1, mPhoneSwitcherUT.getActiveDataSubId());
+        assertEquals(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID,
+                mPhoneSwitcherUT.getAutoSelectedDataSubId());
+    }
+
+    @Test
     @SmallTest
     public void testMultiSimConfigChange() throws Exception {
         doReturn(true).when(mMockRadioConfig).isSetPreferredDataCommandSupported();
@@ -1558,9 +1605,9 @@
         setDefaultDataSubId(1);
         NetworkRequest internetRequest = addInternetNetworkRequest(null, 50);
         assertTrue(mPhoneSwitcherUT.shouldApplyNetworkRequest(
-                new TelephonyNetworkRequest(internetRequest, mPhone), 0));
+                new TelephonyNetworkRequest(internetRequest, mPhone, mFeatureFlags), 0));
         assertFalse(mPhoneSwitcherUT.shouldApplyNetworkRequest(
-                new TelephonyNetworkRequest(internetRequest, mPhone), 1));
+                new TelephonyNetworkRequest(internetRequest, mPhone, mFeatureFlags), 1));
         clearInvocations(mMockRadioConfig);
         setAllPhonesInactive();
         // Initialization done.
@@ -1599,9 +1646,9 @@
         setDefaultDataSubId(1);
         NetworkRequest internetRequest = addInternetNetworkRequest(null, 50);
         assertTrue(mPhoneSwitcherUT.shouldApplyNetworkRequest(
-                new TelephonyNetworkRequest(internetRequest, mPhone), 0));
+                new TelephonyNetworkRequest(internetRequest, mPhone, mFeatureFlags), 0));
         assertFalse(mPhoneSwitcherUT.shouldApplyNetworkRequest(
-                new TelephonyNetworkRequest(internetRequest, mPhone), 1));
+                new TelephonyNetworkRequest(internetRequest, mPhone, mFeatureFlags), 1));
         clearInvocations(mMockRadioConfig);
         setAllPhonesInactive();
         // Initialization done.
@@ -1862,10 +1909,10 @@
             if (defaultDataSub == (i + 1)) {
                 // sub id is always phoneId+1 for testing
                 assertTrue(mPhoneSwitcherUT.shouldApplyNetworkRequest(
-                        new TelephonyNetworkRequest(internetRequest, mPhone), i));
+                        new TelephonyNetworkRequest(internetRequest, mPhone, mFeatureFlags), i));
             } else {
                 assertFalse(mPhoneSwitcherUT.shouldApplyNetworkRequest(
-                        new TelephonyNetworkRequest(internetRequest, mPhone), i));
+                        new TelephonyNetworkRequest(internetRequest, mPhone, mFeatureFlags), i));
             }
         }
     }
diff --git a/tests/telephonytests/src/com/android/internal/telephony/data/TelephonyNetworkFactoryTest.java b/tests/telephonytests/src/com/android/internal/telephony/data/TelephonyNetworkFactoryTest.java
index ad99eaf..e1a0eac 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/data/TelephonyNetworkFactoryTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/data/TelephonyNetworkFactoryTest.java
@@ -135,7 +135,8 @@
     }
 
     private void activatePhoneInPhoneSwitcher(int phoneId, NetworkRequest nr, boolean active) {
-        TelephonyNetworkRequest networkRequest = new TelephonyNetworkRequest(nr, mPhone);
+        TelephonyNetworkRequest networkRequest =
+                new TelephonyNetworkRequest(nr, mPhone, mFeatureFlags);
         doReturn(active).when(mPhoneSwitcher).shouldApplyNetworkRequest(
                 eq(networkRequest), eq(phoneId));
         mTelephonyNetworkFactoryUT.mInternalHandler.sendEmptyMessage(
diff --git a/tests/telephonytests/src/com/android/internal/telephony/data/TelephonyNetworkRequestTest.java b/tests/telephonytests/src/com/android/internal/telephony/data/TelephonyNetworkRequestTest.java
index 26a9fde..1517006 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/data/TelephonyNetworkRequestTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/data/TelephonyNetworkRequestTest.java
@@ -18,6 +18,9 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.when;
+
 import android.net.ConnectivityManager;
 import android.net.NetworkCapabilities;
 import android.net.NetworkRequest;
@@ -123,7 +126,7 @@
                 .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
                 .build();
         TelephonyNetworkRequest internetRequest =
-                new TelephonyNetworkRequest(nativeRequest, mPhone);
+                new TelephonyNetworkRequest(nativeRequest, mPhone, mFeatureFlags);
         assertThat(internetRequest.getNativeNetworkRequest()).isEqualTo(nativeRequest);
     }
 
@@ -132,11 +135,11 @@
         TelephonyNetworkRequest internetRequest = new TelephonyNetworkRequest(
                 new NetworkRequest.Builder()
                         .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
-                        .build(), mPhone);
+                        .build(), mPhone, mFeatureFlags);
         TelephonyNetworkRequest imsRequest = new TelephonyNetworkRequest(
                 new NetworkRequest.Builder()
                         .addCapability(NetworkCapabilities.NET_CAPABILITY_IMS)
-                        .build(), mPhone);
+                        .build(), mPhone, mFeatureFlags);
 
         assertThat(internetRequest.getPriority()).isEqualTo(20);
         assertThat(imsRequest.getPriority()).isEqualTo(40);
@@ -152,7 +155,7 @@
                         .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
                         .addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR)
                         .setNetworkSpecifier(telephonyNetworkSpecifier)
-                        .build(), mPhone);
+                        .build(), mPhone, mFeatureFlags);
         assertThat(internetRequest.getNetworkSpecifier()).isEqualTo(telephonyNetworkSpecifier);
     }
 
@@ -164,7 +167,7 @@
                         .addCapability(NetworkCapabilities.NET_CAPABILITY_TRUSTED)
                         .addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED)
                         .addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VPN)
-                        .build(), mPhone);
+                        .build(), mPhone, mFeatureFlags);
         assertThat(internetRequest.getCapabilities()).isEqualTo(
                 new int[]{NetworkCapabilities.NET_CAPABILITY_INTERNET,
                         NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED,
@@ -191,7 +194,7 @@
                         .addCapability(NetworkCapabilities.NET_CAPABILITY_MMS)
                         .addCapability(NetworkCapabilities.NET_CAPABILITY_ENTERPRISE)
                         .addCapability(NetworkCapabilities.NET_CAPABILITY_SUPL)
-                        .build(), mPhone);
+                        .build(), mPhone, mFeatureFlags);
         assertThat(request.getApnTypeNetworkCapability())
                 .isEqualTo(NetworkCapabilities.NET_CAPABILITY_SUPL);
 
@@ -200,7 +203,7 @@
                         .addCapability(NetworkCapabilities.NET_CAPABILITY_FOTA)
                         .addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED)
                         .addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED)
-                        .build(), mPhone);
+                        .build(), mPhone, mFeatureFlags);
         assertThat(request.getApnTypeNetworkCapability())
                 .isEqualTo(NetworkCapabilities.NET_CAPABILITY_FOTA);
 
@@ -209,7 +212,7 @@
                         .addCapability(NetworkCapabilities.NET_CAPABILITY_EIMS)
                         .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
                         .addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED)
-                        .build(), mPhone);
+                        .build(), mPhone, mFeatureFlags);
         assertThat(request.getApnTypeNetworkCapability())
                 .isEqualTo(NetworkCapabilities.NET_CAPABILITY_EIMS);
     }
@@ -219,7 +222,7 @@
         TelephonyNetworkRequest internetRequest = new TelephonyNetworkRequest(
                 new NetworkRequest.Builder()
                         .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
-                        .build(), mPhone);
+                        .build(), mPhone, mFeatureFlags);
         NetworkCapabilities caps = new NetworkCapabilities.Builder()
                 .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
                 .addCapability(NetworkCapabilities.NET_CAPABILITY_MMS)
@@ -233,7 +236,7 @@
         TelephonyNetworkRequest rcsRequest = new TelephonyNetworkRequest(
                 new NetworkRequest.Builder()
                         .addCapability(NetworkCapabilities.NET_CAPABILITY_RCS)
-                        .build(), mPhone);
+                        .build(), mPhone, mFeatureFlags);
         caps = new NetworkCapabilities.Builder()
                 .addCapability(NetworkCapabilities.NET_CAPABILITY_RCS)
                 .addCapability(NetworkCapabilities.NET_CAPABILITY_MMS)
@@ -250,15 +253,15 @@
         TelephonyNetworkRequest internetRequest = new TelephonyNetworkRequest(
                 new NetworkRequest.Builder()
                         .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
-                        .build(), mPhone);
+                        .build(), mPhone, mFeatureFlags);
         TelephonyNetworkRequest mmsRequest = new TelephonyNetworkRequest(
                 new NetworkRequest.Builder()
                         .addCapability(NetworkCapabilities.NET_CAPABILITY_MMS)
-                        .build(), mPhone);
+                        .build(), mPhone, mFeatureFlags);
         TelephonyNetworkRequest rcsRequest = new TelephonyNetworkRequest(
                 new NetworkRequest.Builder()
                         .addCapability(NetworkCapabilities.NET_CAPABILITY_RCS)
-                        .build(), mPhone);
+                        .build(), mPhone, mFeatureFlags);
         DataProfile internetDataProfile = new DataProfile.Builder()
                 .setApnSetting(INTERNET_APN_SETTING)
                 .build();
@@ -281,12 +284,12 @@
         TelephonyNetworkRequest enterpriseRequest1 = new TelephonyNetworkRequest(
                 new NetworkRequest.Builder()
                         .addCapability(NetworkCapabilities.NET_CAPABILITY_ENTERPRISE)
-                        .build(), mPhone);
+                        .build(), mPhone, mFeatureFlags);
         TelephonyNetworkRequest enterpriseRequest2 = new TelephonyNetworkRequest(
                 new NetworkRequest(new NetworkCapabilities()
                         .addCapability(NetworkCapabilities.NET_CAPABILITY_ENTERPRISE)
                         .addEnterpriseId(2), ConnectivityManager.TYPE_NONE,
-                        0, NetworkRequest.Type.REQUEST), mPhone);
+                        0, NetworkRequest.Type.REQUEST), mPhone, mFeatureFlags);
 
         DataProfile enterpriseDataProfile1 = new DataProfile.Builder()
                 .setTrafficDescriptor(new TrafficDescriptor(null, new TrafficDescriptor.OsAppId(
@@ -309,18 +312,18 @@
                 new NetworkRequest.Builder()
                         .addCapability(NetworkCapabilities.NET_CAPABILITY_ENTERPRISE)
                         .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
-                        .build(), mPhone);
+                        .build(), mPhone, mFeatureFlags);
         TelephonyNetworkRequest enterpriseRequest2 = new TelephonyNetworkRequest(
                 new NetworkRequest(new NetworkCapabilities()
                         .addCapability(NetworkCapabilities.NET_CAPABILITY_ENTERPRISE)
                         .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
                         .addEnterpriseId(2), ConnectivityManager.TYPE_NONE,
-                        0, NetworkRequest.Type.REQUEST), mPhone);
+                        0, NetworkRequest.Type.REQUEST), mPhone, mFeatureFlags);
         TelephonyNetworkRequest internetRequest = new TelephonyNetworkRequest(
                 new NetworkRequest(new NetworkCapabilities()
                         .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET),
                         ConnectivityManager.TYPE_NONE,
-                        0, NetworkRequest.Type.REQUEST), mPhone);
+                        0, NetworkRequest.Type.REQUEST), mPhone, mFeatureFlags);
 
         DataProfile enterpriseDataProfile = new DataProfile.Builder()
                 .setApnSetting(ENTERPRISE_APN_SETTING)
@@ -342,12 +345,12 @@
         TelephonyNetworkRequest urllcRequest = new TelephonyNetworkRequest(
                 new NetworkRequest.Builder()
                         .addCapability(NetworkCapabilities.NET_CAPABILITY_PRIORITIZE_LATENCY)
-                        .build(), mPhone);
+                        .build(), mPhone, mFeatureFlags);
 
         TelephonyNetworkRequest embbRequest = new TelephonyNetworkRequest(
                 new NetworkRequest.Builder()
                         .addCapability(NetworkCapabilities.NET_CAPABILITY_PRIORITIZE_BANDWIDTH)
-                        .build(), mPhone);
+                        .build(), mPhone, mFeatureFlags);
 
         DataProfile urllcDataProfile = new DataProfile.Builder()
                 .setTrafficDescriptor(new TrafficDescriptor(null, new TrafficDescriptor.OsAppId(
@@ -364,12 +367,12 @@
         TelephonyNetworkRequest urllcRequest = new TelephonyNetworkRequest(
                 new NetworkRequest.Builder()
                         .addCapability(NetworkCapabilities.NET_CAPABILITY_PRIORITIZE_LATENCY)
-                        .build(), mPhone);
+                        .build(), mPhone, mFeatureFlags);
 
         TelephonyNetworkRequest embbRequest = new TelephonyNetworkRequest(
                 new NetworkRequest.Builder()
                         .addCapability(NetworkCapabilities.NET_CAPABILITY_PRIORITIZE_BANDWIDTH)
-                        .build(), mPhone);
+                        .build(), mPhone, mFeatureFlags);
 
         DataProfile embbDataProfile = new DataProfile.Builder()
                 .setTrafficDescriptor(new TrafficDescriptor(null, new TrafficDescriptor.OsAppId(
@@ -386,12 +389,12 @@
         TelephonyNetworkRequest cbsRequest = new TelephonyNetworkRequest(
                 new NetworkRequest.Builder()
                         .addCapability(NetworkCapabilities.NET_CAPABILITY_CBS)
-                        .build(), mPhone);
+                        .build(), mPhone, mFeatureFlags);
 
         TelephonyNetworkRequest embbRequest = new TelephonyNetworkRequest(
                 new NetworkRequest.Builder()
                         .addCapability(NetworkCapabilities.NET_CAPABILITY_PRIORITIZE_BANDWIDTH)
-                        .build(), mPhone);
+                        .build(), mPhone, mFeatureFlags);
 
         DataProfile cbsDataProfile = new DataProfile.Builder()
                 .setTrafficDescriptor(new TrafficDescriptor(null, new TrafficDescriptor.OsAppId(
@@ -402,4 +405,92 @@
         assertThat(cbsRequest.canBeSatisfiedBy(cbsDataProfile)).isTrue();
         assertThat(embbRequest.canBeSatisfiedBy(cbsDataProfile)).isFalse();
     }
+
+    @Test
+    public void testSatelliteNetworkRequest() {
+        when(mFeatureFlags.satelliteInternet()).thenReturn(true);
+        TelephonyNetworkRequest satelliteRequest = new TelephonyNetworkRequest(
+                new NetworkRequest.Builder()
+                        .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
+                        .addTransportType(NetworkCapabilities.TRANSPORT_SATELLITE)
+                        .build(), mPhone, mFeatureFlags);
+
+        TelephonyNetworkRequest generalRequest = new TelephonyNetworkRequest(
+                new NetworkRequest.Builder()
+                        .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
+                        .build(), mPhone, mFeatureFlags);
+
+        ApnSetting satelliteInternetApn = new ApnSetting.Builder()
+                .setEntryName("apn")
+                .setApnName("apn")
+                .setApnTypeBitmask(ApnSetting.TYPE_DEFAULT)
+                .setCarrierEnabled(true)
+                .setInfrastructureBitmask(ApnSetting.INFRASTRUCTURE_SATELLITE)
+                .build();
+
+        ApnSetting cellularInternetApn = new ApnSetting.Builder()
+                .setEntryName("apn")
+                .setApnName("apn")
+                .setApnTypeBitmask(ApnSetting.TYPE_DEFAULT)
+                .setCarrierEnabled(true)
+                .setInfrastructureBitmask(ApnSetting.INFRASTRUCTURE_CELLULAR)
+                .build();
+
+        DataProfile satelliteInternetDataProfile = new DataProfile.Builder()
+                .setApnSetting(satelliteInternetApn)
+                .build();
+
+        DataProfile cellularInternetDataProfile = new DataProfile.Builder()
+                .setApnSetting(cellularInternetApn)
+                .build();
+
+        assertThat(satelliteRequest.canBeSatisfiedBy(satelliteInternetDataProfile)).isTrue();
+        assertThat(generalRequest.canBeSatisfiedBy(satelliteInternetDataProfile)).isTrue();
+        assertThat(satelliteRequest.canBeSatisfiedBy(cellularInternetDataProfile)).isFalse();
+        assertThat(generalRequest.canBeSatisfiedBy(cellularInternetDataProfile)).isTrue();
+    }
+
+    @Test
+    public void testCellularNetworkRequest() {
+        doReturn(true).when(mFeatureFlags).satelliteInternet();
+        TelephonyNetworkRequest cellularRequest = new TelephonyNetworkRequest(
+                new NetworkRequest.Builder()
+                        .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
+                        .addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR)
+                        .build(), mPhone, mFeatureFlags);
+
+        TelephonyNetworkRequest generalRequest = new TelephonyNetworkRequest(
+                new NetworkRequest.Builder()
+                        .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
+                        .build(), mPhone, mFeatureFlags);
+
+        ApnSetting satelliteInternetApn = new ApnSetting.Builder()
+                .setEntryName("apn")
+                .setApnName("apn")
+                .setApnTypeBitmask(ApnSetting.TYPE_DEFAULT)
+                .setCarrierEnabled(true)
+                .setInfrastructureBitmask(ApnSetting.INFRASTRUCTURE_SATELLITE)
+                .build();
+
+        ApnSetting cellularInternetApn = new ApnSetting.Builder()
+                .setEntryName("apn")
+                .setApnName("apn")
+                .setApnTypeBitmask(ApnSetting.TYPE_DEFAULT)
+                .setCarrierEnabled(true)
+                .setInfrastructureBitmask(ApnSetting.INFRASTRUCTURE_CELLULAR)
+                .build();
+
+        DataProfile satelliteInternetDataProfile = new DataProfile.Builder()
+                .setApnSetting(satelliteInternetApn)
+                .build();
+
+        DataProfile cellularInternetDataProfile = new DataProfile.Builder()
+                .setApnSetting(cellularInternetApn)
+                .build();
+
+        assertThat(cellularRequest.canBeSatisfiedBy(satelliteInternetDataProfile)).isFalse();
+        assertThat(generalRequest.canBeSatisfiedBy(satelliteInternetDataProfile)).isTrue();
+        assertThat(cellularRequest.canBeSatisfiedBy(cellularInternetDataProfile)).isTrue();
+        assertThat(generalRequest.canBeSatisfiedBy(cellularInternetDataProfile)).isTrue();
+    }
 }
diff --git a/tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsPhoneTest.java b/tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsPhoneTest.java
index 14cff4b..992f50a 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsPhoneTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsPhoneTest.java
@@ -73,6 +73,7 @@
 import android.os.Message;
 import android.os.PersistableBundle;
 import android.sysprop.TelephonyProperties;
+import android.telecom.VideoProfile;
 import android.telephony.CarrierConfigManager;
 import android.telephony.ServiceState;
 import android.telephony.SubscriptionInfo;
@@ -284,6 +285,14 @@
         doReturn(Call.State.INCOMING).when(mRingingCall).getState();
         assertEquals(true, mImsPhoneUT.handleInCallMmiCommands("2"));
         verify(mImsCT).acceptCall(ImsCallProfile.CALL_TYPE_VOICE);
+
+        // Verify b/286499659, fixed media type
+        doReturn(true).when(mFeatureFlags).answerAudioOnlyWhenAnsweringViaMmiCode();
+        doReturn(Call.State.IDLE).when(mForegroundCall).getState();
+        doReturn(Call.State.IDLE).when(mBackgroundCall).getState();
+        doReturn(Call.State.INCOMING).when(mRingingCall).getState();
+        assertEquals(true, mImsPhoneUT.handleInCallMmiCommands("2"));
+        verify(mImsCT).acceptCall(VideoProfile.STATE_AUDIO_ONLY);
     }
 
     @Test
diff --git a/tests/telephonytests/src/com/android/internal/telephony/metrics/MetricsCollectorTest.java b/tests/telephonytests/src/com/android/internal/telephony/metrics/MetricsCollectorTest.java
index 0426737..35f1bb7 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/metrics/MetricsCollectorTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/metrics/MetricsCollectorTest.java
@@ -70,8 +70,8 @@
                     .setCoolDownMillis(24L * 3600L * 1000L)
                     .build();
     private static final long MIN_COOLDOWN_MILLIS = 23L * 3600L * 1000L;
-    private static final long CELL_SERVICE_MIN_COOLDOWN_MILLIS =
-            IS_DEBUGGABLE ? 4L *  60L * 1000L : MIN_COOLDOWN_MILLIS;
+    private static final long POWER_CORRELATED_MIN_COOLDOWN_MILLIS =
+            IS_DEBUGGABLE ? 4L *  60L * 1000L : 5L * 3600L * 1000L;
     private static final long MIN_CALLS_PER_BUCKET = 5L;
 
     // NOTE: these fields are currently 32-bit internally and padded to 64-bit by TelephonyManager
@@ -402,6 +402,9 @@
     @SmallTest
     public void onPullAtom_cellularServiceState_tooFrequent() throws Exception {
         doReturn(null).when(mPersistAtomsStorage).getCellularServiceStates(anyLong());
+        mContextFixture.putIntResource(
+                com.android.internal.R.integer.config_metrics_pull_cooldown_millis,
+                (int) POWER_CORRELATED_MIN_COOLDOWN_MILLIS);
         List<StatsEvent> actualAtoms = new ArrayList<>();
 
         int result = mMetricsCollector.onPullAtom(CELLULAR_SERVICE_STATE, actualAtoms);
@@ -409,7 +412,7 @@
         assertThat(actualAtoms).hasSize(0);
         assertThat(result).isEqualTo(StatsManager.PULL_SKIP);
         verify(mPersistAtomsStorage, times(1)).getCellularServiceStates(
-                eq(CELL_SERVICE_MIN_COOLDOWN_MILLIS));
+                eq(POWER_CORRELATED_MIN_COOLDOWN_MILLIS));
         verifyNoMoreInteractions(mPersistAtomsStorage);
     }
 
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 bf841d0..0f77e31 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/satellite/SatelliteControllerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/satellite/SatelliteControllerTest.java
@@ -1684,6 +1684,8 @@
 
         // Trigger carrier config changed with carrierEnabledSatelliteFlag enabled
         when(mFeatureFlags.carrierEnabledSatelliteFlag()).thenReturn(true);
+        mCarrierConfigBundle.putBoolean(CarrierConfigManager.KEY_SATELLITE_ATTACH_SUPPORTED_BOOL,
+                true);
         for (Pair<Executor, CarrierConfigManager.CarrierConfigChangeListener> pair
                 : mCarrierConfigChangedListenerList) {
             pair.first.execute(() -> pair.second.onCarrierConfigChanged(
@@ -2689,8 +2691,8 @@
         verify(mMockSatelliteModemInterface, times(1)).setSatellitePlmn(anyInt(),
                 eq(plmnListPerCarrier), eq(allSatellitePlmnList), any(Message.class));
 
-        // If the PlmnListPerCarrier and the overlay config plmn list are exist verify passing
-        // the modem.
+        // If the PlmnListPerCarrier and the overlay config plmn list are exist but
+        // KEY_SATELLITE_ATTACH_SUPPORTED_BOOL is false, verify passing to the modem.
         entitlementPlmnList = Arrays.stream(new String[]{"00101", "00102", "00103"}).toList();
         overlayConfigPlmnList =
                 Arrays.stream(new String[]{"00101", "00102", "00104"}).toList();
@@ -2701,6 +2703,22 @@
                 entitlementPlmnList, mIIntegerConsumer);
 
         plmnListPerCarrier = mSatelliteControllerUT.getSatellitePlmnsForCarrier(SUB_ID);
+        assertEquals(new ArrayList<>(), plmnListPerCarrier);
+        allSatellitePlmnList = SatelliteServiceUtils.mergeStrLists(
+                entitlementPlmnList, overlayConfigPlmnList);
+        verify(mMockSatelliteModemInterface, times(1)).setSatellitePlmn(anyInt(),
+                eq(entitlementPlmnList), eq(allSatellitePlmnList), any(Message.class));
+
+        // If the PlmnListPerCarrier and the overlay config plmn list are exist and
+        // KEY_SATELLITE_ATTACH_SUPPORTED_BOOL is true verify passing the modem.
+        reset(mMockSatelliteModemInterface);
+        mCarrierConfigBundle.putBoolean(CarrierConfigManager.KEY_SATELLITE_ATTACH_SUPPORTED_BOOL,
+                true);
+
+        mSatelliteControllerUT.onSatelliteEntitlementStatusUpdated(SUB_ID, true,
+                entitlementPlmnList, mIIntegerConsumer);
+
+        plmnListPerCarrier = mSatelliteControllerUT.getSatellitePlmnsForCarrier(SUB_ID);
         allSatellitePlmnList = SatelliteServiceUtils.mergeStrLists(
                 plmnListPerCarrier, overlayConfigPlmnList);
 
diff --git a/tests/telephonytests/src/com/android/internal/telephony/security/CellularNetworkSecuritySafetySourceTest.java b/tests/telephonytests/src/com/android/internal/telephony/security/CellularNetworkSecuritySafetySourceTest.java
index 76118c4..77759a0 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/security/CellularNetworkSecuritySafetySourceTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/security/CellularNetworkSecuritySafetySourceTest.java
@@ -36,6 +36,7 @@
 import android.content.Context;
 import android.content.Intent;
 import android.safetycenter.SafetySourceData;
+import android.safetycenter.SafetySourceIssue;
 import android.util.Singleton;
 
 import com.android.internal.R;
@@ -50,6 +51,7 @@
 import org.mockito.ArgumentCaptor;
 
 import java.time.Instant;
+import java.util.List;
 
 public final class CellularNetworkSecuritySafetySourceTest extends TelephonyTest {
 
@@ -76,6 +78,8 @@
 
         mContextFixture.putResource(R.string.scCellularNetworkSecurityTitle, "fake");
         mContextFixture.putResource(R.string.scCellularNetworkSecuritySummary, "fake");
+        mContextFixture.putResource(R.string.scCellularNetworkSecurityLearnMore,
+                "https://support.google.com/android?p=cellular_security");
         mContextFixture.putResource(R.string.scNullCipherIssueNonEncryptedTitle, "fake %1$s");
         mContextFixture.putResource(R.string.scNullCipherIssueNonEncryptedSummary, "fake");
         mContextFixture.putResource(R.string.scNullCipherIssueEncryptedTitle, "fake %1$s");
@@ -172,6 +176,26 @@
     }
 
     @Test
+    public void clearNullCipherState() {
+        ArgumentCaptor<SafetySourceData> data = ArgumentCaptor.forClass(SafetySourceData.class);
+
+        mSafetySource.setNullCipherIssueEnabled(mContext, true);
+        mSafetySource.setNullCipherState(mContext, 0, NULL_CIPHER_STATE_NOTIFY_ENCRYPTED);
+        mSafetySource.clearNullCipherState(mContext, 0);
+
+        // Once for enable, once for encrypted state, and once for clearing state
+        verify(mSafetyCenterManagerWrapper, times(3)).setSafetySourceData(data.capture());
+
+        // initial check that our encrypted state update created an issue
+        assertThat(data.getAllValues().get(1).getStatus()).isNotNull();
+        assertThat(data.getAllValues().get(1).getIssues()).hasSize(1);
+
+        // assert that our last call to clear state results in no issues sent to SC
+        assertThat(data.getAllValues().get(2).getStatus()).isNotNull();
+        assertThat(data.getAllValues().get(2).getIssues()).isEmpty();
+    }
+
+    @Test
     public void disableIdentifierDisclosueIssue_nullData() {
         // We must first enable before disabling, since a standalone call to disable may result in
         // a no-op when the default for a new notifier is to be disabled.
@@ -245,4 +269,24 @@
         assertThat(data.getAllValues().get(3).getStatus()).isNotNull();
         assertThat(data.getAllValues().get(3).getIssues()).hasSize(2);
     }
+
+    @Test
+    public void learnMoreLinkEmpty_learnMoreIsHidden() {
+        mContextFixture.putResource(R.string.scCellularNetworkSecurityLearnMore, "");
+
+        ArgumentCaptor<SafetySourceData> data = ArgumentCaptor.forClass(SafetySourceData.class);
+
+        mSafetySource.setNullCipherIssueEnabled(mContext, true);
+        mSafetySource.setNullCipherState(mContext, 0, NULL_CIPHER_STATE_NOTIFY_NON_ENCRYPTED);
+        mSafetySource.setIdentifierDisclosureIssueEnabled(mContext, true);
+        mSafetySource.setIdentifierDisclosure(mContext, 0, 12, Instant.now(), Instant.now());
+
+        verify(mSafetyCenterManagerWrapper, times(4)).setSafetySourceData(data.capture());
+        List<SafetySourceIssue.Action> actions = data.getAllValues().get(
+                3).getIssues().getFirst().getActions();
+
+        // we only see the action that takes you to the settings page
+        assertThat(actions).hasSize(1);
+        assertThat(actions.getFirst().getId()).isEqualTo("cellular_security_settings");
+    }
 }
\ No newline at end of file
diff --git a/tests/telephonytests/src/com/android/internal/telephony/security/NullCipherNotifierTest.java b/tests/telephonytests/src/com/android/internal/telephony/security/NullCipherNotifierTest.java
index 0bb7b76..6a4d2fb 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/security/NullCipherNotifierTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/security/NullCipherNotifierTest.java
@@ -45,6 +45,7 @@
 public class NullCipherNotifierTest {
 
     private static final int SUB_ID = 3425;
+    private static final int PHONE_ID = 999;
     private static final List<Integer> NON_TRANSPORT_LAYER_EVENTS =
             List.of(SecurityAlgorithmUpdate.CONNECTION_EVENT_VOLTE_SIP,
                     SecurityAlgorithmUpdate.CONNECTION_EVENT_VOLTE_SIP_SOS,
@@ -149,9 +150,11 @@
     @Test
     public void onSecurityAlgorithmUpdate_enabled_unprotectedEmergency_noSafetySourceUpdate() {
         NullCipherNotifier notifier = new NullCipherNotifier(mExecutor, mSafetySource);
+        notifier.enable(mContext);
 
         notifier.onSecurityAlgorithmUpdate(
                 mContext,
+                PHONE_ID,
                 SUB_ID,
                 new SecurityAlgorithmUpdate(
                         SecurityAlgorithmUpdate.CONNECTION_EVENT_AS_SIGNALLING_5G,
@@ -163,6 +166,24 @@
     }
 
     @Test
+    public void onSecurityAlgorithmUpdate_disabled_noSafetySourceUpdate() {
+        NullCipherNotifier notifier = new NullCipherNotifier(mExecutor, mSafetySource);
+        notifier.disable(mContext);
+
+        notifier.onSecurityAlgorithmUpdate(
+                mContext,
+                PHONE_ID,
+                SUB_ID,
+                new SecurityAlgorithmUpdate(
+                        SecurityAlgorithmUpdate.CONNECTION_EVENT_AS_SIGNALLING_5G,
+                        SecurityAlgorithmUpdate.SECURITY_ALGORITHM_EEA2,
+                        SecurityAlgorithmUpdate.SECURITY_ALGORITHM_HMAC_SHA1_96,
+                        /* isUnprotectedEmergency= */ false));
+
+        verify(mSafetySource, never()).setNullCipherState(any(), anyInt(), anyInt());
+    }
+
+    @Test
     public void onSecurityAlgorithmUpdate_enabled_nonTransportLayerEvent_noSafetySourceUpdate() {
         NullCipherNotifier notifier = new NullCipherNotifier(mExecutor, mSafetySource);
 
@@ -170,6 +191,7 @@
             clearInvocations(mSafetySource);
             notifier.onSecurityAlgorithmUpdate(
                     mContext,
+                    PHONE_ID,
                     SUB_ID,
                     new SecurityAlgorithmUpdate(
                             connectionEvent,
@@ -185,12 +207,14 @@
     @Test
     public void onUpdate_enabled_transportLayerEvent_encryptionNullCipher_notifyNonEncrypted() {
         NullCipherNotifier notifier = new NullCipherNotifier(mExecutor, mSafetySource);
+        notifier.enable(mContext);
 
         for (int connectionEvent : TRANSPORT_LAYER_EVENTS) {
             for (int encryptionAlgorithm : NULL_CIPHERS) {
                 clearInvocations(mSafetySource);
                 notifier.onSecurityAlgorithmUpdate(
                         mContext,
+                        PHONE_ID,
                         SUB_ID,
                         new SecurityAlgorithmUpdate(
                                 connectionEvent,
@@ -214,12 +238,14 @@
     @Test
     public void onUpdate_enabled_transportLayerEvent_integrityNullCipher_notifyNonEncrypted() {
         NullCipherNotifier notifier = new NullCipherNotifier(mExecutor, mSafetySource);
+        notifier.enable(mContext);
 
         for (int connectionEvent : TRANSPORT_LAYER_EVENTS) {
             for (int integrityAlgorithm : NULL_CIPHERS) {
                 clearInvocations(mSafetySource);
                 notifier.onSecurityAlgorithmUpdate(
                         mContext,
+                        PHONE_ID,
                         SUB_ID,
                         new SecurityAlgorithmUpdate(
                                 connectionEvent,
@@ -243,12 +269,14 @@
     @Test
     public void onUpdate_enabled_transportLayerEvent_encryptionNonNullCipher_encrypted() {
         NullCipherNotifier notifier = new NullCipherNotifier(mExecutor, mSafetySource);
+        notifier.enable(mContext);
 
         for (int connectionEvent : TRANSPORT_LAYER_EVENTS) {
             for (int encryptionAlgorithm : NON_NULL_CIPHERS) {
                 clearInvocations(mSafetySource);
                 notifier.onSecurityAlgorithmUpdate(
                         mContext,
+                        PHONE_ID,
                         SUB_ID,
                         new SecurityAlgorithmUpdate(
                                 connectionEvent,
@@ -272,12 +300,14 @@
     @Test
     public void onUpdate_enabled_transportLayerEvent_integrityNonNullCipher_encrypted() {
         NullCipherNotifier notifier = new NullCipherNotifier(mExecutor, mSafetySource);
+        notifier.enable(mContext);
 
         for (int connectionEvent : TRANSPORT_LAYER_EVENTS) {
             for (int integrityAlgorithm : NON_NULL_CIPHERS) {
                 clearInvocations(mSafetySource);
                 notifier.onSecurityAlgorithmUpdate(
                         mContext,
+                        PHONE_ID,
                         SUB_ID,
                         new SecurityAlgorithmUpdate(
                                 connectionEvent,
@@ -301,11 +331,13 @@
     @Test
     public void onUpdate_enabled_transportLayerEvent_encryptionNonNullCipher_notifyEncrypted() {
         NullCipherNotifier notifier = new NullCipherNotifier(mExecutor, mSafetySource);
+        notifier.enable(mContext);
 
         for (int connectionEvent : TRANSPORT_LAYER_EVENTS) {
             for (int encryptionAlgorithm : NON_NULL_CIPHERS) {
                 notifier.onSecurityAlgorithmUpdate(
                         mContext,
+                        PHONE_ID,
                         SUB_ID,
                         new SecurityAlgorithmUpdate(
                                 connectionEvent,
@@ -316,6 +348,7 @@
                 clearInvocations(mSafetySource);
                 notifier.onSecurityAlgorithmUpdate(
                         mContext,
+                        PHONE_ID,
                         SUB_ID,
                         new SecurityAlgorithmUpdate(
                                 connectionEvent,
@@ -345,6 +378,7 @@
             for (int integrityAlgorithm : NON_NULL_CIPHERS) {
                 notifier.onSecurityAlgorithmUpdate(
                         mContext,
+                        PHONE_ID,
                         SUB_ID,
                         new SecurityAlgorithmUpdate(
                                 connectionEvent,
@@ -355,6 +389,7 @@
                 clearInvocations(mSafetySource);
                 notifier.onSecurityAlgorithmUpdate(
                         mContext,
+                        PHONE_ID,
                         SUB_ID,
                         new SecurityAlgorithmUpdate(
                                 connectionEvent,
@@ -374,4 +409,88 @@
             }
         }
     }
+
+    @Test
+    public void onSecurityAlgorithmUpdate_updateSubscriptionId_clearsOldId() {
+        NullCipherNotifier notifier = new NullCipherNotifier(mExecutor, mSafetySource);
+        notifier.enable(mContext);
+
+        int connectionEvent = SecurityAlgorithmUpdate.CONNECTION_EVENT_AS_SIGNALLING_5G;
+        int encryptionAlgorithm = SecurityAlgorithmUpdate.SECURITY_ALGORITHM_EEA2;
+        int subId2 = 1337;
+
+        notifier.onSecurityAlgorithmUpdate(
+                mContext,
+                PHONE_ID,
+                SUB_ID,
+                getWellEncryptedUpdate());
+
+        notifier.setSubscriptionMapping(mContext, PHONE_ID, subId2);
+
+        verify(
+                mSafetySource,
+                times(1).description(
+                        "Connection event: " + connectionEvent
+                                + " Encryption algorithm: " + encryptionAlgorithm))
+                .setNullCipherState(
+                        eq(mContext),
+                        eq(SUB_ID),
+                        eq(NULL_CIPHER_STATE_ENCRYPTED));
+
+        verify(mSafetySource, times(1)).clearNullCipherState(eq(mContext), eq(SUB_ID));
+    }
+
+    @Test
+    public void onSecurityAlgorithmUpdate_newSubIdOnAlgoUpdate_clearsOldId() {
+        NullCipherNotifier notifier = new NullCipherNotifier(mExecutor, mSafetySource);
+        notifier.enable(mContext);
+
+        int connectionEvent = SecurityAlgorithmUpdate.CONNECTION_EVENT_AS_SIGNALLING_5G;
+        int encryptionAlgorithm = SecurityAlgorithmUpdate.SECURITY_ALGORITHM_EEA2;
+        int subId2 = 1337;
+
+        notifier.onSecurityAlgorithmUpdate(
+                mContext,
+                PHONE_ID,
+                SUB_ID,
+                getWellEncryptedUpdate());
+
+        notifier.onSecurityAlgorithmUpdate(
+                mContext,
+                PHONE_ID,
+                subId2,
+                getWellEncryptedUpdate());
+
+        verify(
+                mSafetySource,
+                times(1).description(
+                        "SubId: " + SUB_ID + "Connection event: " + connectionEvent
+                                + " Encryption algorithm: " + encryptionAlgorithm))
+                .setNullCipherState(
+                        eq(mContext),
+                        eq(SUB_ID),
+                        eq(NULL_CIPHER_STATE_ENCRYPTED));
+
+        // The update with subId2 should clear subId1 data since they have the same phone id
+        verify(mSafetySource, times(1)).clearNullCipherState(eq(mContext), eq(SUB_ID));
+
+        verify(
+                mSafetySource,
+                times(1).description(
+                        "SubId: " + SUB_ID + "Connection event: " + connectionEvent
+                                + " Encryption algorithm: " + encryptionAlgorithm))
+                .setNullCipherState(
+                        eq(mContext),
+                        eq(subId2),
+                        eq(NULL_CIPHER_STATE_ENCRYPTED));
+
+    }
+
+    private SecurityAlgorithmUpdate getWellEncryptedUpdate() {
+        return new SecurityAlgorithmUpdate(
+                SecurityAlgorithmUpdate.CONNECTION_EVENT_AS_SIGNALLING_5G,
+                SecurityAlgorithmUpdate.SECURITY_ALGORITHM_EEA2,
+                SecurityAlgorithmUpdate.SECURITY_ALGORITHM_HMAC_SHA1_96,
+                /* isUnprotectedEmergency= */ false);
+    }
 }