Merge "CarrierServiceBindHelper: incorrect user unlocked event received in HSUM" into main
diff --git a/src/java/com/android/internal/telephony/Connection.java b/src/java/com/android/internal/telephony/Connection.java
index 82b4c2b8e..7a1c8fe 100644
--- a/src/java/com/android/internal/telephony/Connection.java
+++ b/src/java/com/android/internal/telephony/Connection.java
@@ -692,8 +692,18 @@
                     && mEmergencyNumberInfo.getEmergencyCallRouting()
                         != EmergencyNumber.EMERGENCY_CALL_ROUTING_EMERGENCY) {
                 int eccCategory = dialArgs.intentExtras.getInt(
-                        PhoneConstants.EXTRA_EMERGENCY_SERVICE_CATEGORY,
-                        mEmergencyNumberInfo.getEmergencyServiceCategoryBitmask());
+                    PhoneConstants.EXTRA_EMERGENCY_SERVICE_CATEGORY,
+                    mEmergencyNumberInfo.getEmergencyServiceCategoryBitmask());
+                // According to 3gpp 23.167 section 7.1.2, when CS domain is selected,
+                // emergency routing is performed only if the emergency category is provided.
+                if (this instanceof GsmCdmaConnection
+                        && dialArgs.intentExtras.getInt(
+                                PhoneConstants.EXTRA_EMERGENCY_SERVICE_CATEGORY,
+                                EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_UNSPECIFIED)
+                                == EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_UNSPECIFIED) {
+                    Rlog.d(TAG, "setEmergencyCallInfo: specific eccCategory is required");
+                    return;
+                }
                 Rlog.d(TAG, "setEmergencyCallInfo: enforce emergency routing eccCategory="
                         + eccCategory);
                 List<String> emergencyUrns = dialArgs.intentExtras.getStringArrayList(
@@ -706,13 +716,32 @@
                         mEmergencyNumberInfo.getMnc(),
                         eccCategory,
                         emergencyUrns,
-                        mEmergencyNumberInfo.getEmergencyNumberSourceBitmask(),
+                        getEmergencyNumberSourceForEmergencyRouting(),
                         EmergencyNumber.EMERGENCY_CALL_ROUTING_EMERGENCY);
             }
         }
     }
 
     /**
+     * Get the emergency number source to be used for emergency routing calls.
+     * This is not getting actual source, instead its forcing the source to
+     * EMERGENCY_NUMBER_SOURCE_NETWORK_SIGNALING.
+     * Even when the source is EMERGENCY_NUMBER_SOURCE_DATABASE,
+     * to allow the category information delivered by the network to be used,
+     * the source is set to EMERGENCY_NUMBER_SOURCE_NETWORK_SIGNALING.
+     */
+    private int getEmergencyNumberSourceForEmergencyRouting() {
+        int source = mEmergencyNumberInfo.getEmergencyNumberSourceBitmask();
+        Rlog.d(TAG, "getEmergencyNumberSourceForEmergencyRouting: source=" + source);
+
+        if (source != EmergencyNumber.EMERGENCY_NUMBER_SOURCE_TEST) {
+            source = EmergencyNumber.EMERGENCY_NUMBER_SOURCE_NETWORK_SIGNALING;
+        }
+
+        return source;
+    }
+
+    /**
      * Set the non-detectable emergency number information.
      */
     public void setNonDetectableEmergencyCallInfo(int eccCategory,
diff --git a/src/java/com/android/internal/telephony/GsmCdmaConnection.java b/src/java/com/android/internal/telephony/GsmCdmaConnection.java
index cc07047..d96663a 100644
--- a/src/java/com/android/internal/telephony/GsmCdmaConnection.java
+++ b/src/java/com/android/internal/telephony/GsmCdmaConnection.java
@@ -30,6 +30,7 @@
 import android.telephony.DisconnectCause;
 import android.telephony.PhoneNumberUtils;
 import android.telephony.ServiceState;
+import android.telephony.emergency.EmergencyNumber;
 import android.text.TextUtils;
 
 import com.android.internal.telephony.PhoneInternalInterface.DialArgs;
@@ -186,7 +187,7 @@
 
         mAddress = PhoneNumberUtils.extractNetworkPortionAlt(dialString);
         if (dialArgs.isEmergency) {
-            setEmergencyCallInfo(mOwner, null);
+            setEmergencyCallInfo(mOwner, dialArgs);
 
             // There was no emergency number info found for this call, however it is
             // still marked as an emergency number. This may happen if it was a redialed
diff --git a/src/java/com/android/internal/telephony/InboundSmsHandler.java b/src/java/com/android/internal/telephony/InboundSmsHandler.java
index 8e7505e..c7c05bc 100644
--- a/src/java/com/android/internal/telephony/InboundSmsHandler.java
+++ b/src/java/com/android/internal/telephony/InboundSmsHandler.java
@@ -2154,8 +2154,9 @@
                 UserManager userManager =
                         (UserManager) context.getSystemService(Context.USER_SERVICE);
                 if (userManager.isUserUnlocked()) {
-                    context.startActivity(context.getPackageManager().getLaunchIntentForPackage(
-                            Telephony.Sms.getDefaultSmsPackage(context)));
+                    context.startActivityAsUser(context.getPackageManager()
+                            .getLaunchIntentForPackage(Telephony.Sms.getDefaultSmsPackage(context)),
+                            UserHandle.CURRENT);
                 }
             }
         }
diff --git a/src/java/com/android/internal/telephony/NetworkScanRequestTracker.java b/src/java/com/android/internal/telephony/NetworkScanRequestTracker.java
index c09f8fb..9b2b847 100644
--- a/src/java/com/android/internal/telephony/NetworkScanRequestTracker.java
+++ b/src/java/com/android/internal/telephony/NetworkScanRequestTracker.java
@@ -33,6 +33,7 @@
 import android.os.Messenger;
 import android.os.Process;
 import android.os.RemoteException;
