Merge changes from topic "move-emergency-phone-update"

* changes:
  Update docs for onEmergencyNumberListChanged
  Call onOutgoingEmergencyCall only once.
  Expose onEmergencyNumberListChanged, semantics change
diff --git a/api/current.txt b/api/current.txt
index 90c0eab..b251612 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -47801,6 +47801,7 @@
     method public void onDataConnectionStateChanged(int);
     method public void onDataConnectionStateChanged(int, int);
     method @RequiresPermission("android.permission.READ_PHONE_STATE") public void onDisplayInfoChanged(@NonNull android.telephony.TelephonyDisplayInfo);
+    method public void onEmergencyNumberListChanged(@NonNull java.util.Map<java.lang.Integer,java.util.List<android.telephony.emergency.EmergencyNumber>>);
     method @RequiresPermission("android.permission.READ_PRECISE_PHONE_STATE") public void onImsCallDisconnectCauseChanged(@NonNull android.telephony.ims.ImsReasonInfo);
     method public void onMessageWaitingIndicatorChanged(boolean);
     method @RequiresPermission("android.permission.MODIFY_PHONE_STATE") public void onPreciseDataConnectionStateChanged(@NonNull android.telephony.PreciseDataConnectionState);
diff --git a/api/system-current.txt b/api/system-current.txt
index 11b2828..e586d75 100755
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -10814,7 +10814,8 @@
 
   public class PhoneStateListener {
     method public void onCallAttributesChanged(@NonNull android.telephony.CallAttributes);
-    method public void onOutgoingEmergencyCall(@NonNull android.telephony.emergency.EmergencyNumber);
+    method @Deprecated public void onOutgoingEmergencyCall(@NonNull android.telephony.emergency.EmergencyNumber);
+    method public void onOutgoingEmergencyCall(@NonNull android.telephony.emergency.EmergencyNumber, int);
     method public void onOutgoingEmergencySms(@NonNull android.telephony.emergency.EmergencyNumber);
     method @RequiresPermission("android.permission.READ_PRECISE_PHONE_STATE") public void onPreciseCallStateChanged(@NonNull android.telephony.PreciseCallState);
     method public void onRadioPowerStateChanged(int);
diff --git a/api/test-current.txt b/api/test-current.txt
index bdf797e..0cabd6f 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -1627,6 +1627,10 @@
     method public static void setMinMatchForTest(int);
   }
 
+  public class PhoneStateListener {
+    method public void onOutgoingEmergencyCall(@NonNull android.telephony.emergency.EmergencyNumber, int);
+  }
+
   public final class PreciseDataConnectionState implements android.os.Parcelable {
     ctor @Deprecated public PreciseDataConnectionState(int, int, int, @NonNull String, @Nullable android.net.LinkProperties, int);
   }
diff --git a/core/java/android/telephony/PhoneStateListener.java b/core/java/android/telephony/PhoneStateListener.java
index 2be50e4..1ef52e2 100644
--- a/core/java/android/telephony/PhoneStateListener.java
+++ b/core/java/android/telephony/PhoneStateListener.java
@@ -20,6 +20,7 @@
 import android.annotation.NonNull;
 import android.annotation.RequiresPermission;
 import android.annotation.SystemApi;
+import android.annotation.TestApi;
 import android.compat.annotation.ChangeId;
 import android.compat.annotation.UnsupportedAppUsage;
 import android.os.Binder;
