diff options
author | 2024-01-16 22:58:12 +0000 | |
---|---|---|
committer | 2024-01-16 22:58:12 +0000 | |
commit | 5f7657c4d4a736c463f9f844b0aea5cd08549949 (patch) | |
tree | 1bfa18382950acd096cc2c9640be131ed246e363 | |
parent | 6b2c10dbc55b99c08723cbe4e1b2f212db262773 (diff) | |
parent | 5d8575908bb444db46538a00c89d98877726dbf4 (diff) |
Merge "Adds API for notifying Cellular Simultaneous Calling" into main
8 files changed, 177 insertions, 4 deletions
diff --git a/core/api/system-current.txt b/core/api/system-current.txt index d26662d9039d..95fa903a4243 100644 --- a/core/api/system-current.txt +++ b/core/api/system-current.txt @@ -14554,6 +14554,7 @@ package android.telephony { field public static final int EVENT_SERVICE_STATE_CHANGED = 1; // 0x1 field public static final int EVENT_SIGNAL_STRENGTHS_CHANGED = 9; // 0x9 field public static final int EVENT_SIGNAL_STRENGTH_CHANGED = 2; // 0x2 + field @FlaggedApi("com.android.internal.telephony.flags.simultaneous_calling_indications") @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public static final int EVENT_SIMULTANEOUS_CELLULAR_CALLING_SUBSCRIPTIONS_CHANGED = 41; // 0x29 field @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public static final int EVENT_SRVCC_STATE_CHANGED = 16; // 0x10 field public static final int EVENT_USER_MOBILE_DATA_STATE_CHANGED = 20; // 0x14 field @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public static final int EVENT_VOICE_ACTIVATION_STATE_CHANGED = 18; // 0x12 @@ -14600,6 +14601,10 @@ package android.telephony { method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public void onRadioPowerStateChanged(int); } + @FlaggedApi("com.android.internal.telephony.flags.simultaneous_calling_indications") public static interface TelephonyCallback.SimultaneousCellularCallingSupportListener { + method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public void onSimultaneousCellularCallingSubscriptionsChanged(@NonNull java.util.Set<java.lang.Integer>); + } + public static interface TelephonyCallback.SrvccStateListener { method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public void onSrvccStateChanged(int); } diff --git a/core/java/android/telephony/PhoneStateListener.java b/core/java/android/telephony/PhoneStateListener.java index cf1156db55e5..fb57921b1529 100644 --- a/core/java/android/telephony/PhoneStateListener.java +++ b/core/java/android/telephony/PhoneStateListener.java @@ -1681,6 +1681,10 @@ public class PhoneStateListener { @EmergencyCallbackModeStopReason int reason) { // not support. Can't override. Use TelephonyCallback. } + + public final void onSimultaneousCallingStateChanged(int[] subIds) { + // not supported on the deprecated interface - Use TelephonyCallback instead + } } private void log(String s) { diff --git a/core/java/android/telephony/TelephonyCallback.java b/core/java/android/telephony/TelephonyCallback.java index 19bcf28d6b83..dc6a035a8176 100644 --- a/core/java/android/telephony/TelephonyCallback.java +++ b/core/java/android/telephony/TelephonyCallback.java @@ -18,6 +18,7 @@ package android.telephony; import android.Manifest; import android.annotation.CallbackExecutor; +import android.annotation.FlaggedApi; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.RequiresPermission; @@ -33,15 +34,19 @@ import android.util.Log; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.telephony.IPhoneStateListener; +import com.android.internal.telephony.flags.Flags; import dalvik.system.VMRuntime; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.ref.WeakReference; +import java.util.Arrays; import java.util.List; import java.util.Map; +import java.util.Set; import java.util.concurrent.Executor; +import java.util.stream.Collectors; /** * A callback class for monitoring changes in specific telephony states @@ -627,6 +632,18 @@ public class TelephonyCallback { public static final int EVENT_EMERGENCY_CALLBACK_MODE_CHANGED = 40; /** + * Event for listening to changes in simultaneous cellular calling subscriptions. + * + * @see SimultaneousCellularCallingSupportListener + * + * @hide + */ + @FlaggedApi(Flags.FLAG_SIMULTANEOUS_CALLING_INDICATIONS) + @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE) + @SystemApi + public static final int EVENT_SIMULTANEOUS_CELLULAR_CALLING_SUBSCRIPTIONS_CHANGED = 41; + + /** * @hide */ @IntDef(prefix = {"EVENT_"}, value = { @@ -669,7 +686,8 @@ public class TelephonyCallback { EVENT_LINK_CAPACITY_ESTIMATE_CHANGED, EVENT_TRIGGER_NOTIFY_ANBR, EVENT_MEDIA_QUALITY_STATUS_CHANGED, - EVENT_EMERGENCY_CALLBACK_MODE_CHANGED + EVENT_EMERGENCY_CALLBACK_MODE_CHANGED, + EVENT_SIMULTANEOUS_CELLULAR_CALLING_SUBSCRIPTIONS_CHANGED }) @Retention(RetentionPolicy.SOURCE) public @interface TelephonyEvent { @@ -1373,6 +1391,44 @@ public class TelephonyCallback { } /** + * Interface for listening to changes in the simultaneous cellular calling state for active + * cellular subscriptions. + * + * @hide + */ + @FlaggedApi(Flags.FLAG_SIMULTANEOUS_CALLING_INDICATIONS) + @SystemApi + public interface SimultaneousCellularCallingSupportListener { + /** + * Notify the Listener that the subscriptions available for simultaneous <b>cellular</b> + * calling have changed. + * <p> + * If we have an ongoing <b>cellular</b> call on one subscription in this Set, a + * simultaneous incoming or outgoing <b>cellular</b> call is possible on any of the + * subscriptions in this Set. On a traditional Dual Sim Dual Standby device, simultaneous + * calling is not possible between subscriptions, where on a Dual Sim Dual Active device, + * simultaneous calling may be possible between subscriptions in certain network conditions. + * <p> + * Note: This listener only tracks the capability of the modem to perform simultaneous + * cellular calls and does not track the simultaneous calling state of scenarios based on + * multiple IMS registration over multiple transports (WiFi/Internet calling). + * <p> + * Note: This listener fires for all changes to cellular calling subscriptions independent + * of which subscription it is registered on. + * + * @param simultaneousCallingSubscriptionIds The Set of subscription IDs that support + * simultaneous calling. If there is an ongoing call on a subscription in this Set, then a + * simultaneous incoming or outgoing call is only possible for other subscriptions in this + * Set. If there is an ongoing call on a subscription that is not in this Set, then + * simultaneous calling is not possible at the current time. + * + */ + @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE) + void onSimultaneousCellularCallingSubscriptionsChanged( + @NonNull Set<Integer> simultaneousCallingSubscriptionIds); + } + + /** * Interface for call attributes listener. * * @hide @@ -1976,6 +2032,17 @@ public class TelephonyCallback { allowedNetworkType))); } + public void onSimultaneousCallingStateChanged(int[] subIds) { + SimultaneousCellularCallingSupportListener listener = + (SimultaneousCellularCallingSupportListener) mTelephonyCallbackWeakRef.get(); + if (listener == null) return; + + Binder.withCleanCallingIdentity( + () -> mExecutor.execute( + () -> listener.onSimultaneousCellularCallingSubscriptionsChanged( + Arrays.stream(subIds).boxed().collect(Collectors.toSet())))); + } + public void onLinkCapacityEstimateChanged( List<LinkCapacityEstimate> linkCapacityEstimateList) { LinkCapacityEstimateChangedListener listener = diff --git a/core/java/android/telephony/TelephonyRegistryManager.java b/core/java/android/telephony/TelephonyRegistryManager.java index 886727ea43ef..0de450519646 100644 --- a/core/java/android/telephony/TelephonyRegistryManager.java +++ b/core/java/android/telephony/TelephonyRegistryManager.java @@ -994,6 +994,21 @@ public class TelephonyRegistryManager { } } + /** + * Notify external listeners that the subscriptions supporting simultaneous cellular calling + * have changed. + * @param subIds The new set of subIds supporting simultaneous cellular calling. + */ + public void notifySimultaneousCellularCallingSubscriptionsChanged(Set<Integer> subIds) { + try { + sRegistry.notifySimultaneousCellularCallingSubscriptionsChanged( + subIds.stream().mapToInt(i -> i).toArray()); + } catch (RemoteException ex) { + // system server crash + throw ex.rethrowFromSystemServer(); + } + } + public @NonNull Set<Integer> getEventsFromCallback( @NonNull TelephonyCallback telephonyCallback) { Set<Integer> eventList = new ArraySet<>(); @@ -1135,7 +1150,11 @@ public class TelephonyRegistryManager { eventList.add(TelephonyCallback.EVENT_EMERGENCY_CALLBACK_MODE_CHANGED); } - + if (telephonyCallback + instanceof TelephonyCallback.SimultaneousCellularCallingSupportListener) { + eventList.add( + TelephonyCallback.EVENT_SIMULTANEOUS_CELLULAR_CALLING_SUBSCRIPTIONS_CHANGED); + } return eventList; } diff --git a/core/java/com/android/internal/telephony/IPhoneStateListener.aidl b/core/java/com/android/internal/telephony/IPhoneStateListener.aidl index 03cfd4f2ab91..969f95db002d 100644 --- a/core/java/com/android/internal/telephony/IPhoneStateListener.aidl +++ b/core/java/com/android/internal/telephony/IPhoneStateListener.aidl @@ -80,4 +80,5 @@ oneway interface IPhoneStateListener { void onMediaQualityStatusChanged(in MediaQualityStatus mediaQualityStatus); void onCallBackModeStarted(int type); void onCallBackModeStopped(int type, int reason); + void onSimultaneousCallingStateChanged(in int[] subIds); } diff --git a/core/java/com/android/internal/telephony/ITelephonyRegistry.aidl b/core/java/com/android/internal/telephony/ITelephonyRegistry.aidl index aab22421b334..0203ea49f252 100644 --- a/core/java/com/android/internal/telephony/ITelephonyRegistry.aidl +++ b/core/java/com/android/internal/telephony/ITelephonyRegistry.aidl @@ -104,6 +104,7 @@ interface ITelephonyRegistry { void notifyAllowedNetworkTypesChanged(in int phoneId, in int subId, in int reason, in long allowedNetworkType); void notifyLinkCapacityEstimateChanged(in int phoneId, in int subId, in List<LinkCapacityEstimate> linkCapacityEstimateList); + void notifySimultaneousCellularCallingSubscriptionsChanged(in int[] subIds); void addCarrierPrivilegesCallback( int phoneId, ICarrierPrivilegesCallback callback, String pkg, String featureId); diff --git a/services/core/java/com/android/server/TelephonyRegistry.java b/services/core/java/com/android/server/TelephonyRegistry.java index eb6fdd72f2c3..f921b0b94b25 100644 --- a/services/core/java/com/android/server/TelephonyRegistry.java +++ b/services/core/java/com/android/server/TelephonyRegistry.java @@ -418,6 +418,8 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { LinkCapacityEstimate.INVALID, LinkCapacityEstimate.INVALID))); private List<List<LinkCapacityEstimate>> mLinkCapacityEstimateLists; + private int[] mSimultaneousCellularCallingSubIds = {}; + private int[] mECBMReason; private boolean[] mECBMStarted; private int[] mSCBMReason; @@ -564,7 +566,9 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { || events.contains(TelephonyCallback.EVENT_VOICE_ACTIVATION_STATE_CHANGED) || events.contains(TelephonyCallback.EVENT_RADIO_POWER_STATE_CHANGED) || events.contains(TelephonyCallback.EVENT_ALLOWED_NETWORK_TYPE_LIST_CHANGED) - || events.contains(TelephonyCallback.EVENT_EMERGENCY_CALLBACK_MODE_CHANGED); + || events.contains(TelephonyCallback.EVENT_EMERGENCY_CALLBACK_MODE_CHANGED) + || events.contains(TelephonyCallback + .EVENT_SIMULTANEOUS_CELLULAR_CALLING_SUBSCRIPTIONS_CHANGED); } private static final int MSG_USER_SWITCHED = 1; @@ -1427,6 +1431,15 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { remove(r.binder); } } + if (events.contains(TelephonyCallback + .EVENT_SIMULTANEOUS_CELLULAR_CALLING_SUBSCRIPTIONS_CHANGED)) { + try { + r.callback.onSimultaneousCallingStateChanged( + mSimultaneousCellularCallingSubIds); + } catch (RemoteException ex) { + remove(r.binder); + } + } if (events.contains( TelephonyCallback.EVENT_LINK_CAPACITY_ESTIMATE_CHANGED)) { try { @@ -3092,6 +3105,43 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { } } + /** + * Notify the listeners that simultaneous cellular calling subscriptions have changed + * @param subIds The set of subIds that support simultaneous cellular calling + */ + public void notifySimultaneousCellularCallingSubscriptionsChanged(int[] subIds) { + if (!checkNotifyPermission("notifySimultaneousCellularCallingSubscriptionsChanged()")) { + return; + } + + if (VDBG) { + StringBuilder b = new StringBuilder(); + b.append("notifySimultaneousCellularCallingSubscriptionsChanged: "); + b.append("subIds = {"); + for (int i : subIds) { + b.append(" "); + b.append(i); + } + b.append("}"); + log(b.toString()); + } + + synchronized (mRecords) { + mSimultaneousCellularCallingSubIds = subIds; + for (Record r : mRecords) { + if (r.matchTelephonyCallbackEvent(TelephonyCallback + .EVENT_SIMULTANEOUS_CELLULAR_CALLING_SUBSCRIPTIONS_CHANGED)) { + try { + r.callback.onSimultaneousCallingStateChanged(subIds); + } catch (RemoteException ex) { + mRemoveList.add(r.binder); + } + } + } + handleRemoveListLocked(); + } + } + @Override public void addCarrierPrivilegesCallback( int phoneId, diff --git a/telephony/java/android/telephony/ims/ImsService.java b/telephony/java/android/telephony/ims/ImsService.java index 4c37f7d3184c..b84ff2977b34 100644 --- a/telephony/java/android/telephony/ims/ImsService.java +++ b/telephony/java/android/telephony/ims/ImsService.java @@ -16,6 +16,7 @@ package android.telephony.ims; +import android.annotation.FlaggedApi; import android.annotation.LongDef; import android.annotation.NonNull; import android.annotation.Nullable; @@ -46,6 +47,7 @@ import android.util.SparseBooleanArray; import com.android.ims.internal.IImsFeatureStatusCallback; import com.android.internal.annotations.VisibleForTesting; +import com.android.internal.telephony.flags.Flags; import com.android.internal.telephony.util.TelephonyUtils; import java.lang.annotation.Retention; @@ -152,12 +154,36 @@ public class ImsService extends Service { public static final long CAPABILITY_TERMINAL_BASED_CALL_WAITING = 1 << 2; /** + * This ImsService supports the capability to manage calls on multiple subscriptions at the same + * time. + * <p> + * When set, this ImsService supports managing calls on multiple subscriptions at the same time + * for all WLAN network configurations. Telephony will allow new outgoing/incoming IMS calls to + * be set up on other subscriptions while there is an ongoing call. The ImsService must also + * support managing calls on WWAN + WWAN configurations whenever the modem also reports + * simultaneous calling availability, which can be listened to using the + * {@link android.telephony.TelephonyCallback.SimultaneousCellularCallingSupportListener} API. + * Telephony will only allow additional ongoing/incoming IMS calls on another subscription to be + * set up on WWAN + WWAN configurations when the modem reports that simultaneous cellular + * calling is allowed at the current time on both subscriptions where there are ongoing calls. + * <p> + * When unset (default), this ImsService can not support calls on multiple subscriptions at the + * same time for any WLAN or WWAN configurations, so pending outgoing call placed on another + * cellular subscription while there is an ongoing call will be cancelled by Telephony. + * Similarly, any incoming call notification on another cellular subscription while there is an + * ongoing call will be rejected. + * @hide TODO: move this to system API when we have a backing implementation + CTS testing + */ + @FlaggedApi(Flags.FLAG_SIMULTANEOUS_CALLING_INDICATIONS) + public static final long CAPABILITY_SUPPORTS_SIMULTANEOUS_CALLING = 1 << 3; + + /** * Used for internal correctness checks of capabilities set by the ImsService implementation and * tracks the index of the largest defined flag in the capabilities long. * @hide */ public static final long CAPABILITY_MAX_INDEX = - Long.numberOfTrailingZeros(CAPABILITY_TERMINAL_BASED_CALL_WAITING); + Long.numberOfTrailingZeros(CAPABILITY_SUPPORTS_SIMULTANEOUS_CALLING); /** * @hide |