Merge tag 'android-16.0.0_r4' into staging/lineage-23.2_merge-android-16.0.0_r4

Android 16.0.0 release 4

# -----BEGIN PGP SIGNATURE-----
#
# iF0EABECAB0WIQRDQNE1cO+UXoOBCWTorT+BmrEOeAUCaS5htAAKCRDorT+BmrEO
# eJutAJ48PgRjYCUcVGGjq+s9qz2r8KD8hgCfXBBXNWF8SNR3SlAd9qYouNdM31s=
# =DUYm
# -----END PGP SIGNATURE-----
# gpg: Signature made Tue Dec  2 05:49:08 2025 EET
# gpg:                using DSA key 4340D13570EF945E83810964E8AD3F819AB10E78
# gpg: Good signature from "The Android Open Source Project <initial-contribution@android.com>" [ultimate]

* tag 'android-16.0.0_r4': (190 commits)
  Restored the incorrect CDMA code removal
  Fixed the incorrect dead code removal
  Fixed network capabilities metrics
  [Flag Removal] Remove flag com.android.internal.telephony.flags.qos_update_network_agent
  flags: fix namespace in minimal_telephony_cdm_check_board_api_level
  Fix to not mark MT CS call as an emergency call
  DSRM: Prevent data stall recovered events without prior data stall detected
  Prevent ClassCastException in UiccCarrierPrivilegeRules by adding a type check for the result of iccOpenLogicalChannel.
  Add P-CSCF address flag
  Check against current board API level to look for C/D/M support
  Always use TelephonyCapabilities to check for C/D/M support
  Send onEmergencyModeChanged before returning the result of the enable request
  [Flag Removal] Remove flag com.android.internal.telephony.flags.immediately_process_do_not_show_again_broadcast
  Set emergency mode for E-SMS with test number
  Cleanup flag: disableEcbmBasedOnRat
  Supports to get NR Duplex Mode in ServiceState
  fetch 3 digit mnc correctly for 262-800 mcc mnc
  Fixed multiple remote SIM can't be inserted issue
  Allow NONE service class in terminal based call waiting
  [Telephony][Security Fix] Launch Browser only if device is unlocked.
  ...

 Conflicts:
	proto/src/persist_atoms.proto
	src/java/com/android/internal/telephony/metrics/MetricsCollector.java
	src/java/com/android/internal/telephony/metrics/SatelliteStats.java
	src/java/com/android/internal/telephony/satellite/SatelliteController.java
	src/java/com/android/internal/telephony/satellite/metrics/ControllerMetricsStats.java
	tests/telephonytests/src/com/android/internal/telephony/metrics/PersistAtomsStorageTest.java
	tests/telephonytests/src/com/android/internal/telephony/satellite/SatelliteControllerTest.java