@@ -923,19 +924,21 @@
     /**
      * Callback invoked when the current emergency number list has changed on the registered
      * subscription.
-     * Note, the registration subId comes from {@link TelephonyManager} object which registers
-     * PhoneStateListener by {@link TelephonyManager#listen(PhoneStateListener, int)}.
+     *
+     * Note, the registered subscription is associated with {@link TelephonyManager} object
+     * on which {@link TelephonyManager#listen(PhoneStateListener, int)} was called.
      * If this TelephonyManager object was created with
      * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the
-     * subId. Otherwise, this callback applies to
+     * given subId. Otherwise, this callback applies to
      * {@link SubscriptionManager#getDefaultSubscriptionId()}.
      *
-     * @param emergencyNumberList Map including the key as the active subscription ID
-     *                           (Note: if there is no active subscription, the key is
-     *                           {@link SubscriptionManager#getDefaultSubscriptionId})
-     *                           and the value as the list of {@link EmergencyNumber};
-     *                           null if this information is not available.
-     * @hide
+     * @param emergencyNumberList Map associating all active subscriptions on the device with the
+     *                            list of emergency numbers originating from that subscription.
+     *                            If there are no active subscriptions, the map will contain a
+     *                            single entry with
+     *                            {@link SubscriptionManager#INVALID_SUBSCRIPTION_ID} as
+     *                            the key and a list of emergency numbers as the value. If no
+     *                            emergency number information is available, the value will be null.
      */
     public void onEmergencyNumberListChanged(
             @NonNull Map<Integer, List<EmergencyNumber>> emergencyNumberList) {
@@ -945,16 +948,47 @@
     /**
      * Callback invoked when an outgoing call is placed to an emergency number.
      *
-     * @param placedEmergencyNumber the emergency number {@link EmergencyNumber} the call is placed
-     *                              to.
+     * This method will be called when an emergency call is placed on any subscription (including
+     * the no-SIM case), regardless of which subscription this listener was registered on.
+     *
+     * @param placedEmergencyNumber The {@link EmergencyNumber} the emergency call was placed to.
+     *
+     * @deprecated Use {@link #onOutgoingEmergencyCall(EmergencyNumber, int)}.
      * @hide
      */
     @SystemApi
+    @Deprecated
     public void onOutgoingEmergencyCall(@NonNull EmergencyNumber placedEmergencyNumber) {
         // default implementation empty
     }
 
     /**
+     * Callback invoked when an outgoing call is placed to an emergency number.
+     *
+     * This method will be called when an emergency call is placed on any subscription (including
+     * the no-SIM case), regardless of which subscription this listener was registered on.
+     *
+     * The default implementation of this method calls
+     * {@link #onOutgoingEmergencyCall(EmergencyNumber)} for backwards compatibility purposes. Do
+     * not call {@code super(...)} from within your implementation unless you want
+     * {@link #onOutgoingEmergencyCall(EmergencyNumber)} to be called as well.
+     *
+     * @param placedEmergencyNumber The {@link EmergencyNumber} the emergency call was placed to.
+     * @param subscriptionId The subscription ID used to place the emergency call. If the
+     *                       emergency call was placed without a valid subscription (e.g. when there
+     *                       are no SIM cards in the device), this will be equal to
+     *                       {@link SubscriptionManager#INVALID_SUBSCRIPTION_ID}.
+     * @hide
+     */
+    @SystemApi
+    @TestApi
+    public void onOutgoingEmergencyCall(@NonNull EmergencyNumber placedEmergencyNumber,
+            int subscriptionId) {
+        // Default implementation for backwards compatibility
+        onOutgoingEmergencyCall(placedEmergencyNumber);
+    }
+
+    /**
      * Callback invoked when an outgoing SMS is placed to an emergency number.
      *
      * @param sentEmergencyNumber the emergency number {@link EmergencyNumber} the SMS is sent to.
@@ -1331,13 +1365,15 @@
                             () -> psl.onEmergencyNumberListChanged(emergencyNumberList)));
         }
 
-        public void onOutgoingEmergencyCall(@NonNull EmergencyNumber placedEmergencyNumber) {
+        public void onOutgoingEmergencyCall(@NonNull EmergencyNumber placedEmergencyNumber,
+                int subscriptionId) {
             PhoneStateListener psl = mPhoneStateListenerWeakRef.get();
             if (psl == null) return;
 
             Binder.withCleanCallingIdentity(
                     () -> mExecutor.execute(
-                            () -> psl.onOutgoingEmergencyCall(placedEmergencyNumber)));
+                            () -> psl.onOutgoingEmergencyCall(placedEmergencyNumber,
+                                    subscriptionId)));
         }
 
         public void onOutgoingEmergencySms(@NonNull EmergencyNumber sentEmergencyNumber) {
diff --git a/core/java/com/android/internal/telephony/IPhoneStateListener.aidl b/core/java/com/android/internal/telephony/IPhoneStateListener.aidl
index b2c5a99..d41d307 100644
--- a/core/java/com/android/internal/telephony/IPhoneStateListener.aidl
+++ b/core/java/com/android/internal/telephony/IPhoneStateListener.aidl
@@ -61,7 +61,7 @@
     void onRadioPowerStateChanged(in int state);
     void onCallAttributesChanged(in CallAttributes callAttributes);
     void onEmergencyNumberListChanged(in Map emergencyNumberList);
-    void onOutgoingEmergencyCall(in EmergencyNumber placedEmergencyNumber);
+    void onOutgoingEmergencyCall(in EmergencyNumber placedEmergencyNumber, int subscriptionId);
     void onOutgoingEmergencySms(in EmergencyNumber sentEmergencyNumber);
     void onCallDisconnectCauseChanged(in int disconnectCause, in int preciseDisconnectCause);
     void onImsCallDisconnectCauseChanged(in ImsReasonInfo imsReasonInfo);
diff --git a/non-updatable-api/current.txt b/non-updatable-api/current.txt
index e730636..c9959da 100644
--- a/non-updatable-api/current.txt
+++ b/non-updatable-api/current.txt
@@ -45969,6 +45969,7 @@
     method public void onDataConnectionStateChanged(int);
     method public void onDataConnectionStateChanged(int, int);
     method @RequiresPermission("android.permission.READ_PHONE_STATE") public void onDisplayInfoChanged(@NonNull android.telephony.TelephonyDisplayInfo);
+    method public void onEmergencyNumberListChanged(@NonNull java.util.Map<java.lang.Integer,java.util.List<android.telephony.emergency.EmergencyNumber>>);
     method @RequiresPermission("android.permission.READ_PRECISE_PHONE_STATE") public void onImsCallDisconnectCauseChanged(@NonNull android.telephony.ims.ImsReasonInfo);
     method public void onMessageWaitingIndicatorChanged(boolean);
     method @RequiresPermission("android.permission.MODIFY_PHONE_STATE") public void onPreciseDataConnectionStateChanged(@NonNull android.telephony.PreciseDataConnectionState);
diff --git a/non-updatable-api/system-current.txt b/non-updatable-api/system-current.txt
index 515d368..264f012 100644
--- a/non-updatable-api/system-current.txt
+++ b/non-updatable-api/system-current.txt
@@ -9696,7 +9696,8 @@
 
   public class PhoneStateListener {
     method public void onCallAttributesChanged(@NonNull android.telephony.CallAttributes);
-    method public void onOutgoingEmergencyCall(@NonNull android.telephony.emergency.EmergencyNumber);
+    method @Deprecated public void onOutgoingEmergencyCall(@NonNull android.telephony.emergency.EmergencyNumber);
+    method public void onOutgoingEmergencyCall(@NonNull android.telephony.emergency.EmergencyNumber, int);
     method public void onOutgoingEmergencySms(@NonNull android.telephony.emergency.EmergencyNumber);
     method @RequiresPermission("android.permission.READ_PRECISE_PHONE_STATE") public void onPreciseCallStateChanged(@NonNull android.telephony.PreciseCallState);
     method public void onRadioPowerStateChanged(int);
diff --git a/services/core/java/com/android/server/TelephonyRegistry.java b/services/core/java/com/android/server/TelephonyRegistry.java
index df23da6..4851c55 100644
--- a/services/core/java/com/android/server/TelephonyRegistry.java
+++ b/services/core/java/com/android/server/TelephonyRegistry.java
@@ -2101,20 +2101,20 @@
         synchronized (mRecords) {
             if (validatePhoneId(phoneId)) {
                 mOutgoingCallEmergencyNumber[phoneId] = emergencyNumber;
-                for (Record r : mRecords) {
-                    if (r.matchPhoneStateListenerEvent(
-                            PhoneStateListener.LISTEN_OUTGOING_EMERGENCY_CALL)
-                                    && idMatch(r.subId, subId, phoneId)) {
-                        try {
-                            r.callback.onOutgoingEmergencyCall(emergencyNumber);
-                        } catch (RemoteException ex) {
-                            mRemoveList.add(r.binder);
-                        }
+            }
+            for (Record r : mRecords) {
+                // Send to all listeners regardless of subscription
+                if (r.matchPhoneStateListenerEvent(
+                        PhoneStateListener.LISTEN_OUTGOING_EMERGENCY_CALL)) {
+                    try {
+                        r.callback.onOutgoingEmergencyCall(emergencyNumber, subId);
+                    } catch (RemoteException ex) {
+                        mRemoveList.add(r.binder);
                     }
                 }
             }
-            handleRemoveListLocked();
         }
+        handleRemoveListLocked();
     }
 
     @Override