+import android.os.UserHandle;
 import android.telephony.CellInfo;
 import android.telephony.LocationAccessPolicy;
 import android.telephony.NetworkScan;
@@ -567,8 +568,8 @@
         //   3. The live scan is not requested by mobile network setting menu
         private synchronized boolean interruptLiveScan(NetworkScanRequestInfo nsri) {
             if (mLiveRequestInfo != null && mPendingRequestInfo == null
-                    && nsri.mUid == Process.SYSTEM_UID
-                            && mLiveRequestInfo.mUid != Process.SYSTEM_UID) {
+                    && UserHandle.isSameApp(nsri.mUid, Process.SYSTEM_UID)
+                            && !UserHandle.isSameApp(mLiveRequestInfo.mUid, Process.SYSTEM_UID)) {
                 doInterruptScan(mLiveRequestInfo.mScanId);
                 mPendingRequestInfo = nsri;
                 notifyMessenger(mLiveRequestInfo, TelephonyScanManager.CALLBACK_SCAN_ERROR,
diff --git a/src/java/com/android/internal/telephony/Phone.java b/src/java/com/android/internal/telephony/Phone.java
index 2bbcc99..69b19aa 100644
--- a/src/java/com/android/internal/telephony/Phone.java
+++ b/src/java/com/android/internal/telephony/Phone.java
@@ -898,6 +898,8 @@
                         Rlog.e(mLogTag, "Invalid Exception for usage setting " + ar.exception);
                         break; // technically extraneous, but good hygiene
                     }
+                } else {
+                    mUsageSettingFromModem = msg.arg1;
                 }
                 break;
             default:
@@ -4484,7 +4486,8 @@
             mCi.getUsageSetting(obtainMessage(EVENT_GET_USAGE_SETTING_DONE));
             // If the modem value is already known, and the value has changed, proceed to update.
         } else if (mPreferredUsageSetting != mUsageSettingFromModem) {
-            mCi.setUsageSetting(obtainMessage(EVENT_SET_USAGE_SETTING_DONE),
+            mCi.setUsageSetting(obtainMessage(EVENT_SET_USAGE_SETTING_DONE,
+                        mPreferredUsageSetting, 0 /* unused */),
                     mPreferredUsageSetting);
         }
         return true;
diff --git a/src/java/com/android/internal/telephony/emergency/RadioOnStateListener.java b/src/java/com/android/internal/telephony/emergency/RadioOnStateListener.java
index eaff539..1b1922c 100644
--- a/src/java/com/android/internal/telephony/emergency/RadioOnStateListener.java
+++ b/src/java/com/android/internal/telephony/emergency/RadioOnStateListener.java
@@ -152,6 +152,11 @@
         public void onEmergencyModeChanged(boolean isEmergency) {
             Rlog.d(TAG, "onEmergencyModeChanged: ignored " + isEmergency);
         }
+
+        @Override
+        public void onRegistrationFailure(int causeCode) {
+            Rlog.d(TAG, "onRegistrationFailure: causeCode " + causeCode);
+        }
     };
 
     private Callback mCallback; // The callback to notify upon completion.
diff --git a/src/java/com/android/internal/telephony/satellite/PointingAppController.java b/src/java/com/android/internal/telephony/satellite/PointingAppController.java
index ae2781d..9606150 100644
--- a/src/java/com/android/internal/telephony/satellite/PointingAppController.java
+++ b/src/java/com/android/internal/telephony/satellite/PointingAppController.java
@@ -34,6 +34,7 @@
 import android.os.Message;
 import android.os.RemoteException;
 import android.os.SystemProperties;
+import android.os.UserHandle;
 import android.telephony.DropBoxManagerLoggerBackend;
 import android.telephony.PersistentLogger;
 import android.telephony.Rlog;
@@ -426,7 +427,7 @@
             mLastNeedFullScreenPointingUI = needFullScreenPointingUI;
             mLastIsDemoMode = isDemoMode;
             mLastIsEmergency = isEmergency;
-            mContext.startActivity(launchIntent);
+            mContext.startActivityAsUser(launchIntent, UserHandle.CURRENT);
         } catch (ActivityNotFoundException ex) {
             ploge("startPointingUI: Pointing UI app activity is not found, ex=" + ex);
         }
diff --git a/src/java/com/android/internal/telephony/satellite/SatelliteController.java b/src/java/com/android/internal/telephony/satellite/SatelliteController.java
index 52ec0ba..695887e 100644
--- a/src/java/com/android/internal/telephony/satellite/SatelliteController.java
+++ b/src/java/com/android/internal/telephony/satellite/SatelliteController.java
@@ -261,6 +261,7 @@
     protected static final int
             EVENT_WAIT_FOR_UPDATE_SATELLITE_ENABLE_ATTRIBUTES_RESPONSE_TIMED_OUT = 52;
     private static final int EVENT_WAIT_FOR_REPORT_ENTITLED_TO_MERTICS_HYSTERESIS_TIMED_OUT = 53;
+    protected static final int EVENT_SATELLITE_REGISTRATION_FAILURE = 54;
 
     @NonNull private static SatelliteController sInstance;
     @NonNull private final Context mContext;
@@ -341,6 +342,8 @@
             new AtomicBoolean(false);
     private final AtomicBoolean mRegisteredForSatelliteSupportedStateChanged =
             new AtomicBoolean(false);
+    private final AtomicBoolean mRegisteredForSatelliteRegistrationFailure =
+            new AtomicBoolean(false);
     /**
      * Map key: subId, value: callback to get error code of the provision request.
      */
@@ -369,6 +372,12 @@
      */
     private final ConcurrentHashMap<IBinder, ISatelliteSupportedStateCallback>
             mSatelliteSupportedStateChangedListeners = new ConcurrentHashMap<>();