Change-Id: I30ac66865c8cfc9a747a472d2f828c48b48a27c2
diff --git a/src/java/com/android/internal/telephony/CarrierServiceStateTracker.java b/src/java/com/android/internal/telephony/CarrierServiceStateTracker.java
index 0fba3cd..02872f7 100644
--- a/src/java/com/android/internal/telephony/CarrierServiceStateTracker.java
+++ b/src/java/com/android/internal/telephony/CarrierServiceStateTracker.java
@@ -1,5 +1,6 @@
 /*
  * Copyright (C) 2016 The Android Open Source Project
+ * Copyright (C) 2025 The LineageOS Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -178,7 +179,7 @@
             mPhone.getContext().registerReceiver(
                     mActionReceiver,
                     new IntentFilter(ACTION_NEVER_ASK_AGAIN),
-                    Context.RECEIVER_NOT_EXPORTED);
+                    Context.RECEIVER_EXPORTED);
         }
     }
 
diff --git a/src/java/com/android/internal/telephony/RadioMessagingProxy.java b/src/java/com/android/internal/telephony/RadioMessagingProxy.java
index 0313efe..165bc98 100644
--- a/src/java/com/android/internal/telephony/RadioMessagingProxy.java
+++ b/src/java/com/android/internal/telephony/RadioMessagingProxy.java
@@ -251,15 +251,16 @@
         if (isAidl()) {
             android.hardware.radio.messaging.ImsSmsMessage msg =
                     new android.hardware.radio.messaging.ImsSmsMessage();
-            msg.tech = android.hardware.radio.RadioTechnologyFamily.THREE_GPP;
             msg.retry = (byte) retry >= 1;
             msg.messageRef = messageRef;
             if (gsmPdu != null) {
+                msg.tech = android.hardware.radio.RadioTechnologyFamily.THREE_GPP;
                 msg.gsmMessage = new android.hardware.radio.messaging.GsmSmsMessage[]{
                         RILUtils.convertToHalGsmSmsMessageAidl(smscPdu, gsmPdu)};
                 msg.cdmaMessage = new android.hardware.radio.messaging.CdmaSmsMessage[0];
             }
             if (cdmaPdu != null) {
+                msg.tech = android.hardware.radio.RadioTechnologyFamily.THREE_GPP2;
                 msg.gsmMessage = new android.hardware.radio.messaging.GsmSmsMessage[0];
                 msg.cdmaMessage = new android.hardware.radio.messaging.CdmaSmsMessage[]{
                         RILUtils.convertToHalCdmaSmsMessageAidl(cdmaPdu)};
@@ -268,13 +269,14 @@
         } else {
             android.hardware.radio.V1_0.ImsSmsMessage msg =
                     new android.hardware.radio.V1_0.ImsSmsMessage();
-            msg.tech = android.hardware.radio.V1_0.RadioTechnologyFamily.THREE_GPP;
             msg.retry = (byte) retry >= 1;
             msg.messageRef = messageRef;
             if (gsmPdu != null) {
+                msg.tech = android.hardware.radio.V1_0.RadioTechnologyFamily.THREE_GPP;
                 msg.gsmMessage.add(RILUtils.convertToHalGsmSmsMessage(smscPdu, gsmPdu));
             }
             if (cdmaPdu != null) {
+                msg.tech = android.hardware.radio.V1_0.RadioTechnologyFamily.THREE_GPP2;
                 msg.cdmaMessage.add(RILUtils.convertToHalCdmaSmsMessage(cdmaPdu));
             }
             mRadioProxy.sendImsSms(serial, msg);
diff --git a/src/java/com/android/internal/telephony/data/PhoneSwitcher.java b/src/java/com/android/internal/telephony/data/PhoneSwitcher.java
index ff73367..f81b594 100644
--- a/src/java/com/android/internal/telephony/data/PhoneSwitcher.java
+++ b/src/java/com/android/internal/telephony/data/PhoneSwitcher.java
@@ -1185,7 +1185,7 @@
 
     private void switchPhone(int phoneId, boolean active) {
         PhoneState state = mPhoneStates[phoneId];
-        if (state.active == active) return;
+        if (mHalCommandToUse != HAL_COMMAND_ALLOW_DATA && state.active == active) return;
         state.active = active;
         logl((active ? "activate " : "deactivate ") + phoneId);
         state.lastRequested = System.currentTimeMillis();
@@ -1835,6 +1835,11 @@
                     hold the retry until sim gets ready */
                     logl("onDdsSwitchResponse: Wait for SIM to get READY");
                     return;
+                } else if (error == CommandException.Error.RADIO_NOT_AVAILABLE) {
+                    logl("onDdsSwitchResponse: Falling back to HAL_COMMAND_ALLOW_DATA");
+                    mHalCommandToUse = HAL_COMMAND_ALLOW_DATA;
+                    sendRilCommands(phoneId);
+                    return;
                 }
             }
             logl("onDdsSwitchResponse: Scheduling DDS switch retry");
diff --git a/src/java/com/android/internal/telephony/imsphone/ImsPhoneCallTracker.java b/src/java/com/android/internal/telephony/imsphone/ImsPhoneCallTracker.java
index 56963f3..c500a19 100644
--- a/src/java/com/android/internal/telephony/imsphone/ImsPhoneCallTracker.java
+++ b/src/java/com/android/internal/telephony/imsphone/ImsPhoneCallTracker.java
@@ -70,6 +70,7 @@
 import android.os.RegistrantList;
 import android.os.RemoteException;
 import android.os.SystemClock;
+import android.os.SystemProperties;
 import android.os.UserHandle;
 import android.preference.PreferenceManager;
 import android.provider.Settings;
