From e182543791d6af99ae47cb7c2889737f856f37e4 Mon Sep 17 00:00:00 2001 From: Hall Liu Date: Wed, 5 Aug 2020 17:34:49 -0700 Subject: [PATCH 1/3] Expose onEmergencyNumberListChanged, semantics change Expose the onEmergencyNumberListChanged method, which seems to have been left hidden inadvertently when introduced. Add a new version of onOutgoingEmergencyCall that supplies a subscription ID and deprecate the old one. Along with this, send emergency call events from any subscription to all listeners regardless of which subscription the listener specified. Test: atest CtsTelecomTestCases:OutgoingCallTest Bug: 162647577 bug: 165660452 Change-Id: Ia0e10bfb3376ff82d03a6dbc4bf71c22b0ace366 Merged-In: Ia0e10bfb3376ff82d03a6dbc4bf71c22b0ace366 --- api/current.txt | 1 + api/system-current.txt | 3 +- api/test-current.txt | 4 ++ .../android/telephony/PhoneStateListener.java | 47 +++++++++++++++++-- .../telephony/IPhoneStateListener.aidl | 2 +- non-updatable-api/current.txt | 1 + non-updatable-api/system-current.txt | 3 +- .../com/android/server/TelephonyRegistry.java | 20 ++++---- 8 files changed, 64 insertions(+), 17 deletions(-) diff --git a/api/current.txt b/api/current.txt index 90c0eab439c42..b251612cbfdf1 100644 --- a/api/current.txt +++ b/api/current.txt @@ -47801,6 +47801,7 @@ package android.telephony { 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>); 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 11b2828e62472..e586d75d70ada 100755 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -10814,7 +10814,8 @@ package android.telephony { 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 bdf797e80ccc4..0cabd6f9ef383 100644 --- a/api/test-current.txt +++ b/api/test-current.txt @@ -1627,6 +1627,10 @@ package android.telephony { 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 2be50e496b8bb..2854b78b8a498 100644 --- a/core/java/android/telephony/PhoneStateListener.java +++ b/core/java/android/telephony/PhoneStateListener.java @@ -20,6 +20,7 @@ import android.Manifest; 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; @@ -935,7 +936,6 @@ public class PhoneStateListener { * {@link SubscriptionManager#getDefaultSubscriptionId}) * and the value as the list of {@link EmergencyNumber}; * null if this information is not available. - * @hide */ public void onEmergencyNumberListChanged( @NonNull Map> emergencyNumberList) { @@ -945,15 +945,48 @@ public class PhoneStateListener { /** * 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. + * + * This method is deprecated. Both this method and the new + * {@link #onOutgoingEmergencyCall(EmergencyNumber, int)} will be called when an outgoing + * emergency call is placed. + * + * @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. + * + * Both this method and the deprecated {@link #onOutgoingEmergencyCall(EmergencyNumber)} will be + * called when an outgoing emergency call is placed. You should only implement one of these + * methods. + * + * @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) { + } + /** * Callback invoked when an outgoing SMS is placed to an emergency number. * @@ -1331,13 +1364,19 @@ public class PhoneStateListener { () -> 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))); + + Binder.withCleanCallingIdentity( + () -> mExecutor.execute( + () -> 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 b2c5a998e2544..d41d30735d7d1 100644 --- a/core/java/com/android/internal/telephony/IPhoneStateListener.aidl +++ b/core/java/com/android/internal/telephony/IPhoneStateListener.aidl @@ -61,7 +61,7 @@ oneway interface IPhoneStateListener { 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 e7306367daf51..c9959dab93351 100644 --- a/non-updatable-api/current.txt +++ b/non-updatable-api/current.txt @@ -45969,6 +45969,7 @@ package android.telephony { 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>); 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 515d368db9e27..264f01288c9ff 100644 --- a/non-updatable-api/system-current.txt +++ b/non-updatable-api/system-current.txt @@ -9696,7 +9696,8 @@ package android.telephony { 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 df23da650a6ff..4851c5547f7e9 100644 --- a/services/core/java/com/android/server/TelephonyRegistry.java +++ b/services/core/java/com/android/server/TelephonyRegistry.java @@ -2101,20 +2101,20 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { 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 From 486ef8978dcefc54db86302868294f4ea721f116 Mon Sep 17 00:00:00 2001 From: Hall Liu Date: Tue, 25 Aug 2020 16:59:50 -0700 Subject: [PATCH 2/3] Call onOutgoingEmergencyCall only once. For backwards compatibility, instead of calling both the old and new versions of onOutgoingEmergencyCall, only call the new version, and call the old version from the default impl of the new version instead. Change suggested by API council. Bug: 166230518 Test: atest CtsTelecomTestCases:OutgoingCallTest Change-Id: Ifa9276cc615d0e33d37ebc702dbc0cd155e0d489 --- .../android/telephony/PhoneStateListener.java | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/core/java/android/telephony/PhoneStateListener.java b/core/java/android/telephony/PhoneStateListener.java index 2854b78b8a498..5a7cda86a8a86 100644 --- a/core/java/android/telephony/PhoneStateListener.java +++ b/core/java/android/telephony/PhoneStateListener.java @@ -948,10 +948,6 @@ public class PhoneStateListener { * 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. * - * This method is deprecated. Both this method and the new - * {@link #onOutgoingEmergencyCall(EmergencyNumber, int)} will be called when an outgoing - * emergency call is placed. - * * @param placedEmergencyNumber The {@link EmergencyNumber} the emergency call was placed to. * * @deprecated Use {@link #onOutgoingEmergencyCall(EmergencyNumber, int)}. @@ -969,22 +965,24 @@ public class PhoneStateListener { * 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. * - * Both this method and the deprecated {@link #onOutgoingEmergencyCall(EmergencyNumber)} will be - * called when an outgoing emergency call is placed. You should only implement one of these - * methods. + * 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); } /** @@ -1369,10 +1367,6 @@ public class PhoneStateListener { PhoneStateListener psl = mPhoneStateListenerWeakRef.get(); if (psl == null) return; - Binder.withCleanCallingIdentity( - () -> mExecutor.execute( - () -> psl.onOutgoingEmergencyCall(placedEmergencyNumber))); - Binder.withCleanCallingIdentity( () -> mExecutor.execute( () -> psl.onOutgoingEmergencyCall(placedEmergencyNumber, From bed564c95611a4812f35853ef9d5854e00f9e2ed Mon Sep 17 00:00:00 2001 From: Hall Liu Date: Thu, 27 Aug 2020 13:08:16 -0700 Subject: [PATCH 3/3] Update docs for onEmergencyNumberListChanged Clarify structure of the argument for the onEmergencyNumberListChanged callback based on API council feedback. Bug: 166230518 Test: NA Change-Id: I9819337da12a17dc4736ba97b00018a156274680 --- .../android/telephony/PhoneStateListener.java | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/core/java/android/telephony/PhoneStateListener.java b/core/java/android/telephony/PhoneStateListener.java index 5a7cda86a8a86..1ef52e21d6529 100644 --- a/core/java/android/telephony/PhoneStateListener.java +++ b/core/java/android/telephony/PhoneStateListener.java @@ -924,18 +924,21 @@ public class PhoneStateListener { /** * 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. + * @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> emergencyNumberList) {