+
+    /**
+     * Map key: binder of the callback, value: callback to satellite registration failure
+     */
+    private final ConcurrentHashMap<IBinder, ISatelliteModemStateCallback>
+            mSatelliteRegistrationFailureListeners = new ConcurrentHashMap<>();
     private final Object mIsSatelliteSupportedLock = new Object();
     @GuardedBy("mIsSatelliteSupportedLock")
     private Boolean mIsSatelliteSupported = null;
@@ -1790,6 +1799,15 @@
                 break;
             }
 
+            case EVENT_SATELLITE_REGISTRATION_FAILURE:
+                ar = (AsyncResult) msg.obj;
+                if (ar.result == null) {
+                    loge("EVENT_SATELLITE_REGISTRATION_FAILURE: result is null");
+                } else {
+                    handleEventSatelliteRegistrationFailure((int) ar.result);
+                }
+                break;
+
             default:
                 Log.w(TAG, "SatelliteControllerHandler: unexpected message code: " +
                         msg.what);
@@ -2246,12 +2264,6 @@
     public void stopSatelliteTransmissionUpdates(@NonNull IIntegerConsumer errorCallback,
             @NonNull ISatelliteTransmissionUpdateCallback callback) {
         Consumer<Integer> result = FunctionalUtils.ignoreRemoteException(errorCallback::accept);
-        int error = evaluateOemSatelliteRequestAllowed(true);
-        if (error != SATELLITE_RESULT_SUCCESS) {
-            result.accept(error);
-            return;
-        }
-
         mPointingAppController.unregisterForSatelliteTransmissionUpdates(
                 getHighestPrioritySubscrption(), result, callback);
 
@@ -2426,6 +2438,10 @@
             plogd("registerForSatelliteModemStateChanged: oemEnabledSatelliteFlag is disabled");
             return SatelliteManager.SATELLITE_RESULT_NOT_SUPPORTED;
         }
+        if (mFeatureFlags.carrierRoamingNbIotNtn()) {
+            plogd("registerForSatelliteModemStateChanged: add RegistrationFailure Listeners");
+            mSatelliteRegistrationFailureListeners.put(callback.asBinder(), callback);
+        }
         if (mSatelliteSessionController != null) {
             mSatelliteSessionController.registerForSatelliteModemStateChanged(callback);
         } else {
@@ -2455,6 +2471,10 @@
             ploge("unregisterForModemStateChanged: mSatelliteSessionController"
                     + " is not initialized yet");
         }