@@ -382,7 +383,17 @@
         @Nullable
         public IImsCallSessionListener onIncomingCall(
                 @NonNull IImsCallSession c, @Nullable String callId, @Nullable Bundle extras) {
-            return executeAndWaitForReturn(()-> processIncomingCall(c, callId, extras));
+            final boolean shouldBlockBinderThreadOnIncomingCalls = SystemProperties.getBoolean(
+                    "ro.telephony.block_binder_thread_on_incoming_calls", true);
+            if (shouldBlockBinderThreadOnIncomingCalls) {
+                return executeAndWaitForReturn(()-> processIncomingCall(c, callId, extras));
+            } else {
+                // for legacy IMS we want to avoid blocking the binder thread, otherwise
+                // we end up with half dead incoming calls with unattached call session
+                TelephonyUtils.runWithCleanCallingIdentity(()-> processIncomingCall(
+                        c, callId, extras), mExecutor);
+                return null;
+            }
         }
 
         @Override
diff --git a/src/java/com/android/internal/telephony/uicc/UiccProfile.java b/src/java/com/android/internal/telephony/uicc/UiccProfile.java
index 1206ce7..1ea53f9 100644
--- a/src/java/com/android/internal/telephony/uicc/UiccProfile.java
+++ b/src/java/com/android/internal/telephony/uicc/UiccProfile.java
@@ -726,24 +726,16 @@
                 break;
             case APPSTATE_READY:
                 checkAndUpdateIfAnyAppToBeIgnored();
-                if (areAllApplicationsReady()) {
-                    if (areAllRecordsLoaded() && areCarrierPrivilegeRulesLoaded()) {
-                        if (VDBG) log("updateExternalState: setting state to LOADED");
-                        setExternalState(IccCardConstants.State.LOADED);
-                    } else {
-                        if (VDBG) {
-                            log("updateExternalState: setting state to READY; records loaded "
-                                    + areAllRecordsLoaded() + ", carrier privilige rules loaded "
-                                    + areCarrierPrivilegeRulesLoaded());
-                        }
-                        setExternalState(IccCardConstants.State.READY);
-                    }
+                if (areReadyAppsRecordsLoaded() && areCarrierPrivilegeRulesLoaded()) {
+                    if (VDBG) log("updateExternalState: setting state to LOADED");
+                    setExternalState(IccCardConstants.State.LOADED);
                 } else {
                     if (VDBG) {
-                        log("updateExternalState: app state is READY but not for all apps; "
-                                + "setting state to NOT_READY");
+                        log("updateExternalState: setting state to READY; records loaded "
+                                + areReadyAppsRecordsLoaded() + ", carrier privilige rules loaded "
+                                + areCarrierPrivilegeRulesLoaded());
                     }
-                    setExternalState(IccCardConstants.State.NOT_READY);
+                    setExternalState(IccCardConstants.State.READY);
                 }
                 break;
         }
@@ -1245,33 +1237,19 @@
         }
     }
 
-    private boolean areAllApplicationsReady() {
+    private boolean areReadyAppsRecordsLoaded() {
         for (UiccCardApplication app : mUiccApplications) {
-            if (app != null && isSupportedApplication(app) && !app.isReady()
+            if (app != null && isSupportedApplication(app) && app.isReady()
                     && !app.isAppIgnored()) {
-                if (VDBG) log("areAllApplicationsReady: return false");
-                return false;
-            }
-        }
-
-        if (VDBG) {
-            log("areAllApplicationsReady: outside loop, return " + (mUiccApplication != null));
-        }
-        return mUiccApplication != null;
-    }
-
-    private boolean areAllRecordsLoaded() {
-        for (UiccCardApplication app : mUiccApplications) {
-            if (app != null && isSupportedApplication(app) && !app.isAppIgnored()) {
                 IccRecords ir = app.getIccRecords();
                 if (ir == null || !ir.isLoaded()) {
-                    if (VDBG) log("areAllRecordsLoaded: return false");
+                    if (VDBG) log("areReadyAppsRecordsLoaded: return false");
                     return false;
                 }
             }
         }
         if (VDBG) {
-            log("areAllRecordsLoaded: outside loop, return " + (mUiccApplication != null));
+            log("areReadyAppsRecordsLoaded: outside loop, return " + (mUiccApplication != null));
         }
         return mUiccApplication != null;
     }