+        if (mFeatureFlags.carrierRoamingNbIotNtn()) {
+            plogd("unregisterForModemStateChanged: remove RegistrationFailure Listeners");
+            mSatelliteRegistrationFailureListeners.remove(callback.asBinder());
+        }
     }
 
     /**
@@ -2747,7 +2767,7 @@
             @NonNull INtnSignalStrengthCallback callback) throws RemoteException {
         if (DBG) plogd("registerForNtnSignalStrengthChanged()");
 
-        int error = evaluateOemSatelliteRequestAllowed(true);
+        int error = evaluateOemSatelliteRequestAllowed(false);
         if (error == SATELLITE_RESULT_SUCCESS) {
             mNtnSignalStrengthChangedListeners.put(callback.asBinder(), callback);
             synchronized (mNtnSignalsStrengthLock) {
@@ -2775,11 +2795,7 @@
     public void unregisterForNtnSignalStrengthChanged(
             @NonNull INtnSignalStrengthCallback callback) {
         if (DBG) plogd("unregisterForNtnSignalStrengthChanged()");
-
-        int error = evaluateOemSatelliteRequestAllowed(true);
-        if (error == SATELLITE_RESULT_SUCCESS) {
-            mNtnSignalStrengthChangedListeners.remove(callback.asBinder());
-        }
+        mNtnSignalStrengthChangedListeners.remove(callback.asBinder());
     }
 
     /**
@@ -2793,7 +2809,7 @@
             @NonNull ISatelliteCapabilitiesCallback callback) {
         if (DBG) plogd("registerForCapabilitiesChanged()");
 
-        int error = evaluateOemSatelliteRequestAllowed(true);
+        int error = evaluateOemSatelliteRequestAllowed(false);
         if (error != SATELLITE_RESULT_SUCCESS) return error;
 
         mSatelliteCapabilitiesChangedListeners.put(callback.asBinder(), callback);
@@ -2811,11 +2827,7 @@
     public void unregisterForCapabilitiesChanged(
             @NonNull ISatelliteCapabilitiesCallback callback) {
         if (DBG) plogd("unregisterForCapabilitiesChanged()");
-
-        int error = evaluateOemSatelliteRequestAllowed(true);
-        if (error == SATELLITE_RESULT_SUCCESS) {
-            mSatelliteCapabilitiesChangedListeners.remove(callback.asBinder());
-        }
+        mSatelliteCapabilitiesChangedListeners.remove(callback.asBinder());
     }
 
     /**
@@ -3892,6 +3904,7 @@
             registerForSatelliteModemStateChanged();
             registerForNtnSignalStrengthChanged();
             registerForCapabilitiesChanged();
+            registerForSatelliteRegistrationFailure();
 
             requestIsSatelliteProvisioned(
                     new ResultReceiver(this) {
@@ -3996,6 +4009,16 @@
         }
     }
 
+    private void registerForSatelliteRegistrationFailure() {
+        if (mFeatureFlags.carrierRoamingNbIotNtn()) {
+            if (!mRegisteredForSatelliteRegistrationFailure.get()) {
+                mSatelliteModemInterface.registerForSatelliteRegistrationFailure(this,
+                        EVENT_SATELLITE_REGISTRATION_FAILURE, null);
+                mRegisteredForSatelliteRegistrationFailure.set(true);
+            }
+        }
+    }
+
     private void handleEventSatelliteProvisionStateChanged(boolean provisioned) {
         plogd("handleSatelliteProvisionStateChangedEvent: provisioned=" + provisioned);
 
@@ -6494,6 +6517,23 @@
         }
     }
 
+    private void handleEventSatelliteRegistrationFailure(int causeCode) {
+        plogd("handleEventSatelliteRegistrationFailure: " + causeCode);
+
+        List<ISatelliteModemStateCallback> deadCallersList = new ArrayList<>();
+        mSatelliteRegistrationFailureListeners.values().forEach(listener -> {
+            try {
+                listener.onRegistrationFailure(causeCode);
+            } catch (RemoteException e) {
+                logd("handleEventSatelliteRegistrationFailure RemoteException: " + e);
+                deadCallersList.add(listener);
+            }
+        });
+        deadCallersList.forEach(listener -> {
+            mSatelliteRegistrationFailureListeners.remove(listener.asBinder());
+        });
+    }
+
     /**
      * This API can be used by only CTS to override the cached value for the device overlay config
      * value :
diff --git a/src/java/com/android/internal/telephony/satellite/SatelliteModemInterface.java b/src/java/com/android/internal/telephony/satellite/SatelliteModemInterface.java
index d644cc1..a19f802 100644
--- a/src/java/com/android/internal/telephony/satellite/SatelliteModemInterface.java
+++ b/src/java/com/android/internal/telephony/satellite/SatelliteModemInterface.java
@@ -102,6 +102,8 @@
             new RegistrantList();
     @NonNull private final RegistrantList mSatelliteSupportedStateChangedRegistrants =
             new RegistrantList();
+    @NonNull private final RegistrantList mSatelliteRegistrationFailureRegistrants =
+            new RegistrantList();
 
     private class SatelliteListener extends ISatelliteListener.Stub {
 
@@ -187,7 +189,7 @@
 
         @Override
         public void onRegistrationFailure(int causeCode) {
-            // TO-DO notify registrants
+            mSatelliteRegistrationFailureRegistrants.notifyResult(causeCode);
         }
 
         private boolean notifyResultIfExpectedListener() {
@@ -564,6 +566,27 @@
     }
 
     /**
+     * Registers for the satellite registration failed.
+     *
+     * @param h Handler for notification message.
+     * @param what User-defined message code.
+     * @param obj User object.
+     */
+    public void registerForSatelliteRegistrationFailure(
+            @NonNull Handler h, int what, @Nullable Object obj) {
+        mSatelliteRegistrationFailureRegistrants.add(h, what, obj);
+    }
+
+    /**
+     * Unregisters for the satellite registration failed.
+     *
+     * @param h Handler to be removed from the registrant list.
+     */
+    public void unregisterForSatelliteRegistrationFailure(@NonNull Handler h) {
+        mSatelliteRegistrationFailureRegistrants.remove(h);
+    }
+
+    /**
      * Request to enable or disable the satellite service listening mode.
      * Listening mode allows the satellite service to listen for incoming pages.
      *
diff --git a/src/java/com/android/internal/telephony/satellite/SatelliteSOSMessageRecommender.java b/src/java/com/android/internal/telephony/satellite/SatelliteSOSMessageRecommender.java
index c4babcb..d42a410 100644
--- a/src/java/com/android/internal/telephony/satellite/SatelliteSOSMessageRecommender.java
+++ b/src/java/com/android/internal/telephony/satellite/SatelliteSOSMessageRecommender.java
@@ -316,7 +316,8 @@
             boolean isCellularAvailable = SatelliteServiceUtils.isCellularAvailable();
             if (!isCellularAvailable
                     && isSatelliteAllowed()
-                    && (isSatelliteViaOemAvailable() || isSatelliteViaCarrierAvailable())
+                    && (isSatelliteViaOemAvailable()
+                    || isSatelliteConnectedViaCarrierWithinHysteresisTime())
                     && shouldTrackCall(mEmergencyConnection.getState())) {
                 plogd("handleTimeoutEvent: Sent EVENT_DISPLAY_EMERGENCY_MESSAGE to Dialer");
                 Bundle extras = createExtraBundleForEventDisplayEmergencyMessage();
@@ -336,7 +337,7 @@
 
     private boolean isSatelliteAllowed() {
         synchronized (mLock) {
-            if (isSatelliteViaCarrierAvailable()) return true;
+            if (isSatelliteConnectedViaCarrierWithinHysteresisTime()) return true;
             return mIsSatelliteAllowedForCurrentLocation;
         }
     }
@@ -358,7 +359,7 @@
         return satelliteProvisioned != null ? satelliteProvisioned : false;
     }
 
-    private boolean isSatelliteViaCarrierAvailable() {
+    private boolean isSatelliteConnectedViaCarrierWithinHysteresisTime() {
         return mIsSatelliteConnectedViaCarrierWithinHysteresisTime.get();
     }
 
@@ -532,7 +533,7 @@
     }
 
     private void selectEmergencyCallWaitForConnectionTimeoutDuration() {
-        if (mSatelliteController.isSatelliteEmergencyMessagingSupportedViaCarrier()) {
+        if (isSatelliteConnectedViaCarrierWithinHysteresisTime()) {
             mTimeoutMillis =
                     mSatelliteController.getCarrierEmergencyCallWaitForConnectionTimeoutMillis();
         } else {
@@ -639,7 +640,7 @@
         String className = oemSatelliteMessagingApp.second;
         String action = getSatelliteEmergencyHandoverIntentActionFromOverlayConfig(mContext);
 
-        if (isSatelliteViaCarrierAvailable()
+        if (isSatelliteConnectedViaCarrierWithinHysteresisTime()
                 || isEmergencyCallToSatelliteHandoverTypeT911Enforced()) {
             ComponentName defaultSmsAppComponent = getDefaultSmsApp();
             handoverType = EMERGENCY_CALL_TO_SATELLITE_HANDOVER_TYPE_T911;
@@ -723,7 +724,7 @@
     @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE)
     public int getEmergencyCallToSatelliteHandoverType() {
         if (Flags.carrierRoamingNbIotNtn() && isSatelliteViaOemAvailable()
-                && isSatelliteViaCarrierAvailable()) {
+                && isSatelliteConnectedViaCarrierWithinHysteresisTime()) {
             Phone satellitePhone = mSatelliteController.getSatellitePhone();
             if (satellitePhone == null) {
                 ploge("getEmergencyCallToSatelliteHandoverType: satellitePhone is null");
@@ -732,7 +733,7 @@
             int satelliteSubId = satellitePhone.getSubId();
             return mSatelliteController.getCarrierRoamingNtnEmergencyCallToSatelliteHandoverType(
                     satelliteSubId);
-        } else if (isSatelliteViaCarrierAvailable()) {
+        } else if (isSatelliteConnectedViaCarrierWithinHysteresisTime()) {
             return EMERGENCY_CALL_TO_SATELLITE_HANDOVER_TYPE_T911;
         } else {
             return EMERGENCY_CALL_TO_SATELLITE_HANDOVER_TYPE_SOS;
diff --git a/src/java/com/android/internal/telephony/uicc/InstallCarrierAppTrampolineActivity.java b/src/java/com/android/internal/telephony/uicc/InstallCarrierAppTrampolineActivity.java
index 2c29266..a07c2ec 100644
--- a/src/java/com/android/internal/telephony/uicc/InstallCarrierAppTrampolineActivity.java
+++ b/src/java/com/android/internal/telephony/uicc/InstallCarrierAppTrampolineActivity.java
@@ -22,6 +22,7 @@
 import android.content.Intent;
 import android.content.res.Resources;
 import android.os.Bundle;
+import android.os.UserHandle;
 import android.provider.Settings;
 import android.text.TextUtils;
 import android.util.Log;
@@ -107,7 +108,8 @@
         super.onActivityResult(requestCode, resultCode, data);
         if (requestCode == INSTALL_CARRIER_APP_DIALOG_REQUEST) {
             if (resultCode == DOWNLOAD_RESULT) {
-                startActivity(InstallCarrierAppUtils.getPlayStoreIntent(mPackageName));
+                startActivityAsUser(InstallCarrierAppUtils.getPlayStoreIntent(mPackageName),
+                        UserHandle.CURRENT);
             }
             finishNoAnimation();
         }
diff --git a/src/java/com/android/internal/telephony/uicc/UiccProfile.java b/src/java/com/android/internal/telephony/uicc/UiccProfile.java
index 6d9ef37..2551cb8 100644
--- a/src/java/com/android/internal/telephony/uicc/UiccProfile.java
+++ b/src/java/com/android/internal/telephony/uicc/UiccProfile.java
@@ -41,6 +41,7 @@
 import android.os.PersistableBundle;
 import android.os.Registrant;
 import android.os.RegistrantList;
+import android.os.UserHandle;
 import android.os.UserManager;
 import android.preference.PreferenceManager;
 import android.provider.Settings;
@@ -1356,7 +1357,7 @@
     private void promptInstallCarrierApp(String pkgName) {
         Intent showDialogIntent = InstallCarrierAppTrampolineActivity.get(mContext, pkgName);
         showDialogIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-        mContext.startActivity(showDialogIntent);
+        mContext.startActivityAsUser(showDialogIntent, UserHandle.CURRENT);
     }
 
     private void onCarrierPrivilegesLoadedMessage() {
diff --git a/tests/telephonytests/src/com/android/internal/telephony/ContextFixture.java b/tests/telephonytests/src/com/android/internal/telephony/ContextFixture.java
index 3ecb1e2..70e3dee 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/ContextFixture.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/ContextFixture.java
@@ -687,6 +687,9 @@
 
         @Override
         public void startActivity(Intent intent) {}
+
+        @Override
+        public void startActivityAsUser(Intent intent, UserHandle user) {}
     }
 
     private final Multimap<String, ComponentName> mComponentNamesByAction =
diff --git a/tests/telephonytests/src/com/android/internal/telephony/GsmCdmaConnectionTest.java b/tests/telephonytests/src/com/android/internal/telephony/GsmCdmaConnectionTest.java
index 45f8c12..e56ac90 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/GsmCdmaConnectionTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/GsmCdmaConnectionTest.java
@@ -21,10 +21,12 @@
 import static org.junit.Assert.*;
 import static org.mockito.Mockito.*;
 
+import android.os.Bundle;
 import android.os.Handler;
 import android.os.Looper;
 import android.telephony.DisconnectCause;
 import android.telephony.PhoneNumberUtils;
+import android.telephony.emergency.EmergencyNumber;
 import android.testing.AndroidTestingRunner;
 import android.testing.TestableLooper;
 
@@ -313,4 +315,52 @@
         assertEquals(DisconnectCause.OUT_OF_SERVICE,
                 connection.disconnectCauseFromCode(CallFailCause.LOCAL_SERVICE_UNAVAILABLE));
     }
+
+    @Test
+    public void testUpdateEmergencyRouting() {
+        Bundle extras = new Bundle();
+        extras.putBoolean(PhoneConstants.EXTRA_USE_EMERGENCY_ROUTING, true);
+
+        DialArgs dialArgs = new DialArgs.Builder()
+                .setIsEmergency(true)
+                .setIntentExtras(extras)
+                .build();
+
+        doReturn(true).when(mDomainSelectionResolver).isDomainSelectionSupported();
+
+        connection = new GsmCdmaConnection(mPhone, "911", mCT, null, dialArgs);
+        // Not updated when category is unset.
+        assertEquals(getTestEmergencyNumber(), connection.getEmergencyNumberInfo());
+
+        extras.putInt(PhoneConstants.EXTRA_EMERGENCY_SERVICE_CATEGORY,
+                EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_UNSPECIFIED);
+
+        dialArgs = new DialArgs.Builder()
+                .setIsEmergency(true)
+                .setIntentExtras(extras)
+                .build();
+
+        connection = new GsmCdmaConnection(mPhone, "911", mCT, null, dialArgs);
+        // Not updated when category is EMERGENCY_SERVICE_CATEGORY_UNSPECIFIED.
+        assertEquals(getTestEmergencyNumber(), connection.getEmergencyNumberInfo());
+
+        extras.putInt(PhoneConstants.EXTRA_EMERGENCY_SERVICE_CATEGORY,
+                EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_POLICE);
+
+        dialArgs = new DialArgs.Builder()
+                .setIsEmergency(true)
+                .setIntentExtras(extras)
+                .build();
+
+        connection = new GsmCdmaConnection(mPhone, "911", mCT, null, dialArgs);
+
+        EmergencyNumber expectedNumber = new EmergencyNumber("911", "us", "30",
+                EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_POLICE,
+                new ArrayList<String>(), EmergencyNumber.EMERGENCY_NUMBER_SOURCE_NETWORK_SIGNALING,
+                EmergencyNumber.EMERGENCY_CALL_ROUTING_EMERGENCY);
+
+        // Updated when category is not EMERGENCY_SERVICE_CATEGORY_UNSPECIFIED.
+        assertNotEquals(getTestEmergencyNumber(), connection.getEmergencyNumberInfo());
+        assertEquals(expectedNumber, connection.getEmergencyNumberInfo());
+    }
 }
diff --git a/tests/telephonytests/src/com/android/internal/telephony/GsmCdmaPhoneTest.java b/tests/telephonytests/src/com/android/internal/telephony/GsmCdmaPhoneTest.java
index ba08f8b..7735c97 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/GsmCdmaPhoneTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/GsmCdmaPhoneTest.java
@@ -2018,6 +2018,42 @@
 
     @Test
     @SmallTest
+    public void testUsageSettingUpdate_ResetToDefault() {
+        setupUsageSettingResources();
+        mPhoneUT.mCi = mMockCi;
+
+        SubscriptionInfoInternal si = makeSubscriptionInfoInternal(
+                false, SubscriptionManager.USAGE_SETTING_DATA_CENTRIC);
+        doReturn(si).when(mSubscriptionManagerService).getSubscriptionInfoInternal(anyInt());
+
+        mPhoneUT.updateUsageSetting();
+        processAllMessages();
+
+        verify(mMockCi).getUsageSetting(any());
+        mPhoneUT.sendMessage(mPhoneUT.obtainMessage(GsmCdmaPhone.EVENT_GET_USAGE_SETTING_DONE,
+                new AsyncResult(null,
+                        new int[]{SubscriptionManager.USAGE_SETTING_VOICE_CENTRIC}, null)));
+        processAllMessages();
+
+        // Grab the message to ensure it returns the preferred value for updating the cache
+        ArgumentCaptor<Message> messageCaptor = ArgumentCaptor.forClass(Message.class);
+        verify(mMockCi).setUsageSetting(
+                messageCaptor.capture(), eq(SubscriptionManager.USAGE_SETTING_DATA_CENTRIC));
+        AsyncResult.forMessage(messageCaptor.getValue());
+        messageCaptor.getValue().sendToTarget();
+        processAllMessages();
+
+        si = makeSubscriptionInfoInternal(false, SubscriptionManager.USAGE_SETTING_VOICE_CENTRIC);
+        doReturn(si).when(mSubscriptionManagerService).getSubscriptionInfoInternal(anyInt());
+
+        mPhoneUT.updateUsageSetting();
+        processAllMessages();
+
+        verify(mMockCi).setUsageSetting(any(), eq(SubscriptionManager.USAGE_SETTING_VOICE_CENTRIC));
+    }
+
+    @Test
+    @SmallTest
     public void testUsageSettingUpdate_DefaultOpportunistic() {
         setupUsageSettingResources();
         mPhoneUT.mCi = mMockCi;
diff --git a/tests/telephonytests/src/com/android/internal/telephony/satellite/PointingAppControllerTest.java b/tests/telephonytests/src/com/android/internal/telephony/satellite/PointingAppControllerTest.java
index aa24fb9..a228617 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/satellite/PointingAppControllerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/satellite/PointingAppControllerTest.java
@@ -39,6 +39,7 @@
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.Message;
+import android.os.UserHandle;
 import android.telephony.satellite.ISatelliteTransmissionUpdateCallback;
 import android.telephony.satellite.PointingInfo;
 import android.telephony.satellite.SatelliteManager;
@@ -321,7 +322,7 @@
     public void testStartPointingUI() throws Exception {
         ArgumentCaptor<Intent> startedIntentCaptor = ArgumentCaptor.forClass(Intent.class);
         mPointingAppController.startPointingUI(true, true, true);
-        verify(mContext).startActivity(startedIntentCaptor.capture());
+        verify(mContext).startActivityAsUser(startedIntentCaptor.capture(), eq(UserHandle.CURRENT));
         Intent intent = startedIntentCaptor.getValue();
         assertEquals(KEY_POINTING_UI_PACKAGE_NAME, intent.getComponent().getPackageName());
         assertEquals(KEY_POINTING_UI_CLASS_NAME, intent.getComponent().getClassName());
@@ -337,10 +338,12 @@
     @Test
     public void testRestartPointingUi() throws Exception {
         mPointingAppController.startPointingUI(true, false, true);
-        mInOrderForPointingUi.verify(mContext).startActivity(any(Intent.class));
+        mInOrderForPointingUi.verify(mContext).startActivityAsUser(any(Intent.class),
+                eq(UserHandle.CURRENT));
         testRestartPointingUi(true, false, true);
         mPointingAppController.startPointingUI(false, true, false);
-        mInOrderForPointingUi.verify(mContext).startActivity(any(Intent.class));
+        mInOrderForPointingUi.verify(mContext).startActivityAsUser(any(Intent.class),
+                eq(UserHandle.CURRENT));
         testRestartPointingUi(false, true, false);
     }
 
@@ -351,7 +354,8 @@
             .getPackagesForUid(anyInt());
         mPointingAppController.mUidImportanceListener.onUidImportance(1, IMPORTANCE_GONE);
         ArgumentCaptor<Intent> restartedIntentCaptor = ArgumentCaptor.forClass(Intent.class);
-        mInOrderForPointingUi.verify(mContext).startActivity(restartedIntentCaptor.capture());
+        mInOrderForPointingUi.verify(mContext).startActivityAsUser(restartedIntentCaptor.capture(),
+                eq(UserHandle.CURRENT));
         Intent restartIntent = restartedIntentCaptor.getValue();
         assertEquals(KEY_POINTING_UI_PACKAGE_NAME, restartIntent.getComponent().getPackageName());
         assertEquals(KEY_POINTING_UI_CLASS_NAME, restartIntent.getComponent().getClassName());
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 1d2889a..7f31f30 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/satellite/SatelliteControllerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/satellite/SatelliteControllerTest.java
@@ -1471,49 +1471,6 @@
 
     @Test
     public void testStopSatelliteTransmissionUpdates() {
-        mIIntegerConsumerSemaphore.drainPermits();
-        mIIntegerConsumerResults.clear();
-        mSatelliteControllerUT.stopSatelliteTransmissionUpdates(mIIntegerConsumer,
-                mStopTransmissionUpdateCallback);
-        processAllMessages();
-        assertTrue(waitForIIntegerConsumerResult(1));
-        assertEquals(SATELLITE_RESULT_INVALID_TELEPHONY_STATE,
-                (long) mIIntegerConsumerResults.get(0));
-
-        mIIntegerConsumerResults.clear();
-        setUpResponseForRequestIsSatelliteSupported(false, SATELLITE_RESULT_SUCCESS);
-        verifySatelliteSupported(false, SATELLITE_RESULT_SUCCESS);
-        mSatelliteControllerUT.stopSatelliteTransmissionUpdates(mIIntegerConsumer,
-                mStopTransmissionUpdateCallback);
-        processAllMessages();
-        assertTrue(waitForIIntegerConsumerResult(1));
-        assertEquals(SATELLITE_RESULT_NOT_SUPPORTED, (long) mIIntegerConsumerResults.get(0));
-
-        resetSatelliteControllerUT();
-        mIIntegerConsumerResults.clear();
-        setUpResponseForRequestIsSatelliteSupported(true, SATELLITE_RESULT_SUCCESS);
-        verifySatelliteSupported(true, SATELLITE_RESULT_SUCCESS);
-        mSatelliteControllerUT.stopSatelliteTransmissionUpdates(mIIntegerConsumer,
-                mStopTransmissionUpdateCallback);
-        processAllMessages();
-        assertTrue(waitForIIntegerConsumerResult(1));
-        assertEquals(SATELLITE_RESULT_SERVICE_NOT_PROVISIONED,
-                (long) mIIntegerConsumerResults.get(0));
-
-        resetSatelliteControllerUT();
-        mIIntegerConsumerResults.clear();
-        setUpResponseForRequestIsSatelliteSupported(true, SATELLITE_RESULT_SUCCESS);
-        setUpResponseForRequestIsSatelliteProvisioned(false, SATELLITE_RESULT_SUCCESS);
-        verifySatelliteSupported(true, SATELLITE_RESULT_SUCCESS);
-        verifySatelliteProvisioned(false, SATELLITE_RESULT_SUCCESS);
-        setUpResponseForStopSatelliteTransmissionUpdates(SATELLITE_RESULT_SUCCESS);
-        mSatelliteControllerUT.stopSatelliteTransmissionUpdates(mIIntegerConsumer,
-                mStopTransmissionUpdateCallback);
-        processAllMessages();
-        assertTrue(waitForIIntegerConsumerResult(1));
-        assertEquals(SATELLITE_RESULT_SERVICE_NOT_PROVISIONED,
-                (long) mIIntegerConsumerResults.get(0));
-
         resetSatelliteControllerUT();
         mIIntegerConsumerResults.clear();
         provisionSatelliteService();
@@ -1533,7 +1490,11 @@
         setUpResponseForStopSatelliteTransmissionUpdates(SATELLITE_RESULT_INVALID_TELEPHONY_STATE);
         mSatelliteControllerUT.stopSatelliteTransmissionUpdates(mIIntegerConsumer,
                 mStopTransmissionUpdateCallback);
+        verify(mMockPointingAppController, times(2)).unregisterForSatelliteTransmissionUpdates(
+                anyInt(), any(), eq(mStopTransmissionUpdateCallback));
         processAllMessages();
+        verify(mMockPointingAppController, times(2)).stopSatelliteTransmissionUpdates(
+                any(Message.class));
         assertTrue(waitForIIntegerConsumerResult(1));
         assertEquals(SATELLITE_RESULT_INVALID_TELEPHONY_STATE,
                 (long) mIIntegerConsumerResults.get(0));
@@ -1636,6 +1597,11 @@
             public void onEmergencyModeChanged(boolean isEmergency) {
                 logd("onEmergencyModeChanged: emergency=" + isEmergency);
             }
+
+            @Override
+            public void onRegistrationFailure(int causeCode) {
+                logd("onRegistrationFailure: causeCode=" + causeCode);
+            }
         };
         int errorCode = mSatelliteControllerUT.registerForSatelliteModemStateChanged(callback);
         assertEquals(SATELLITE_RESULT_INVALID_TELEPHONY_STATE, errorCode);
@@ -1662,6 +1628,11 @@
             public void onEmergencyModeChanged(boolean isEmergency) {
                 logd("onEmergencyModeChanged: emergency=" + isEmergency);
             }
+
+            @Override
+            public void onRegistrationFailure(int causeCode) {
+                logd("onRegistrationFailure: causeCode=" + causeCode);
+            }
         };
         mSatelliteControllerUT.unregisterForModemStateChanged(callback);
         verify(mMockSatelliteSessionController, never())
@@ -4189,6 +4160,46 @@
         assertFalse(mSatelliteControllerUT.getWwanIsInService(mServiceState));
     }
 
+    @Test
+    public void testRegistrationFailureCallback() {
+        when(mFeatureFlags.carrierRoamingNbIotNtn()).thenReturn(true);
+        Semaphore semaphore = new Semaphore(0);
+        final int[] resultErrorCode = new int[1];
+        ISatelliteModemStateCallback callback = new ISatelliteModemStateCallback.Stub() {
+            @Override
+            public void onSatelliteModemStateChanged(int state) {
+                logd("onSatelliteModemStateChanged: state=" + state);
+            }
+
+            @Override
+            public void onEmergencyModeChanged(boolean isEmergency) {
+                logd("onEmergencyModeChanged: emergency=" + isEmergency);
+            }
+
+            @Override
+            public void onRegistrationFailure(int causeCode) {
+                logd("onRegistrationFailure: causeCode=" + causeCode);
+                resultErrorCode[0] = causeCode;
+                semaphore.release();
+            }
+        };
+        resetSatelliteControllerUTToSupportedAndProvisionedState();
+        mSatelliteControllerUT.setSatelliteSessionController(mMockSatelliteSessionController);
+
+        int RegisterErrorCode = mSatelliteControllerUT.registerForSatelliteModemStateChanged(
+                callback);
+        assertEquals(SATELLITE_RESULT_SUCCESS, RegisterErrorCode);
+        verify(mMockSatelliteSessionController).registerForSatelliteModemStateChanged(callback);
+
+        int expectedErrorCode = 100;
+        mIIntegerConsumerResults.clear();
+        sendSatelliteRegistrationFailureEvent(100, null);
+        processAllMessages();
+        assertTrue(waitForForEvents(
+                semaphore, 1, "testRegistrationFailureCallback"));
+        assertEquals(expectedErrorCode, resultErrorCode[0]);
+    }
+
     private boolean mProvisionState = false;
     private int mProvisionSateResultCode = -1;
     private Semaphore mProvisionSateSemaphore = new Semaphore(0);
@@ -5109,6 +5120,13 @@
         msg.sendToTarget();
     }
 
+    private void sendSatelliteRegistrationFailureEvent(int errorCode, Throwable exception) {
+        Message msg = mSatelliteControllerUT.obtainMessage(
+                54 /* EVENT_SATELLITE_REGISTRATION_FAILURE */);
+        msg.obj = new AsyncResult(null, errorCode, exception);
+        msg.sendToTarget();
+    }
+
     private void setRadioPower(boolean on) {
         mSimulatedCommands.setRadioPower(on, false, false, null);
     }
diff --git a/tests/telephonytests/src/com/android/internal/telephony/satellite/SatelliteSOSMessageRecommenderTest.java b/tests/telephonytests/src/com/android/internal/telephony/satellite/SatelliteSOSMessageRecommenderTest.java
index 4cb8a03..358ec47 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/satellite/SatelliteSOSMessageRecommenderTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/satellite/SatelliteSOSMessageRecommenderTest.java
@@ -549,9 +549,22 @@
         assertEquals(TEST_EMERGENCY_CALL_TO_SOS_MSG_HYSTERESIS_TIMEOUT_MILLIS,
                 mTestSOSMessageRecommender.getTimeOutMillis());
 
-        // Both OEM and carrier support satellite. Thus, carrier's timeout duration will be used
+        // Both OEM and carrier support satellite, but device is not connected to carrier satellite
+        // within hysteresis time. Thus, OEM timer will be used.
         long carrierTimeoutMillis = 1000;
         mTestSatelliteController.isSatelliteEmergencyMessagingSupportedViaCarrier = true;
+        mTestSatelliteController.setSatelliteConnectedViaCarrierWithinHysteresisTime(false);
+        mTestSatelliteController.carrierEmergencyCallWaitForConnectionTimeoutMillis =
+                carrierTimeoutMillis;
+        mTestSOSMessageRecommender.onEmergencyCallStarted(mTestConnection);
+        processAllMessages();
+        assertEquals(TEST_EMERGENCY_CALL_TO_SOS_MSG_HYSTERESIS_TIMEOUT_MILLIS,
+                mTestSOSMessageRecommender.getTimeOutMillis());
+
+        // Both OEM and carrier support satellite, and device is connected to carrier satellite
+        // within hysteresis time. Thus, carrier timer will be used.
+        mTestSatelliteController.isSatelliteEmergencyMessagingSupportedViaCarrier = true;
+        mTestSatelliteController.setSatelliteConnectedViaCarrierWithinHysteresisTime(true);
         mTestSatelliteController.carrierEmergencyCallWaitForConnectionTimeoutMillis =
                 carrierTimeoutMillis;
         mTestSOSMessageRecommender.onEmergencyCallStarted(mTestConnection);
diff --git a/tests/telephonytests/src/com/android/internal/telephony/satellite/SatelliteSessionControllerTest.java b/tests/telephonytests/src/com/android/internal/telephony/satellite/SatelliteSessionControllerTest.java
index 95924dd..b4af458 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/satellite/SatelliteSessionControllerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/satellite/SatelliteSessionControllerTest.java
@@ -1488,6 +1488,11 @@
             }
         }
 
+        @Override
+        public void onRegistrationFailure(int causeCode) {
+            logd("onRegistrationFailure: causeCode=" + causeCode);
+        }
+
         public boolean waitUntilResultForModemStateChanged() {
             try {
                 if (!mSemaphoreForModemStateChanged.tryAcquire(EVENT_PROCESSING_TIME_MILLIS,