summaryrefslogtreecommitdiff
path: root/telephony
diff options
context:
space:
mode:
Diffstat (limited to 'telephony')
-rw-r--r--telephony/OWNERS6
-rw-r--r--telephony/common/com/android/internal/telephony/SmsApplication.java234
-rw-r--r--telephony/common/com/android/internal/telephony/TelephonyPermissions.java76
-rw-r--r--telephony/common/com/android/internal/telephony/util/TelephonyUtils.java111
-rw-r--r--telephony/java/android/service/euicc/EuiccProfileInfo.java3
-rw-r--r--telephony/java/android/service/euicc/EuiccService.java59
-rw-r--r--telephony/java/android/service/euicc/IEuiccService.aidl6
-rw-r--r--telephony/java/android/telephony/Annotation.java33
-rw-r--r--telephony/java/android/telephony/AnomalyReporter.java19
-rw-r--r--telephony/java/android/telephony/CallAttributes.java2
-rw-r--r--telephony/java/android/telephony/CallState.aidl20
-rw-r--r--telephony/java/android/telephony/CallState.java409
-rw-r--r--telephony/java/android/telephony/CarrierConfigManager.java1931
-rw-r--r--telephony/java/android/telephony/CarrierRestrictionRules.java27
-rw-r--r--telephony/java/android/telephony/CellBroadcastIdRange.aidl19
-rw-r--r--telephony/java/android/telephony/CellBroadcastIdRange.java165
-rw-r--r--telephony/java/android/telephony/CellIdentityCdma.java7
-rw-r--r--telephony/java/android/telephony/CellSignalStrengthNr.java41
-rw-r--r--telephony/java/android/telephony/DataSpecificRegistrationInfo.java200
-rw-r--r--telephony/java/android/telephony/DisconnectCause.java327
-rw-r--r--telephony/java/android/telephony/DomainSelectionService.aidl19
-rw-r--r--telephony/java/android/telephony/DomainSelectionService.java864
-rw-r--r--telephony/java/android/telephony/DomainSelector.java45
-rw-r--r--telephony/java/android/telephony/EmergencyRegResult.aidl19
-rw-r--r--telephony/java/android/telephony/EmergencyRegResult.java318
-rw-r--r--telephony/java/android/telephony/ModemActivityInfo.java12
-rw-r--r--telephony/java/android/telephony/NetworkRegistrationInfo.java46
-rw-r--r--telephony/java/android/telephony/PhoneCapability.java145
-rw-r--r--telephony/java/android/telephony/PhoneNumberUtils.java422
-rw-r--r--telephony/java/android/telephony/PreciseCallState.java5
-rw-r--r--telephony/java/android/telephony/PreciseDisconnectCause.java17
-rw-r--r--telephony/java/android/telephony/RadioAccessFamily.java4
-rw-r--r--telephony/java/android/telephony/ServiceState.java52
-rw-r--r--telephony/java/android/telephony/SignalStrength.java12
-rw-r--r--telephony/java/android/telephony/SignalThresholdInfo.java201
-rw-r--r--telephony/java/android/telephony/SmsManager.java268
-rw-r--r--telephony/java/android/telephony/SubscriptionInfo.java25
-rw-r--r--telephony/java/android/telephony/SubscriptionManager.java227
-rw-r--r--telephony/java/android/telephony/TelephonyFrameworkInitializer.java6
-rw-r--r--telephony/java/android/telephony/TelephonyManager.java1428
-rw-r--r--telephony/java/android/telephony/TransportSelectorCallback.java62
-rw-r--r--telephony/java/android/telephony/UiccCardInfo.java2
-rw-r--r--telephony/java/android/telephony/UiccPortInfo.java2
-rw-r--r--telephony/java/android/telephony/UiccSlotInfo.java15
-rw-r--r--telephony/java/android/telephony/VisualVoicemailService.java4
-rw-r--r--telephony/java/android/telephony/WwanSelectorCallback.java52
-rw-r--r--telephony/java/android/telephony/cdma/CdmaCellLocation.java7
-rw-r--r--telephony/java/android/telephony/data/ApnSetting.java17
-rw-r--r--telephony/java/android/telephony/data/IQualifiedNetworksService.aidl1
-rw-r--r--telephony/java/android/telephony/data/QosBearerSession.java3
-rw-r--r--telephony/java/android/telephony/data/QualifiedNetworksService.java30
-rw-r--r--telephony/java/android/telephony/emergency/EmergencyNumber.java198
-rw-r--r--telephony/java/android/telephony/euicc/EuiccCardManager.java10
-rw-r--r--telephony/java/android/telephony/euicc/EuiccManager.java62
-rw-r--r--telephony/java/android/telephony/ims/ImsCallProfile.java6
-rwxr-xr-xtelephony/java/android/telephony/ims/ImsCallSession.java99
-rw-r--r--telephony/java/android/telephony/ims/ImsCallSessionListener.java29
-rw-r--r--telephony/java/android/telephony/ims/ImsMmTelManager.java8
-rw-r--r--telephony/java/android/telephony/ims/ImsRcsManager.java4
-rw-r--r--telephony/java/android/telephony/ims/ImsRegistrationAttributes.java58
-rw-r--r--telephony/java/android/telephony/ims/ImsService.java205
-rw-r--r--telephony/java/android/telephony/ims/MediaQualityStatus.aidl19
-rw-r--r--telephony/java/android/telephony/ims/MediaQualityStatus.java203
-rw-r--r--telephony/java/android/telephony/ims/MediaThreshold.aidl19
-rw-r--r--telephony/java/android/telephony/ims/MediaThreshold.java333
-rw-r--r--telephony/java/android/telephony/ims/ProvisioningManager.java9
-rw-r--r--telephony/java/android/telephony/ims/PublishAttributes.aidl19
-rw-r--r--telephony/java/android/telephony/ims/PublishAttributes.java186
-rw-r--r--telephony/java/android/telephony/ims/RcsConfig.java23
-rw-r--r--telephony/java/android/telephony/ims/RcsUceAdapter.java107
-rw-r--r--telephony/java/android/telephony/ims/RegistrationManager.java92
-rw-r--r--telephony/java/android/telephony/ims/SipDelegateManager.java65
-rw-r--r--telephony/java/android/telephony/ims/SipDetails.aidl19
-rw-r--r--telephony/java/android/telephony/ims/SipDetails.java309
-rw-r--r--telephony/java/android/telephony/ims/SipDialogState.aidl19
-rw-r--r--telephony/java/android/telephony/ims/SipDialogState.java135
-rw-r--r--telephony/java/android/telephony/ims/SipDialogStateCallback.java103
-rw-r--r--telephony/java/android/telephony/ims/SrvccCall.aidl19
-rw-r--r--telephony/java/android/telephony/ims/SrvccCall.java153
-rw-r--r--telephony/java/android/telephony/ims/aidl/CapabilityExchangeAidlWrapper.java30
-rw-r--r--telephony/java/android/telephony/ims/aidl/ICapabilityExchangeEventListener.aidl5
-rw-r--r--telephony/java/android/telephony/ims/aidl/IImsCallSessionListener.aidl13
-rw-r--r--telephony/java/android/telephony/ims/aidl/IImsMmTelFeature.aidl13
-rw-r--r--telephony/java/android/telephony/ims/aidl/IImsMmTelListener.aidl12
-rw-r--r--telephony/java/android/telephony/ims/aidl/IImsRcsController.aidl5
-rw-r--r--telephony/java/android/telephony/ims/aidl/IImsRegistration.aidl1
-rw-r--r--telephony/java/android/telephony/ims/aidl/IImsRegistrationCallback.aidl6
-rw-r--r--telephony/java/android/telephony/ims/aidl/IImsServiceController.aidl1
-rw-r--r--telephony/java/android/telephony/ims/aidl/IImsSmsListener.aidl1
-rw-r--r--telephony/java/android/telephony/ims/aidl/IImsTrafficSessionCallback.aidl27
-rw-r--r--telephony/java/android/telephony/ims/aidl/IPublishResponseCallback.aidl4
-rw-r--r--telephony/java/android/telephony/ims/aidl/IRcsUceControllerCallback.aidl6
-rw-r--r--telephony/java/android/telephony/ims/aidl/IRcsUcePublishStateCallback.aidl3
-rw-r--r--telephony/java/android/telephony/ims/aidl/ISrvccStartedCallback.aidl28
-rw-r--r--telephony/java/android/telephony/ims/aidl/ISubscribeResponseCallback.aidl4
-rw-r--r--telephony/java/android/telephony/ims/aidl/RcsPublishResponseAidlWrapper.java28
-rw-r--r--telephony/java/android/telephony/ims/aidl/RcsSubscribeResponseAidlWrapper.java27
-rwxr-xr-xtelephony/java/android/telephony/ims/compat/stub/ImsCallSessionImplBase.java21
-rw-r--r--telephony/java/android/telephony/ims/feature/ConnectionFailureInfo.aidl19
-rw-r--r--telephony/java/android/telephony/ims/feature/ConnectionFailureInfo.java185
-rw-r--r--telephony/java/android/telephony/ims/feature/ImsFeature.java4
-rw-r--r--telephony/java/android/telephony/ims/feature/ImsTrafficSessionCallback.java38
-rw-r--r--telephony/java/android/telephony/ims/feature/MmTelFeature.java907
-rw-r--r--telephony/java/android/telephony/ims/stub/CapabilityExchangeEventListener.java24
-rw-r--r--telephony/java/android/telephony/ims/stub/ImsCallSessionImplBase.java73
-rw-r--r--telephony/java/android/telephony/ims/stub/ImsConfigImplBase.java68
-rw-r--r--telephony/java/android/telephony/ims/stub/ImsRegistrationImplBase.java251
-rw-r--r--telephony/java/android/telephony/ims/stub/ImsSmsImplBase.java115
-rw-r--r--telephony/java/android/telephony/ims/stub/RcsCapabilityExchangeImplBase.java63
-rw-r--r--telephony/java/android/telephony/mbms/MbmsDownloadReceiver.java16
-rw-r--r--telephony/java/android/telephony/satellite/AntennaDirection.aidl19
-rw-r--r--telephony/java/android/telephony/satellite/AntennaDirection.java138
-rw-r--r--telephony/java/android/telephony/satellite/AntennaPosition.aidl19
-rw-r--r--telephony/java/android/telephony/satellite/AntennaPosition.java117
-rw-r--r--telephony/java/android/telephony/satellite/ISatelliteDatagramCallback.aidl40
-rw-r--r--telephony/java/android/telephony/satellite/ISatelliteProvisionStateCallback.aidl30
-rw-r--r--telephony/java/android/telephony/satellite/ISatelliteStateCallback.aidl30
-rw-r--r--telephony/java/android/telephony/satellite/ISatelliteTransmissionUpdateCallback.aidl50
-rw-r--r--telephony/java/android/telephony/satellite/PointingInfo.aidl19
-rw-r--r--telephony/java/android/telephony/satellite/PointingInfo.java96
-rw-r--r--telephony/java/android/telephony/satellite/SatelliteCapabilities.aidl19
-rw-r--r--telephony/java/android/telephony/satellite/SatelliteCapabilities.java218
-rw-r--r--telephony/java/android/telephony/satellite/SatelliteDatagram.aidl19
-rw-r--r--telephony/java/android/telephony/satellite/SatelliteDatagram.java73
-rw-r--r--telephony/java/android/telephony/satellite/SatelliteDatagramCallback.java41
-rw-r--r--telephony/java/android/telephony/satellite/SatelliteManager.java1561
-rw-r--r--telephony/java/android/telephony/satellite/SatelliteProvisionStateCallback.java32
-rw-r--r--telephony/java/android/telephony/satellite/SatelliteStateCallback.java30
-rw-r--r--telephony/java/android/telephony/satellite/SatelliteTransmissionUpdateCallback.java56
-rw-r--r--telephony/java/android/telephony/satellite/stub/ISatellite.aidl385
-rw-r--r--telephony/java/android/telephony/satellite/stub/ISatelliteCapabilitiesConsumer.aidl27
-rw-r--r--telephony/java/android/telephony/satellite/stub/ISatelliteGateway.aidl26
-rw-r--r--telephony/java/android/telephony/satellite/stub/ISatelliteListener.aidl62
-rw-r--r--telephony/java/android/telephony/satellite/stub/NTRadioTechnology.aidl45
-rw-r--r--telephony/java/android/telephony/satellite/stub/PointingInfo.aidl32
-rw-r--r--telephony/java/android/telephony/satellite/stub/SatelliteCapabilities.aidl49
-rw-r--r--telephony/java/android/telephony/satellite/stub/SatelliteDatagram.aidl27
-rw-r--r--telephony/java/android/telephony/satellite/stub/SatelliteError.aidl110
-rw-r--r--telephony/java/android/telephony/satellite/stub/SatelliteGatewayService.java77
-rw-r--r--telephony/java/android/telephony/satellite/stub/SatelliteImplBase.java621
-rw-r--r--telephony/java/android/telephony/satellite/stub/SatelliteModemState.aidl53
-rw-r--r--telephony/java/android/telephony/satellite/stub/SatelliteService.java64
-rw-r--r--telephony/java/com/android/ims/internal/IImsCallSession.aidl13
-rw-r--r--telephony/java/com/android/ims/internal/IImsCallSessionListener.aidl13
-rw-r--r--telephony/java/com/android/internal/telephony/IDomainSelectionServiceController.aidl29
-rw-r--r--telephony/java/com/android/internal/telephony/IDomainSelector.aidl25
-rw-r--r--telephony/java/com/android/internal/telephony/ILongConsumer.aidl25
-rw-r--r--telephony/java/com/android/internal/telephony/IPhoneSubInfo.aidl57
-rw-r--r--telephony/java/com/android/internal/telephony/ISipDialogStateCallback.aidl27
-rw-r--r--telephony/java/com/android/internal/telephony/ISms.aidl19
-rw-r--r--telephony/java/com/android/internal/telephony/ISmsImplBase.java10
-rw-r--r--telephony/java/com/android/internal/telephony/ISub.aidl13
-rw-r--r--telephony/java/com/android/internal/telephony/ITelephony.aidl461
-rw-r--r--telephony/java/com/android/internal/telephony/ITransportSelectorCallback.aidl29
-rw-r--r--telephony/java/com/android/internal/telephony/ITransportSelectorResultCallback.aidl23
-rw-r--r--telephony/java/com/android/internal/telephony/IVoidConsumer.aidl25
-rw-r--r--telephony/java/com/android/internal/telephony/IWwanSelectorCallback.aidl26
-rw-r--r--telephony/java/com/android/internal/telephony/IWwanSelectorResultCallback.aidl23
-rw-r--r--telephony/java/com/android/internal/telephony/PhoneConstants.java18
-rw-r--r--telephony/java/com/android/internal/telephony/RILConstants.java46
-rw-r--r--telephony/java/com/android/internal/telephony/TelephonyIntents.java17
-rw-r--r--telephony/java/com/android/internal/telephony/gsm/SmsBroadcastConfigInfo.java22
162 files changed, 15944 insertions, 1696 deletions
diff --git a/telephony/OWNERS b/telephony/OWNERS
index 025869dd2999..3158ad8fc58e 100644
--- a/telephony/OWNERS
+++ b/telephony/OWNERS
@@ -11,12 +11,6 @@ chinmayd@google.com
amruthr@google.com
sasindran@google.com
-# Temporarily reduced the owner during refactoring
-per-file SubscriptionManager.java=set noparent
-per-file SubscriptionManager.java=jackyu@google.com,amruthr@google.com
-per-file SubscriptionInfo.java=set noparent
-per-file SubscriptionInfo.java=jackyu@google.com,amruthr@google.com
-
# Requiring TL ownership for new carrier config keys.
per-file CarrierConfigManager.java=set noparent
per-file CarrierConfigManager.java=amruthr@google.com,tgunn@google.com,rgreenwalt@google.com,satk@google.com
diff --git a/telephony/common/com/android/internal/telephony/SmsApplication.java b/telephony/common/com/android/internal/telephony/SmsApplication.java
index 423022599de6..a9cdf7e5bc08 100644
--- a/telephony/common/com/android/internal/telephony/SmsApplication.java
+++ b/telephony/common/com/android/internal/telephony/SmsApplication.java
@@ -190,12 +190,11 @@ public final class SmsApplication {
}
/**
- * Returns the userId of the Context object, if called from a system app,
+ * Returns the userId of the current process, if called from a system app,
* otherwise it returns the caller's userId
- * @param context The context object passed in by the caller.
- * @return
+ * @return userId of the caller.
*/
- private static int getIncomingUserId(Context context) {
+ private static int getIncomingUserId() {
int contextUserId = UserHandle.myUserId();
final int callingUid = Binder.getCallingUid();
if (DEBUG_MULTIUSER) {
@@ -211,6 +210,15 @@ public final class SmsApplication {
}
/**
+ * Returns the userHandle of the current process, if called from a system app,
+ * otherwise it returns the caller's userHandle
+ * @return userHandle of the caller.
+ */
+ private static UserHandle getIncomingUserHandle() {
+ return UserHandle.of(getIncomingUserId());
+ }
+
+ /**
* Returns the list of available SMS apps defined as apps that are registered for both the
* SMS_RECEIVED_ACTION (SMS) and WAP_PUSH_RECEIVED_ACTION (MMS) broadcasts (and their broadcast
* receivers are enabled)
@@ -231,7 +239,7 @@ public final class SmsApplication {
*/
@UnsupportedAppUsage
public static Collection<SmsApplicationData> getApplicationCollection(Context context) {
- return getApplicationCollectionAsUser(context, getIncomingUserId(context));
+ return getApplicationCollectionAsUser(context, getIncomingUserId());
}
/**
@@ -590,7 +598,7 @@ public final class SmsApplication {
*/
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
public static void setDefaultApplication(String packageName, Context context) {
- setDefaultApplicationAsUser(packageName, context, getIncomingUserId(context));
+ setDefaultApplicationAsUser(packageName, context, getIncomingUserId());
}
/**
@@ -952,24 +960,28 @@ public final class SmsApplication {
*/
@UnsupportedAppUsage
public static ComponentName getDefaultSmsApplication(Context context, boolean updateIfNeeded) {
- return getDefaultSmsApplicationAsUser(context, updateIfNeeded, getIncomingUserId(context));
+ return getDefaultSmsApplicationAsUser(context, updateIfNeeded, getIncomingUserHandle());
}
/**
* Gets the default SMS application on a given user
* @param context context from the calling app
* @param updateIfNeeded update the default app if there is no valid default app configured.
- * @param userId target user ID.
+ * @param userHandle target user handle
+ * if {@code null} is passed in then calling package uid is used to find out target user handle.
* @return component name of the app and class to deliver SMS messages to
*/
- @VisibleForTesting
public static ComponentName getDefaultSmsApplicationAsUser(Context context,
- boolean updateIfNeeded, int userId) {
+ boolean updateIfNeeded, @Nullable UserHandle userHandle) {
+ if (userHandle == null) {
+ userHandle = getIncomingUserHandle();
+ }
+
final long token = Binder.clearCallingIdentity();
try {
ComponentName component = null;
SmsApplicationData smsApplicationData = getApplication(context, updateIfNeeded,
- userId);
+ userHandle.getIdentifier());
if (smsApplicationData != null) {
component = new ComponentName(smsApplicationData.mPackageName,
smsApplicationData.mSmsReceiverClass);
@@ -988,12 +1000,28 @@ public final class SmsApplication {
*/
@UnsupportedAppUsage
public static ComponentName getDefaultMmsApplication(Context context, boolean updateIfNeeded) {
- int userId = getIncomingUserId(context);
+ return getDefaultMmsApplicationAsUser(context, updateIfNeeded, getIncomingUserHandle());
+ }
+
+ /**
+ * Gets the default MMS application on a given user
+ * @param context context from the calling app
+ * @param updateIfNeeded update the default app if there is no valid default app configured.
+ * @param userHandle target user handle
+ * if {@code null} is passed in then calling package uid is used to find out target user handle.
+ * @return component name of the app and class to deliver MMS messages to.
+ */
+ public static ComponentName getDefaultMmsApplicationAsUser(Context context,
+ boolean updateIfNeeded, @Nullable UserHandle userHandle) {
+ if (userHandle == null) {
+ userHandle = getIncomingUserHandle();
+ }
+
final long token = Binder.clearCallingIdentity();
try {
ComponentName component = null;
SmsApplicationData smsApplicationData = getApplication(context, updateIfNeeded,
- userId);
+ userHandle.getIdentifier());
if (smsApplicationData != null) {
component = new ComponentName(smsApplicationData.mPackageName,
smsApplicationData.mMmsReceiverClass);
@@ -1013,12 +1041,29 @@ public final class SmsApplication {
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
public static ComponentName getDefaultRespondViaMessageApplication(Context context,
boolean updateIfNeeded) {
- int userId = getIncomingUserId(context);
+ return getDefaultRespondViaMessageApplicationAsUser(context, updateIfNeeded,
+ getIncomingUserHandle());
+ }
+
+ /**
+ * Gets the default Respond Via Message application on a given user
+ * @param context context from the calling app
+ * @param updateIfNeeded update the default app if there is no valid default app configured
+ * @param userHandle target user handle
+ * if {@code null} is passed in then calling package uid is used to find out target user handle.
+ * @return component name of the app and class to direct Respond Via Message intent to
+ */
+ public static ComponentName getDefaultRespondViaMessageApplicationAsUser(Context context,
+ boolean updateIfNeeded, @Nullable UserHandle userHandle) {
+ if (userHandle == null) {
+ userHandle = getIncomingUserHandle();
+ }
+
final long token = Binder.clearCallingIdentity();
try {
ComponentName component = null;
SmsApplicationData smsApplicationData = getApplication(context, updateIfNeeded,
- userId);
+ userHandle.getIdentifier());
if (smsApplicationData != null) {
component = new ComponentName(smsApplicationData.mPackageName,
smsApplicationData.mRespondViaMessageClass);
@@ -1039,7 +1084,8 @@ public final class SmsApplication {
*/
public static ComponentName getDefaultSendToApplication(Context context,
boolean updateIfNeeded) {
- int userId = getIncomingUserId(context);
+ int userId = getIncomingUserId();
+
final long token = Binder.clearCallingIdentity();
try {
ComponentName component = null;
@@ -1064,12 +1110,30 @@ public final class SmsApplication {
*/
public static ComponentName getDefaultExternalTelephonyProviderChangedApplication(
Context context, boolean updateIfNeeded) {
- int userId = getIncomingUserId(context);
+ return getDefaultExternalTelephonyProviderChangedApplicationAsUser(context, updateIfNeeded,
+ getIncomingUserHandle());
+ }
+
+ /**
+ * Gets the default application that handles external changes to the SmsProvider and
+ * MmsProvider on a given user.
+ * @param context context from the calling app
+ * @param updateIfNeeded update the default app if there is no valid default app configured
+ * @param userHandle target user handle
+ * if {@code null} is passed in then calling package uid is used to find out target user handle.
+ * @return component name of the app and class to deliver change intents to.
+ */
+ public static ComponentName getDefaultExternalTelephonyProviderChangedApplicationAsUser(
+ Context context, boolean updateIfNeeded, @Nullable UserHandle userHandle) {
+ if (userHandle == null) {
+ userHandle = getIncomingUserHandle();
+ }
+
final long token = Binder.clearCallingIdentity();
try {
ComponentName component = null;
SmsApplicationData smsApplicationData = getApplication(context, updateIfNeeded,
- userId);
+ userHandle.getIdentifier());
if (smsApplicationData != null
&& smsApplicationData.mProviderChangedReceiverClass != null) {
component = new ComponentName(smsApplicationData.mPackageName,
@@ -1089,12 +1153,28 @@ public final class SmsApplication {
*/
public static ComponentName getDefaultSimFullApplication(
Context context, boolean updateIfNeeded) {
- int userId = getIncomingUserId(context);
+ return getDefaultSimFullApplicationAsUser(context, updateIfNeeded, getIncomingUserHandle());
+ }
+
+ /**
+ * Gets the default application that handles sim full event on a given user.
+ * @param context context from the calling app
+ * @param updateIfNeeded update the default app if there is no valid default app configured
+ * @param userHandle target user handle
+ * if {@code null} is passed in then calling package uid is used to find out target user handle.
+ * @return component name of the app and class to deliver change intents to
+ */
+ public static ComponentName getDefaultSimFullApplicationAsUser(Context context,
+ boolean updateIfNeeded, @Nullable UserHandle userHandle) {
+ if (userHandle == null) {
+ userHandle = getIncomingUserHandle();
+ }
+
final long token = Binder.clearCallingIdentity();
try {
ComponentName component = null;
SmsApplicationData smsApplicationData = getApplication(context, updateIfNeeded,
- userId);
+ userHandle.getIdentifier());
if (smsApplicationData != null
&& smsApplicationData.mSimFullReceiverClass != null) {
component = new ComponentName(smsApplicationData.mPackageName,
@@ -1107,13 +1187,35 @@ public final class SmsApplication {
}
/**
- * Returns whether need to write the SMS message to SMS database for this package.
+ * Returns whether it is required to write the SMS message to SMS database for this package.
+ *
+ * @param packageName the name of the package to be checked
+ * @param context context from the calling app
+ * @return true if it is required to write SMS message to SMS database for this package.
+ *
* <p>
* Caller must pass in the correct user context if calling from a singleton service.
*/
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
public static boolean shouldWriteMessageForPackage(String packageName, Context context) {
- return !isDefaultSmsApplication(context, packageName);
+ return !shouldWriteMessageForPackageAsUser(packageName, context, getIncomingUserHandle());
+ }
+
+ /**
+ * Returns whether it is required to write the SMS message to SMS database for this package.
+ *
+ * @param packageName the name of the package to be checked
+ * @param context context from the calling app
+ * @param userHandle target user handle
+ * if {@code null} is passed in then calling package uid is used to find out target user handle.
+ * @return true if it is required to write SMS message to SMS database for this package.
+ *
+ * <p>
+ * Caller must pass in the correct user context if calling from a singleton service.
+ */
+ public static boolean shouldWriteMessageForPackageAsUser(String packageName, Context context,
+ @Nullable UserHandle userHandle) {
+ return !isDefaultSmsApplicationAsUser(context, packageName, userHandle);
}
/**
@@ -1125,28 +1227,48 @@ public final class SmsApplication {
*/
@UnsupportedAppUsage
public static boolean isDefaultSmsApplication(Context context, String packageName) {
+ return isDefaultSmsApplicationAsUser(context, packageName, getIncomingUserHandle());
+ }
+
+ /**
+ * Check if a package is default sms app (or equivalent, like bluetooth) on a given user.
+ *
+ * @param context context from the calling app
+ * @param packageName the name of the package to be checked
+ * @param userHandle target user handle
+ * if {@code null} is passed in then calling package uid is used to find out target user handle.
+ * @return true if the package is default sms app or bluetooth
+ */
+ public static boolean isDefaultSmsApplicationAsUser(Context context, String packageName,
+ @Nullable UserHandle userHandle) {
if (packageName == null) {
return false;
}
- final String defaultSmsPackage = getDefaultSmsApplicationPackageName(context);
- final String bluetoothPackageName = context.getResources()
+
+ if (userHandle == null) {
+ userHandle = getIncomingUserHandle();
+ }
+
+ ComponentName component = getDefaultSmsApplicationAsUser(context, false,
+ userHandle);
+ if (component == null) {
+ return false;
+ }
+
+ String defaultSmsPackage = component.getPackageName();
+ if (defaultSmsPackage == null) {
+ return false;
+ }
+
+ String bluetoothPackageName = context.getResources()
.getString(com.android.internal.R.string.config_systemBluetoothStack);
- if ((defaultSmsPackage != null && defaultSmsPackage.equals(packageName))
- || bluetoothPackageName.equals(packageName)) {
+ if (defaultSmsPackage.equals(packageName) || bluetoothPackageName.equals(packageName)) {
return true;
}
return false;
}
- private static String getDefaultSmsApplicationPackageName(Context context) {
- final ComponentName component = getDefaultSmsApplication(context, false);
- if (component != null) {
- return component.getPackageName();
- }
- return null;
- }
-
/**
* Check if a package is default mms app (or equivalent, like bluetooth)
*
@@ -1156,25 +1278,45 @@ public final class SmsApplication {
*/
@UnsupportedAppUsage
public static boolean isDefaultMmsApplication(Context context, String packageName) {
+ return isDefaultMmsApplicationAsUser(context, packageName, getIncomingUserHandle());
+ }
+
+ /**
+ * Check if a package is default mms app (or equivalent, like bluetooth) on a given user.
+ *
+ * @param context context from the calling app
+ * @param packageName the name of the package to be checked
+ * @param userHandle target user handle
+ * if {@code null} is passed in then calling package uid is used to find out target user handle.
+ * @return true if the package is default mms app or bluetooth
+ */
+ public static boolean isDefaultMmsApplicationAsUser(Context context, String packageName,
+ @Nullable UserHandle userHandle) {
if (packageName == null) {
return false;
}
- String defaultMmsPackage = getDefaultMmsApplicationPackageName(context);
+
+ if (userHandle == null) {
+ userHandle = getIncomingUserHandle();
+ }
+
+ ComponentName component = getDefaultMmsApplicationAsUser(context, false,
+ userHandle);
+ if (component == null) {
+ return false;
+ }
+
+ String defaultMmsPackage = component.getPackageName();
+ if (defaultMmsPackage == null) {
+ return false;
+ }
+
String bluetoothPackageName = context.getResources()
.getString(com.android.internal.R.string.config_systemBluetoothStack);
- if ((defaultMmsPackage != null && defaultMmsPackage.equals(packageName))
- || bluetoothPackageName.equals(packageName)) {
+ if (defaultMmsPackage.equals(packageName)|| bluetoothPackageName.equals(packageName)) {
return true;
}
return false;
}
-
- private static String getDefaultMmsApplicationPackageName(Context context) {
- ComponentName component = getDefaultMmsApplication(context, false);
- if (component != null) {
- return component.getPackageName();
- }
- return null;
- }
-}
+} \ No newline at end of file
diff --git a/telephony/common/com/android/internal/telephony/TelephonyPermissions.java b/telephony/common/com/android/internal/telephony/TelephonyPermissions.java
index f90eabc7175e..29a952a5d6d1 100644
--- a/telephony/common/com/android/internal/telephony/TelephonyPermissions.java
+++ b/telephony/common/com/android/internal/telephony/TelephonyPermissions.java
@@ -20,6 +20,7 @@ import static android.content.pm.PackageManager.PERMISSION_GRANTED;
import android.Manifest;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.RequiresPermission;
import android.app.AppOpsManager;
import android.content.Context;
import android.content.pm.ApplicationInfo;
@@ -108,6 +109,21 @@ public final class TelephonyPermissions {
}
}
+ /**
+ * Check whether the caller (or self, if not processing an IPC) has internet permission.
+ * @param context app context
+ * @param message detail message
+ * @return true if permission is granted, else false
+ */
+ public static boolean checkInternetPermissionNoThrow(Context context, String message) {
+ try {
+ context.enforcePermission(Manifest.permission.INTERNET,
+ Binder.getCallingPid(), Binder.getCallingUid(), message);
+ return true;
+ } catch (SecurityException se) {
+ return false;
+ }
+ }
/**
* Check whether the caller (or self, if not processing an IPC) has non dangerous
@@ -315,8 +331,8 @@ public final class TelephonyPermissions {
* Same as {@link #checkCallingOrSelfReadSubscriberIdentifiers(Context, int, String, String,
* String)} except this allows an additional parameter reportFailure. Caller may not want to
* report a failure when this is an internal/intermediate check, for example,
- * SubscriptionController calls this with an INVALID_SUBID to check if caller has the required
- * permissions to bypass carrier privilege checks.
+ * SubscriptionManagerService calls this with an INVALID_SUBID to check if caller has the
+ * required permissions to bypass carrier privilege checks.
* @param reportFailure Indicates if failure should be reported.
*/
public static boolean checkCallingOrSelfReadSubscriberIdentifiers(Context context, int subId,
@@ -826,6 +842,37 @@ public final class TelephonyPermissions {
/**
* Check if calling user is associated with the given subscription.
+ * Subscription-user association check is skipped if destination address is an emergency number.
+ *
+ * @param context Context
+ * @param subId subscription ID
+ * @param callerUserHandle caller user handle
+ * @param destAddr destination address of the message
+ * @return true if destAddr is an emergency number
+ * and return false if user is not associated with the subscription.
+ */
+ public static boolean checkSubscriptionAssociatedWithUser(@NonNull Context context, int subId,
+ @NonNull UserHandle callerUserHandle, @NonNull String destAddr) {
+ // Skip subscription-user association check for emergency numbers
+ TelephonyManager tm = context.getSystemService(TelephonyManager.class);
+ final long token = Binder.clearCallingIdentity();
+ try {
+ if (tm != null && tm.isEmergencyNumber(destAddr)) {
+ Log.d(LOG_TAG, "checkSubscriptionAssociatedWithUser:"
+ + " destAddr is emergency number");
+ return true;
+ }
+ } catch(Exception e) {
+ Log.e(LOG_TAG, "Cannot verify if destAddr is an emergency number: " + e);
+ } finally {
+ Binder.restoreCallingIdentity(token);
+ }
+
+ return checkSubscriptionAssociatedWithUser(context, subId, callerUserHandle);
+ }
+
+ /**
+ * Check if calling user is associated with the given subscription.
* @param context Context
* @param subId subscription ID
* @param callerUserHandle caller user handle
@@ -844,7 +891,7 @@ public final class TelephonyPermissions {
if ((subManager != null) &&
(!subManager.isSubscriptionAssociatedWithUser(subId, callerUserHandle))) {
// If subId is not associated with calling user, return false.
- Log.e(LOG_TAG,"User[User ID:" + callerUserHandle.getIdentifier()
+ Log.e(LOG_TAG, "User[User ID:" + callerUserHandle.getIdentifier()
+ "] is not associated with Subscription ID:" + subId);
return false;
@@ -854,4 +901,27 @@ public final class TelephonyPermissions {
}
return true;
}
+
+ /**
+ * Ensure the caller (or self, if not processing an IPC) has
+ * {@link android.Manifest.permission#READ_PRIVILEGED_PHONE_STATE} or
+ * {@link android.Manifest.permission#READ_PHONE_NUMBERS}.
+ *
+ * @throws SecurityException if the caller does not have the required permission/privileges
+ */
+ @RequiresPermission(anyOf = {
+ android.Manifest.permission.READ_PHONE_NUMBERS,
+ android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE
+ })
+ public static boolean checkCallingOrSelfReadPrivilegedPhoneStatePermissionOrReadPhoneNumber(
+ Context context, int subId, String callingPackage, @Nullable String callingFeatureId,
+ String message) {
+ if (!SubscriptionManager.isValidSubscriptionId(subId)) {
+ return false;
+ }
+ return (context.checkCallingOrSelfPermission(
+ Manifest.permission.READ_PRIVILEGED_PHONE_STATE) == PERMISSION_GRANTED
+ || checkCallingOrSelfReadPhoneNumber(context, subId, callingPackage,
+ callingFeatureId, message));
+ }
}
diff --git a/telephony/common/com/android/internal/telephony/util/TelephonyUtils.java b/telephony/common/com/android/internal/telephony/util/TelephonyUtils.java
index 5179babbd31d..9a8c9655375d 100644
--- a/telephony/common/com/android/internal/telephony/util/TelephonyUtils.java
+++ b/telephony/common/com/android/internal/telephony/util/TelephonyUtils.java
@@ -19,6 +19,8 @@ import static android.telephony.Annotation.DataState;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.app.ActivityManager;
+import android.app.role.RoleManager;
import android.content.Context;
import android.content.pm.ComponentInfo;
import android.content.pm.PackageManager;
@@ -26,8 +28,16 @@ import android.content.pm.ResolveInfo;
import android.os.Binder;
import android.os.Bundle;
import android.os.PersistableBundle;
+import android.os.RemoteException;
import android.os.SystemProperties;
+import android.os.UserHandle;
+import android.os.UserManager;
+import android.telephony.SubscriptionManager;
+import android.telephony.TelephonyFrameworkInitializer;
import android.telephony.TelephonyManager;
+import android.util.Log;
+
+import com.android.internal.telephony.ITelephony;
import java.io.PrintWriter;
import java.util.Collections;
@@ -41,6 +51,8 @@ import java.util.function.Supplier;
* This class provides various util functions
*/
public final class TelephonyUtils {
+ private static final String LOG_TAG = "TelephonyUtils";
+
public static boolean IS_USER = "user".equals(android.os.Build.TYPE);
public static boolean IS_DEBUGGABLE = SystemProperties.getInt("ro.debuggable", 0) == 1;
@@ -206,8 +218,105 @@ public final class TelephonyUtils {
return "DATA_ON_NON_DEFAULT_DURING_VOICE_CALL";
case TelephonyManager.MOBILE_DATA_POLICY_MMS_ALWAYS_ALLOWED:
return "MMS_ALWAYS_ALLOWED";
+ case TelephonyManager.MOBILE_DATA_POLICY_AUTO_DATA_SWITCH:
+ return "AUTO_DATA_SWITCH";
default:
return "UNKNOWN(" + mobileDataPolicy + ")";
}
}
-}
+
+ /**
+ * Utility method to get user handle associated with this subscription.
+ *
+ * This method should be used internally as it returns null instead of throwing
+ * IllegalArgumentException or IllegalStateException.
+ *
+ * @param context Context object
+ * @param subId the subId of the subscription.
+ * @return userHandle associated with this subscription
+ * or {@code null} if:
+ * 1. subscription is not associated with any user
+ * 2. subId is invalid.
+ * 3. subscription service is not available.
+ *
+ * @throws SecurityException if the caller doesn't have permissions required.
+ */
+ @Nullable
+ public static UserHandle getSubscriptionUserHandle(Context context, int subId) {
+ UserHandle userHandle = null;
+ SubscriptionManager subManager = context.getSystemService(SubscriptionManager.class);
+ if ((subManager != null) && (SubscriptionManager.isValidSubscriptionId(subId))) {
+ userHandle = subManager.getSubscriptionUserHandle(subId);
+ }
+ return userHandle;
+ }
+
+ /**
+ * Show switch to managed profile dialog if subscription is associated with managed profile.
+ *
+ * @param context Context object
+ * @param subId subscription id
+ * @param callingUid uid for the calling app
+ * @param callingPackage package name of the calling app
+ */
+ public static void showSwitchToManagedProfileDialogIfAppropriate(Context context,
+ int subId, int callingUid, String callingPackage) {
+ final long token = Binder.clearCallingIdentity();
+ try {
+ UserHandle callingUserHandle = UserHandle.getUserHandleForUid(callingUid);
+ // We only want to show this dialog, while user actually trying to send the message from
+ // a messaging app, in other cases this dialog don't make sense.
+ if (!TelephonyUtils.isUidForeground(context, callingUid)
+ || !TelephonyUtils.isPackageSMSRoleHolderForUser(context, callingPackage,
+ callingUserHandle)) {
+ return;
+ }
+
+ SubscriptionManager subscriptionManager = context.getSystemService(
+ SubscriptionManager.class);
+ UserHandle associatedUserHandle = subscriptionManager.getSubscriptionUserHandle(subId);
+ UserManager um = context.getSystemService(UserManager.class);
+
+ if (associatedUserHandle != null && um.isManagedProfile(
+ associatedUserHandle.getIdentifier())) {
+
+ ITelephony iTelephony = ITelephony.Stub.asInterface(
+ TelephonyFrameworkInitializer
+ .getTelephonyServiceManager()
+ .getTelephonyServiceRegisterer()
+ .get());
+ if (iTelephony != null) {
+ try {
+ iTelephony.showSwitchToManagedProfileDialog();
+ } catch (RemoteException e) {
+ Log.e(LOG_TAG, "Failed to launch switch to managed profile dialog.");
+ }
+ }
+ }
+ } finally {
+ Binder.restoreCallingIdentity(token);
+ }
+ }
+
+ private static boolean isUidForeground(Context context, int uid) {
+ ActivityManager am = context.getSystemService(ActivityManager.class);
+ boolean result = am != null && am.getUidImportance(uid)
+ == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
+ return result;
+ }
+
+ private static boolean isPackageSMSRoleHolderForUser(Context context, String callingPackage,
+ UserHandle user) {
+ RoleManager roleManager = context.getSystemService(RoleManager.class);
+ final List<String> smsRoleHolder = roleManager.getRoleHoldersAsUser(
+ RoleManager.ROLE_SMS, user);
+
+ // ROLE_SMS is an exclusive role per user, so there would just be one entry in the
+ // retuned list if not empty
+ if (!smsRoleHolder.isEmpty() && callingPackage.equals(smsRoleHolder.get(0))) {
+ return true;
+ }
+ return false;
+
+ }
+} \ No newline at end of file
diff --git a/telephony/java/android/service/euicc/EuiccProfileInfo.java b/telephony/java/android/service/euicc/EuiccProfileInfo.java
index 7eccd1a4482f..f7c8237bdda4 100644
--- a/telephony/java/android/service/euicc/EuiccProfileInfo.java
+++ b/telephony/java/android/service/euicc/EuiccProfileInfo.java
@@ -24,6 +24,7 @@ import android.os.Build;
import android.os.Parcel;
import android.os.Parcelable;
import android.service.carrier.CarrierIdentifier;
+import android.telephony.SubscriptionInfo;
import android.telephony.UiccAccessRule;
import android.text.TextUtils;
@@ -451,6 +452,8 @@ public final class EuiccProfileInfo implements Parcelable {
+ mPolicyRules
+ ", accessRules="
+ Arrays.toString(mAccessRules)
+ + ", iccid="
+ + SubscriptionInfo.getPrintableId(mIccid)
+ ")";
}
}
diff --git a/telephony/java/android/service/euicc/EuiccService.java b/telephony/java/android/service/euicc/EuiccService.java
index e19117bc805f..b59e855825b9 100644
--- a/telephony/java/android/service/euicc/EuiccService.java
+++ b/telephony/java/android/service/euicc/EuiccService.java
@@ -17,10 +17,12 @@ package android.service.euicc;
import static android.telephony.euicc.EuiccCardManager.ResetOption;
+import android.Manifest;
import android.annotation.CallSuper;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.RequiresPermission;
import android.annotation.SdkConstant;
import android.annotation.SystemApi;
import android.app.PendingIntent;
@@ -132,13 +134,25 @@ public abstract class EuiccService extends Service {
* @see android.telephony.euicc.EuiccManager#ACTION_MANAGE_EMBEDDED_SUBSCRIPTIONS
* The difference is this one is used by system to bring up the LUI.
*/
+ @RequiresPermission(Manifest.permission.BIND_EUICC_SERVICE)
public static final String ACTION_MANAGE_EMBEDDED_SUBSCRIPTIONS =
"android.service.euicc.action.MANAGE_EMBEDDED_SUBSCRIPTIONS";
/** @see android.telephony.euicc.EuiccManager#ACTION_PROVISION_EMBEDDED_SUBSCRIPTION */
+ @RequiresPermission(Manifest.permission.BIND_EUICC_SERVICE)
public static final String ACTION_PROVISION_EMBEDDED_SUBSCRIPTION =
"android.service.euicc.action.PROVISION_EMBEDDED_SUBSCRIPTION";
+ /** @see android.telephony.euicc.EuiccManager#ACTION_TRANSFER_EMBEDDED_SUBSCRIPTIONS */
+ @RequiresPermission(Manifest.permission.BIND_EUICC_SERVICE)
+ public static final String ACTION_TRANSFER_EMBEDDED_SUBSCRIPTIONS =
+ "android.service.euicc.action.TRANSFER_EMBEDDED_SUBSCRIPTIONS";
+
+ /** @see android.telephony.euicc.EuiccManager#ACTION_CONVERT_TO_EMBEDDED_SUBSCRIPTION */
+ @RequiresPermission(Manifest.permission.BIND_EUICC_SERVICE)
+ public static final String ACTION_CONVERT_TO_EMBEDDED_SUBSCRIPTION =
+ "android.service.euicc.action.CONVERT_TO_EMBEDDED_SUBSCRIPTION";
+
/**
* @see android.telephony.euicc.EuiccManager#ACTION_TOGGLE_SUBSCRIPTION_PRIVILEGED. This is
* a protected intent that can only be sent by the system, and requires the
@@ -490,6 +504,28 @@ public abstract class EuiccService extends Service {
int slotId, DownloadableSubscription subscription, boolean forceDeactivateSim);
/**
+ * Populate {@link DownloadableSubscription} metadata for the given downloadable subscription.
+ *
+ * @param slotId ID of the SIM slot to use for the operation.
+ * @param portIndex Index of the port from the slot. portIndex is used if the eUICC must
+ * be activated to perform the operation.
+ * @param subscription A subscription whose metadata needs to be populated.
+ * @param forceDeactivateSim If true, and if an active SIM must be deactivated to access the
+ * eUICC, perform this action automatically. Otherwise, {@link #RESULT_MUST_DEACTIVATE_SIM}
+ * should be returned to allow the user to consent to this operation first.
+ * @return The result of the operation.
+ * @see android.telephony.euicc.EuiccManager#getDownloadableSubscriptionMetadata
+ */
+ @NonNull
+ public GetDownloadableSubscriptionMetadataResult onGetDownloadableSubscriptionMetadata(
+ int slotId, int portIndex, @NonNull DownloadableSubscription subscription,
+ boolean forceDeactivateSim) {
+ // stub implementation, LPA needs to implement this
+ throw new UnsupportedOperationException(
+ "LPA must override onGetDownloadableSubscriptionMetadata");
+ }
+
+ /**
* Return metadata for subscriptions which are available for download for this device.
*
* @param slotId ID of the SIM slot to use for the operation.
@@ -833,16 +869,31 @@ public abstract class EuiccService extends Service {
}
@Override
- public void getDownloadableSubscriptionMetadata(int slotId,
+ public void getDownloadableSubscriptionMetadata(int slotId, int portIndex,
DownloadableSubscription subscription,
- boolean forceDeactivateSim,
+ boolean switchAfterDownload, boolean forceDeactivateSim,
IGetDownloadableSubscriptionMetadataCallback callback) {
mExecutor.execute(new Runnable() {
@Override
public void run() {
- GetDownloadableSubscriptionMetadataResult result =
- EuiccService.this.onGetDownloadableSubscriptionMetadata(
+ GetDownloadableSubscriptionMetadataResult result;
+ if (switchAfterDownload) {
+ try {
+ result = EuiccService.this.onGetDownloadableSubscriptionMetadata(
+ slotId, portIndex, subscription, forceDeactivateSim);
+ } catch (UnsupportedOperationException | AbstractMethodError e) {
+ Log.w(TAG, "The new onGetDownloadableSubscriptionMetadata(int, int, "
+ + "DownloadableSubscription, boolean) is not implemented."
+ + " Fall back to the old one.", e);
+ result = EuiccService.this.onGetDownloadableSubscriptionMetadata(
slotId, subscription, forceDeactivateSim);
+ }
+ } else {
+ // When switchAfterDownload is false, this operation is port agnostic.
+ // Call API without portIndex.
+ result = EuiccService.this.onGetDownloadableSubscriptionMetadata(
+ slotId, subscription, forceDeactivateSim);
+ }
try {
callback.onComplete(result);
} catch (RemoteException e) {
diff --git a/telephony/java/android/service/euicc/IEuiccService.aidl b/telephony/java/android/service/euicc/IEuiccService.aidl
index 6b0397d67015..f8d5ae9ca86d 100644
--- a/telephony/java/android/service/euicc/IEuiccService.aidl
+++ b/telephony/java/android/service/euicc/IEuiccService.aidl
@@ -38,8 +38,10 @@ oneway interface IEuiccService {
void downloadSubscription(int slotId, int portIndex, in DownloadableSubscription subscription,
boolean switchAfterDownload, boolean forceDeactivateSim, in Bundle resolvedBundle,
in IDownloadSubscriptionCallback callback);
- void getDownloadableSubscriptionMetadata(int slotId, in DownloadableSubscription subscription,
- boolean forceDeactivateSim, in IGetDownloadableSubscriptionMetadataCallback callback);
+ void getDownloadableSubscriptionMetadata(
+ int slotId, int portIndex, in DownloadableSubscription subscription,
+ boolean switchAfterDownload, boolean forceDeactivateSim,
+ in IGetDownloadableSubscriptionMetadataCallback callback);
void getEid(int slotId, in IGetEidCallback callback);
void getOtaStatus(int slotId, in IGetOtaStatusCallback callback);
void startOtaIfNecessary(int slotId, in IOtaStatusChangedCallback statusChangedCallback);
diff --git a/telephony/java/android/telephony/Annotation.java b/telephony/java/android/telephony/Annotation.java
index 86b98f1cbe79..2435243f0044 100644
--- a/telephony/java/android/telephony/Annotation.java
+++ b/telephony/java/android/telephony/Annotation.java
@@ -5,6 +5,7 @@ import android.net.NetworkAgent;
import android.net.NetworkCapabilities;
import android.telecom.Connection;
import android.telephony.data.ApnSetting;
+import android.telephony.ims.ImsCallProfile;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@@ -494,7 +495,7 @@ public class Annotation {
PreciseCallState.PRECISE_CALL_STATE_HOLDING,
PreciseCallState.PRECISE_CALL_STATE_DIALING,
PreciseCallState.PRECISE_CALL_STATE_ALERTING,
- PreciseCallState. PRECISE_CALL_STATE_INCOMING,
+ PreciseCallState.PRECISE_CALL_STATE_INCOMING,
PreciseCallState.PRECISE_CALL_STATE_WAITING,
PreciseCallState.PRECISE_CALL_STATE_DISCONNECTED,
PreciseCallState.PRECISE_CALL_STATE_DISCONNECTING})
@@ -727,6 +728,36 @@ public class Annotation {
})
public @interface ValidationStatus {}
+ /**
+ * IMS call Service types
+ */
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef(prefix = { "SERVICE_TYPE_" }, value = {
+ ImsCallProfile.SERVICE_TYPE_NONE,
+ ImsCallProfile.SERVICE_TYPE_NORMAL,
+ ImsCallProfile.SERVICE_TYPE_EMERGENCY,
+ })
+ public @interface ImsCallServiceType {}
+
+ /**
+ * IMS call types
+ */
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef(prefix = { "CALL_TYPE_" }, value = {
+ ImsCallProfile.CALL_TYPE_NONE,
+ ImsCallProfile.CALL_TYPE_VOICE_N_VIDEO,
+ ImsCallProfile.CALL_TYPE_VOICE,
+ ImsCallProfile.CALL_TYPE_VIDEO_N_VOICE,
+ ImsCallProfile.CALL_TYPE_VT,
+ ImsCallProfile.CALL_TYPE_VT_TX,
+ ImsCallProfile.CALL_TYPE_VT_RX,
+ ImsCallProfile.CALL_TYPE_VT_NODIR,
+ ImsCallProfile.CALL_TYPE_VS,
+ ImsCallProfile.CALL_TYPE_VS_TX,
+ ImsCallProfile.CALL_TYPE_VS_RX,
+ })
+ public @interface ImsCallType {}
+
/** @hide */
@Retention(RetentionPolicy.SOURCE)
@IntDef(prefix = { "NET_CAPABILITY_ENTERPRISE_SUB_LEVEL" }, value = {
diff --git a/telephony/java/android/telephony/AnomalyReporter.java b/telephony/java/android/telephony/AnomalyReporter.java
index 061b71b25275..db38f8873a02 100644
--- a/telephony/java/android/telephony/AnomalyReporter.java
+++ b/telephony/java/android/telephony/AnomalyReporter.java
@@ -105,13 +105,22 @@ public final class AnomalyReporter {
* @param carrierId the carrier of the id associated with this event.
*/
public static void reportAnomaly(@NonNull UUID eventId, String description, int carrierId) {
+ Rlog.i(TAG, "reportAnomaly: Received anomaly event report with eventId= " + eventId
+ + " and description= " + description);
if (sContext == null) {
Rlog.w(TAG, "AnomalyReporter not yet initialized, dropping event=" + eventId);
return;
}
- // Don't report if the server-side flag isn't loaded, as it implies other anomaly report
- // related config hasn't loaded.
+ //always write atoms to statsd
+ TelephonyStatsLog.write(
+ TELEPHONY_ANOMALY_DETECTED,
+ carrierId,
+ eventId.getLeastSignificantBits(),
+ eventId.getMostSignificantBits());
+
+ // Don't report via Intent if the server-side flag isn't loaded, as it implies other anomaly
+ // report related config hasn't loaded.
try {
boolean isAnomalyReportEnabledFromServer = DeviceConfig.getBoolean(
DeviceConfig.NAMESPACE_TELEPHONY, KEY_IS_TELEPHONY_ANOMALY_REPORT_ENABLED,
@@ -122,12 +131,6 @@ public final class AnomalyReporter {
return;
}
- TelephonyStatsLog.write(
- TELEPHONY_ANOMALY_DETECTED,
- carrierId,
- eventId.getLeastSignificantBits(),
- eventId.getMostSignificantBits());
-
// If this event has already occurred, skip sending intents for it; regardless log its
// invocation here.
Integer count = sEvents.containsKey(eventId) ? sEvents.get(eventId) + 1 : 1;
diff --git a/telephony/java/android/telephony/CallAttributes.java b/telephony/java/android/telephony/CallAttributes.java
index b7bef39aa275..1dc64a9200fc 100644
--- a/telephony/java/android/telephony/CallAttributes.java
+++ b/telephony/java/android/telephony/CallAttributes.java
@@ -29,8 +29,10 @@ import java.util.Objects;
* Contains information about a call's attributes as passed up from the HAL. If there are multiple
* ongoing calls, the CallAttributes will pertain to the call in the foreground.
* @hide
+ * @deprecated use {@link CallState} for call information for each call.
*/
@SystemApi
+@Deprecated
public final class CallAttributes implements Parcelable {
private PreciseCallState mPreciseCallState;
@NetworkType
diff --git a/telephony/java/android/telephony/CallState.aidl b/telephony/java/android/telephony/CallState.aidl
new file mode 100644
index 000000000000..dd5af8e65921
--- /dev/null
+++ b/telephony/java/android/telephony/CallState.aidl
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.telephony;
+
+parcelable CallState;
+
diff --git a/telephony/java/android/telephony/CallState.java b/telephony/java/android/telephony/CallState.java
new file mode 100644
index 000000000000..836cb53488ef
--- /dev/null
+++ b/telephony/java/android/telephony/CallState.java
@@ -0,0 +1,409 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.telephony;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SystemApi;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.telephony.Annotation.ImsCallServiceType;
+import android.telephony.Annotation.ImsCallType;
+import android.telephony.Annotation.NetworkType;
+import android.telephony.Annotation.PreciseCallStates;
+import android.telephony.ims.ImsCallProfile;
+import android.telephony.ims.ImsCallSession;
+
+import java.util.Objects;
+
+/**
+ * Contains information about various states for a call.
+ * @hide
+ */
+@SystemApi
+public final class CallState implements Parcelable {
+
+ /**
+ * Call classifications are just used for backward compatibility of deprecated API {@link
+ * TelephonyCallback#CallAttributesListener#onCallAttributesChanged}, Since these will be
+ * removed when the deprecated API is removed, they should not be opened.
+ */
+ /**
+ * Call classification is not valid. It should not be opened.
+ * @hide
+ */
+ public static final int CALL_CLASSIFICATION_UNKNOWN = -1;
+
+ /**
+ * Call classification indicating foreground call
+ * @hide
+ */
+ public static final int CALL_CLASSIFICATION_RINGING = 0;
+
+ /**
+ * Call classification indicating background call
+ * @hide
+ */
+ public static final int CALL_CLASSIFICATION_FOREGROUND = 1;
+
+ /**
+ * Call classification indicating ringing call
+ * @hide
+ */
+ public static final int CALL_CLASSIFICATION_BACKGROUND = 2;
+
+ /**
+ * Call classification Max value.
+ * @hide
+ */
+ public static final int CALL_CLASSIFICATION_MAX = CALL_CLASSIFICATION_BACKGROUND + 1;
+
+ @PreciseCallStates
+ private final int mPreciseCallState;
+
+ @NetworkType
+ private final int mNetworkType; // TelephonyManager.NETWORK_TYPE_* ints
+ private final CallQuality mCallQuality;
+
+ private final int mCallClassification;
+ /**
+ * IMS call session ID. {@link ImsCallSession#getCallId()}
+ */
+ @Nullable
+ private String mImsCallId;
+
+ /**
+ * IMS call service type of this call
+ */
+ @ImsCallServiceType
+ private int mImsCallServiceType;
+
+ /**
+ * IMS call type of this call.
+ */
+ @ImsCallType
+ private int mImsCallType;
+
+ /**
+ * Constructor of CallAttributes
+ *
+ * @param callState call state defined in {@link PreciseCallState}
+ * @param networkType network type for this call attributes
+ * @param callQuality call quality for this call attributes, only CallState in
+ * {@link PreciseCallState#PRECISE_CALL_STATE_ACTIVE} will have valid call
+ * quality.
+ * @param callClassification call classification
+ * @param imsCallId IMS call session ID for this call attributes
+ * @param imsCallServiceType IMS call service type for this call attributes
+ * @param imsCallType IMS call type for this call attributes
+ */
+ private CallState(@PreciseCallStates int callState, @NetworkType int networkType,
+ @NonNull CallQuality callQuality, int callClassification, @Nullable String imsCallId,
+ @ImsCallServiceType int imsCallServiceType, @ImsCallType int imsCallType) {
+ this.mPreciseCallState = callState;
+ this.mNetworkType = networkType;
+ this.mCallQuality = callQuality;
+ this.mCallClassification = callClassification;
+ this.mImsCallId = imsCallId;
+ this.mImsCallServiceType = imsCallServiceType;
+ this.mImsCallType = imsCallType;
+ }
+
+ @NonNull
+ @Override
+ public String toString() {
+ return "mPreciseCallState=" + mPreciseCallState + " mNetworkType=" + mNetworkType
+ + " mCallQuality=" + mCallQuality + " mCallClassification" + mCallClassification
+ + " mImsCallId=" + mImsCallId + " mImsCallServiceType=" + mImsCallServiceType
+ + " mImsCallType=" + mImsCallType;
+ }
+
+ private CallState(Parcel in) {
+ this.mPreciseCallState = in.readInt();
+ this.mNetworkType = in.readInt();
+ this.mCallQuality = in.readParcelable(
+ CallQuality.class.getClassLoader(), CallQuality.class);
+ this.mCallClassification = in.readInt();
+ this.mImsCallId = in.readString();
+ this.mImsCallServiceType = in.readInt();
+ this.mImsCallType = in.readInt();
+ }
+
+ // getters
+ /**
+ * Returns the precise call state of the call.
+ */
+ @PreciseCallStates
+ public int getCallState() {
+ return mPreciseCallState;
+ }
+
+ /**
+ * Returns the {@link TelephonyManager#NetworkType} of the call.
+ *
+ * @see TelephonyManager#NETWORK_TYPE_UNKNOWN
+ * @see TelephonyManager#NETWORK_TYPE_GPRS
+ * @see TelephonyManager#NETWORK_TYPE_EDGE
+ * @see TelephonyManager#NETWORK_TYPE_UMTS
+ * @see TelephonyManager#NETWORK_TYPE_CDMA
+ * @see TelephonyManager#NETWORK_TYPE_EVDO_0
+ * @see TelephonyManager#NETWORK_TYPE_EVDO_A
+ * @see TelephonyManager#NETWORK_TYPE_1xRTT
+ * @see TelephonyManager#NETWORK_TYPE_HSDPA
+ * @see TelephonyManager#NETWORK_TYPE_HSUPA
+ * @see TelephonyManager#NETWORK_TYPE_HSPA
+ * @see TelephonyManager#NETWORK_TYPE_IDEN
+ * @see TelephonyManager#NETWORK_TYPE_EVDO_B
+ * @see TelephonyManager#NETWORK_TYPE_LTE
+ * @see TelephonyManager#NETWORK_TYPE_EHRPD
+ * @see TelephonyManager#NETWORK_TYPE_HSPAP
+ * @see TelephonyManager#NETWORK_TYPE_GSM
+ * @see TelephonyManager#NETWORK_TYPE_TD_SCDMA
+ * @see TelephonyManager#NETWORK_TYPE_IWLAN
+ * @see TelephonyManager#NETWORK_TYPE_LTE_CA
+ * @see TelephonyManager#NETWORK_TYPE_NR
+ */
+ @NetworkType
+ public int getNetworkType() {
+ return mNetworkType;
+ }
+
+ /**
+ * Returns the {#link CallQuality} of the call.
+ * @return call quality for this call attributes, only CallState in {@link
+ * PreciseCallState#PRECISE_CALL_STATE_ACTIVE} will have valid call quality. It will be
+ * null for the call which is not in {@link PreciseCallState#PRECISE_CALL_STATE_ACTIVE}.
+ */
+ @Nullable
+ public CallQuality getCallQuality() {
+ return mCallQuality;
+ }
+
+ /**
+ * Returns the call classification.
+ * @hide
+ */
+ public int getCallClassification() {
+ return mCallClassification;
+ }
+
+ /**
+ * Returns the IMS call session ID.
+ */
+ @Nullable
+ public String getImsCallSessionId() {
+ return mImsCallId;
+ }
+
+ /**
+ * Returns the IMS call service type.
+ */
+ @ImsCallServiceType
+ public int getImsCallServiceType() {
+ return mImsCallServiceType;
+ }
+
+ /**
+ * Returns the IMS call type.
+ */
+ @ImsCallType
+ public int getImsCallType() {
+ return mImsCallType;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(mPreciseCallState, mNetworkType, mCallQuality, mCallClassification,
+ mImsCallId, mImsCallServiceType, mImsCallType);
+ }
+
+ @Override
+ public boolean equals(@Nullable Object o) {
+ if (o == null || !(o instanceof CallState) || hashCode() != o.hashCode()) {
+ return false;
+ }
+
+ if (this == o) {
+ return true;
+ }
+
+ CallState s = (CallState) o;
+
+ return (mPreciseCallState == s.mPreciseCallState
+ && mNetworkType == s.mNetworkType
+ && Objects.equals(mCallQuality, s.mCallQuality)
+ && mCallClassification == s.mCallClassification
+ && Objects.equals(mImsCallId, s.mImsCallId)
+ && mImsCallType == s.mImsCallType
+ && mImsCallServiceType == s.mImsCallServiceType);
+ }
+
+ /**
+ * {@link Parcelable#describeContents}
+ */
+ public int describeContents() {
+ return 0;
+ }
+
+ /**
+ * {@link Parcelable#writeToParcel}
+ */
+ public void writeToParcel(@Nullable Parcel dest, int flags) {
+ dest.writeInt(mPreciseCallState);
+ dest.writeInt(mNetworkType);
+ dest.writeParcelable(mCallQuality, flags);
+ dest.writeInt(mCallClassification);
+ dest.writeString(mImsCallId);
+ dest.writeInt(mImsCallServiceType);
+ dest.writeInt(mImsCallType);
+ }
+
+ public static final @NonNull Creator<CallState> CREATOR = new Creator() {
+ public CallState createFromParcel(Parcel in) {
+ return new CallState(in);
+ }
+
+ public CallState[] newArray(int size) {
+ return new CallState[size];
+ }
+ };
+
+ /**
+ * Builder of {@link CallState}
+ *
+ * <p>The example below shows how you might create a new {@code CallState}. A precise call state
+ * {@link PreciseCallStates} is mandatory to build a CallState.
+ *
+ * <pre><code>
+ *
+ * CallState = new CallState.Builder({@link PreciseCallStates})
+ * .setNetworkType({@link TelephonyManager#NETWORK_TYPE_LTE})
+ * .setCallQuality({@link CallQuality})
+ * .setImsCallSessionId({@link String})
+ * .setImsCallServiceType({@link ImsCallProfile#SERVICE_TYPE_NORMAL})
+ * .setImsCallType({@link ImsCallProfile#CALL_TYPE_VOICE})
+ * .build();
+ * </code></pre>
+ */
+ public static final class Builder {
+ private @PreciseCallStates int mPreciseCallState;
+ private @NetworkType int mNetworkType = TelephonyManager.NETWORK_TYPE_UNKNOWN;
+ private CallQuality mCallQuality = null;
+ private int mCallClassification = CALL_CLASSIFICATION_UNKNOWN;
+ private String mImsCallId;
+ private @ImsCallServiceType int mImsCallServiceType = ImsCallProfile.SERVICE_TYPE_NONE;
+ private @ImsCallType int mImsCallType = ImsCallProfile.CALL_TYPE_NONE;
+
+
+ /**
+ * Default constructor for the Builder.
+ */
+ public Builder(@PreciseCallStates int preciseCallState) {
+ mPreciseCallState = preciseCallState;
+ }
+
+ /**
+ * Set network type of this call.
+ *
+ * @param networkType the transport type.
+ * @return The same instance of the builder.
+ */
+ @NonNull
+ public CallState.Builder setNetworkType(@NetworkType int networkType) {
+ this.mNetworkType = networkType;
+ return this;
+ }
+
+ /**
+ * Set the call quality {@link CallQuality} of this call.
+ *
+ * @param callQuality call quality of active call.
+ * @return The same instance of the builder.
+ */
+ @NonNull
+ public CallState.Builder setCallQuality(@Nullable CallQuality callQuality) {
+ this.mCallQuality = callQuality;
+ return this;
+ }
+
+ /**
+ * Set call classification for this call.
+ *
+ * @param classification call classification type defined in this class.
+ * @return The same instance of the builder.
+ * @hide
+ */
+ @NonNull
+ public CallState.Builder setCallClassification(int classification) {
+ this.mCallClassification = classification;
+ return this;
+ }
+
+ /**
+ * Set IMS call session ID of this call.
+ *
+ * @param imsCallId IMS call session ID.
+ * @return The same instance of the builder.
+ */
+ @NonNull
+ public CallState.Builder setImsCallSessionId(@Nullable String imsCallId) {
+ this.mImsCallId = imsCallId;
+ return this;
+ }
+
+ /**
+ * Set IMS call service type of this call.
+ *
+ * @param serviceType IMS call service type defined in {@link ImsCallProfile}.
+ * @return The same instance of the builder.
+ */
+ @NonNull
+ public CallState.Builder setImsCallServiceType(@ImsCallServiceType int serviceType) {
+ this.mImsCallServiceType = serviceType;
+ return this;
+ }
+
+ /**
+ * Set IMS call type of this call.
+ *
+ * @param callType IMS call type defined in {@link ImsCallProfile}.
+ * @return The same instance of the builder.
+ */
+ @NonNull
+ public CallState.Builder setImsCallType(@ImsCallType int callType) {
+ this.mImsCallType = callType;
+ return this;
+ }
+
+ /**
+ * Build the {@link CallState}
+ *
+ * @return the {@link CallState} object
+ */
+ @NonNull
+ public CallState build() {
+ return new CallState(
+ mPreciseCallState,
+ mNetworkType,
+ mCallQuality,
+ mCallClassification,
+ mImsCallId,
+ mImsCallServiceType,
+ mImsCallType);
+ }
+ }
+}
diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java
index 34a901c69f77..7193de789743 100644
--- a/telephony/java/android/telephony/CarrierConfigManager.java
+++ b/telephony/java/android/telephony/CarrierConfigManager.java
@@ -34,6 +34,7 @@ import android.content.pm.PackageManager;
import android.net.NetworkCapabilities;
import android.net.ipsec.ike.SaProposal;
import android.os.Build;
+import android.os.Handler;
import android.os.PersistableBundle;
import android.os.RemoteException;
import android.service.carrier.CarrierService;
@@ -45,9 +46,11 @@ import android.telephony.gba.UaSecurityProtocolIdentifier;
import android.telephony.ims.ImsReasonInfo;
import android.telephony.ims.ImsRegistrationAttributes;
import android.telephony.ims.ImsSsData;
+import android.telephony.ims.MediaQualityStatus;
import android.telephony.ims.RcsUceAdapter;
import android.telephony.ims.feature.MmTelFeature;
import android.telephony.ims.feature.RcsFeature;
+import android.telephony.ims.stub.ImsRegistrationImplBase;
import com.android.internal.telephony.ICarrierConfigLoader;
import com.android.telephony.Rlog;
@@ -56,6 +59,7 @@ import java.util.List;
import java.util.Objects;
import java.util.concurrent.Executor;
import java.util.concurrent.TimeUnit;
+import java.util.function.Consumer;
/**
* Provides access to telephony configuration values that are carrier-specific.
@@ -63,7 +67,7 @@ import java.util.concurrent.TimeUnit;
@SystemService(Context.CARRIER_CONFIG_SERVICE)
@RequiresFeature(PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION)
public class CarrierConfigManager {
- private final static String TAG = "CarrierConfigManager";
+ private static final String TAG = "CarrierConfigManager";
/**
* Extra included in {@link #ACTION_CARRIER_CONFIG_CHANGED} to indicate the slot index that the
@@ -106,25 +110,25 @@ public class CarrierConfigManager {
* Only send USSD over IMS while CS is out of service, otherwise send USSD over CS.
* {@link #KEY_CARRIER_USSD_METHOD_INT}
*/
- public static final int USSD_OVER_CS_PREFERRED = 0;
+ public static final int USSD_OVER_CS_PREFERRED = 0;
/**
* Send USSD over IMS or CS while IMS is out of service or silent redial over CS if needed.
* {@link #KEY_CARRIER_USSD_METHOD_INT}
*/
- public static final int USSD_OVER_IMS_PREFERRED = 1;
+ public static final int USSD_OVER_IMS_PREFERRED = 1;
/**
* Only send USSD over CS.
* {@link #KEY_CARRIER_USSD_METHOD_INT}
*/
- public static final int USSD_OVER_CS_ONLY = 2;
+ public static final int USSD_OVER_CS_ONLY = 2;
/**
* Only send USSD over IMS and disallow silent redial over CS.
* {@link #KEY_CARRIER_USSD_METHOD_INT}
*/
- public static final int USSD_OVER_IMS_ONLY = 3;
+ public static final int USSD_OVER_IMS_ONLY = 3;
/**
* Indicates CARRIER_NR_AVAILABILITY_NSA determine that the carrier enable the non-standalone
@@ -159,8 +163,8 @@ public class CarrierConfigManager {
* @see TelephonyManager#getSimCarrierId()
* @see TelephonyManager#getSimSpecificCarrierId()
*/
- public static final String
- ACTION_CARRIER_CONFIG_CHANGED = "android.telephony.action.CARRIER_CONFIG_CHANGED";
+ public static final String ACTION_CARRIER_CONFIG_CHANGED =
+ "android.telephony.action.CARRIER_CONFIG_CHANGED";
// Below are the keys used in carrier config bundles. To add a new variable, define the key and
// give it a default value in sDefaults. If you need to ship a per-network override in the
@@ -181,8 +185,8 @@ public class CarrierConfigManager {
* @deprecated Use {@link Ims#KEY_CARRIER_RCS_PROVISIONING_REQUIRED_BOOL} instead.
*/
@Deprecated
- public static final String
- KEY_CARRIER_VOLTE_PROVISIONED_BOOL = "carrier_volte_provisioned_bool";
+ public static final String KEY_CARRIER_VOLTE_PROVISIONED_BOOL =
+ "carrier_volte_provisioned_bool";
/**
* Boolean indicating the Supplementary Services(SS) is disable when airplane mode on in the
@@ -215,29 +219,29 @@ public class CarrierConfigManager {
public static final String KEY_CALL_FORWARDING_WHEN_UNREACHABLE_SUPPORTED_BOOL =
"call_forwarding_when_unreachable_supported_bool";
- /**
- * Boolean indicating if carrier supports call forwarding option "When unanswered".
- *
- * {@code true}: Call forwarding option "When unanswered" is supported.
- * {@code false}: Call forwarding option "When unanswered" is not supported. Option will be
- * removed in the UI.
- *
- * By default this value is true.
- * @hide
- */
+ /**
+ * Boolean indicating if carrier supports call forwarding option "When unanswered".
+ *
+ * {@code true}: Call forwarding option "When unanswered" is supported.
+ * {@code false}: Call forwarding option "When unanswered" is not supported. Option will be
+ * removed in the UI.
+ *
+ * By default this value is true.
+ * @hide
+ */
public static final String KEY_CALL_FORWARDING_WHEN_UNANSWERED_SUPPORTED_BOOL =
"call_forwarding_when_unanswered_supported_bool";
- /**
- * Boolean indicating if carrier supports call forwarding option "When busy".
- *
- * {@code true}: Call forwarding option "When busy" is supported.
- * {@code false}: Call forwarding option "When busy" is not supported. Option will be
- * removed in the UI.
- *
- * By default this value is true.
- * @hide
- */
+ /**
+ * Boolean indicating if carrier supports call forwarding option "When busy".
+ *
+ * {@code true}: Call forwarding option "When busy" is supported.
+ * {@code false}: Call forwarding option "When busy" is not supported. Option will be
+ * removed in the UI.
+ *
+ * By default this value is true.
+ * @hide
+ */
public static final String KEY_CALL_FORWARDING_WHEN_BUSY_SUPPORTED_BOOL =
"call_forwarding_when_busy_supported_bool";
@@ -259,12 +263,12 @@ public class CarrierConfigManager {
public static final String KEY_ADDITIONAL_SETTINGS_CALL_WAITING_VISIBILITY_BOOL =
"additional_settings_call_waiting_visibility_bool";
- /**
- * Boolean indicating if the "Call barring" item is visible in the Call Settings menu.
- * If true, the "Call Barring" menu will be visible. If false, the menu will be gone.
- *
- * Disabled by default.
- */
+ /**
+ * Boolean indicating if the "Call barring" item is visible in the Call Settings menu.
+ * If true, the "Call Barring" menu will be visible. If false, the menu will be gone.
+ *
+ * Disabled by default.
+ */
public static final String KEY_CALL_BARRING_VISIBILITY_BOOL =
"call_barring_visibility_bool";
@@ -321,8 +325,8 @@ public class CarrierConfigManager {
* If true, this will prevent the IccNetworkDepersonalizationPanel from being shown, and
* effectively disable the "Sim network lock" feature.
*/
- public static final String
- KEY_IGNORE_SIM_NETWORK_LOCKED_EVENTS_BOOL = "ignore_sim_network_locked_events_bool";
+ public static final String KEY_IGNORE_SIM_NETWORK_LOCKED_EVENTS_BOOL =
+ "ignore_sim_network_locked_events_bool";
/**
* When checking if a given number is the voicemail number, if this flag is true
@@ -340,16 +344,15 @@ public class CarrierConfigManager {
* consequence: there will be no way to make an Emergency Call if your SIM is network-locked and
* you don't know the PIN.)
*/
- public static final String
- KEY_SIM_NETWORK_UNLOCK_ALLOW_DISMISS_BOOL = "sim_network_unlock_allow_dismiss_bool";
+ public static final String KEY_SIM_NETWORK_UNLOCK_ALLOW_DISMISS_BOOL =
+ "sim_network_unlock_allow_dismiss_bool";
/**
* Flag indicating whether or not sending emergency SMS messages over IMS
* is supported when in LTE/limited LTE (Emergency only) service mode..
- *
*/
- public static final String
- KEY_SUPPORT_EMERGENCY_SMS_OVER_IMS_BOOL = "support_emergency_sms_over_ims_bool";
+ public static final String KEY_SUPPORT_EMERGENCY_SMS_OVER_IMS_BOOL =
+ "support_emergency_sms_over_ims_bool";
/** Flag indicating if the phone is a world phone */
public static final String KEY_WORLD_PHONE_BOOL = "world_phone_bool";
@@ -359,8 +362,8 @@ public class CarrierConfigManager {
* If true, entitlement checks will be executed if device has been configured for it,
* If false, entitlement checks will be skipped.
*/
- public static final String
- KEY_REQUIRE_ENTITLEMENT_CHECKS_BOOL = "require_entitlement_checks_bool";
+ public static final String KEY_REQUIRE_ENTITLEMENT_CHECKS_BOOL =
+ "require_entitlement_checks_bool";
/**
* Flag indicating if the carrier supports tethering of mobile data.
@@ -392,8 +395,8 @@ public class CarrierConfigManager {
* consistent with the regular Dialer, this value should agree with the corresponding values
* from config.xml under apps/Contacts.
*/
- public static final String
- KEY_ENABLE_DIALER_KEY_VIBRATION_BOOL = "enable_dialer_key_vibration_bool";
+ public static final String KEY_ENABLE_DIALER_KEY_VIBRATION_BOOL =
+ "enable_dialer_key_vibration_bool";
/** Flag indicating if dtmf tone type is enabled */
public static final String KEY_DTMF_TYPE_ENABLED_BOOL = "dtmf_type_enabled_bool";
@@ -416,11 +419,12 @@ public class CarrierConfigManager {
* @hide
*/
public static final String KEY_PLAY_CALL_RECORDING_TONE_BOOL = "play_call_recording_tone_bool";
+
/**
* Determines if the carrier requires converting the destination number before sending out an
* SMS. Certain networks and numbering plans require different formats.
*/
- public static final String KEY_SMS_REQUIRES_DESTINATION_NUMBER_CONVERSION_BOOL=
+ public static final String KEY_SMS_REQUIRES_DESTINATION_NUMBER_CONVERSION_BOOL =
"sms_requires_destination_number_conversion_bool";
/**
@@ -428,7 +432,8 @@ public class CarrierConfigManager {
* platforms, even the ones with hard SEND/END keys, but for maximum flexibility it's controlled
* by a flag here (which can be overridden on a per-product basis.)
*/
- public static final String KEY_SHOW_ONSCREEN_DIAL_BUTTON_BOOL = "show_onscreen_dial_button_bool";
+ public static final String KEY_SHOW_ONSCREEN_DIAL_BUTTON_BOOL =
+ "show_onscreen_dial_button_bool";
/** Determines if device implements a noise suppression device for in call audio. */
public static final String
@@ -440,8 +445,8 @@ public class CarrierConfigManager {
* accidental redialing from the call log UI. This is a good idea, so the default here is
* false.)
*/
- public static final String
- KEY_ALLOW_EMERGENCY_NUMBERS_IN_CALL_LOG_BOOL = "allow_emergency_numbers_in_call_log_bool";
+ public static final String KEY_ALLOW_EMERGENCY_NUMBERS_IN_CALL_LOG_BOOL =
+ "allow_emergency_numbers_in_call_log_bool";
/**
* A string array containing numbers that shouldn't be included in the call log.
@@ -467,10 +472,9 @@ public class CarrierConfigManager {
* Flag indicating whether to show single operator row in the choose network setting.
*
* The device configuration value {@code config_enableNewAutoSelectNetworkUI} ultimately
- * controls whether this carrier configuration option is used. Where
- * {@code config_enableNewAutoSelectNetworkUI} is false, the value of the
- * {@link #KEY_SHOW_SINGLE_OPERATOR_ROW_IN_CHOOSE_NETWORK_SETTING_BOOL} carrier configuration
- * option is ignored.
+ * controls whether this carrier configuration option is used.
+ * Where {@code config_enableNewAutoSelectNetworkUI} is false, the value of this
+ * carrier configuration is ignored.
*
* If {@code true}, default value, merge the duplicate networks which with the same plmn, keep
* the one that with the higher signal strength level.
@@ -494,19 +498,22 @@ public class CarrierConfigManager {
/**
* Control whether users receive a simplified network settings UI and improved network
* selection.
+ *
+ * @deprecated Never implemented. Has no behavior impact when override. DO NOT USE.
*/
- public static final String
- KEY_SIMPLIFIED_NETWORK_SETTINGS_BOOL = "simplified_network_settings_bool";
+ @Deprecated
+ public static final String KEY_SIMPLIFIED_NETWORK_SETTINGS_BOOL =
+ "simplified_network_settings_bool";
/** Control whether users can reach the SIM lock settings. */
- public static final String
- KEY_HIDE_SIM_LOCK_SETTINGS_BOOL = "hide_sim_lock_settings_bool";
+ public static final String KEY_HIDE_SIM_LOCK_SETTINGS_BOOL = "hide_sim_lock_settings_bool";
/** Control whether users can edit APNs in Settings. */
public static final String KEY_APN_EXPAND_BOOL = "apn_expand_bool";
/** Control whether users can choose a network operator. */
- public static final String KEY_OPERATOR_SELECTION_EXPAND_BOOL = "operator_selection_expand_bool";
+ public static final String KEY_OPERATOR_SELECTION_EXPAND_BOOL =
+ "operator_selection_expand_bool";
/**
* Used in the Preferred Network Types menu to determine if the 2G option is displayed.
@@ -530,11 +537,11 @@ public class CarrierConfigManager {
/**
* CDMA activation goes through OTASP.
- * <p>
- * TODO: This should be combined with config_use_hfa_for_provisioning and implemented as an enum
- * (NONE, HFA, OTASP).
*/
- public static final String KEY_USE_OTASP_FOR_PROVISIONING_BOOL = "use_otasp_for_provisioning_bool";
+ // TODO: This should be combined with config_use_hfa_for_provisioning and implemented as an enum
+ // (NONE, HFA, OTASP).
+ public static final String KEY_USE_OTASP_FOR_PROVISIONING_BOOL =
+ "use_otasp_for_provisioning_bool";
/** Display carrier settings menu if true */
public static final String KEY_CARRIER_SETTINGS_ENABLE_BOOL = "carrier_settings_enable_bool";
@@ -559,41 +566,41 @@ public class CarrierConfigManager {
* available the user cannot use voicemail. This flag allows the user to edit the voicemail
* number in such cases, and is false by default.
*/
- public static final String KEY_EDITABLE_VOICEMAIL_NUMBER_BOOL= "editable_voicemail_number_bool";
+ public static final String KEY_EDITABLE_VOICEMAIL_NUMBER_BOOL =
+ "editable_voicemail_number_bool";
/**
* Determine whether the voicemail notification is persistent in the notification bar. If true,
* the voicemail notifications cannot be dismissed from the notification bar.
*/
- public static final String
- KEY_VOICEMAIL_NOTIFICATION_PERSISTENT_BOOL = "voicemail_notification_persistent_bool";
+ public static final String KEY_VOICEMAIL_NOTIFICATION_PERSISTENT_BOOL =
+ "voicemail_notification_persistent_bool";
/** For IMS video over LTE calls, determines whether video pause signalling is supported. */
- public static final String
- KEY_SUPPORT_PAUSE_IMS_VIDEO_CALLS_BOOL = "support_pause_ims_video_calls_bool";
+ public static final String KEY_SUPPORT_PAUSE_IMS_VIDEO_CALLS_BOOL =
+ "support_pause_ims_video_calls_bool";
/**
* Disables dialing "*228" (OTASP provisioning) on CDMA carriers where it is not supported or is
* potentially harmful by locking the SIM to 3G.
*/
- public static final String
- KEY_DISABLE_CDMA_ACTIVATION_CODE_BOOL = "disable_cdma_activation_code_bool";
+ public static final String KEY_DISABLE_CDMA_ACTIVATION_CODE_BOOL =
+ "disable_cdma_activation_code_bool";
/**
* List of network type constants which support only a single data connection at a time.
* Some carriers do not support multiple PDP on UMTS.
* @see TelephonyManager NETWORK_TYPE_*
+ * @see #KEY_ONLY_SINGLE_DC_ALLOWED_INT_ARRAY
*/
- public static final String
- KEY_ONLY_SINGLE_DC_ALLOWED_INT_ARRAY = "only_single_dc_allowed_int_array";
+ public static final String KEY_ONLY_SINGLE_DC_ALLOWED_INT_ARRAY =
+ "only_single_dc_allowed_int_array";
/**
- * List of network capabilities which, if requested, will exempt the request from single PDN
- * connection checks.
+ * Only apply if {@link #KEY_ONLY_SINGLE_DC_ALLOWED_INT_ARRAY} specifies the network types that
+ * support a single data connection at a time. This key defines a list of network capabilities
+ * which, if requested, will exempt the request from single data connection checks.
* @see NetworkCapabilities NET_CAPABILITY_*
- * @see #KEY_ONLY_SINGLE_DC_ALLOWED_INT_ARRAY
- *
- * @hide
*/
public static final String KEY_CAPABILITIES_EXEMPT_FROM_SINGLE_DC_CHECK_INT_ARRAY =
"capabilities_exempt_from_single_dc_check_int_array";
@@ -602,15 +609,15 @@ public class CarrierConfigManager {
* Override the platform's notion of a network operator being considered roaming.
* Value is string array of MCCMNCs to be considered roaming for 3GPP RATs.
*/
- public static final String
- KEY_GSM_ROAMING_NETWORKS_STRING_ARRAY = "gsm_roaming_networks_string_array";
+ public static final String KEY_GSM_ROAMING_NETWORKS_STRING_ARRAY =
+ "gsm_roaming_networks_string_array";
/**
* Override the platform's notion of a network operator being considered not roaming.
* Value is string array of MCCMNCs to be considered not roaming for 3GPP RATs.
*/
- public static final String
- KEY_GSM_NONROAMING_NETWORKS_STRING_ARRAY = "gsm_nonroaming_networks_string_array";
+ public static final String KEY_GSM_NONROAMING_NETWORKS_STRING_ARRAY =
+ "gsm_nonroaming_networks_string_array";
/**
* The package name containing the ImsService that will be bound to the telephony framework to
@@ -620,6 +627,7 @@ public class CarrierConfigManager {
* {@link #KEY_CONFIG_IMS_RCS_PACKAGE_OVERRIDE_STRING} instead to configure these values
* separately. If any of those values are not empty, they will override this value.
*/
+ @Deprecated
public static final String KEY_CONFIG_IMS_PACKAGE_OVERRIDE_STRING =
"config_ims_package_override_string";
@@ -666,7 +674,7 @@ public class CarrierConfigManager {
/**
* Override the platform's notion of a network operator being considered non roaming.
- * If true all networks are considered as home network a.k.a non-roaming. When false,
+ * If true all networks are considered as home network a.k.a. non-roaming. When false,
* the 2 pairs of CMDA and GSM roaming/non-roaming arrays are consulted.
*
* @see #KEY_GSM_ROAMING_NETWORKS_STRING_ARRAY
@@ -701,8 +709,7 @@ public class CarrierConfigManager {
* <li>3: {@link #USSD_OVER_IMS_ONLY} </li>
* </ul>
*/
- public static final String KEY_CARRIER_USSD_METHOD_INT =
- "carrier_ussd_method_int";
+ public static final String KEY_CARRIER_USSD_METHOD_INT = "carrier_ussd_method_int";
/**
* Flag specifying whether to show an alert dialog for 5G disable when the user disables VoLTE.
@@ -733,8 +740,7 @@ public class CarrierConfigManager {
* downgrading the call in the process.
* @hide
*/
- public static final String KEY_ALLOW_MERGING_RTT_CALLS_BOOL =
- "allow_merging_rtt_calls_bool";
+ public static final String KEY_ALLOW_MERGING_RTT_CALLS_BOOL = "allow_merging_rtt_calls_bool";
/**
* Flag specifying whether the carrier wants to notify the user when a VT call has been handed
@@ -795,7 +801,7 @@ public class CarrierConfigManager {
/**
* When {@code true}, changes to the mobile data enabled switch will not cause the VT
- * registration state to change. That is, turning on or off mobile data will not cause VT to be
+ * registration state to change. That is, turning on or off mobile data will not cause VT to be
* enabled or disabled.
* When {@code false}, disabling mobile data will cause VT to be de-registered.
*/
@@ -818,7 +824,8 @@ public class CarrierConfigManager {
* carrier provisioning. If false: hard disabled. If true: then depends on carrier
* provisioning, availability etc.
*/
- public static final String KEY_CARRIER_WFC_IMS_AVAILABLE_BOOL = "carrier_wfc_ims_available_bool";
+ public static final String KEY_CARRIER_WFC_IMS_AVAILABLE_BOOL =
+ "carrier_wfc_ims_available_bool";
/**
* Flag specifying whether Cross SIM over IMS should be available for carrier.
@@ -858,8 +865,8 @@ public class CarrierConfigManager {
"international_roaming_dial_string_replace_string_array";
/**
- * Flag specifying whether WFC over IMS supports the "wifi only" option. If false, the wifi
- * calling settings will not include an option for "wifi only". If true, the wifi calling
+ * Flag specifying whether WFC over IMS supports the "wifi only" option. If false, the wifi
+ * calling settings will not include an option for "wifi only". If true, the wifi calling
* settings will include an option for "wifi only"
* <p>
* By default, it is assumed that WFC supports "wifi only".
@@ -902,7 +909,7 @@ public class CarrierConfigManager {
/**
* Flag indicating whether failed calls due to no service should prompt the user to enable
- * WIFI calling. When {@code true}, if the user attempts to establish a call when there is no
+ * WIFI calling. When {@code true}, if the user attempts to establish a call when there is no
* service available, they are connected to WIFI, and WIFI calling is disabled, a different
* call failure message will be used to encourage the user to enable WIFI calling.
* @hide
@@ -928,8 +935,8 @@ public class CarrierConfigManager {
* {@link Ims#KEY_MMTEL_REQUIRES_PROVISIONING_BUNDLE}
*/
@Deprecated
- public static final String KEY_CARRIER_VOLTE_PROVISIONING_REQUIRED_BOOL
- = "carrier_volte_provisioning_required_bool";
+ public static final String KEY_CARRIER_VOLTE_PROVISIONING_REQUIRED_BOOL =
+ "carrier_volte_provisioning_required_bool";
/**
* Flag indicating whether or not the IMS MmTel UT capability requires carrier provisioning
@@ -972,22 +979,22 @@ public class CarrierConfigManager {
* As of now, Verizon is the only carrier enforcing this dependency in their
* WFC awareness and activation requirements.
*/
- public static final String KEY_CARRIER_VOLTE_OVERRIDE_WFC_PROVISIONING_BOOL
- = "carrier_volte_override_wfc_provisioning_bool";
+ public static final String KEY_CARRIER_VOLTE_OVERRIDE_WFC_PROVISIONING_BOOL =
+ "carrier_volte_override_wfc_provisioning_bool";
/**
* Override the device's configuration for the cellular data service to use for this SIM card.
* @hide
*/
- public static final String KEY_CARRIER_DATA_SERVICE_WWAN_PACKAGE_OVERRIDE_STRING
- = "carrier_data_service_wwan_package_override_string";
+ public static final String KEY_CARRIER_DATA_SERVICE_WWAN_PACKAGE_OVERRIDE_STRING =
+ "carrier_data_service_wwan_package_override_string";
/**
* Override the device's configuration for the IWLAN data service to use for this SIM card.
* @hide
*/
- public static final String KEY_CARRIER_DATA_SERVICE_WLAN_PACKAGE_OVERRIDE_STRING
- = "carrier_data_service_wlan_package_override_string";
+ public static final String KEY_CARRIER_DATA_SERVICE_WLAN_PACKAGE_OVERRIDE_STRING =
+ "carrier_data_service_wlan_package_override_string";
/**
* Override the device's configuration for the cellular data service class to use
@@ -1006,8 +1013,8 @@ public class CarrierConfigManager {
"carrier_data_service_wlan_class_override_string";
/** Flag specifying whether VoLTE TTY is supported. */
- public static final String KEY_CARRIER_VOLTE_TTY_SUPPORTED_BOOL
- = "carrier_volte_tty_supported_bool";
+ public static final String KEY_CARRIER_VOLTE_TTY_SUPPORTED_BOOL =
+ "carrier_volte_tty_supported_bool";
/** Flag specifying whether VoWIFI TTY is supported.
* @hide
@@ -1019,37 +1026,37 @@ public class CarrierConfigManager {
* Flag specifying whether IMS service can be turned off. If false then the service will not be
* turned-off completely, but individual features can be disabled.
*/
- public static final String KEY_CARRIER_ALLOW_TURNOFF_IMS_BOOL
- = "carrier_allow_turnoff_ims_bool";
+ public static final String KEY_CARRIER_ALLOW_TURNOFF_IMS_BOOL =
+ "carrier_allow_turnoff_ims_bool";
/**
* Flag specifying whether Generic Bootstrapping Architecture capable SIM is required for IMS.
*/
- public static final String KEY_CARRIER_IMS_GBA_REQUIRED_BOOL
- = "carrier_ims_gba_required_bool";
+ public static final String KEY_CARRIER_IMS_GBA_REQUIRED_BOOL =
+ "carrier_ims_gba_required_bool";
/**
- * Flag specifying whether IMS instant lettering is available for the carrier. {@code True} if
+ * Flag specifying whether IMS instant lettering is available for the carrier. {@code True} if
* instant lettering is available for the carrier, {@code false} otherwise.
*/
public static final String KEY_CARRIER_INSTANT_LETTERING_AVAILABLE_BOOL =
"carrier_instant_lettering_available_bool";
- /*
+ /**
* Flag specifying whether IMS should be the first phone attempted for E911 even if the
* phone is not in service.
*/
- public static final String KEY_CARRIER_USE_IMS_FIRST_FOR_EMERGENCY_BOOL
- = "carrier_use_ims_first_for_emergency_bool";
+ public static final String KEY_CARRIER_USE_IMS_FIRST_FOR_EMERGENCY_BOOL =
+ "carrier_use_ims_first_for_emergency_bool";
/**
* When {@code true}, the determination of whether to place a call as an emergency call will be
* based on the known {@link android.telephony.emergency.EmergencyNumber}s for the SIM on which
- * the call is being placed. In a dual SIM scenario, if Sim A has the emergency numbers
+ * the call is being placed. In a dual SIM scenario, if Sim A has the emergency numbers
* 123, 456 and Sim B has the emergency numbers 789, and the user places a call on SIM A to 789,
* it will not be treated as an emergency call in this case.
* When {@code false}, the determination is based on the emergency numbers from all device SIMs,
- * regardless of which SIM the call is being placed on. If Sim A has the emergency numbers
+ * regardless of which SIM the call is being placed on. If Sim A has the emergency numbers
* 123, 456 and Sim B has the emergency numbers 789, and the user places a call on SIM A to 789,
* the call will be dialed as an emergency number, but with an unspecified routing.
* @hide
@@ -1060,7 +1067,7 @@ public class CarrierConfigManager {
/**
* When IMS instant lettering is available for a carrier (see
* {@link #KEY_CARRIER_INSTANT_LETTERING_AVAILABLE_BOOL}), determines the list of characters
- * which may not be contained in messages. Should be specified as a regular expression suitable
+ * which may not be contained in messages. Should be specified as a regular expression suitable
* for use with {@link String#matches(String)}.
*/
public static final String KEY_CARRIER_INSTANT_LETTERING_INVALID_CHARS_STRING =
@@ -1069,8 +1076,8 @@ public class CarrierConfigManager {
/**
* When IMS instant lettering is available for a carrier (see
* {@link #KEY_CARRIER_INSTANT_LETTERING_AVAILABLE_BOOL}), determines a list of characters which
- * must be escaped with a backslash '\' character. Should be specified as a string containing
- * the characters to be escaped. For example to escape quote and backslash the string would be
+ * must be escaped with a backslash '\' character. Should be specified as a string containing
+ * the characters to be escaped. For example to escape quote and backslash the string would be
* a quote and a backslash.
*/
public static final String KEY_CARRIER_INSTANT_LETTERING_ESCAPED_CHARS_STRING =
@@ -1079,10 +1086,10 @@ public class CarrierConfigManager {
/**
* When IMS instant lettering is available for a carrier (see
* {@link #KEY_CARRIER_INSTANT_LETTERING_AVAILABLE_BOOL}), determines the character encoding
- * which will be used when determining the length of messages. Used in the InCall UI to limit
- * the number of characters the user may type. If empty-string, the instant lettering
- * message size limit will be enforced on a 1:1 basis. That is, each character will count
- * towards the messages size limit as a single bye. If a character encoding is specified, the
+ * which will be used when determining the length of messages. Used in the InCall UI to limit
+ * the number of characters the user may type. If empty-string, the instant lettering
+ * message size limit will be enforced on a 1:1 basis. That is, each character will count
+ * towards the messages size limit as a single byte. If a character encoding is specified, the
* message size limit will be based on the number of bytes in the message per the specified
* encoding.
*/
@@ -1091,7 +1098,7 @@ public class CarrierConfigManager {
/**
* When IMS instant lettering is available for a carrier (see
- * {@link #KEY_CARRIER_INSTANT_LETTERING_AVAILABLE_BOOL}), the length limit for messages. Used
+ * {@link #KEY_CARRIER_INSTANT_LETTERING_AVAILABLE_BOOL}), the length limit for messages. Used
* in the InCall UI to ensure the user cannot enter more characters than allowed by the carrier.
* See also {@link #KEY_CARRIER_INSTANT_LETTERING_ENCODING_STRING} for more information on how
* the length of the message is calculated.
@@ -1112,7 +1119,8 @@ public class CarrierConfigManager {
* manager can control and route outgoing and incoming phone calls, even if they're placed
* using another connection service (PSTN, for example).
*/
- public static final String KEY_DEFAULT_SIM_CALL_MANAGER_STRING = "default_sim_call_manager_string";
+ public static final String KEY_DEFAULT_SIM_CALL_MANAGER_STRING =
+ "default_sim_call_manager_string";
/**
* The default flag specifying whether ETWS/CMAS test setting is forcibly disabled in
@@ -1148,21 +1156,65 @@ public class CarrierConfigManager {
"carrier_data_call_apn_retry_after_disconnect_long";
/**
- * Data call setup permanent failure causes by the carrier
+ * Data call setup permanent failure causes by the carrier.
+ *
+ * @deprecated This API key was added in mistake and is not used anymore by the telephony data
+ * frameworks.
*/
@Deprecated
public static final String KEY_CARRIER_DATA_CALL_PERMANENT_FAILURE_STRINGS =
"carrier_data_call_permanent_failure_strings";
/**
- * Default APN types that are metered by the carrier
- * @hide
+ * A string array indicating the default APN types that are metered by the carrier.
+ *
+ * The string in the array is the name of the APN type. For example, "default" for
+ * {@link ApnSetting#TYPE_DEFAULT}, "mms" for {@link ApnSetting#TYPE_MMS}, etc.
+ *
+ * The default value is {@code {"default", "mms", "dun", "supl"}}.
+ *
+ * @see ApnSetting#TYPE_DEFAULT
+ * @see ApnSetting#TYPE_MMS
+ * @see ApnSetting#TYPE_SUPL
+ * @see ApnSetting#TYPE_DUN
+ * @see ApnSetting#TYPE_HIPRI
+ * @see ApnSetting#TYPE_FOTA
+ * @see ApnSetting#TYPE_IMS
+ * @see ApnSetting#TYPE_CBS
+ * @see ApnSetting#TYPE_IA
+ * @see ApnSetting#TYPE_EMERGENCY
+ * @see ApnSetting#TYPE_MCX
+ * @see ApnSetting#TYPE_XCAP
+ * @see ApnSetting#TYPE_BIP
+ * @see ApnSetting#TYPE_VSIM
+ * @see ApnSetting#TYPE_ENTERPRISE
*/
public static final String KEY_CARRIER_METERED_APN_TYPES_STRINGS =
"carrier_metered_apn_types_strings";
+
/**
- * Default APN types that are roaming-metered by the carrier
- * @hide
+ * A string array indicating the default APN types that are roaming-metered by the carrier.
+ *
+ * The string in the array is the name of the APN type. For example, "default" for
+ * {@link ApnSetting#TYPE_DEFAULT}, "mms" for {@link ApnSetting#TYPE_MMS}, etc.
+ *
+ * The default value is {@code {"default", "mms", "dun", "supl"}}.
+ *
+ * @see ApnSetting#TYPE_DEFAULT
+ * @see ApnSetting#TYPE_MMS
+ * @see ApnSetting#TYPE_SUPL
+ * @see ApnSetting#TYPE_DUN
+ * @see ApnSetting#TYPE_HIPRI
+ * @see ApnSetting#TYPE_FOTA
+ * @see ApnSetting#TYPE_IMS
+ * @see ApnSetting#TYPE_CBS
+ * @see ApnSetting#TYPE_IA
+ * @see ApnSetting#TYPE_EMERGENCY
+ * @see ApnSetting#TYPE_MCX
+ * @see ApnSetting#TYPE_XCAP
+ * @see ApnSetting#TYPE_BIP
+ * @see ApnSetting#TYPE_VSIM
+ * @see ApnSetting#TYPE_ENTERPRISE
*/
public static final String KEY_CARRIER_METERED_ROAMING_APN_TYPES_STRINGS =
"carrier_metered_roaming_apn_types_strings";
@@ -1171,8 +1223,7 @@ public class CarrierConfigManager {
* CDMA carrier ERI (Enhanced Roaming Indicator) file name
* @hide
*/
- public static final String KEY_CARRIER_ERI_FILE_NAME_STRING =
- "carrier_eri_file_name_string";
+ public static final String KEY_CARRIER_ERI_FILE_NAME_STRING = "carrier_eri_file_name_string";
/* The following 3 fields are related to carrier visual voicemail. */
@@ -1196,13 +1247,12 @@ public class CarrierConfigManager {
* Whether cellular data is required to access visual voicemail.
*/
public static final String KEY_VVM_CELLULAR_DATA_REQUIRED_BOOL =
- "vvm_cellular_data_required_bool";
+ "vvm_cellular_data_required_bool";
/**
* The default OMTP visual voicemail client prefix to use. Defaulted to "//VVM"
*/
- public static final String KEY_VVM_CLIENT_PREFIX_STRING =
- "vvm_client_prefix_string";
+ public static final String KEY_VVM_CLIENT_PREFIX_STRING = "vvm_client_prefix_string";
/**
* Whether to use SSL to connect to the visual voicemail IMAP server. Defaulted to false.
@@ -1227,8 +1277,7 @@ public class CarrierConfigManager {
* <p>This is for carriers that does not support VVM deactivation so voicemail can continue to
* function without the data cost.
*/
- public static final String KEY_VVM_LEGACY_MODE_ENABLED_BOOL =
- "vvm_legacy_mode_enabled_bool";
+ public static final String KEY_VVM_LEGACY_MODE_ENABLED_BOOL = "vvm_legacy_mode_enabled_bool";
/**
* Whether to prefetch audio data on new voicemail arrival, defaulted to true.
@@ -1242,7 +1291,8 @@ public class CarrierConfigManager {
* @deprecated use {@link #KEY_CARRIER_VVM_PACKAGE_NAME_STRING_ARRAY}.
*/
@Deprecated
- public static final String KEY_CARRIER_VVM_PACKAGE_NAME_STRING = "carrier_vvm_package_name_string";
+ public static final String KEY_CARRIER_VVM_PACKAGE_NAME_STRING =
+ "carrier_vvm_package_name_string";
/**
* A list of the carrier's visual voicemail app package names to ensure that dialer visual
@@ -1261,7 +1311,7 @@ public class CarrierConfigManager {
* Status screen. The default value is true.
*/
public static final String KEY_SHOW_SIGNAL_STRENGTH_IN_SIM_STATUS_BOOL =
- "show_signal_strength_in_sim_status_bool";
+ "show_signal_strength_in_sim_status_bool";
/**
* Flag specifying if we should interpret all signal strength as one bar higher
@@ -1340,9 +1390,8 @@ public class CarrierConfigManager {
public static final String KEY_IGNORE_RTT_MODE_SETTING_BOOL =
"ignore_rtt_mode_setting_bool";
-
/**
- * Determines whether adhoc conference calls are supported by a carrier. When {@code true},
+ * Determines whether adhoc conference calls are supported by a carrier. When {@code true},
* adhoc conference calling is supported, {@code false otherwise}.
*/
public static final String KEY_SUPPORT_ADHOC_CONFERENCE_CALLS_BOOL =
@@ -1350,14 +1399,14 @@ public class CarrierConfigManager {
/**
* Determines whether conference participants can be added to existing call to form an adhoc
- * conference call (in contrast to merging calls to form a conference). When {@code true},
+ * conference call (in contrast to merging calls to form a conference). When {@code true},
* adding conference participants to existing call is supported, {@code false otherwise}.
*/
public static final String KEY_SUPPORT_ADD_CONFERENCE_PARTICIPANTS_BOOL =
"support_add_conference_participants_bool";
/**
- * Determines whether conference calls are supported by a carrier. When {@code true},
+ * Determines whether conference calls are supported by a carrier. When {@code true},
* conference calling is supported, {@code false otherwise}.
*/
public static final String KEY_SUPPORT_CONFERENCE_CALL_BOOL = "support_conference_call_bool";
@@ -1365,7 +1414,7 @@ public class CarrierConfigManager {
/**
* Determines whether a maximum size limit for IMS conference calls is enforced on the device.
* When {@code true}, IMS conference calls will be limited to at most
- * {@link #KEY_IMS_CONFERENCE_SIZE_LIMIT_INT} participants. When {@code false}, no attempt is
+ * {@link #KEY_IMS_CONFERENCE_SIZE_LIMIT_INT} participants. When {@code false}, no attempt is
* made to limit the number of participants in a conference (the carrier will raise an error
* when an attempt is made to merge too many participants into a conference).
* <p>
@@ -1379,14 +1428,14 @@ public class CarrierConfigManager {
/**
* Determines the maximum number of participants the carrier supports for a conference call.
- * This number is exclusive of the current device. A conference between 3 devices, for example,
+ * This number is exclusive of the current device. A conference between 3 devices, for example,
* would have a size limit of 2 participants.
* Enforced when {@link #KEY_IS_IMS_CONFERENCE_SIZE_ENFORCED_BOOL} is {@code true}.
*/
public static final String KEY_IMS_CONFERENCE_SIZE_LIMIT_INT = "ims_conference_size_limit_int";
/**
- * Determines whether manage IMS conference calls is supported by a carrier. When {@code true},
+ * Determines whether manage IMS conference calls is supported by a carrier. When {@code true},
* manage IMS conference call is supported, {@code false otherwise}.
* @hide
*/
@@ -1409,7 +1458,7 @@ public class CarrierConfigManager {
* and B and C are considered the conference peers.
* <p>
* When {@code true}, the conference peer will display the conference state if it receives
- * conference event package data from the network. When {@code false}, the conference peer will
+ * conference event package data from the network. When {@code false}, the conference peer will
* ignore conference event package data received from the network.
* @hide
*/
@@ -1427,7 +1476,7 @@ public class CarrierConfigManager {
/**
* Indicates whether the carrier supports the negotiations of RFC8285 compliant RTP header
- * extensions supported on a call during the Session Description Protocol (SDP). This option
+ * extensions supported on a call during the Session Description Protocol (SDP). This option
* is only used when {@link #KEY_SUPPORTS_DEVICE_TO_DEVICE_COMMUNICATION_USING_RTP_BOOL} is
* {@code true}.
* <p>
@@ -1457,7 +1506,7 @@ public class CarrierConfigManager {
"display_hd_audio_property_bool";
/**
- * Determines whether IMS conference calls are supported by a carrier. When {@code true},
+ * Determines whether IMS conference calls are supported by a carrier. When {@code true},
* IMS conference calling is supported, {@code false} otherwise.
* @hide
*/
@@ -1466,9 +1515,9 @@ public class CarrierConfigManager {
/**
* Determines whether the device will locally disconnect an IMS conference when the participant
- * count drops to zero. When {@code true}, it is assumed the carrier does NOT disconnect a
+ * count drops to zero. When {@code true}, it is assumed the carrier does NOT disconnect a
* conference when the participant count drops to zero and that the device must do this by
- * disconnecting the conference locally. When {@code false}, it is assumed that the carrier
+ * disconnecting the conference locally. When {@code false}, it is assumed that the carrier
* is responsible for disconnecting the conference when there are no longer any participants
* present.
* <p>
@@ -1484,8 +1533,8 @@ public class CarrierConfigManager {
"local_disconnect_empty_ims_conference_bool";
/**
- * Determines whether video conference calls are supported by a carrier. When {@code true},
- * video calls can be merged into conference calls, {@code false} otherwiwse.
+ * Determines whether video conference calls are supported by a carrier. When {@code true},
+ * video calls can be merged into conference calls, {@code false} otherwise.
* <p>
* Note: even if video conference calls are not supported, audio calls may be merged into a
* conference if {@link #KEY_SUPPORT_CONFERENCE_CALL_BOOL} is {@code true}.
@@ -1522,7 +1571,8 @@ public class CarrierConfigManager {
/**
* Determine whether preferred network type can be shown.
*/
- public static final String KEY_HIDE_PREFERRED_NETWORK_TYPE_BOOL = "hide_preferred_network_type_bool";
+ public static final String KEY_HIDE_PREFERRED_NETWORK_TYPE_BOOL =
+ "hide_preferred_network_type_bool";
/**
* String array for package names that need to be enabled for this carrier.
@@ -1578,6 +1628,7 @@ public class CarrierConfigManager {
* <li> 9: WiFi Calling</li>
* <li> 10: VoWifi</li>
* <li> 11: %s WiFi Calling</li>
+ * <li> 12: WiFi Call</li>
* @hide
*/
public static final String KEY_WFC_SPN_FORMAT_IDX_INT = "wfc_spn_format_idx_int";
@@ -1750,26 +1801,24 @@ public class CarrierConfigManager {
* Instead, each sim carrier should have a single country code, apply per carrier based iso
* code as an override. The overridden value can be read from
* {@link TelephonyManager#getSimCountryIso()} and {@link SubscriptionInfo#getCountryIso()}
- *
- * @hide
*/
public static final String KEY_SIM_COUNTRY_ISO_OVERRIDE_STRING =
"sim_country_iso_override_string";
- /**
- * The Component Name of a carrier-provided CallScreeningService implementation. Telecom will
- * bind to {@link android.telecom.CallScreeningService} for ALL incoming calls and provide
- * the carrier
- * CallScreeningService with the opportunity to allow or block calls.
- * <p>
- * The String includes the package name/the class name.
- * Example:
- * <item>com.android.carrier/com.android.carrier.callscreeningserviceimpl</item>
- * <p>
- * Using {@link ComponentName#flattenToString()} to convert a ComponentName object to String.
- * Using {@link ComponentName#unflattenFromString(String)} to convert a String object to a
- * ComponentName.
- */
+ /**
+ * The Component Name of a carrier-provided CallScreeningService implementation. Telecom will
+ * bind to {@link android.telecom.CallScreeningService} for ALL incoming calls and provide
+ * the carrier
+ * CallScreeningService with the opportunity to allow or block calls.
+ * <p>
+ * The String includes the package name/the class name.
+ * Example:
+ * <item>com.android.carrier/com.android.carrier.callscreeningserviceimpl</item>
+ * <p>
+ * Using {@link ComponentName#flattenToString()} to convert a ComponentName object to String.
+ * Using {@link ComponentName#unflattenFromString(String)} to convert a String object to a
+ * ComponentName.
+ */
public static final String KEY_CARRIER_CALL_SCREENING_APP_STRING = "call_screening_app";
/**
@@ -1881,20 +1930,20 @@ public class CarrierConfigManager {
"broadcast_emergency_call_state_changes_bool";
/**
- * Indicates whether STK LAUNCH_BROWSER command is disabled.
- * If {@code true}, then the browser will not be launched
- * on UI for the LAUNCH_BROWSER STK command.
- * @hide
- */
+ * Indicates whether STK LAUNCH_BROWSER command is disabled.
+ * If {@code true}, then the browser will not be launched
+ * on UI for the LAUNCH_BROWSER STK command.
+ * @hide
+ */
public static final String KEY_STK_DISABLE_LAUNCH_BROWSER_BOOL =
"stk_disable_launch_browser_bool";
/**
- * Boolean indicating if the helper text for STK GET INKEY/INPUT commands with the digit only
- * mode is displayed on the input screen.
- * The helper text is dispayed regardless of the input mode, if {@code false}.
- * @hide
- */
+ * Boolean indicating if the helper text for STK GET INKEY/INPUT commands with the digit only
+ * mode is displayed on the input screen.
+ * The helper text is displayed regardless of the input mode, if {@code false}.
+ * @hide
+ */
public static final String KEY_HIDE_DIGITS_HELPER_TEXT_ON_STK_INPUT_SCREEN_BOOL =
"hide_digits_helper_text_on_stk_input_screen_bool";
@@ -1926,8 +1975,13 @@ public class CarrierConfigManager {
/**
* Boolean indicating if LTE+ icon should be shown if available.
*/
- public static final String KEY_HIDE_LTE_PLUS_DATA_ICON_BOOL =
- "hide_lte_plus_data_icon_bool";
+ public static final String KEY_HIDE_LTE_PLUS_DATA_ICON_BOOL = "hide_lte_plus_data_icon_bool";
+
+ /**
+ * Boolean indicting if the 5G slice icon should be shown if available.
+ * @hide
+ */
+ public static final String KEY_SHOW_5G_SLICE_ICON_BOOL = "show_5g_slice_icon_bool";
/**
* The combined channel bandwidth threshold (non-inclusive) in KHz required to display the
@@ -1957,13 +2011,24 @@ public class CarrierConfigManager {
* cell bandwidth meets the required threshold for NR advanced.
*
* @see TelephonyDisplayInfo#OVERRIDE_NETWORK_TYPE_NR_ADVANCED
- *
- * @hide
*/
public static final String KEY_INCLUDE_LTE_FOR_NR_ADVANCED_THRESHOLD_BANDWIDTH_BOOL =
"include_lte_for_nr_advanced_threshold_bandwidth_bool";
/**
+ * Indicating whether to ratchet the aggregated cell bandwidths on receiving new values when
+ * the device is in RRC IDLE mode.
+ * The aggregated cell bandwidths are used for determining NR advanced state.
+ *
+ * If this is {@code true}, we will only update the aggregate cell bandwidths if the new
+ * aggregate is higher than the current aggregate and the anchor NR cell is the same.
+ * If this is {@code false}, we will always update the aggregate cell bandwidths when receiving
+ * new values.
+ */
+ public static final String KEY_RATCHET_NR_ADVANCED_BANDWIDTH_IF_RRC_IDLE_BOOL =
+ "ratchet_nr_advanced_bandwidth_if_rrc_idle_bool";
+
+ /**
* Boolean indicating if operator name should be shown in the status bar
* @hide
*/
@@ -2043,16 +2108,22 @@ public class CarrierConfigManager {
public static final String KEY_MMS_ALLOW_ATTACH_AUDIO_BOOL = "allowAttachAudio";
public static final String KEY_MMS_APPEND_TRANSACTION_ID_BOOL = "enabledTransID";
public static final String KEY_MMS_GROUP_MMS_ENABLED_BOOL = "enableGroupMms";
- public static final String KEY_MMS_MMS_DELIVERY_REPORT_ENABLED_BOOL = "enableMMSDeliveryReports";
+ public static final String KEY_MMS_MMS_DELIVERY_REPORT_ENABLED_BOOL =
+ "enableMMSDeliveryReports";
public static final String KEY_MMS_MMS_ENABLED_BOOL = "enabledMMS";
public static final String KEY_MMS_MMS_READ_REPORT_ENABLED_BOOL = "enableMMSReadReports";
public static final String KEY_MMS_MULTIPART_SMS_ENABLED_BOOL = "enableMultipartSMS";
public static final String KEY_MMS_NOTIFY_WAP_MMSC_ENABLED_BOOL = "enabledNotifyWapMMSC";
- public static final String KEY_MMS_SEND_MULTIPART_SMS_AS_SEPARATE_MESSAGES_BOOL = "sendMultipartSmsAsSeparateMessages";
- public static final String KEY_MMS_SHOW_CELL_BROADCAST_APP_LINKS_BOOL = "config_cellBroadcastAppLinks";
- public static final String KEY_MMS_SMS_DELIVERY_REPORT_ENABLED_BOOL = "enableSMSDeliveryReports";
- public static final String KEY_MMS_SUPPORT_HTTP_CHARSET_HEADER_BOOL = "supportHttpCharsetHeader";
- public static final String KEY_MMS_SUPPORT_MMS_CONTENT_DISPOSITION_BOOL = "supportMmsContentDisposition";
+ public static final String KEY_MMS_SEND_MULTIPART_SMS_AS_SEPARATE_MESSAGES_BOOL =
+ "sendMultipartSmsAsSeparateMessages";
+ public static final String KEY_MMS_SHOW_CELL_BROADCAST_APP_LINKS_BOOL =
+ "config_cellBroadcastAppLinks";
+ public static final String KEY_MMS_SMS_DELIVERY_REPORT_ENABLED_BOOL =
+ "enableSMSDeliveryReports";
+ public static final String KEY_MMS_SUPPORT_HTTP_CHARSET_HEADER_BOOL =
+ "supportHttpCharsetHeader";
+ public static final String KEY_MMS_SUPPORT_MMS_CONTENT_DISPOSITION_BOOL =
+ "supportMmsContentDisposition";
public static final String KEY_MMS_ALIAS_MAX_CHARS_INT = "aliasMaxChars";
public static final String KEY_MMS_ALIAS_MIN_CHARS_INT = "aliasMinChars";
public static final String KEY_MMS_HTTP_SOCKET_TIMEOUT_INT = "httpSocketTimeout";
@@ -2061,7 +2132,8 @@ public class CarrierConfigManager {
public static final String KEY_MMS_MAX_MESSAGE_SIZE_INT = "maxMessageSize";
public static final String KEY_MMS_MESSAGE_TEXT_MAX_SIZE_INT = "maxMessageTextSize";
public static final String KEY_MMS_RECIPIENT_LIMIT_INT = "recipientLimit";
- public static final String KEY_MMS_SMS_TO_MMS_TEXT_LENGTH_THRESHOLD_INT = "smsToMmsTextLengthThreshold";
+ public static final String KEY_MMS_SMS_TO_MMS_TEXT_LENGTH_THRESHOLD_INT =
+ "smsToMmsTextLengthThreshold";
public static final String KEY_MMS_SMS_TO_MMS_TEXT_THRESHOLD_INT = "smsToMmsTextThreshold";
public static final String KEY_MMS_SUBJECT_MAX_LENGTH_INT = "maxSubjectLength";
public static final String KEY_MMS_EMAIL_GATEWAY_NUMBER_STRING = "emailGatewayNumber";
@@ -2090,7 +2162,7 @@ public class CarrierConfigManager {
* The flatten {@link android.content.ComponentName componentName} of the activity that can
* setup the device and activate with the network per carrier requirements.
*
- * e.g, com.google.android.carrierPackageName/.CarrierActivityName
+ * e.g., com.google.android.carrierPackageName/.CarrierActivityName
* @hide
*/
@SystemApi
@@ -2231,7 +2303,7 @@ public class CarrierConfigManager {
/**
* Determines whether the carrier supports making non-emergency phone calls while the phone is
- * in emergency callback mode. Default value is {@code true}, meaning that non-emergency calls
+ * in emergency callback mode. Default value is {@code true}, meaning that non-emergency calls
* are allowed in emergency callback mode.
*/
public static final String KEY_ALLOW_NON_EMERGENCY_CALLS_IN_ECM_BOOL =
@@ -2254,7 +2326,7 @@ public class CarrierConfigManager {
/**
* Flag indicating whether to allow carrier video calls to emergency numbers.
- * When {@code true}, video calls to emergency numbers will be allowed. When {@code false},
+ * When {@code true}, video calls to emergency numbers will be allowed. When {@code false},
* video calls to emergency numbers will be initiated as audio-only calls instead.
*/
public static final String KEY_ALLOW_EMERGENCY_VIDEO_CALLS_BOOL =
@@ -2282,7 +2354,7 @@ public class CarrierConfigManager {
* When presence is supported, the device should use the
* {@link android.provider.ContactsContract.Data#CARRIER_PRESENCE} bit mask and set the
* {@link android.provider.ContactsContract.Data#CARRIER_PRESENCE_VT_CAPABLE} bit to indicate
- * whether each contact supports video calling. The UI is made aware that presence is enabled
+ * whether each contact supports video calling. The UI is made aware that presence is enabled
* via {@link android.telecom.PhoneAccount#CAPABILITY_VIDEO_CALLING_RELIES_ON_PRESENCE}
* and can choose to hide or show the video calling icon based on whether a contact supports
* video.
@@ -2306,7 +2378,7 @@ public class CarrierConfigManager {
* contacts emergency services. Platform considers values for below cases:
* 1) 0 <= VALUE <= 604800(one week): the value will be used as the duration directly.
* 2) VALUE > 604800(one week): will use the default value as duration instead.
- * 3) VALUE < 0: block will be disabled forever until user re-eanble block manually,
+ * 3) VALUE < 0: block will be disabled forever until user re-enable block manually,
* the suggested value to disable forever is -1.
* See {@code android.provider.BlockedNumberContract#notifyEmergencyContact(Context)}
* See {@code android.provider.BlockedNumberContract#isBlocked(Context, String)}.
@@ -2336,7 +2408,7 @@ public class CarrierConfigManager {
/**
* For carriers which require an empty flash to be sent before sending the normal 3-way calling
- * flash, the duration in milliseconds of the empty flash to send. When {@code 0}, no empty
+ * flash, the duration in milliseconds of the empty flash to send. When {@code 0}, no empty
* flash is sent.
*/
public static final String KEY_CDMA_3WAYCALL_FLASH_DELAY_INT = "cdma_3waycall_flash_delay_int";
@@ -2376,8 +2448,7 @@ public class CarrierConfigManager {
* Int indicating the max number length for FDN
* @hide
*/
- public static final String KEY_FDN_NUMBER_LENGTH_LIMIT_INT =
- "fdn_number_length_limit_int";
+ public static final String KEY_FDN_NUMBER_LENGTH_LIMIT_INT = "fdn_number_length_limit_int";
/**
* Report IMEI as device id even if it's a CDMA/LTE phone.
@@ -2389,16 +2460,15 @@ public class CarrierConfigManager {
/**
* The families of Radio Access Technologies that will get clustered and ratcheted,
* ie, we will report transitions up within the family, but not down until we change
- * cells. This prevents flapping between base technologies and higher techs that are
+ * cells. This prevents flapping between base technologies and higher techs that are
* granted on demand within the cell.
* @hide
*/
- public static final String KEY_RATCHET_RAT_FAMILIES =
- "ratchet_rat_families";
+ public static final String KEY_RATCHET_RAT_FAMILIES = "ratchet_rat_families";
/**
* Flag indicating whether some telephony logic will treat a call which was formerly a video
- * call as if it is still a video call. When {@code true}:
+ * call as if it is still a video call. When {@code true}:
* <p>
* Logic which will automatically drop a video call which takes place over WIFI when a
* voice call is answered (see {@link #KEY_DROP_VIDEO_CALL_WHEN_ANSWERING_AUDIO_CALL_BOOL}.
@@ -2410,7 +2480,7 @@ public class CarrierConfigManager {
/**
* When {@code true}, if the user is in an ongoing video call over WIFI and answers an incoming
- * audio call, the video call will be disconnected before the audio call is answered. This is
+ * audio call, the video call will be disconnected before the audio call is answered. This is
* in contrast to the usual expected behavior where a foreground video call would be put into
* the background and held when an incoming audio call is answered.
*/
@@ -2420,8 +2490,8 @@ public class CarrierConfigManager {
/**
* Flag indicating whether the carrier supports merging wifi calls when VoWIFI is disabled.
* This can happen in the case of a carrier which allows offloading video calls to WIFI
- * separately of whether voice over wifi is enabled. In such a scenario when two video calls
- * are downgraded to voice, they remain over wifi. However, if VoWIFI is disabled, these calls
+ * separately of whether voice over wifi is enabled. In such a scenario when two video calls
+ * are downgraded to voice, they remain over wifi. However, if VoWIFI is disabled, these calls
* cannot be merged.
*/
public static final String KEY_ALLOW_MERGE_WIFI_CALLS_WHEN_VOWIFI_OFF_BOOL =
@@ -2431,9 +2501,9 @@ public class CarrierConfigManager {
* Flag indicating whether the carrier supports the Hold command while in an IMS call.
* <p>
* The device configuration value {@code config_device_respects_hold_carrier_config} ultimately
- * controls whether this carrier configuration option is used. Where
- * {@code config_device_respects_hold_carrier_config} is false, the value of the
- * {@link #KEY_ALLOW_HOLD_IN_IMS_CALL_BOOL} carrier configuration option is ignored.
+ * controls whether this carrier configuration option is used.
+ * Where {@code config_device_respects_hold_carrier_config} is false, the value of
+ * this carrier configuration is ignored.
* @hide
*/
public static final String KEY_ALLOW_HOLD_IN_IMS_CALL_BOOL = "allow_hold_in_ims_call";
@@ -2488,8 +2558,7 @@ public class CarrierConfigManager {
* <p>
* This is {@code true} by default.
*/
- public static final String KEY_ALLOW_HOLD_VIDEO_CALL_BOOL =
- "allow_hold_video_call_bool";
+ public static final String KEY_ALLOW_HOLD_VIDEO_CALL_BOOL = "allow_hold_video_call_bool";
/**
* When true, indicates that the HD audio icon in the in-call screen should not be shown for
@@ -2583,7 +2652,8 @@ public class CarrierConfigManager {
* is returned.
* @hide
*/
- public static final String KEY_FILTERED_CNAP_NAMES_STRING_ARRAY = "filtered_cnap_names_string_array";
+ public static final String KEY_FILTERED_CNAP_NAMES_STRING_ARRAY =
+ "filtered_cnap_names_string_array";
/**
* The RCS configuration server URL. This URL is used to initiate RCS provisioning.
@@ -2651,9 +2721,9 @@ public class CarrierConfigManager {
"emergency_notification_delay_int";
/**
- * When {@code true}, the carrier allows the user of the
- * {@link TelephonyManager#sendUssdRequest(String, TelephonyManager.UssdResponseCallback,
- * Handler)} API to perform USSD requests. {@code True} by default.
+ * When {@code true}, the carrier allows the user of the {@link
+ * TelephonyManager#sendUssdRequest(String, TelephonyManager.UssdResponseCallback, Handler)}
+ * API to perform USSD requests. {@code True} by default.
* @hide
*/
public static final String KEY_ALLOW_USSD_REQUESTS_VIA_TELEPHONY_MANAGER_BOOL =
@@ -2665,7 +2735,7 @@ public class CarrierConfigManager {
* fails.
*/
public static final String KEY_SUPPORT_3GPP_CALL_FORWARDING_WHILE_ROAMING_BOOL =
- "support_3gpp_call_forwarding_while_roaming_bool";
+ "support_3gpp_call_forwarding_while_roaming_bool";
/**
* Boolean indicating whether to display voicemail number as default call forwarding number in
@@ -2731,8 +2801,7 @@ public class CarrierConfigManager {
* This setting may be still overridden by explicit user choice. By default,
* {@link #DATA_CYCLE_USE_PLATFORM_DEFAULT} will be used.
*/
- public static final String KEY_MONTHLY_DATA_CYCLE_DAY_INT =
- "monthly_data_cycle_day_int";
+ public static final String KEY_MONTHLY_DATA_CYCLE_DAY_INT = "monthly_data_cycle_day_int";
/**
* When {@link #KEY_MONTHLY_DATA_CYCLE_DAY_INT}, {@link #KEY_DATA_LIMIT_THRESHOLD_BYTES_LONG},
@@ -2778,7 +2847,7 @@ public class CarrierConfigManager {
/**
* Controls if the device should automatically warn the user that sim voice & data function
- * might be limited due to dual sim scenario. When set to {@true} display the notification,
+ * might be limited due to dual sim scenario. When set to {@code true} display the notification,
* {@code false} otherwise.
* @hide
*/
@@ -2804,16 +2873,14 @@ public class CarrierConfigManager {
* their cellular data limit. When set to {@code false} the carrier is
* expected to have implemented their own notification mechanism. {@code true} by default.
*/
- public static final String KEY_DATA_LIMIT_NOTIFICATION_BOOL =
- "data_limit_notification_bool";
+ public static final String KEY_DATA_LIMIT_NOTIFICATION_BOOL = "data_limit_notification_bool";
/**
* Controls if the device should automatically notify the user when rapid
* cellular data usage is observed. When set to {@code false} the carrier is
- * expected to have implemented their own notification mechanism. {@code true} by default.
+ * expected to have implemented their own notification mechanism. {@code true} by default.
*/
- public static final String KEY_DATA_RAPID_NOTIFICATION_BOOL =
- "data_rapid_notification_bool";
+ public static final String KEY_DATA_RAPID_NOTIFICATION_BOOL = "data_rapid_notification_bool";
/**
* Offset to be reduced from rsrp threshold while calculating signal strength level.
@@ -2846,8 +2913,7 @@ public class CarrierConfigManager {
* "nrarfcn2_start-nrarfcn2_end" ... }
* @hide
*/
- public static final String KEY_BOOSTED_NRARFCNS_STRING_ARRAY =
- "boosted_nrarfcns_string_array";
+ public static final String KEY_BOOSTED_NRARFCNS_STRING_ARRAY = "boosted_nrarfcns_string_array";
/**
* Determine whether to use only RSRP for the number of LTE signal bars.
@@ -2947,6 +3013,39 @@ public class CarrierConfigManager {
"5g_nr_sssinr_thresholds_int_array";
/**
+ * An interval in dB for {@link SignalThresholdInfo#SIGNAL_MEASUREMENT_TYPE_SSRSRP} measurement
+ * type defining the required magnitude change between reports.
+ *
+ * <p>The default value is 2 and the minimum allowed value is 0. If no value or negative value
+ * is set, the default value 2 is used.
+ * @hide
+ */
+ public static final String KEY_NGRAN_SSRSRP_HYSTERESIS_DB_INT =
+ "ngran_ssrsrp_hysteresis_db_int";
+
+ /**
+ * An interval in dB for {@link SignalThresholdInfo#SIGNAL_MEASUREMENT_TYPE_SSRSRQ} measurement
+ * type defining the required magnitude change between reports.
+ *
+ * <p>The default value is 2 and the minimum allowed value is 0. If no value or negative value
+ * is set, the default value 2 is used.
+ * @hide
+ */
+ public static final String KEY_NGRAN_SSRSRQ_HYSTERESIS_DB_INT =
+ "ngran_ssrsrq_hysteresis_db_int";
+
+ /**
+ * An interval in dB for {@link SignalThresholdInfo#SIGNAL_MEASUREMENT_TYPE_SSSINR} measurement
+ * type defining the required magnitude change between reports.
+ *
+ * <p>The default value is 2 and the minimum allowed value is 0. If no value or negative value
+ * is set, the default value 2 is used.
+ * @hide
+ */
+ public static final String KEY_NGRAN_SSSINR_HYSTERESIS_DB_INT =
+ "ngran_sssinr_hysteresis_db_int";
+
+ /**
* Bit-field integer to determine whether to use SS reference signal received power (SSRSRP),
* SS reference signal received quality (SSRSRQ), or/and SS signal-to-noise and interference
* ratio (SSSINR) for the number of 5G NR signal bars and signal criteria reporting enabling.
@@ -3032,8 +3131,7 @@ public class CarrierConfigManager {
* A match on this supersedes a match on {@link #KEY_NON_ROAMING_OPERATOR_STRING_ARRAY}.
* @hide
*/
- public static final String KEY_ROAMING_OPERATOR_STRING_ARRAY =
- "roaming_operator_string_array";
+ public static final String KEY_ROAMING_OPERATOR_STRING_ARRAY = "roaming_operator_string_array";
/**
* URL from which the proto containing the public key of the Carrier used for
@@ -3102,7 +3200,7 @@ public class CarrierConfigManager {
* Boolean flag indicating whether the carrier supports TTY.
* <p>
* Note that {@link #KEY_CARRIER_VOLTE_TTY_SUPPORTED_BOOL} controls availability of TTY over
- * VoLTE; if {@link #KEY_TTY_SUPPORTED_BOOL} is disabled, then
+ * VoLTE; if this carrier configuration is disabled, then
* {@link #KEY_CARRIER_VOLTE_TTY_SUPPORTED_BOOL} is also implicitly disabled.
* <p>
* {@link TelecomManager#isTtySupported()} should be used to determine if a device supports TTY,
@@ -3226,11 +3324,11 @@ public class CarrierConfigManager {
public static final String KEY_CHECK_PRICING_WITH_CARRIER_FOR_DATA_ROAMING_BOOL =
"check_pricing_with_carrier_data_roaming_bool";
- /**
- * Determines whether we should show a notification when the phone established a data
- * connection in roaming network, to warn users about possible roaming charges.
- * @hide
- */
+ /**
+ * Determines whether we should show a notification when the phone established a data
+ * connection in roaming network, to warn users about possible roaming charges.
+ * @hide
+ */
public static final String KEY_SHOW_DATA_CONNECTED_ROAMING_NOTIFICATION_BOOL =
"show_data_connected_roaming_notification";
@@ -3245,8 +3343,7 @@ public class CarrierConfigManager {
* these boundaries is considered invalid.
* @hide
*/
- public static final String KEY_LTE_RSRP_THRESHOLDS_INT_ARRAY =
- "lte_rsrp_thresholds_int_array";
+ public static final String KEY_LTE_RSRP_THRESHOLDS_INT_ARRAY = "lte_rsrp_thresholds_int_array";
/**
* A list of 4 customized LTE Reference Signal Received Quality (RSRQ) thresholds.
@@ -3263,8 +3360,7 @@ public class CarrierConfigManager {
* This key is considered invalid if the format is violated. If the key is invalid or
* not configured, a default value set will apply.
*/
- public static final String KEY_LTE_RSRQ_THRESHOLDS_INT_ARRAY =
- "lte_rsrq_thresholds_int_array";
+ public static final String KEY_LTE_RSRQ_THRESHOLDS_INT_ARRAY = "lte_rsrq_thresholds_int_array";
/**
* A list of 4 customized LTE Reference Signal Signal to Noise Ratio (RSSNR) thresholds.
@@ -3283,6 +3379,37 @@ public class CarrierConfigManager {
"lte_rssnr_thresholds_int_array";
/**
+ * An interval in dB for {@link SignalThresholdInfo#SIGNAL_MEASUREMENT_TYPE_RSRP} measurement
+ * type defining the required magnitude change between reports.
+ *
+ * <p>The default value is 2 and the minimum allowed value is 0. If no value or negative value
+ * is set, the default value 2 is used.
+ * @hide
+ */
+ public static final String KEY_EUTRAN_RSRP_HYSTERESIS_DB_INT = "eutran_rsrp_hysteresis_db_int";
+
+ /**
+ * An interval in dB for {@link SignalThresholdInfo#SIGNAL_MEASUREMENT_TYPE_RSRQ} measurement
+ * type defining the required magnitude change between reports.
+ *
+ * <p>The default value is 2 and the minimum allowed value is 0. If no value or negative value
+ * is set, the default value 2 is used.
+ * @hide
+ */
+ public static final String KEY_EUTRAN_RSRQ_HYSTERESIS_DB_INT = "eutran_rsrq_hysteresis_db_int";
+
+ /**
+ * An interval in dB for {@link SignalThresholdInfo#SIGNAL_MEASUREMENT_TYPE_RSSNR} measurement
+ * type defining the required magnitude change between reports.
+ *
+ * <p>The default value is 2 and the minimum allowed value is 0. If no value or negative value
+ * is set, the default value 2 is used.
+ * @hide
+ */
+ public static final String KEY_EUTRAN_RSSNR_HYSTERESIS_DB_INT =
+ "eutran_rssnr_hysteresis_db_int";
+
+ /**
* Decides when clients try to bind to iwlan network service, which package name will
* the binding intent go to.
* @hide
@@ -3329,28 +3456,64 @@ public class CarrierConfigManager {
*/
public static final String KEY_CARRIER_QUALIFIED_NETWORKS_SERVICE_CLASS_OVERRIDE_STRING =
"carrier_qualified_networks_service_class_override_string";
+
/**
- * A list of 4 LTE RSCP thresholds above which a signal level is considered POOR,
+ * A list of 4 WCDMA RSCP thresholds above which a signal level is considered POOR,
* MODERATE, GOOD, or EXCELLENT, to be used in SignalStrength reporting.
*
* Note that the min and max thresholds are fixed at -120 and -24, as set in 3GPP TS 27.007
* section 8.69.
* <p>
- * See SignalStrength#MAX_WCDMA_RSCP and SignalStrength#MIN_WDCMA_RSCP. Any signal level outside
- * these boundaries is considered invalid.
+ * See CellSignalStrengthWcdma#WCDMA_RSCP_MAX and CellSignalStrengthWcdma#WCDMA_RSCP_MIN.
+ * Any signal level outside these boundaries is considered invalid.
* @hide
*/
public static final String KEY_WCDMA_RSCP_THRESHOLDS_INT_ARRAY =
"wcdma_rscp_thresholds_int_array";
/**
+ * A list of 4 WCDMA ECNO thresholds above which a signal level is considered POOR,
+ * MODERATE, GOOD, or EXCELLENT, to be used in SignalStrength reporting.
+ *
+ * Note that the min and max thresholds are fixed at -24 and 1, as set in 3GPP TS 25.215
+ * section 5.1.5.
+ * Any signal level outside these boundaries is considered invalid.
+ * <p>
+ *
+ * The default value is {@code {-24, -14, -6, 1}}.
+ * @hide
+ */
+ public static final String KEY_WCDMA_ECNO_THRESHOLDS_INT_ARRAY =
+ "wcdma_ecno_thresholds_int_array";
+
+ /**
+ * An interval in dB for {@link SignalThresholdInfo#SIGNAL_MEASUREMENT_TYPE_RSCP} measurement
+ * type defining the required magnitude change between reports.
+ *
+ * <p>The default value is 2 and the minimum allowed value is 0. If no value or negative value
+ * is set, the default value 2 is used.
+ * @hide
+ */
+ public static final String KEY_UTRAN_RSCP_HYSTERESIS_DB_INT = "utran_rscp_hysteresis_db_int";
+
+ /**
+ * An interval in dB for {@link SignalThresholdInfo#SIGNAL_MEASUREMENT_TYPE_ECNO} measurement
+ * type defining the required magnitude change between reports.
+ *
+ * <p>The default value is 2 and the minimum allowed value is 0. If no value or negative value
+ * is set, the default value 2 is used.
+ * @hide
+ */
+ public static final String KEY_UTRAN_ECNO_HYSTERESIS_DB_INT = "utran_ecno_hysteresis_db_int";
+
+ /**
* The default measurement to use for signal strength reporting. If this is not specified, the
* RSSI is used.
* <p>
* e.g.) To use RSCP by default, set the value to "rscp". The signal strength level will
* then be determined by #KEY_WCDMA_RSCP_THRESHOLDS_INT_ARRAY
* <p>
- * Currently this supports the value "rscp" and "rssi".
+ * Currently this supports the value "rscp","rssi" and "ecno".
* @hide
*/
// FIXME: this key and related keys must not be exposed without a consistent philosophy for
@@ -3369,7 +3532,7 @@ public class CarrierConfigManager {
/**
* Specifies a carrier-defined {@link android.telecom.CallRedirectionService} which Telecom
- * will bind to for outgoing calls. An empty string indicates that no carrier-defined
+ * will bind to for outgoing calls. An empty string indicates that no carrier-defined
* {@link android.telecom.CallRedirectionService} is specified.
*/
public static final String KEY_CALL_REDIRECTION_SERVICE_COMPONENT_NAME_STRING =
@@ -3669,7 +3832,7 @@ public class CarrierConfigManager {
* This configuration allows the framework to use user data communication to detect Idle state,
* and this is used on the 5G icon.
*
- * There is a new way for for RRC state detection at Android 12. If
+ * There is a new way for RRC state detection at Android 12. If
* {@link android.telephony.TelephonyManager#isRadioInterfaceCapabilitySupported}(
* {@link TelephonyManager#CAPABILITY_PHYSICAL_CHANNEL_CONFIG_1_6_SUPPORTED}) returns true,
* then framework can use PHYSICAL_CHANNEL_CONFIG for RRC state detection. Based on this
@@ -3769,8 +3932,7 @@ public class CarrierConfigManager {
* FQDN (Fully Qualified Domain Name) of the SM-DP+ (e.g., smdp.gsma.com) restricted to the
* Alphanumeric mode character set defined in table 5 of ISO/IEC 18004 excluding '$'.
*/
- public static final String KEY_SMDP_SERVER_ADDRESS_STRING =
- "smdp_server_address_string";
+ public static final String KEY_SMDP_SERVER_ADDRESS_STRING = "smdp_server_address_string";
/**
* This timer value is used in the eSIM Exponential Backoff download retry algorithm.
@@ -3821,7 +3983,7 @@ public class CarrierConfigManager {
public static final String KEY_OPPORTUNISTIC_ESIM_DOWNLOAD_VIA_WIFI_ONLY_BOOL =
"opportunistic_esim_download_via_wifi_only_bool";
-/**
+ /**
* Controls RSRP threshold, in dBm, at which OpportunisticNetworkService will decide whether
* the opportunistic network is good enough for internet data.
*
@@ -3915,6 +4077,7 @@ public class CarrierConfigManager {
*/
public static final String KEY_OPPORTUNISTIC_NETWORK_PING_PONG_TIME_LONG =
"opportunistic_network_ping_pong_time_long";
+
/**
* Controls back off time in milli seconds for switching back to
* opportunistic subscription. This time will be added to
@@ -4134,7 +4297,7 @@ public class CarrierConfigManager {
* If opportunistic network is determined as out of service or below
* {@link #KEY_EXIT_THRESHOLD_SS_RSRP_INT} or
* {@link #KEY_EXIT_THRESHOLD_SS_RSRQ_DOUBLE} within
- * {@link #KEY_5G_PING_PONG_TIME_LONG} of switching to opportunistic network,
+ * the time specified by this carrier config of switching to opportunistic network,
* it will be determined as ping pong situation by system app or 1st party app.
*
* @hide
@@ -4190,29 +4353,30 @@ public class CarrierConfigManager {
public static final String KEY_ENABLE_4G_OPPORTUNISTIC_NETWORK_SCAN_BOOL =
"enabled_4g_opportunistic_network_scan_bool";
- /**
- * Only relevant when the device supports opportunistic networks but does not support
- * simultaneuous 5G+5G. Controls how long, in milliseconds, to wait before opportunistic network
- * goes out of service before switching the 5G capability back to primary stack. The idea of
- * waiting a few seconds is to minimize the calling of the expensive capability switching
- * operation in the case where CBRS goes back into service shortly after going out of it.
- *
- * @hide
- */
- public static final String KEY_TIME_TO_SWITCH_BACK_TO_PRIMARY_IF_OPPORTUNISTIC_OOS_LONG =
+ /**
+ * Only relevant when the device supports opportunistic networks but does not support
+ * simultaneous 5G+5G. Controls how long, in milliseconds, to wait before opportunistic network
+ * goes out of service before switching the 5G capability back to primary stack. The idea of
+ * waiting a few seconds is to minimize the calling of the expensive capability switching
+ * operation in the case where CBRS goes back into service shortly after going out of it.
+ *
+ * @hide
+ */
+ public static final String KEY_TIME_TO_SWITCH_BACK_TO_PRIMARY_IF_OPPORTUNISTIC_OOS_LONG =
"time_to_switch_back_to_primary_if_opportunistic_oos_long";
- /**
- * Only relevant when the device supports opportunistic networks but does not support
- * simultaneuous 5G+5G. Controls how long, in milliseconds, after 5G capability has switched back
- * to primary stack due to opportunistic network being OOS. The idea is to minimizing the
- * 'ping-ponging' effect where device is constantly witching capability back and forth between
- * primary and opportunistic stack.
- *
- * @hide
- */
- public static final String KEY_OPPORTUNISTIC_TIME_TO_SCAN_AFTER_CAPABILITY_SWITCH_TO_PRIMARY_LONG
- = "opportunistic_time_to_scan_after_capability_switch_to_primary_long";
+ /**
+ * Only relevant when the device supports opportunistic networks but does not support
+ * simultaneous 5G+5G. Controls how long, in milliseconds, after 5G capability has switched back
+ * to primary stack due to opportunistic network being OOS. The idea is to minimizing the
+ * 'ping-ponging' effect where device is constantly witching capability back and forth between
+ * primary and opportunistic stack.
+ *
+ * @hide
+ */
+ public static final String
+ KEY_OPPORTUNISTIC_TIME_TO_SCAN_AFTER_CAPABILITY_SWITCH_TO_PRIMARY_LONG =
+ "opportunistic_time_to_scan_after_capability_switch_to_primary_long";
/**
* Indicates zero or more emergency number prefix(es), because some carrier requires
@@ -4355,8 +4519,7 @@ public class CarrierConfigManager {
* @hide
*/
@SystemApi
- public static final String KEY_GBA_UA_SECURITY_PROTOCOL_INT =
- "gba_ua_security_protocol_int";
+ public static final String KEY_GBA_UA_SECURITY_PROTOCOL_INT = "gba_ua_security_protocol_int";
/**
* An integer representing the cipher suite to be used when building the
@@ -4366,8 +4529,7 @@ public class CarrierConfigManager {
* @hide
*/
@SystemApi
- public static final String KEY_GBA_UA_TLS_CIPHER_SUITE_INT =
- "gba_ua_tls_cipher_suite_int";
+ public static final String KEY_GBA_UA_TLS_CIPHER_SUITE_INT = "gba_ua_tls_cipher_suite_int";
/**
* The data stall recovery timers array in milliseconds, each element is the delay before
@@ -4577,7 +4739,6 @@ public class CarrierConfigManager {
*/
public static final int SUPL_EMERGENCY_MODE_TYPE_DP_ONLY = 2;
-
/**
* Determine whether current lpp_mode used for E-911 needs to be kept persistently.
* {@code false} - not keeping the lpp_mode means using default configuration of gps.conf
@@ -4695,8 +4856,8 @@ public class CarrierConfigManager {
* The default value for this configuration is {@link #SUPL_EMERGENCY_MODE_TYPE_CP_ONLY}.
* @hide
*/
- public static final String KEY_ES_SUPL_CONTROL_PLANE_SUPPORT_INT = KEY_PREFIX
- + "es_supl_control_plane_support_int";
+ public static final String KEY_ES_SUPL_CONTROL_PLANE_SUPPORT_INT =
+ KEY_PREFIX + "es_supl_control_plane_support_int";
/**
* A list of roaming PLMNs where SUPL ES mode does not support a control-plane mechanism to
@@ -4731,13 +4892,14 @@ public class CarrierConfigManager {
}
}
- /**
- * An int array containing CDMA enhanced roaming indicator values for Home (non-roaming) network.
- * The default values come from 3GPP2 C.R1001 table 8.1-1.
- * Enhanced Roaming Indicator Number Assignments
- *
- * @hide
- */
+ /**
+ * An int array containing CDMA enhanced roaming indicator values for Home (non-roaming)
+ * network.
+ * The default values come from 3GPP2 C.R1001 table 8.1-1.
+ * Enhanced Roaming Indicator Number Assignments
+ *
+ * @hide
+ */
public static final String KEY_CDMA_ENHANCED_ROAMING_INDICATOR_FOR_HOME_NETWORK_INT_ARRAY =
"cdma_enhanced_roaming_indicator_for_home_network_int_array";
@@ -4749,7 +4911,7 @@ public class CarrierConfigManager {
/**
* Indicates use 3GPP application to replace 3GPP2 application even if it's a CDMA/CDMA-LTE
- * phone, becasue some carriers's CSIM application is present but not supported.
+ * phone, because some carriers' CSIM application is present but not supported.
* @hide
*/
public static final String KEY_USE_USIM_BOOL = "use_usim_bool";
@@ -4812,8 +4974,7 @@ public class CarrierConfigManager {
* {@see SubscriptionInfo#getUsageSetting}
*
*/
- public static final String KEY_CELLULAR_USAGE_SETTING_INT =
- "cellular_usage_setting_int";
+ public static final String KEY_CELLULAR_USAGE_SETTING_INT = "cellular_usage_setting_int";
/**
* Data switch validation minimal gap time, in milliseconds.
@@ -4877,7 +5038,7 @@ public class CarrierConfigManager {
* "Carrier Provisioning Info" or "Trigger Carrier Provisioning" button clicked.
*
* <p>
- * e.g, com.google.android.carrierPackageName/.CarrierReceiverName
+ * e.g., com.google.android.carrierPackageName/.CarrierReceiverName
*
* @hide
*/
@@ -4917,9 +5078,9 @@ public class CarrierConfigManager {
* Capability Exchange (UCE). See RCC.71, section 3 for more information.
* <p>
* If this key's value is set to false, the procedure for RCS contact capability exchange
- * via SIP SUBSCRIBE/NOTIFY will also be disabled internally, and
- * {@link Ims#KEY_ENABLE_PRESENCE_PUBLISH_BOOL} must also be set to false to ensure
- * apps do not improperly think that capability exchange via SIP PUBLISH is enabled.
+ * via SIP SUBSCRIBE/NOTIFY will also be disabled internally, and this key must also be set
+ * to false to ensure apps do not improperly think that capability exchange via SIP PUBLISH
+ * is enabled.
* <p> The default value for this key is {@code false}.
*/
public static final String KEY_ENABLE_PRESENCE_PUBLISH_BOOL =
@@ -4975,7 +5136,6 @@ public class CarrierConfigManager {
public static final String KEY_ENABLE_PRESENCE_CAPABILITY_EXCHANGE_BOOL =
KEY_PREFIX + "enable_presence_capability_exchange_bool";
-
/**
* Flag indicating whether or not the carrier expects the RCS UCE service to periodically
* refresh the RCS capabilities cache of the user's contacts as well as request the
@@ -5109,7 +5269,7 @@ public class CarrierConfigManager {
KEY_PREFIX + "sip_timer_j_millis_int";
/** Specifies the SIP Server default port. */
- public static final String KEY_SIP_SERVER_PORT_NUMBER_INT =
+ public static final String KEY_SIP_SERVER_PORT_NUMBER_INT =
KEY_PREFIX + "sip_server_port_number_int";
/**
@@ -5121,7 +5281,6 @@ public class CarrierConfigManager {
/** @hide */
@IntDef({REQUEST_URI_FORMAT_TEL, REQUEST_URI_FORMAT_SIP})
-
public @interface RequestUriFormatType {}
/**
@@ -5168,7 +5327,6 @@ public class CarrierConfigManager {
PREFERRED_TRANSPORT_DYNAMIC_UDP_TCP,
PREFERRED_TRANSPORT_TLS
})
-
public @interface PreferredTransportType {}
/** Preferred Transport is always UDP. */
@@ -5249,7 +5407,6 @@ public class CarrierConfigManager {
/** @hide */
@IntDef({IPSEC_AUTHENTICATION_ALGORITHM_HMAC_MD5, IPSEC_AUTHENTICATION_ALGORITHM_HMAC_SHA1})
-
public @interface IpsecAuthenticationAlgorithmType {}
/** IPSec Authentication algorithm is HMAC-MD5. see Annex H of TS 33.203 */
@@ -5274,7 +5431,6 @@ public class CarrierConfigManager {
IPSEC_ENCRYPTION_ALGORITHM_DES_EDE3_CBC,
IPSEC_ENCRYPTION_ALGORITHM_AES_CBC
})
-
public @interface IpsecEncryptionAlgorithmType {}
/** IPSec Encryption algorithm is NULL. see Annex H of TS 33.203 */
@@ -5333,7 +5489,6 @@ public class CarrierConfigManager {
GEOLOCATION_PIDF_FOR_NON_EMERGENCY_ON_CELLULAR,
GEOLOCATION_PIDF_FOR_EMERGENCY_ON_CELLULAR
})
-
public @interface GeolocationPidfAllowedType {}
/**
@@ -5427,7 +5582,6 @@ public class CarrierConfigManager {
NETWORK_TYPE_HOME,
NETWORK_TYPE_ROAMING
})
-
public @interface NetworkType {}
/** Indicates HOME Network. */
@@ -5444,7 +5598,6 @@ public class CarrierConfigManager {
E911_RTCP_INACTIVITY_ON_CONNECTED,
E911_RTP_INACTIVITY_ON_CONNECTED
})
-
public @interface MediaInactivityReason {}
/** RTCP inactivity occurred when call is on HOLD. */
@@ -5490,7 +5643,7 @@ public class CarrierConfigManager {
* <li>{@link #KEY_CAPABILITY_TYPE_CALL_COMPOSER_INT_ARRAY}</li>
* </ul>
* <p> The values are defined in
- * {@link android.telephony.ims.stub.ImsRegistrationImplBase.ImsRegistrationTech}
+ * {@link ImsRegistrationImplBase.ImsRegistrationTech}
*
* changing mmtel_requires_provisioning_bundle requires changes to
* carrier_volte_provisioning_required_bool and vice versa
@@ -5504,10 +5657,10 @@ public class CarrierConfigManager {
* is supported.
* @see MmTelFeature.MmTelCapabilities#CAPABILITY_TYPE_VOICE
* <p>Possible values are,
- * {@link android.telephony.ims.stub.ImsRegistrationImplBase.ImsRegistrationTech#REGISTRATION_TECH_LTE}
- * {@link android.telephony.ims.stub.ImsRegistrationImplBase.ImsRegistrationTech#REGISTRATION_TECH_IWLAN}
- * {@link android.telephony.ims.stub.ImsRegistrationImplBase.ImsRegistrationTech#REGISTRATION_TECH_CROSS_SIM}
- * {@link android.telephony.ims.stub.ImsRegistrationImplBase.ImsRegistrationTech#REGISTRATION_TECH_NR}
+ * {@link ImsRegistrationImplBase.ImsRegistrationTech#REGISTRATION_TECH_LTE}
+ * {@link ImsRegistrationImplBase.ImsRegistrationTech#REGISTRATION_TECH_IWLAN}
+ * {@link ImsRegistrationImplBase.ImsRegistrationTech#REGISTRATION_TECH_CROSS_SIM}
+ * {@link ImsRegistrationImplBase.ImsRegistrationTech#REGISTRATION_TECH_NR}
*/
public static final String KEY_CAPABILITY_TYPE_VOICE_INT_ARRAY =
KEY_PREFIX + "capability_type_voice_int_array";
@@ -5517,10 +5670,10 @@ public class CarrierConfigManager {
* is supported.
* @see MmTelFeature.MmTelCapabilities#CAPABILITY_TYPE_VIDEO
* <p>Possible values are,
- * {@link android.telephony.ims.stub.ImsRegistrationImplBase.ImsRegistrationImplBase.ImsRegistrationTech#REGISTRATION_TECH_LTE}
- * {@link android.telephony.ims.stub.ImsRegistrationImplBase.ImsRegistrationImplBase.ImsRegistrationTech#REGISTRATION_TECH_IWLAN}
- * {@link android.telephony.ims.stub.ImsRegistrationImplBase.ImsRegistrationImplBase.ImsRegistrationTech#REGISTRATION_TECH_CROSS_SIM}
- * {@link android.telephony.ims.stub.ImsRegistrationImplBase.ImsRegistrationImplBase.ImsRegistrationTech#REGISTRATION_TECH_NR}
+ * {@link ImsRegistrationImplBase.ImsRegistrationTech#REGISTRATION_TECH_LTE}
+ * {@link ImsRegistrationImplBase.ImsRegistrationTech#REGISTRATION_TECH_IWLAN}
+ * {@link ImsRegistrationImplBase.ImsRegistrationTech#REGISTRATION_TECH_CROSS_SIM}
+ * {@link ImsRegistrationImplBase.ImsRegistrationTech#REGISTRATION_TECH_NR}
*/
public static final String KEY_CAPABILITY_TYPE_VIDEO_INT_ARRAY =
KEY_PREFIX + "capability_type_video_int_array";
@@ -5530,10 +5683,10 @@ public class CarrierConfigManager {
* supplementary services. (IR.92) is supported.
* @see MmTelFeature.MmTelCapabilities#CAPABILITY_TYPE_UT
* <p>Possible values are,
- * {@link android.telephony.ims.stub.ImsRegistrationImplBase.ImsRegistrationImplBase.ImsRegistrationTech#REGISTRATION_TECH_LTE}
- * {@link android.telephony.ims.stub.ImsRegistrationImplBase.ImsRegistrationImplBase.ImsRegistrationTech#REGISTRATION_TECH_IWLAN}
- * {@link android.telephony.ims.stub.ImsRegistrationImplBase.ImsRegistrationImplBase.ImsRegistrationTech#REGISTRATION_TECH_CROSS_SIM}
- * {@link android.telephony.ims.stub.ImsRegistrationImplBase.ImsRegistrationImplBase.ImsRegistrationTech#REGISTRATION_TECH_NR}
+ * {@link ImsRegistrationImplBase.ImsRegistrationTech#REGISTRATION_TECH_LTE}
+ * {@link ImsRegistrationImplBase.ImsRegistrationTech#REGISTRATION_TECH_IWLAN}
+ * {@link ImsRegistrationImplBase.ImsRegistrationTech#REGISTRATION_TECH_CROSS_SIM}
+ * {@link ImsRegistrationImplBase.ImsRegistrationTech#REGISTRATION_TECH_NR}
*/
public static final String KEY_CAPABILITY_TYPE_UT_INT_ARRAY =
KEY_PREFIX + "capability_type_ut_int_array";
@@ -5542,10 +5695,10 @@ public class CarrierConfigManager {
* List of different RAT technologies on which Provisioning for SMS (IR.92) is supported.
* @see MmTelFeature.MmTelCapabilities#CAPABILITY_TYPE_SMS
* <p>Possible values are,
- * {@link android.telephony.ims.stub.ImsRegistrationImplBase.ImsRegistrationImplBase.ImsRegistrationTech#REGISTRATION_TECH_LTE}
- * {@link android.telephony.ims.stub.ImsRegistrationImplBase.ImsRegistrationImplBase.ImsRegistrationTech#REGISTRATION_TECH_IWLAN}
- * {@link android.telephony.ims.stub.ImsRegistrationImplBase.ImsRegistrationImplBase.ImsRegistrationTech#REGISTRATION_TECH_CROSS_SIM}
- * {@link android.telephony.ims.stub.ImsRegistrationImplBase.ImsRegistrationImplBase.ImsRegistrationTech#REGISTRATION_TECH_NR}
+ * {@link ImsRegistrationImplBase.ImsRegistrationTech#REGISTRATION_TECH_LTE}
+ * {@link ImsRegistrationImplBase.ImsRegistrationTech#REGISTRATION_TECH_IWLAN}
+ * {@link ImsRegistrationImplBase.ImsRegistrationTech#REGISTRATION_TECH_CROSS_SIM}
+ * {@link ImsRegistrationImplBase.ImsRegistrationTech#REGISTRATION_TECH_NR}
*/
public static final String KEY_CAPABILITY_TYPE_SMS_INT_ARRAY =
KEY_PREFIX + "capability_type_sms_int_array";
@@ -5555,10 +5708,10 @@ public class CarrierConfigManager {
* (section 2.4 of RCC.20) is supported.
* @see MmTelFeature.MmTelCapabilities#CAPABILITY_TYPE_CALL_COMPOSER
* <p>Possible values are,
- * {@link android.telephony.ims.stub.ImsRegistrationImplBase.ImsRegistrationImplBase.ImsRegistrationTech#REGISTRATION_TECH_LTE}
- * {@link android.telephony.ims.stub.ImsRegistrationImplBase.ImsRegistrationImplBase.ImsRegistrationTech#REGISTRATION_TECH_IWLAN}
- * {@link android.telephony.ims.stub.ImsRegistrationImplBase.ImsRegistrationImplBase.ImsRegistrationTech#REGISTRATION_TECH_CROSS_SIM}
- * {@link android.telephony.ims.stub.ImsRegistrationImplBase.ImsRegistrationImplBase.ImsRegistrationTech#REGISTRATION_TECH_NR}
+ * {@link ImsRegistrationImplBase.ImsRegistrationTech#REGISTRATION_TECH_LTE}
+ * {@link ImsRegistrationImplBase.ImsRegistrationTech#REGISTRATION_TECH_IWLAN}
+ * {@link ImsRegistrationImplBase.ImsRegistrationTech#REGISTRATION_TECH_CROSS_SIM}
+ * {@link ImsRegistrationImplBase.ImsRegistrationTech#REGISTRATION_TECH_NR}
*/
public static final String KEY_CAPABILITY_TYPE_CALL_COMPOSER_INT_ARRAY =
KEY_PREFIX + "capability_type_call_composer_int_array";
@@ -5574,7 +5727,7 @@ public class CarrierConfigManager {
* <li>{@link #KEY_CAPABILITY_TYPE_PRESENCE_UCE_INT_ARRAY}</li>
* </ul>
* <p> The values are defined in
- * {@link android.telephony.ims.stub.ImsRegistrationImplBase.ImsRegistrationTech}
+ * {@link ImsRegistrationImplBase.ImsRegistrationTech}
*/
public static final String KEY_RCS_REQUIRES_PROVISIONING_BUNDLE =
KEY_PREFIX + "rcs_requires_provisioning_bundle";
@@ -5585,10 +5738,10 @@ public class CarrierConfigManager {
* If not set, this RcsFeature should not service capability requests.
* @see RcsFeature.RcsImsCapabilities#CAPABILITY_TYPE_OPTIONS_UCE
* <p>Possible values are,
- * {@link android.telephony.ims.stub.ImsRegistrationImplBase.ImsRegistrationImplBase.ImsRegistrationTech#REGISTRATION_TECH_LTE}
- * {@link android.telephony.ims.stub.ImsRegistrationImplBase.ImsRegistrationImplBase.ImsRegistrationTech#REGISTRATION_TECH_IWLAN}
- * {@link android.telephony.ims.stub.ImsRegistrationImplBase.ImsRegistrationImplBase.ImsRegistrationTech#REGISTRATION_TECH_CROSS_SIM}
- * {@link android.telephony.ims.stub.ImsRegistrationImplBase.ImsRegistrationImplBase.ImsRegistrationTech#REGISTRATION_TECH_NR}
+ * {@link ImsRegistrationImplBase.ImsRegistrationTech#REGISTRATION_TECH_LTE}
+ * {@link ImsRegistrationImplBase.ImsRegistrationTech#REGISTRATION_TECH_IWLAN}
+ * {@link ImsRegistrationImplBase.ImsRegistrationTech#REGISTRATION_TECH_CROSS_SIM}
+ * {@link ImsRegistrationImplBase.ImsRegistrationTech#REGISTRATION_TECH_NR}
*/
public static final String KEY_CAPABILITY_TYPE_OPTIONS_UCE_INT_ARRAY =
KEY_PREFIX + "capability_type_options_uce_int_array";
@@ -5600,14 +5753,66 @@ public class CarrierConfigManager {
* requests using presence.
* @see RcsFeature.RcsImsCapabilities#CAPABILITY_TYPE_PRESENCE_UCE
* <p>Possible values are,
- * {@link android.telephony.ims.stub.ImsRegistrationImplBase.ImsRegistrationImplBase.ImsRegistrationTech#REGISTRATION_TECH_LTE}
- * {@link android.telephony.ims.stub.ImsRegistrationImplBase.ImsRegistrationImplBase.ImsRegistrationTech#REGISTRATION_TECH_IWLAN}
- * {@link android.telephony.ims.stub.ImsRegistrationImplBase.ImsRegistrationImplBase.ImsRegistrationTech#REGISTRATION_TECH_CROSS_SIM}
- * {@link android.telephony.ims.stub.ImsRegistrationImplBase.ImsRegistrationImplBase.ImsRegistrationTech#REGISTRATION_TECH_NR}
+ * {@link ImsRegistrationImplBase.ImsRegistrationTech#REGISTRATION_TECH_LTE}
+ * {@link ImsRegistrationImplBase.ImsRegistrationTech#REGISTRATION_TECH_IWLAN}
+ * {@link ImsRegistrationImplBase.ImsRegistrationTech#REGISTRATION_TECH_CROSS_SIM}
+ * {@link ImsRegistrationImplBase.ImsRegistrationTech#REGISTRATION_TECH_NR}
*/
public static final String KEY_CAPABILITY_TYPE_PRESENCE_UCE_INT_ARRAY =
KEY_PREFIX + "capability_type_presence_uce_int_array";
+ /**
+ * Specifies the policy for disabling NR SA mode. Default value is
+ *{@link #SA_DISABLE_POLICY_NONE}.
+ * The value set as below:
+ * <ul>
+ * <li>0: {@link #SA_DISABLE_POLICY_NONE }</li>
+ * <li>1: {@link #SA_DISABLE_POLICY_WFC_ESTABLISHED }</li>
+ * <li>2: {@link #SA_DISABLE_POLICY_WFC_ESTABLISHED_WHEN_VONR_DISABLED }</li>
+ * <li>3: {@link #SA_DISABLE_POLICY_VOWIFI_REGISTERED }</li>
+ * </ul>
+ * @hide
+ */
+ public static final String KEY_NR_SA_DISABLE_POLICY_INT =
+ KEY_PREFIX + "sa_disable_policy_int";
+
+ /** @hide */
+ @IntDef({
+ NR_SA_DISABLE_POLICY_NONE,
+ NR_SA_DISABLE_POLICY_WFC_ESTABLISHED,
+ NR_SA_DISABLE_POLICY_WFC_ESTABLISHED_WHEN_VONR_DISABLED,
+ NR_SA_DISABLE_POLICY_VOWIFI_REGISTERED
+ })
+ public @interface NrSaDisablePolicy {}
+
+ /**
+ * Do not disables NR SA mode.
+ * @hide
+ */
+ public static final int NR_SA_DISABLE_POLICY_NONE = 0;
+
+ /**
+ * Disables NR SA mode when VoWiFi call is established in order to improve the delay or
+ * voice mute when the handover from ePDG to NR is not supported in UE or network.
+ * @hide
+ */
+ public static final int NR_SA_DISABLE_POLICY_WFC_ESTABLISHED = 1;
+
+ /**
+ * Disables NR SA mode when VoWiFi call is established when VoNR is disabled in order to
+ * improve the delay or voice mute when the handover from ePDG to NR is not supported
+ * in UE or network.
+ * @hide
+ */
+ public static final int NR_SA_DISABLE_POLICY_WFC_ESTABLISHED_WHEN_VONR_DISABLED = 2;
+
+ /**
+ * Disables NR SA mode when IMS is registered over WiFi in order to improve the delay or
+ * voice mute when the handover from ePDG to NR is not supported in UE or network.
+ * @hide
+ */
+ public static final int NR_SA_DISABLE_POLICY_VOWIFI_REGISTERED = 3;
+
private Ims() {}
private static PersistableBundle getDefaults() {
@@ -5616,7 +5821,7 @@ public class CarrierConfigManager {
defaults.putBoolean(KEY_IMS_SINGLE_REGISTRATION_REQUIRED_BOOL, false);
defaults.putBoolean(KEY_ENABLE_PRESENCE_PUBLISH_BOOL, false);
defaults.putStringArray(KEY_PUBLISH_SERVICE_DESC_FEATURE_TAG_MAP_OVERRIDE_STRING_ARRAY,
- new String[] {});
+ new String[0]);
defaults.putBoolean(KEY_ENABLE_PRESENCE_CAPABILITY_EXCHANGE_BOOL, false);
defaults.putBoolean(KEY_RCS_BULK_CAPABILITY_EXCHANGE_BOOL, false);
defaults.putBoolean(KEY_ENABLE_PRESENCE_GROUP_SUBSCRIBE_BOOL, false);
@@ -5679,6 +5884,7 @@ public class CarrierConfigManager {
defaults.putInt(KEY_REGISTRATION_RETRY_BASE_TIMER_MILLIS_INT, 30000);
defaults.putInt(KEY_REGISTRATION_RETRY_MAX_TIMER_MILLIS_INT, 1800000);
defaults.putInt(KEY_REGISTRATION_SUBSCRIBE_EXPIRY_TIMER_SEC_INT, 600000);
+ defaults.putInt(KEY_NR_SA_DISABLE_POLICY_INT, NR_SA_DISABLE_POLICY_NONE);
defaults.putIntArray(
KEY_IPSEC_AUTHENTICATION_ALGORITHMS_INT_ARRAY,
@@ -5741,7 +5947,7 @@ public class CarrierConfigManager {
* <p>If {@code false}: hard disabled.
* If {@code true}: then depends on availability, etc.
*/
- public static final String KEY_CARRIER_VOLTE_ROAMING_AVAILABLE_BOOL =
+ public static final String KEY_CARRIER_VOLTE_ROAMING_AVAILABLE_BOOL =
KEY_PREFIX + "carrier_volte_roaming_available_bool";
/**
@@ -5752,7 +5958,7 @@ public class CarrierConfigManager {
* will be sent in the dialed string in the SIP:INVITE.
* If {@code false}, *67 and *82 will be removed.
*/
- public static final String KEY_INCLUDE_CALLER_ID_SERVICE_CODES_IN_SIP_INVITE_BOOL =
+ public static final String KEY_INCLUDE_CALLER_ID_SERVICE_CODES_IN_SIP_INVITE_BOOL =
KEY_PREFIX + "include_caller_id_service_codes_in_sip_invite_bool";
/**
@@ -5796,7 +6002,6 @@ public class CarrierConfigManager {
SESSION_REFRESHER_TYPE_UAC,
SESSION_REFRESHER_TYPE_UAS
})
-
public @interface SessionRefresherType {}
/**
@@ -5838,14 +6043,12 @@ public class CarrierConfigManager {
public static final String KEY_SESSION_REFRESHER_TYPE_INT =
KEY_PREFIX + "session_refresher_type_int";
-
/** @hide */
@IntDef({
SESSION_PRIVACY_TYPE_HEADER,
SESSION_PRIVACY_TYPE_NONE,
SESSION_PRIVACY_TYPE_ID
})
-
public @interface SessionPrivacyType {}
/**
@@ -5883,7 +6086,7 @@ public class CarrierConfigManager {
* If {@code true}, SIP 18x responses (other than SIP 183 response)
* are sent reliably.
*/
- public static final String KEY_PRACK_SUPPORTED_FOR_18X_BOOL =
+ public static final String KEY_PRACK_SUPPORTED_FOR_18X_BOOL =
KEY_PREFIX + "prack_supported_for_18x_bool";
/** @hide */
@@ -5891,7 +6094,6 @@ public class CarrierConfigManager {
CONFERENCE_SUBSCRIBE_TYPE_IN_DIALOG,
CONFERENCE_SUBSCRIBE_TYPE_OUT_OF_DIALOG
})
-
public @interface ConferenceSubscribeType {}
/**
@@ -5912,7 +6114,7 @@ public class CarrierConfigManager {
/**
* This is used to specify whether the SIP SUBSCRIBE to conference state events,
- * is sent in or out of the SIP INVITE dialog between the UE and the
+ * is sent in or out of the SIP INVITE dialog between the UE and the
* conference server.
*
* <p>Reference: IR.92 Section 2.3.3.
@@ -5937,7 +6139,7 @@ public class CarrierConfigManager {
*
* <p>Reference: 3GPP TS 24.229
*/
- public static final String KEY_VOICE_QOS_PRECONDITION_SUPPORTED_BOOL =
+ public static final String KEY_VOICE_QOS_PRECONDITION_SUPPORTED_BOOL =
KEY_PREFIX + "voice_qos_precondition_supported_bool";
/**
@@ -5945,7 +6147,7 @@ public class CarrierConfigManager {
*
* <p>If {@code true}: voice packets can be sent on default bearer. {@code false} otherwise.
*/
- public static final String KEY_VOICE_ON_DEFAULT_BEARER_SUPPORTED_BOOL =
+ public static final String KEY_VOICE_ON_DEFAULT_BEARER_SUPPORTED_BOOL =
KEY_PREFIX + "voice_on_default_bearer_supported_bool";
/**
@@ -5967,7 +6169,6 @@ public class CarrierConfigManager {
PREALERTING_SRVCC_SUPPORT,
MIDCALL_SRVCC_SUPPORT
})
-
public @interface SrvccType {}
/**
@@ -6065,7 +6266,6 @@ public class CarrierConfigManager {
SESSION_REFRESH_METHOD_INVITE,
SESSION_REFRESH_METHOD_UPDATE_PREFERRED
})
-
public @interface SessionRefreshMethod {}
/**
@@ -6100,7 +6300,7 @@ public class CarrierConfigManager {
* determination of the originating party identity in OIP.
* {@code false} otherwise.
*/
- public static final String KEY_OIP_SOURCE_FROM_HEADER_BOOL =
+ public static final String KEY_OIP_SOURCE_FROM_HEADER_BOOL =
KEY_PREFIX + "oip_source_from_header_bool";
/**
@@ -6188,7 +6388,7 @@ public class CarrierConfigManager {
* <p>Payload type is an integer in dynamic payload type range 96-127
* as per RFC RFC 3551 Section 6.
*/
- public static final String KEY_EVS_PAYLOAD_TYPE_INT_ARRAY =
+ public static final String KEY_EVS_PAYLOAD_TYPE_INT_ARRAY =
KEY_PREFIX + "evs_payload_type_int_array";
/**
@@ -6197,7 +6397,7 @@ public class CarrierConfigManager {
* <p>Payload type is an integer in dynamic payload type range 96-127
* as per RFC RFC 3551 Section 6.
*/
- public static final String KEY_AMRWB_PAYLOAD_TYPE_INT_ARRAY =
+ public static final String KEY_AMRWB_PAYLOAD_TYPE_INT_ARRAY =
KEY_PREFIX + "amrwb_payload_type_int_array";
/**
@@ -6206,7 +6406,7 @@ public class CarrierConfigManager {
* <p>Payload type is an integer in dynamic payload type range 96-127
* as per RFC RFC 3551 Section 6.
*/
- public static final String KEY_AMRNB_PAYLOAD_TYPE_INT_ARRAY =
+ public static final String KEY_AMRNB_PAYLOAD_TYPE_INT_ARRAY =
KEY_PREFIX + "amrnb_payload_type_int_array";
/**
@@ -6215,7 +6415,7 @@ public class CarrierConfigManager {
* <p>Payload type is an integer in dynamic payload type range 96-127
* as per RFC RFC 3551 Section 6.
*/
- public static final String KEY_DTMFWB_PAYLOAD_TYPE_INT_ARRAY =
+ public static final String KEY_DTMFWB_PAYLOAD_TYPE_INT_ARRAY =
KEY_PREFIX + "dtmfwb_payload_type_int_array";
/**
@@ -6224,15 +6424,56 @@ public class CarrierConfigManager {
* <p>Payload type is an integer in dynamic payload type range 96-127
* as per RFC RFC 3551 Section 6.
*/
- public static final String KEY_DTMFNB_PAYLOAD_TYPE_INT_ARRAY =
+ public static final String KEY_DTMFNB_PAYLOAD_TYPE_INT_ARRAY =
KEY_PREFIX + "dtmfnb_payload_type_int_array";
+ /**
+ * This indicates the threshold for RTP packet loss rate in percentage. If measured packet
+ * loss rate crosses this, a callback with {@link MediaQualityStatus} will be invoked to
+ * listeners.
+ * See {@link android.telephony.TelephonyCallback.MediaQualityStatusChangedListener}
+ *
+ * <p/>
+ * Valid threshold range : 0 ~ 100
+ *
+ * @hide
+ */
+ public static final String KEY_VOICE_RTP_PACKET_LOSS_RATE_THRESHOLD_INT =
+ KEY_PREFIX + "rtp_packet_loss_rate_threshold_int";
+
+ /**
+ * This indicates the threshold for RTP jitter value in milliseconds (RFC3550). If measured
+ * jitter value crosses this, a callback with {@link MediaQualityStatus} will be invoked
+ * to listeners.
+ * See {@link android.telephony.TelephonyCallback.MediaQualityStatusChangedListener}
+ *
+ * <p/>
+ * Valid threshold range : 0 ~ 10000
+ *
+ * @hide
+ */
+ public static final String KEY_VOICE_RTP_JITTER_THRESHOLD_MILLIS_INT =
+ KEY_PREFIX + "rtp_jitter_threshold_millis_int";
+
+ /**
+ * This indicates the threshold for RTP inactivity time in milliseconds. If measured
+ * inactivity timer crosses this, a callback with {@link MediaQualityStatus} will be invoked
+ * to listeners.
+ * See {@link android.telephony.TelephonyCallback.MediaQualityStatusChangedListener}
+ *
+ * <p/>
+ * Valid threshold range : 0 ~ 60000
+ *
+ * @hide
+ */
+ public static final String KEY_VOICE_RTP_INACTIVITY_TIME_THRESHOLD_MILLIS_LONG =
+ KEY_PREFIX + "rtp_inactivity_time_threshold_millis_long";
+
/** @hide */
@IntDef({
BANDWIDTH_EFFICIENT,
OCTET_ALIGNED
})
-
public @interface AmrPayloadFormat {}
/** AMR NB/WB Payload format is bandwidth-efficient. */
@@ -6253,7 +6494,7 @@ public class CarrierConfigManager {
*
* <p>Reference: RFC 4867 Section 8.1.
*/
- public static final String KEY_AMR_CODEC_ATTRIBUTE_PAYLOAD_FORMAT_INT =
+ public static final String KEY_AMR_CODEC_ATTRIBUTE_PAYLOAD_FORMAT_INT =
KEY_PREFIX + "amr_codec_attribute_payload_format_int";
/**
@@ -6268,7 +6509,7 @@ public class CarrierConfigManager {
* <p>Possible values are subset of,
* [0,1,2,3,4,5,6,7,8] - AMRWB with the modes representing nine speech codec modes
* with bit rates of 6.6, 8.85, 12.65, 14.25, 15.85, 18.25, 19.85, 23.05, 23.85 kbps.
- * [0,1,2,3,4,5,6,7] - AMRNB with the modes representing eight speech codec modes
+ * [0,1,2,3,4,5,6,7] - AMRNB with the modes representing eight speech codec modes
* with bit rates of 4.75, 5.15, 5.90, 6.70, 7.40, 7.95, 10.2, 12.2 kbps.
*
* <p>If value is not specified, then it means device supports all
@@ -6276,7 +6517,7 @@ public class CarrierConfigManager {
*
* <p>Reference: RFC 4867 Section 8.1, 3GPP 26.445 A.3.1
*/
- public static final String KEY_AMR_CODEC_ATTRIBUTE_MODESET_INT_ARRAY =
+ public static final String KEY_AMR_CODEC_ATTRIBUTE_MODESET_INT_ARRAY =
KEY_PREFIX + "amr_codec_attribute_modeset_int_array";
/**
@@ -6326,7 +6567,6 @@ public class CarrierConfigManager {
EVS_OPERATIONAL_MODE_PRIMARY,
EVS_OPERATIONAL_MODE_AMRWB_IO
})
-
public @interface EvsOperationalMode {}
/** Indicates the EVS primary mode. 3GPP 26.445 Section 3.1 */
@@ -6361,7 +6601,6 @@ public class CarrierConfigManager {
EVS_ENCODED_BW_TYPE_WB_SWB,
EVS_ENCODED_BW_TYPE_WB_SWB_FB
})
-
public @interface EvsEncodedBwType {}
/**
@@ -6437,7 +6676,7 @@ public class CarrierConfigManager {
*
* <p>Reference: 3GPP 26.441 Table 1.
*/
- public static final String KEY_EVS_CODEC_ATTRIBUTE_BANDWIDTH_INT =
+ public static final String KEY_EVS_CODEC_ATTRIBUTE_BANDWIDTH_INT =
KEY_PREFIX + "evs_codec_attribute_bandwidth_int";
/** @hide */
@@ -6455,7 +6694,6 @@ public class CarrierConfigManager {
EVS_PRIMARY_MODE_BITRATE_96_0_KBPS,
EVS_PRIMARY_MODE_BITRATE_128_0_KBPS
})
-
public @interface EvsPrimaryModeBitRate {}
/** EVS primary mode with bitrate 5.9 kbps */
@@ -6521,14 +6759,14 @@ public class CarrierConfigManager {
*
* <p>Reference: 3GPP 26.445 Section A.3.1
*/
- public static final String KEY_EVS_CODEC_ATTRIBUTE_BITRATE_INT_ARRAY =
+ public static final String KEY_EVS_CODEC_ATTRIBUTE_BITRATE_INT_ARRAY =
KEY_PREFIX + "evs_codec_attribute_bitrate_int_array";
/**
* Specifies the Channel aware mode (ch-aw-recv) for the receive direction.
* This is applicable for EVS codec.
*
- * <p>Permissible values are -1, 0, 2, 3, 5, and 7.
+ * <p> Permissible values are -1, 0, 2, 3, 5, and 7.
* If this key is not specified, then the behavior is same as value 0
* (channel aware mode disabled).
* <p> If this key is configured, then device is expected to send
@@ -6536,7 +6774,7 @@ public class CarrierConfigManager {
*
* <p>Reference: 3GPP TS 26.445 section 4.4.5, 3GPP 26.445 Section A.3.1
*/
- public static final String KEY_EVS_CODEC_ATTRIBUTE_CH_AW_RECV_INT =
+ public static final String KEY_EVS_CODEC_ATTRIBUTE_CH_AW_RECV_INT =
KEY_PREFIX + "evs_codec_attribute_ch_aw_recv_int";
/**
@@ -6557,7 +6795,7 @@ public class CarrierConfigManager {
*
* <p>Reference: 3GPP 26.445 Section A.3.1.
*/
- public static final String KEY_EVS_CODEC_ATTRIBUTE_HF_ONLY_INT =
+ public static final String KEY_EVS_CODEC_ATTRIBUTE_HF_ONLY_INT =
KEY_PREFIX + "evs_codec_attribute_hf_only_int";
/**
@@ -6573,7 +6811,7 @@ public class CarrierConfigManager {
* will apply.
* <p>Reference: 3GPP TS 26.445 Section A.3.1.
*/
- public static final String KEY_EVS_CODEC_ATTRIBUTE_DTX_BOOL =
+ public static final String KEY_EVS_CODEC_ATTRIBUTE_DTX_BOOL =
KEY_PREFIX + "evs_codec_attribute_dtx_bool";
/**
@@ -6598,7 +6836,7 @@ public class CarrierConfigManager {
*
* <p>Reference: RFC 3551
*/
- public static final String KEY_EVS_CODEC_ATTRIBUTE_CHANNELS_INT =
+ public static final String KEY_EVS_CODEC_ATTRIBUTE_CHANNELS_INT =
KEY_PREFIX + "evs_codec_attribute_channels_int";
/**
@@ -6611,7 +6849,7 @@ public class CarrierConfigManager {
*
* <p>Reference: 3GPP 26.445 Section A.3.1, 3GPP 26.114 Table 6.2a
*/
- public static final String KEY_EVS_CODEC_ATTRIBUTE_CMR_INT =
+ public static final String KEY_EVS_CODEC_ATTRIBUTE_CMR_INT =
KEY_PREFIX + "codec_attribute_cmr_int";
/**
@@ -6625,7 +6863,7 @@ public class CarrierConfigManager {
*
* <p>Reference: RFC 4867 Section 8.1.
*/
- public static final String KEY_CODEC_ATTRIBUTE_MODE_CHANGE_PERIOD_INT =
+ public static final String KEY_CODEC_ATTRIBUTE_MODE_CHANGE_PERIOD_INT =
KEY_PREFIX + "codec_attribute_mode_change_period_int";
/**
@@ -6639,7 +6877,7 @@ public class CarrierConfigManager {
*
* <p>Reference: RFC 4867 Section 8.1.
*/
- public static final String KEY_CODEC_ATTRIBUTE_MODE_CHANGE_CAPABILITY_INT =
+ public static final String KEY_CODEC_ATTRIBUTE_MODE_CHANGE_CAPABILITY_INT =
KEY_PREFIX + "codec_attribute_mode_change_capability_int";
/**
@@ -6647,7 +6885,7 @@ public class CarrierConfigManager {
* This attribute is applicable for EVS codec in AMR-WB IO mode
* and AMR-WB.
*
- * <p>Possible values are 0, 1. If value is 1, then the sender should only
+ * <p>Possible values are 0, 1. If value is 1, then the sender should only
* perform mode changes to the neighboring modes in the active codec mode set.
* If value is 0, then mode changes between any two modes
* in the active codec mode set is allowed.
@@ -6656,7 +6894,7 @@ public class CarrierConfigManager {
*
* <p>Reference: RFC 4867 Section 8.1.
*/
- public static final String KEY_CODEC_ATTRIBUTE_MODE_CHANGE_NEIGHBOR_INT =
+ public static final String KEY_CODEC_ATTRIBUTE_MODE_CHANGE_NEIGHBOR_INT =
KEY_PREFIX + "codec_attribute_mode_change_neighbor_int";
/**
@@ -6713,6 +6951,9 @@ public class CarrierConfigManager {
defaults.putInt(KEY_AUDIO_AS_BANDWIDTH_KBPS_INT, 41);
defaults.putInt(KEY_AUDIO_RS_BANDWIDTH_BPS_INT, 600);
defaults.putInt(KEY_AUDIO_RR_BANDWIDTH_BPS_INT, 2000);
+ defaults.putInt(KEY_VOICE_RTP_PACKET_LOSS_RATE_THRESHOLD_INT, 40);
+ defaults.putInt(KEY_VOICE_RTP_JITTER_THRESHOLD_MILLIS_INT, 120);
+ defaults.putLong(KEY_VOICE_RTP_INACTIVITY_TIME_THRESHOLD_MILLIS_LONG, 5000);
defaults.putIntArray(
KEY_AUDIO_INACTIVITY_CALL_END_REASONS_INT_ARRAY,
@@ -6817,7 +7058,7 @@ public class CarrierConfigManager {
* <p>If {@code true}: SMS over IMS support available.
* {@code false}: otherwise.
*/
- public static final String KEY_SMS_OVER_IMS_SUPPORTED_BOOL =
+ public static final String KEY_SMS_OVER_IMS_SUPPORTED_BOOL =
KEY_PREFIX + "sms_over_ims_supported_bool";
/**
@@ -6827,7 +7068,7 @@ public class CarrierConfigManager {
* <p>If {@code true}: allow SMS CSFB in case of SMS over PS failure.
* {@code false} otherwise.
*/
- public static final String KEY_SMS_CSFB_RETRY_ON_FAILURE_BOOL =
+ public static final String KEY_SMS_CSFB_RETRY_ON_FAILURE_BOOL =
KEY_PREFIX + "sms_csfb_retry_on_failure_bool";
/** @hide */
@@ -6835,7 +7076,6 @@ public class CarrierConfigManager {
SMS_FORMAT_3GPP,
SMS_FORMAT_3GPP2
})
-
public @interface SmsFormat {}
/** SMS format is 3GPP. */
@@ -6868,6 +7108,79 @@ public class CarrierConfigManager {
public static final String KEY_SMS_OVER_IMS_SUPPORTED_RATS_INT_ARRAY =
KEY_PREFIX + "sms_over_ims_supported_rats_int_array";
+ /**
+ * Maximum Retry Count for Failure, If the Retry Count exceeds this value,
+ * it must display to User Interface as sending failed
+ */
+ public static final String KEY_SMS_MAX_RETRY_COUNT_INT =
+ KEY_PREFIX + "sms_max_retry_count_int";
+
+ /**
+ * Maximum Retry Count for SMS over IMS on Failure, If the Retry Count exceeds this value,
+ * and if the retry count is less than {@link #KEY_SMS_MAX_RETRY_COUNT_INT}
+ * sending SMS should fallback to CS
+ */
+ public static final String KEY_SMS_MAX_RETRY_OVER_IMS_COUNT_INT =
+ KEY_PREFIX + "sms_max_retry_over_ims_count_int";
+
+ /**
+ * Delay Timer Value in milliseconds
+ * Retry SMS over IMS after this Timer expires
+ */
+ public static final String KEY_SMS_OVER_IMS_SEND_RETRY_DELAY_MILLIS_INT =
+ KEY_PREFIX + "sms_over_ims_send_retry_delay_millis_int";
+
+ /**
+ * TR1 Timer Value in milliseconds,
+ * Waits for RP-Ack from network for MO SMS.
+ */
+ public static final String KEY_SMS_TR1_TIMER_MILLIS_INT =
+ KEY_PREFIX + "sms_tr1_timer_millis_int";
+
+ /**
+ * TR2 Timer Value in milliseconds,
+ * Waits for RP-Ack from Transfer Layer for MT SMS.
+ */
+ public static final String KEY_SMS_TR2_TIMER_MILLIS_INT =
+ KEY_PREFIX + "sms_tr2_timer_millis_int";
+
+ /**
+ * SMS RP-Cause Values for which SMS should be retried over IMS
+ *
+ * <p>Possible values are,
+ * {@link SmsManager#SMS_RP_CAUSE_UNALLOCATED_NUMBER}
+ * {@link SmsManager#SMS_RP_CAUSE_OPERATOR_DETERMINED_BARRING}
+ * {@link SmsManager#SMS_RP_CAUSE_CALL_BARRING}
+ * {@link SmsManager#SMS_RP_CAUSE_RESERVED}
+ * {@link SmsManager#SMS_RP_CAUSE_SHORT_MESSAGE_TRANSFER_REJECTED}
+ * {@link SmsManager#SMS_RP_CAUSE_DESTINATION_OUT_OF_ORDER}
+ * {@link SmsManager#SMS_RP_CAUSE_UNIDENTIFIED_SUBSCRIBER}
+ * {@link SmsManager#SMS_RP_CAUSE_FACILITY_REJECTED}
+ * {@link SmsManager#SMS_RP_CAUSE_UNKNOWN_SUBSCRIBER}
+ * {@link SmsManager#SMS_RP_CAUSE_NETWORK_OUT_OF_ORDER}
+ * {@link SmsManager#SMS_RP_CAUSE_TEMPORARY_FAILURE}
+ * {@link SmsManager#SMS_RP_CAUSE_CONGESTION}
+ * {@link SmsManager#SMS_RP_CAUSE_RESOURCES_UNAVAILABLE}
+ * {@link SmsManager#SMS_RP_CAUSE_FACILITY_NOT_SUBSCRIBED}
+ * {@link SmsManager#SMS_RP_CAUSE_FACILITY_NOT_IMPLEMENTED}
+ * {@link SmsManager#SMS_RP_CAUSE_INVALID_MESSAGE_REFERENCE_VALUE}
+ * {@link SmsManager#SMS_RP_CAUSE_SEMANTICALLY_INCORRECT_MESSAGE}
+ * {@link SmsManager#SMS_RP_CAUSE_INVALID_MANDATORY_INFORMATION}
+ * {@link SmsManager#SMS_RP_CAUSE_MESSAGE_TYPE_NON_EXISTENT}
+ * {@link SmsManager#SMS_RP_CAUSE_MESSAGE_INCOMPATIBLE_WITH_PROTOCOL_STATE}
+ * {@link SmsManager#SMS_RP_CAUSE_INFORMATION_ELEMENT_NON_EXISTENT}
+ * {@link SmsManager#SMS_RP_CAUSE_PROTOCOL_ERROR}
+ * {@link SmsManager#SMS_RP_CAUSE_INTERWORKING_UNSPECIFIED
+ */
+ public static final String KEY_SMS_RP_CAUSE_VALUES_TO_RETRY_OVER_IMS_INT_ARRAY =
+ KEY_PREFIX + "sms_rp_cause_values_to_retry_over_ims_int_array";
+
+ /**
+ * SMS RP-Cause Values for which Sending SMS should fallback
+ */
+ public static final String KEY_SMS_RP_CAUSE_VALUES_TO_FALLBACK_INT_ARRAY =
+ KEY_PREFIX + "sms_rp_cause_values_to_fallback_int_array";
+
private static PersistableBundle getDefaults() {
PersistableBundle defaults = new PersistableBundle();
defaults.putBoolean(KEY_SMS_OVER_IMS_SUPPORTED_BOOL, true);
@@ -6875,6 +7188,45 @@ public class CarrierConfigManager {
defaults.putInt(KEY_SMS_OVER_IMS_FORMAT_INT, SMS_FORMAT_3GPP);
+ defaults.putInt(KEY_SMS_MAX_RETRY_COUNT_INT, 3);
+ defaults.putInt(KEY_SMS_MAX_RETRY_OVER_IMS_COUNT_INT, 3);
+ defaults.putInt(KEY_SMS_OVER_IMS_SEND_RETRY_DELAY_MILLIS_INT,
+ 2000);
+ defaults.putInt(KEY_SMS_TR1_TIMER_MILLIS_INT, 130000);
+ defaults.putInt(KEY_SMS_TR2_TIMER_MILLIS_INT, 15000);
+
+ defaults.putIntArray(
+ KEY_SMS_RP_CAUSE_VALUES_TO_RETRY_OVER_IMS_INT_ARRAY,
+ new int[] {
+ SmsManager.SMS_RP_CAUSE_TEMPORARY_FAILURE
+ });
+ defaults.putIntArray(
+ KEY_SMS_RP_CAUSE_VALUES_TO_FALLBACK_INT_ARRAY,
+ new int[] {
+ SmsManager.SMS_RP_CAUSE_UNALLOCATED_NUMBER,
+ SmsManager.SMS_RP_CAUSE_OPERATOR_DETERMINED_BARRING,
+ SmsManager.SMS_RP_CAUSE_CALL_BARRING,
+ SmsManager.SMS_RP_CAUSE_RESERVED,
+ SmsManager.SMS_RP_CAUSE_SHORT_MESSAGE_TRANSFER_REJECTED,
+ SmsManager.SMS_RP_CAUSE_DESTINATION_OUT_OF_ORDER,
+ SmsManager.SMS_RP_CAUSE_UNIDENTIFIED_SUBSCRIBER,
+ SmsManager.SMS_RP_CAUSE_FACILITY_REJECTED,
+ SmsManager.SMS_RP_CAUSE_UNKNOWN_SUBSCRIBER,
+ SmsManager.SMS_RP_CAUSE_NETWORK_OUT_OF_ORDER,
+ SmsManager.SMS_RP_CAUSE_CONGESTION,
+ SmsManager.SMS_RP_CAUSE_RESOURCES_UNAVAILABLE,
+ SmsManager.SMS_RP_CAUSE_FACILITY_NOT_SUBSCRIBED,
+ SmsManager.SMS_RP_CAUSE_FACILITY_NOT_IMPLEMENTED,
+ SmsManager.SMS_RP_CAUSE_INVALID_MESSAGE_REFERENCE_VALUE,
+ SmsManager.SMS_RP_CAUSE_SEMANTICALLY_INCORRECT_MESSAGE,
+ SmsManager.SMS_RP_CAUSE_INVALID_MANDATORY_INFORMATION,
+ SmsManager.SMS_RP_CAUSE_MESSAGE_TYPE_NON_EXISTENT,
+ SmsManager.SMS_RP_CAUSE_MESSAGE_INCOMPATIBLE_WITH_PROTOCOL_STATE,
+ SmsManager.SMS_RP_CAUSE_INFORMATION_ELEMENT_NON_EXISTENT,
+ SmsManager.SMS_RP_CAUSE_PROTOCOL_ERROR,
+ SmsManager.SMS_RP_CAUSE_INTERWORKING_UNSPECIFIED
+ });
+
defaults.putIntArray(
KEY_SMS_OVER_IMS_SUPPORTED_RATS_INT_ARRAY,
new int[] {
@@ -6902,7 +7254,7 @@ public class CarrierConfigManager {
* <p>If {@code true}: text media can be sent on default bearer.
* {@code false} otherwise.
*/
- public static final String KEY_TEXT_ON_DEFAULT_BEARER_SUPPORTED_BOOL =
+ public static final String KEY_TEXT_ON_DEFAULT_BEARER_SUPPORTED_BOOL =
KEY_PREFIX + "text_on_default_bearer_supported_bool";
/**
@@ -6912,7 +7264,7 @@ public class CarrierConfigManager {
* {@code false} otherwise.
* <p>Reference: 3GPP TS 24.229
*/
- public static final String KEY_TEXT_QOS_PRECONDITION_SUPPORTED_BOOL =
+ public static final String KEY_TEXT_QOS_PRECONDITION_SUPPORTED_BOOL =
KEY_PREFIX + "text_qos_precondition_supported_bool";
/**
@@ -6962,14 +7314,14 @@ public class CarrierConfigManager {
* <p>Payload type is an integer in dynamic payload type range 96-127
* as per RFC RFC 3551 Section 6.
*/
- public static final String KEY_T140_PAYLOAD_TYPE_INT =
+ public static final String KEY_T140_PAYLOAD_TYPE_INT =
KEY_PREFIX + "t140_payload_type_int";
/** Integer representing payload type for RED/redundancy codec.
* <p>Payload type is an integer in dynamic payload type range 96-127
* as per RFC RFC 3551 Section 6.
*/
- public static final String KEY_RED_PAYLOAD_TYPE_INT =
+ public static final String KEY_RED_PAYLOAD_TYPE_INT =
KEY_PREFIX + "red_payload_type_int";
private static PersistableBundle getDefaults() {
@@ -7018,7 +7370,7 @@ public class CarrierConfigManager {
* <p>If {@code true}: Allow UE to retry emergency call on
* IMS PDN if emergency PDN setup failed.{@code false} otherwise.
*/
- public static final String KEY_RETRY_EMERGENCY_ON_IMS_PDN_BOOL =
+ public static final String KEY_RETRY_EMERGENCY_ON_IMS_PDN_BOOL =
KEY_PREFIX + "retry_emergency_on_ims_pdn_bool";
/**
@@ -7028,7 +7380,7 @@ public class CarrierConfigManager {
* <p>If {@code true}: Enter ECBM mode after E911 call is ended.
* {@code false} otherwise.
*/
- public static final String KEY_EMERGENCY_CALLBACK_MODE_SUPPORTED_BOOL =
+ public static final String KEY_EMERGENCY_CALLBACK_MODE_SUPPORTED_BOOL =
KEY_PREFIX + "emergency_callback_mode_supported_bool";
/**
@@ -7040,7 +7392,7 @@ public class CarrierConfigManager {
*
* <p>Reference: 3GPP TS 24.229
*/
- public static final String KEY_EMERGENCY_QOS_PRECONDITION_SUPPORTED_BOOL =
+ public static final String KEY_EMERGENCY_QOS_PRECONDITION_SUPPORTED_BOOL =
KEY_PREFIX + "emergency_qos_precondition_supported_bool";
/**
@@ -7071,6 +7423,387 @@ public class CarrierConfigManager {
public static final String KEY_REFRESH_GEOLOCATION_TIMEOUT_MILLIS_INT =
KEY_PREFIX + "refresh_geolocation_timeout_millis_int";
+ /**
+ * List of 3GPP access network technologies where e911 over IMS is supported
+ * in the home network and domestic 3rd-party networks. The order in the list represents
+ * the preference. The domain selection service shall scan the network type in the order
+ * of the preference.
+ *
+ * <p>Possible values are,
+ * {@link AccessNetworkConstants.AccessNetworkType#NGRAN}
+ * {@link AccessNetworkConstants.AccessNetworkType#EUTRAN}
+ *
+ * The default value for this key is
+ * {{@link AccessNetworkConstants.AccessNetworkType#EUTRAN},
+ * @hide
+ */
+ public static final String
+ KEY_EMERGENCY_OVER_IMS_SUPPORTED_3GPP_NETWORK_TYPES_INT_ARRAY = KEY_PREFIX
+ + "emergency_over_ims_supported_3gpp_network_types_int_array";
+
+ /**
+ * List of 3GPP access network technologies where e911 over IMS is supported
+ * in the roaming network and non-domestic 3rd-party networks. The order in the list
+ * represents the preference. The domain selection service shall scan the network type
+ * in the order of the preference.
+ *
+ * <p>Possible values are,
+ * {@link AccessNetworkConstants.AccessNetworkType#NGRAN}
+ * {@link AccessNetworkConstants.AccessNetworkType#EUTRAN}
+ *
+ * The default value for this key is
+ * {{@link AccessNetworkConstants.AccessNetworkType#EUTRAN},
+ * @hide
+ */
+ public static final String
+ KEY_EMERGENCY_OVER_IMS_ROAMING_SUPPORTED_3GPP_NETWORK_TYPES_INT_ARRAY = KEY_PREFIX
+ + "emergency_over_ims_roaming_supported_3gpp_network_types_int_array";
+
+ /**
+ * List of CS access network technologies where circuit-switched emergency calls are
+ * supported in the home network and domestic 3rd-party networks. The order in the list
+ * represents the preference. The domain selection service shall scan the network type
+ * in the order of the preference.
+ *
+ * <p>Possible values are,
+ * {@link AccessNetworkConstants.AccessNetworkType#GERAN}
+ * {@link AccessNetworkConstants.AccessNetworkType#UTRAN}
+ * {@link AccessNetworkConstants.AccessNetworkType#CDMA2000}
+ *
+ * The default value for this key is
+ * {{@link AccessNetworkConstants.AccessNetworkType#UTRAN},
+ * {@link AccessNetworkConstants.AccessNetworkType#GERAN}}.
+ * @hide
+ */
+ public static final String KEY_EMERGENCY_OVER_CS_SUPPORTED_ACCESS_NETWORK_TYPES_INT_ARRAY =
+ KEY_PREFIX + "emergency_over_cs_supported_access_network_types_int_array";
+
+ /**
+ * List of CS access network technologies where circuit-switched emergency calls are
+ * supported in the roaming network and non-domestic 3rd-party networks. The order
+ * in the list represents the preference. The domain selection service shall scan
+ * the network type in the order of the preference.
+ *
+ * <p>Possible values are,
+ * {@link AccessNetworkConstants.AccessNetworkType#GERAN}
+ * {@link AccessNetworkConstants.AccessNetworkType#UTRAN}
+ * {@link AccessNetworkConstants.AccessNetworkType#CDMA2000}
+ *
+ * The default value for this key is
+ * {{@link AccessNetworkConstants.AccessNetworkType#UTRAN},
+ * {@link AccessNetworkConstants.AccessNetworkType#GERAN}}.
+ * @hide
+ */
+ public static final String
+ KEY_EMERGENCY_OVER_CS_ROAMING_SUPPORTED_ACCESS_NETWORK_TYPES_INT_ARRAY = KEY_PREFIX
+ + "emergency_over_cs_roaming_supported_access_network_types_int_array";
+
+ /** @hide */
+ @IntDef({
+ DOMAIN_CS,
+ DOMAIN_PS_3GPP,
+ DOMAIN_PS_NON_3GPP
+ })
+ public @interface EmergencyDomain {}
+
+ /**
+ * Circuit switched domain.
+ * @hide
+ */
+ public static final int DOMAIN_CS = 1;
+
+ /**
+ * Packet switched domain over 3GPP networks.
+ * @hide
+ */
+ public static final int DOMAIN_PS_3GPP = 2;
+
+ /**
+ * Packet switched domain over non-3GPP networks such as Wi-Fi.
+ * @hide
+ */
+ public static final int DOMAIN_PS_NON_3GPP = 3;
+
+ /**
+ * Specifies the emergency call domain preference for the home network.
+ * The domain selection service shall choose the domain in the order
+ * for attempting the emergency call
+ *
+ * <p>Possible values are,
+ * {@link #DOMAIN_CS}
+ * {@link #DOMAIN_PS_3GPP}
+ * {@link #DOMAIN_PS_NON_3GPP}.
+ *
+ * The default value for this key is
+ * {{@link #DOMAIN_PS_3GPP},
+ * {@link #DOMAIN_CS},
+ * {@link #DOMAIN_PS_NON_3GPP}}.
+ * @hide
+ */
+ public static final String KEY_EMERGENCY_DOMAIN_PREFERENCE_INT_ARRAY =
+ KEY_PREFIX + "emergency_domain_preference_int_array";
+
+ /**
+ * Specifies the emergency call domain preference for the roaming network.
+ * The domain selection service shall choose the domain in the order
+ * for attempting the emergency call.
+ *
+ * <p>Possible values are,
+ * {@link #DOMAIN_CS}
+ * {@link #DOMAIN_PS_3GPP}
+ * {@link #DOMAIN_PS_NON_3GPP}.
+ *
+ * The default value for this key is
+ * {{@link #DOMAIN_PS_3GPP},
+ * {@link #DOMAIN_CS},
+ * {@link #DOMAIN_PS_NON_3GPP}}.
+ * @hide
+ */
+ public static final String KEY_EMERGENCY_DOMAIN_PREFERENCE_ROAMING_INT_ARRAY =
+ KEY_PREFIX + "emergency_domain_preference_roaming_int_array";
+
+ /**
+ * Specifies if emergency call shall be attempted on IMS, if PS is attached even though IMS
+ * is not registered and normal calls fallback to the CS networks.
+ *
+ * The default value for this key is {@code false}.
+ * @hide
+ */
+ public static final String KEY_PREFER_IMS_EMERGENCY_WHEN_VOICE_CALLS_ON_CS_BOOL =
+ KEY_PREFIX + "prefer_ims_emergency_when_voice_calls_on_cs_bool";
+
+ /** @hide */
+ @IntDef({
+ VOWIFI_REQUIRES_NONE,
+ VOWIFI_REQUIRES_SETTING_ENABLED,
+ VOWIFI_REQUIRES_VALID_EID,
+ })
+ public @interface VoWiFiRequires {}
+
+ /**
+ * Default value.
+ * If {@link ImsWfc#KEY_EMERGENCY_CALL_OVER_EMERGENCY_PDN_BOOL} is {@code true},
+ * VoWi-Fi emergency call shall be attempted if Wi-Fi network is connected.
+ * Otherwise, it shall be attempted if IMS is registered over Wi-Fi.
+ * @hide
+ */
+ public static final int VOWIFI_REQUIRES_NONE = 0;
+
+ /**
+ * VoWi-Fi emergency call shall be attempted on IMS over Wi-Fi if Wi-Fi network is connected
+ * and Wi-Fi calling setting is enabled. This value is applicable if the value of
+ * {@link ImsWfc#KEY_EMERGENCY_CALL_OVER_EMERGENCY_PDN_BOOL} is {@code true}.
+ * @hide
+ */
+ public static final int VOWIFI_REQUIRES_SETTING_ENABLED = 1;
+
+ /**
+ * VoWi-Fi emergency call shall be attempted on IMS over Wi-Fi if Wi-Fi network is connected
+ * and Wi-Fi calling is activated successfully. This value is applicable if the value of
+ * {@link ImsWfc#KEY_EMERGENCY_CALL_OVER_EMERGENCY_PDN_BOOL} is {@code true}.
+ * @hide
+ */
+ public static final int VOWIFI_REQUIRES_VALID_EID = 2;
+
+ /**
+ * Specifies the condition when emergency call shall be attempted on IMS over Wi-Fi.
+ *
+ * The default value for this key is {@code #VOWIFI_REQUIRES_NONE}.
+ * @hide
+ */
+ public static final String KEY_EMERGENCY_VOWIFI_REQUIRES_CONDITION_INT =
+ KEY_PREFIX + "emergency_vowifi_requires_condition_int";
+
+ /**
+ * Specifies maximum number of emergency call retries over Wi-Fi.
+ * This is valid only when {@link #DOMAIN_PS_NON_3GPP} is included in
+ * {@link #KEY_EMERGENCY_DOMAIN_PREFERENCE_INT_ARRAY} or
+ * {@link #KEY_EMERGENCY_DOMAIN_PREFERENCE_ROAMING_INT_ARRAY}.
+ *
+ * The default value for this key is 1.
+ * @hide
+ */
+ public static final String KEY_MAXIMUM_NUMBER_OF_EMERGENCY_TRIES_OVER_VOWIFI_INT =
+ KEY_PREFIX + "maximum_number_of_emergency_tries_over_vowifi_int";
+
+ /**
+ * Emergency scan timer to wait for scan results from radio before attempting the call
+ * over Wi-Fi. On timer expiry, if emergency call on Wi-Fi is allowed and possible,
+ * telephony shall cancel the scan and place the call on Wi-Fi. If emergency call on Wi-Fi
+ * is not possible, then domain seleciton continues to wait for the scan result from the
+ * radio. If an emergency scan result is received before the timer expires, the timer shall
+ * be stopped and no dialing over Wi-Fi will be tried. If this value is set to 0, then
+ * the timer is never started and domain selection waits for the scan result from the radio.
+ *
+ * The default value for the timer is 10 seconds.
+ * @hide
+ */
+ public static final String KEY_EMERGENCY_SCAN_TIMER_SEC_INT =
+ KEY_PREFIX + "emergency_scan_timer_sec_int";
+
+ /**
+ * The timer to wait for the call completion on the cellular network before attempting the
+ * call over Wi-Fi. On timer expiry, if emergency call on Wi-Fi is allowed and possible,
+ * telephony shall cancel the scan on the cellular network and place the call on Wi-Fi.
+ * If dialing over cellular network is ongoing when timer expires, dialing over Wi-Fi
+ * will be requested only when the ongoing dialing fails. If emergency call on Wi-Fi is not
+ * possible, then domain selection continues to try dialing from the radio and the timer
+ * remains expired. Later when calling over Wi-Fi is possible and dialing over cellular
+ * networks fails, calling over Wi-Fi will be requested. The timer shall be restarted from
+ * initial state if calling over Wi-Fi fails.
+ * If this value is set to {@link #REDIAL_TIMER_DISABLED}, then the timer will never be
+ * started.
+ *
+ * The default value for the timer is {@link #REDIAL_TIMER_DISABLED}.
+ * @hide
+ */
+ public static final String KEY_MAXIMUM_CELLULAR_SEARCH_TIMER_SEC_INT =
+ KEY_PREFIX + "maximum_cellular_search_timer_sec_int";
+
+ /** @hide */
+ @IntDef(prefix = "SCAN_TYPE_",
+ value = {
+ SCAN_TYPE_NO_PREFERENCE,
+ SCAN_TYPE_FULL_SERVICE,
+ SCAN_TYPE_FULL_SERVICE_FOLLOWED_BY_LIMITED_SERVICE})
+ public @interface EmergencyScanType {}
+
+ /**
+ * No specific preference given to the modem. Modem can return an emergency
+ * capable network either with limited service or full service.
+ * @hide
+ */
+ public static final int SCAN_TYPE_NO_PREFERENCE = 0;
+
+ /**
+ * Modem will attempt to camp on a network with full service only.
+ * @hide
+ */
+ public static final int SCAN_TYPE_FULL_SERVICE = 1;
+
+ /**
+ * Telephony shall attempt full service scan first.
+ * If a full service network is not found, telephony shall attempt a limited service scan.
+ * @hide
+ */
+ public static final int SCAN_TYPE_FULL_SERVICE_FOLLOWED_BY_LIMITED_SERVICE = 2;
+
+ /**
+ * Specifies the preferred emergency network scanning type.
+ *
+ * <p>Possible values are,
+ * {@link #SCAN_TYPE_NO_PREFERENCE}
+ * {@link #SCAN_TYPE_FULL_SERVICE}
+ * {@link #SCAN_TYPE_FULL_SERVICE_FOLLOWED_BY_LIMITED_SERVICE}
+ *
+ * The default value for this key is {@link #SCAN_TYPE_NO_PREFERENCE}.
+ * @hide
+ */
+ public static final String KEY_EMERGENCY_NETWORK_SCAN_TYPE_INT =
+ KEY_PREFIX + "emergency_network_scan_type_int";
+
+ /**
+ * Specifies the time by which a call should be set up on the current network
+ * once the call is routed on the network. If the call cannot be set up by timer expiry,
+ * call shall be re-dialed on the next available network.
+ * If this value is set to 0, the timer shall be disabled.
+ *
+ * The default value for this key is 0.
+ * @hide
+ */
+ public static final String KEY_EMERGENCY_CALL_SETUP_TIMER_ON_CURRENT_NETWORK_SEC_INT =
+ KEY_PREFIX + "emergency_call_setup_timer_on_current_network_sec_int";
+
+ /**
+ * Specifies if emergency call shall be attempted on IMS only when IMS is registered.
+ * This is applicable only for the case PS is in service.
+ *
+ * The default value for this key is {@code false}.
+ * @hide
+ */
+ public static final String KEY_EMERGENCY_REQUIRES_IMS_REGISTRATION_BOOL =
+ KEY_PREFIX + "emergency_requires_ims_registration_bool";
+
+ /**
+ * Specifies if LTE is preferred when re-scanning networks after the failure of dialing
+ * over NR. If not, CS will be preferred.
+ *
+ * The default value for this key is {@code false}.
+ * @hide
+ */
+ public static final String KEY_EMERGENCY_LTE_PREFERRED_AFTER_NR_FAILED_BOOL =
+ KEY_PREFIX + "emergency_lte_preferred_after_nr_failed_bool";
+
+ /**
+ * Specifies the numbers to be dialed over CDMA network in case of dialing over CS network.
+ *
+ * The default value for this key is an empty string array.
+ * @hide
+ */
+ public static final String KEY_EMERGENCY_CDMA_PREFERRED_NUMBERS_STRING_ARRAY =
+ KEY_PREFIX + "emergency_cdma_preferred_numbers_string_array";
+
+ /**
+ * Specifies if emergency call shall be attempted on IMS over cellular network
+ * only when VoLTE is enabled.
+ *
+ * The default value for this key is {@code false}.
+ * @hide
+ */
+ public static final String KEY_EMERGENCY_REQUIRES_VOLTE_ENABLED_BOOL =
+ KEY_PREFIX + "emergency_requires_volte_enabled_bool";
+
+ /**
+ * This values indicates that the cross SIM redialing timer and maximum celluar search
+ * timer shall be disabled.
+ *
+ * @see #KEY_CROSS_STACK_REDIAL_TIMER_SEC_INT
+ * @see #KEY_QUICK_CROSS_STACK_REDIAL_TIMER_SEC_INT
+ * @see #KEY_MAXIMUM_CELLULAR_SEARCH_TIMER_SEC_INT
+ * @hide
+ */
+ public static final int REDIAL_TIMER_DISABLED = 0;
+
+ /**
+ * A timer to guard the max attempting time on current SIM slot so that modem will not
+ * stuck in current SIM slot for long time. On timer expiry, if emergency call on the
+ * other SIM slot is preferable, telephony shall cancel the emergency call and place the
+ * call on the other SIM slot. If this value is set to {@link #REDIAL_TIMER_DISABLED}, then
+ * the timer will never be started and domain selection continues on the current SIM slot.
+ * This value should be greater than the value of {@link #KEY_EMERGENCY_SCAN_TIMER_SEC_INT}.
+ *
+ * The default value for the timer is 120 seconds.
+ * @hide
+ */
+ public static final String KEY_CROSS_STACK_REDIAL_TIMER_SEC_INT =
+ KEY_PREFIX + "cross_stack_redial_timer_sec_int";
+
+ /**
+ * If emergency calls are only allowed with normal-registered service and UE should get
+ * normal service in a short time with acquired band information, telephony
+ * expects dialing emergency call will be completed in a short time.
+ * If dialing is not completed with in a certain timeout, telephony shall place on
+ * another SIM slot. If this value is set to {@link #REDIAL_TIMER_DISABLED}, then the timer
+ * will never be started and domain selection continues on the current SIM slot.
+ * The timer shall be started for the first trial of each subscription and shall be ignored
+ * in the roaming networks and non-domestic networks.
+ *
+ * The default value for the timer is {@link #REDIAL_TIMER_DISABLED}.
+ * @hide
+ */
+ public static final String KEY_QUICK_CROSS_STACK_REDIAL_TIMER_SEC_INT =
+ KEY_PREFIX + "quick_cross_stack_redial_timer_sec_int";
+
+ /**
+ * Indicates whether the quick cross stack redial timer will be triggered only when
+ * the device is registered to the network.
+ *
+ * The default value is {@code true}.
+ * @hide
+ */
+ public static final String KEY_START_QUICK_CROSS_STACK_REDIAL_TIMER_WHEN_REGISTERED_BOOL =
+ KEY_PREFIX + "start_quick_cross_stack_redial_timer_when_registered_bool";
+
private static PersistableBundle getDefaults() {
PersistableBundle defaults = new PersistableBundle();
defaults.putBoolean(KEY_RETRY_EMERGENCY_ON_IMS_PDN_BOOL, false);
@@ -7087,6 +7820,62 @@ public class CarrierConfigManager {
defaults.putInt(KEY_EMERGENCY_REGISTRATION_TIMER_MILLIS_INT, 10000);
defaults.putInt(KEY_REFRESH_GEOLOCATION_TIMEOUT_MILLIS_INT, 5000);
+ defaults.putIntArray(
+ KEY_EMERGENCY_OVER_IMS_SUPPORTED_3GPP_NETWORK_TYPES_INT_ARRAY,
+ new int[] {
+ AccessNetworkType.EUTRAN,
+ });
+
+ defaults.putIntArray(
+ KEY_EMERGENCY_OVER_IMS_ROAMING_SUPPORTED_3GPP_NETWORK_TYPES_INT_ARRAY,
+ new int[] {
+ AccessNetworkType.EUTRAN,
+ });
+
+ defaults.putIntArray(
+ KEY_EMERGENCY_OVER_CS_SUPPORTED_ACCESS_NETWORK_TYPES_INT_ARRAY,
+ new int[] {
+ AccessNetworkType.UTRAN,
+ AccessNetworkType.GERAN,
+ });
+
+ defaults.putIntArray(
+ KEY_EMERGENCY_OVER_CS_ROAMING_SUPPORTED_ACCESS_NETWORK_TYPES_INT_ARRAY,
+ new int[] {
+ AccessNetworkType.UTRAN,
+ AccessNetworkType.GERAN,
+ });
+
+ defaults.putIntArray(KEY_EMERGENCY_DOMAIN_PREFERENCE_INT_ARRAY,
+ new int[] {
+ DOMAIN_PS_3GPP,
+ DOMAIN_CS,
+ DOMAIN_PS_NON_3GPP
+ });
+ defaults.putIntArray(KEY_EMERGENCY_DOMAIN_PREFERENCE_ROAMING_INT_ARRAY,
+ new int[] {
+ DOMAIN_PS_3GPP,
+ DOMAIN_CS,
+ DOMAIN_PS_NON_3GPP
+ });
+
+ defaults.putBoolean(KEY_PREFER_IMS_EMERGENCY_WHEN_VOICE_CALLS_ON_CS_BOOL, false);
+ defaults.putInt(KEY_EMERGENCY_VOWIFI_REQUIRES_CONDITION_INT, VOWIFI_REQUIRES_NONE);
+ defaults.putInt(KEY_MAXIMUM_NUMBER_OF_EMERGENCY_TRIES_OVER_VOWIFI_INT, 1);
+ defaults.putInt(KEY_EMERGENCY_SCAN_TIMER_SEC_INT, 10);
+ defaults.putInt(KEY_MAXIMUM_CELLULAR_SEARCH_TIMER_SEC_INT, REDIAL_TIMER_DISABLED);
+ defaults.putInt(KEY_EMERGENCY_NETWORK_SCAN_TYPE_INT, SCAN_TYPE_NO_PREFERENCE);
+ defaults.putInt(KEY_EMERGENCY_CALL_SETUP_TIMER_ON_CURRENT_NETWORK_SEC_INT, 0);
+ defaults.putBoolean(KEY_EMERGENCY_REQUIRES_IMS_REGISTRATION_BOOL, false);
+ defaults.putBoolean(KEY_EMERGENCY_LTE_PREFERRED_AFTER_NR_FAILED_BOOL, false);
+ defaults.putBoolean(KEY_EMERGENCY_REQUIRES_VOLTE_ENABLED_BOOL, false);
+ defaults.putStringArray(KEY_EMERGENCY_CDMA_PREFERRED_NUMBERS_STRING_ARRAY,
+ new String[0]);
+ defaults.putInt(KEY_CROSS_STACK_REDIAL_TIMER_SEC_INT, 120);
+ defaults.putInt(KEY_QUICK_CROSS_STACK_REDIAL_TIMER_SEC_INT, REDIAL_TIMER_DISABLED);
+ defaults.putBoolean(KEY_START_QUICK_CROSS_STACK_REDIAL_TIMER_WHEN_REGISTERED_BOOL,
+ true);
+
return defaults;
}
}
@@ -7106,7 +7895,7 @@ public class CarrierConfigManager {
* <p>If {@code true}: video media can be sent on default bearer.
* {@code false} otherwise.
*/
- public static final String KEY_VIDEO_ON_DEFAULT_BEARER_SUPPORTED_BOOL =
+ public static final String KEY_VIDEO_ON_DEFAULT_BEARER_SUPPORTED_BOOL =
KEY_PREFIX + "video_on_default_bearer_supported_bool";
/**
@@ -7172,7 +7961,7 @@ public class CarrierConfigManager {
* {@code false} otherwise.
* <p>Reference: 3GPP TS 24.229
*/
- public static final String KEY_VIDEO_QOS_PRECONDITION_SUPPORTED_BOOL =
+ public static final String KEY_VIDEO_QOS_PRECONDITION_SUPPORTED_BOOL =
KEY_PREFIX + "video_qos_precondition_supported_bool";
/**
@@ -7197,7 +7986,7 @@ public class CarrierConfigManager {
* <p>Payload type is an integer in dynamic payload type range 96-127
* as per RFC RFC 3551 Section 6.
*/
- public static final String KEY_H264_PAYLOAD_TYPE_INT_ARRAY =
+ public static final String KEY_H264_PAYLOAD_TYPE_INT_ARRAY =
KEY_PREFIX + "h264_payload_type_int_array";
/**
@@ -7239,7 +8028,7 @@ public class CarrierConfigManager {
*
* <p>Reference: RFC 6184 Section 5.4
*/
- public static final String KEY_VIDEO_CODEC_ATTRIBUTE_PACKETIZATION_MODE_INT =
+ public static final String KEY_VIDEO_CODEC_ATTRIBUTE_PACKETIZATION_MODE_INT =
KEY_PREFIX + "video_codec_attribute_packetization_mode_int";
/**
@@ -7253,7 +8042,7 @@ public class CarrierConfigManager {
* <UL>
* <p>Reference: RFC 4566 Section 6, 3GPP 26.114 Section 6.2.3.2
*/
- public static final String KEY_VIDEO_CODEC_ATTRIBUTE_FRAME_RATE_INT =
+ public static final String KEY_VIDEO_CODEC_ATTRIBUTE_FRAME_RATE_INT =
KEY_PREFIX + "video_codec_attribute_frame_rate_int";
/**
@@ -7272,7 +8061,7 @@ public class CarrierConfigManager {
* <p>Reference: RFC 4566 Section 6, 3GPP 26.114 Section 6.2.3.2
*
*/
- public static final String KEY_VIDEO_CODEC_ATTRIBUTE_RESOLUTION_INT_ARRAY =
+ public static final String KEY_VIDEO_CODEC_ATTRIBUTE_RESOLUTION_INT_ARRAY =
KEY_PREFIX + "video_codec_attribute_resolution_int_array";
/**
@@ -7285,7 +8074,7 @@ public class CarrierConfigManager {
*
* <p>Reference: RFC 6184 Section 8.1, ITU-T Recommendation H.264
*/
- public static final String KEY_H264_VIDEO_CODEC_ATTRIBUTE_PROFILE_LEVEL_ID_STRING =
+ public static final String KEY_H264_VIDEO_CODEC_ATTRIBUTE_PROFILE_LEVEL_ID_STRING =
KEY_PREFIX + "h264_video_codec_attribute_profile_level_id_string";
private static PersistableBundle getDefaults() {
@@ -7353,7 +8142,7 @@ public class CarrierConfigManager {
* List of MDNs for which Geo-location PIDF XML with country info
* needs to included for normal calls involving short code.
*/
- public static final String KEY_PIDF_SHORT_CODE_STRING_ARRAY =
+ public static final String KEY_PIDF_SHORT_CODE_STRING_ARRAY =
KEY_PREFIX + "pidf_short_code_string_array";
/**
@@ -7363,15 +8152,14 @@ public class CarrierConfigManager {
* <p>If {@code false}: E911 call uses IMS PDN for E911 call over VoWiFi.
* If {@code true}: E911 call uses Emergency PDN for E911 call over VoWiFi.
*/
- public static final String KEY_EMERGENCY_CALL_OVER_EMERGENCY_PDN_BOOL =
+ public static final String KEY_EMERGENCY_CALL_OVER_EMERGENCY_PDN_BOOL =
KEY_PREFIX + "emergency_call_over_emergency_pdn_bool";
-
private static PersistableBundle getDefaults() {
PersistableBundle defaults = new PersistableBundle();
defaults.putBoolean(KEY_EMERGENCY_CALL_OVER_EMERGENCY_PDN_BOOL, false);
- defaults.putStringArray(KEY_PIDF_SHORT_CODE_STRING_ARRAY, new String[] {});
+ defaults.putStringArray(KEY_PIDF_SHORT_CODE_STRING_ARRAY, new String[0]);
return defaults;
}
@@ -7418,7 +8206,7 @@ public class CarrierConfigManager {
* If XCAP over UT fails, return error.
* if {@code true}, Use CSFB if XCAP over UT fails.
*/
- public static final String KEY_USE_CSFB_ON_XCAP_OVER_UT_FAILURE_BOOL =
+ public static final String KEY_USE_CSFB_ON_XCAP_OVER_UT_FAILURE_BOOL =
KEY_PREFIX + "use_csfb_on_xcap_over_ut_failure_bool";
/**
@@ -7430,7 +8218,7 @@ public class CarrierConfigManager {
*
* Reference: IR.92 Section 5.5.1
*/
- public static final String KEY_UT_SUPPORTED_WHEN_PS_DATA_OFF_BOOL =
+ public static final String KEY_UT_SUPPORTED_WHEN_PS_DATA_OFF_BOOL =
KEY_PREFIX + "ut_supported_when_ps_data_off_bool";
/**
@@ -7440,7 +8228,7 @@ public class CarrierConfigManager {
* <p>If {@code true}: Support Available.{@code false}: Otherwise.
* Reference: 3GPP 24.390.
*/
- public static final String KEY_NETWORK_INITIATED_USSD_OVER_IMS_SUPPORTED_BOOL =
+ public static final String KEY_NETWORK_INITIATED_USSD_OVER_IMS_SUPPORTED_BOOL =
KEY_PREFIX + "network_initiated_ussd_over_ims_supported_bool";
/**
@@ -7524,7 +8312,6 @@ public class CarrierConfigManager {
SUPPLEMENTARY_SERVICE_CB_ACR,
SUPPLEMENTARY_SERVICE_CB_BIL
})
-
public @interface SsType {}
/** Communication Waiting (CW) support as per 3GPP 24.615. */
@@ -7755,6 +8542,99 @@ public class CarrierConfigManager {
public static final String KEY_XCAP_OVER_UT_SUPPORTED_RATS_INT_ARRAY =
KEY_PREFIX + "xcap_over_ut_supported_rats_int_array";
+ /** @hide */
+ @IntDef({
+ CALL_WAITING_SYNC_NONE,
+ CALL_WAITING_SYNC_USER_CHANGE,
+ CALL_WAITING_SYNC_FIRST_POWER_UP,
+ CALL_WAITING_SYNC_FIRST_CHANGE,
+ CALL_WAITING_SYNC_IMS_ONLY
+ })
+ public @interface CwSyncType {}
+
+ /**
+ * Do not synchronize the user's call waiting setting with the network. Call waiting is
+ * always enabled on the carrier network and the user setting for call waiting is applied
+ * on the terminal side. If the user disables call waiting, the call will be rejected on
+ * the terminal.
+ */
+ public static final int CALL_WAITING_SYNC_NONE = 0;
+
+ /**
+ * The change of user’s setting is always passed to the carrier network
+ * and then synchronized to the terminal based call waiting solution over IMS.
+ * If changing the service over the carrier network is not successful,
+ * the setting over IMS shall not be changed.
+ */
+ public static final int CALL_WAITING_SYNC_USER_CHANGE = 1;
+
+ /**
+ * Activate call waiting on the carrier network when the device boots or a subscription
+ * using this carrier is loaded. Call waiting is always considered enabled on the carrier
+ * network and the user setting for call waiting is applied on the terminal side only. If
+ * the user disables call waiting, the call will be rejected on the terminal.
+ * The mismatch between CS calls and IMS calls can happen when the network based call
+ * waiting service is in disabled state in the legacy 3G/2G networks while it's enabled
+ * in the terminal side.
+ */
+ public static final int CALL_WAITING_SYNC_FIRST_POWER_UP = 2;
+
+ /**
+ * Activate call waiting on the carrier network when the user enables call waiting the
+ * first time. Call waiting is then always considered enabled on the carrier network. If
+ * the user disables call waiting, the setting will only be applied to the terminal based
+ * call waiting service and the call will be rejected on the terminal.
+ * The mismatch between CS calls and IMS calls can happen when the network based call
+ * waiting service is in disabled state in the legacy 3G/2G networks while it's enabled
+ * in the terminal side. However, if the user retrieves the setting again when the device
+ * is in the legacy 3G/2G networks, the correct state will be shown to the user.
+ */
+ public static final int CALL_WAITING_SYNC_FIRST_CHANGE = 3;
+
+ /**
+ * Do not synchronize the call waiting service state between the carrier network and
+ * the terminal based IMS call waiting service. If the user changes the call waiting setting
+ * when IMS is registered, the change will only be applied to the terminal based call
+ * waiting service. If IMS is not registered when call waiting is changed, synchronize this
+ * setting with the carrier network.
+ */
+ public static final int CALL_WAITING_SYNC_IMS_ONLY = 4;
+
+ /** @hide */
+ public static final int CALL_WAITING_SYNC_MAX = CALL_WAITING_SYNC_IMS_ONLY;
+
+ /**
+ * Flag indicating the way to synchronize the setting between CS and IMS.
+ *
+ * <p>Possible values are,
+ * {@link #CALL_WAITING_SYNC_NONE},
+ * {@link #CALL_WAITING_SYNC_USER_CHANGE},
+ * {@link #CALL_WAITING_SYNC_FIRST_POWER_UP},
+ * {@link #CALL_WAITING_SYNC_FIRST_CHANGE},
+ * {@link #CALL_WAITING_SYNC_IMS_ONLY}.
+ *
+ * This configuration is valid only when
+ * {@link #KEY_UT_TERMINAL_BASED_SERVICES_INT_ARRAY} includes
+ * {@link #SUPPLEMENTARY_SERVICE_CW}.
+ *
+ * <p>If key is invalid or not configured, the default value
+ * {@link #CALL_WAITING_SYNC_FIRST_CHANGE} will apply.
+ */
+ public static final String KEY_TERMINAL_BASED_CALL_WAITING_SYNC_TYPE_INT =
+ KEY_PREFIX + "terminal_based_call_waiting_sync_type_int";
+
+ /**
+ * Flag indicating whether the user setting for terminal-based call waiting
+ * is enabled by default or not.
+ * This configuration is valid only when
+ * {@link #KEY_UT_TERMINAL_BASED_SERVICES_INT_ARRAY} includes
+ * {@link #SUPPLEMENTARY_SERVICE_CW}.
+ *
+ * The default value for this key is {@code true}.
+ */
+ public static final String KEY_TERMINAL_BASED_CALL_WAITING_DEFAULT_ENABLED_BOOL =
+ KEY_PREFIX + "terminal_based_call_waiting_default_enabled_bool";
+
private static PersistableBundle getDefaults() {
PersistableBundle defaults = new PersistableBundle();
defaults.putBoolean(KEY_UT_REQUIRES_IMS_REGISTRATION_BOOL, false);
@@ -7794,17 +8674,19 @@ public class CarrierConfigManager {
SUPPLEMENTARY_SERVICE_CB_ACR,
SUPPLEMENTARY_SERVICE_CB_BIL
});
- defaults.putIntArray(
- KEY_UT_TERMINAL_BASED_SERVICES_INT_ARRAY,
- new int[] {});
+ defaults.putIntArray(KEY_UT_TERMINAL_BASED_SERVICES_INT_ARRAY, new int[0]);
defaults.putIntArray(
KEY_XCAP_OVER_UT_SUPPORTED_RATS_INT_ARRAY,
new int[] {
AccessNetworkType.EUTRAN,
- AccessNetworkType.IWLAN
+ AccessNetworkType.IWLAN,
+ AccessNetworkType.NGRAN
});
defaults.putString(KEY_UT_AS_SERVER_FQDN_STRING, "");
+ defaults.putBoolean(KEY_TERMINAL_BASED_CALL_WAITING_DEFAULT_ENABLED_BOOL, true);
+ defaults.putInt(KEY_TERMINAL_BASED_CALL_WAITING_SYNC_TYPE_INT,
+ CALL_WAITING_SYNC_FIRST_CHANGE);
return defaults;
}
@@ -7986,7 +8868,6 @@ public class CarrierConfigManager {
public static final String KEY_IKE_SESSION_AES_CBC_KEY_SIZE_INT_ARRAY =
KEY_PREFIX + "ike_session_encryption_aes_cbc_key_size_int_array";
-
/**
* List of supported key sizes for AES Counter (CTR) encryption mode of IKE session.
* Possible values -
@@ -8121,7 +9002,7 @@ public class CarrierConfigManager {
public static final int EPDG_ADDRESS_PCO = 2;
/** Use cellular location to chose epdg server */
public static final int EPDG_ADDRESS_CELLULAR_LOC = 3;
- /* Use Visited Country FQDN rule*/
+ /** Use Visited Country FQDN rule*/
public static final int EPDG_ADDRESS_VISITED_COUNTRY = 4;
/** @hide */
@@ -8295,7 +9176,7 @@ public class CarrierConfigManager {
EPDG_PLMN_RPLMN,
EPDG_PLMN_HPLMN,
EPDG_PLMN_EHPLMN_ALL});
- defaults.putStringArray(KEY_MCC_MNCS_STRING_ARRAY, new String[] {});
+ defaults.putStringArray(KEY_MCC_MNCS_STRING_ARRAY, new String[0]);
defaults.putInt(KEY_IKE_LOCAL_ID_TYPE_INT, ID_TYPE_RFC822_ADDR);
defaults.putInt(KEY_IKE_REMOTE_ID_TYPE_INT, ID_TYPE_FQDN);
defaults.putBoolean(KEY_ADD_KE_TO_CHILD_SESSION_REKEY_BOOL, false);
@@ -8318,8 +9199,17 @@ public class CarrierConfigManager {
* level outside these boundaries is considered invalid.
* @hide
*/
- public static final String KEY_GSM_RSSI_THRESHOLDS_INT_ARRAY =
- "gsm_rssi_thresholds_int_array";
+ public static final String KEY_GSM_RSSI_THRESHOLDS_INT_ARRAY = "gsm_rssi_thresholds_int_array";
+
+ /**
+ * An interval in dB for {@link SignalThresholdInfo#SIGNAL_MEASUREMENT_TYPE_RSSI} measurement
+ * type defining the required magnitude change between reports.
+ *
+ * <p>The default value is 2 and the minimum allowed value is 0. If no value or negative value
+ * is set, the default value 2 is used.
+ * @hide
+ */
+ public static final String KEY_GERAN_RSSI_HYSTERESIS_DB_INT = "geran_rssi_hysteresis_db_int";
/**
* Determines whether Wireless Priority Service call is supported over IMS.
@@ -8327,8 +9217,7 @@ public class CarrierConfigManager {
* See Wireless Priority Service from https://www.fcc.gov/general/wireless-priority-service-wps
* @hide
*/
- public static final String KEY_SUPPORT_WPS_OVER_IMS_BOOL =
- "support_wps_over_ims_bool";
+ public static final String KEY_SUPPORT_WPS_OVER_IMS_BOOL = "support_wps_over_ims_bool";
/**
* The two digital number pattern of MMI code which is defined by carrier.
@@ -8377,8 +9266,7 @@ public class CarrierConfigManager {
* When true, forwarded number is shown.
* When false, forwarded number is not shown.
*/
- public static final String KEY_SHOW_FORWARDED_NUMBER_BOOL =
- "show_forwarded_number_bool";
+ public static final String KEY_SHOW_FORWARDED_NUMBER_BOOL = "show_forwarded_number_bool";
/**
* The list of originating address of missed incoming call SMS. If the SMS has originator
@@ -8390,7 +9278,6 @@ public class CarrierConfigManager {
public static final String KEY_MISSED_INCOMING_CALL_SMS_ORIGINATOR_STRING_ARRAY =
"missed_incoming_call_sms_originator_string_array";
-
/**
* String array of Apn Type configurations.
* The entries should be of form "APN_TYPE_NAME:priority".
@@ -8538,8 +9425,7 @@ public class CarrierConfigManager {
*
* @hide
*/
- public static final String KEY_DEFAULT_RTT_MODE_INT =
- "default_rtt_mode_int";
+ public static final String KEY_DEFAULT_RTT_MODE_INT = "default_rtt_mode_int";
/**
* Indicates whether RTT is supported while roaming.
@@ -8565,10 +9451,9 @@ public class CarrierConfigManager {
* seamlessly after an unattended reboot.
*
* The device configuration value {@code config_allow_pin_storage_for_unattended_reboot}
- * ultimately controls whether this carrier configuration option is used. Where
- * {@code config_allow_pin_storage_for_unattended_reboot} is false, the value of the
- * {@link #KEY_STORE_SIM_PIN_FOR_UNATTENDED_REBOOT_BOOL} carrier configuration option is
- * ignored.
+ * ultimately controls whether this carrier configuration option is used. Where
+ * {@code config_allow_pin_storage_for_unattended_reboot} is false, the value of this
+ * carrier configuration is ignored.
*
* @hide
*/
@@ -8670,7 +9555,6 @@ public class CarrierConfigManager {
*
* Enabled by default.
*
- * @hide
*/
public static final String KEY_VONR_ON_BY_DEFAULT_BOOL = "vonr_on_by_default_bool";
@@ -8683,6 +9567,134 @@ public class CarrierConfigManager {
"unthrottle_data_retry_when_tac_changes_bool";
/**
+ * A list of premium capabilities the carrier supports. Applications can prompt users to
+ * purchase these premium capabilities from their carrier for a performance boost.
+ * Valid values are any of {@link TelephonyManager.PremiumCapability}.
+ *
+ * This is empty by default, indicating that no premium capabilities are supported.
+ *
+ * @see TelephonyManager#isPremiumCapabilityAvailableForPurchase(int)
+ * @see TelephonyManager#purchasePremiumCapability(int, Executor, Consumer)
+ */
+ public static final String KEY_SUPPORTED_PREMIUM_CAPABILITIES_INT_ARRAY =
+ "supported_premium_capabilities_int_array";
+
+ /**
+ * The amount of time in milliseconds the notification for a performance boost via
+ * premium capabilities will be visible to the user after
+ * {@link TelephonyManager#purchasePremiumCapability(int, Executor, Consumer)}
+ * requests user action to purchase the boost from the carrier. Once the timeout expires,
+ * the performance boost notification will be automatically dismissed and the request will fail
+ * with {@link TelephonyManager#PURCHASE_PREMIUM_CAPABILITY_RESULT_TIMEOUT}.
+ *
+ * The default value is 30 minutes.
+ */
+ public static final String KEY_PREMIUM_CAPABILITY_NOTIFICATION_DISPLAY_TIMEOUT_MILLIS_LONG =
+ "premium_capability_notification_display_timeout_millis_long";
+
+ /**
+ * The amount of time in milliseconds that the notification for a performance boost via
+ * premium capabilities should be blocked when
+ * {@link TelephonyManager#purchasePremiumCapability(int, Executor, Consumer)}
+ * returns a failure due to user action or timeout.
+ * The maximum number of performance boost notifications to show the user are defined in
+ * {@link #KEY_PREMIUM_CAPABILITY_MAXIMUM_DAILY_NOTIFICATION_COUNT_INT} and
+ * {@link #KEY_PREMIUM_CAPABILITY_MAXIMUM_MONTHLY_NOTIFICATION_COUNT_INT}.
+ *
+ * The default value is 30 minutes.
+ *
+ * @see TelephonyManager#PURCHASE_PREMIUM_CAPABILITY_RESULT_USER_CANCELED
+ * @see TelephonyManager#PURCHASE_PREMIUM_CAPABILITY_RESULT_TIMEOUT
+ */
+ public static final String
+ KEY_PREMIUM_CAPABILITY_NOTIFICATION_BACKOFF_HYSTERESIS_TIME_MILLIS_LONG =
+ "premium_capability_notification_backoff_hysteresis_time_millis_long";
+
+ /**
+ * The maximum number of times in a day that we display the notification for a performance boost
+ * via premium capabilities when
+ * {@link TelephonyManager#purchasePremiumCapability(int, Executor, Consumer)}
+ * returns a failure due to user action or timeout.
+ *
+ * The default value is 2 times.
+ *
+ * @see TelephonyManager#PURCHASE_PREMIUM_CAPABILITY_RESULT_USER_CANCELED
+ * @see TelephonyManager#PURCHASE_PREMIUM_CAPABILITY_RESULT_TIMEOUT
+ */
+ public static final String KEY_PREMIUM_CAPABILITY_MAXIMUM_DAILY_NOTIFICATION_COUNT_INT =
+ "premium_capability_maximum_daily_notification_count_int";
+
+ /**
+ * The maximum number of times in a month that we display the notification for a performance
+ * boost via premium capabilities when
+ * {@link TelephonyManager#purchasePremiumCapability(int, Executor, Consumer)}
+ * returns a failure due to user action or timeout.
+ *
+ * The default value is 10 times.
+ *
+ * @see TelephonyManager#PURCHASE_PREMIUM_CAPABILITY_RESULT_USER_CANCELED
+ * @see TelephonyManager#PURCHASE_PREMIUM_CAPABILITY_RESULT_TIMEOUT
+ */
+ public static final String KEY_PREMIUM_CAPABILITY_MAXIMUM_MONTHLY_NOTIFICATION_COUNT_INT =
+ "premium_capability_maximum_monthly_notification_count_int";
+
+ /**
+ * The amount of time in milliseconds that the purchase request should be throttled when
+ * {@link TelephonyManager#purchasePremiumCapability(int, Executor, Consumer)}
+ * returns a failure due to the carrier.
+ *
+ * The default value is 30 minutes.
+ *
+ * @see TelephonyManager#PURCHASE_PREMIUM_CAPABILITY_RESULT_CARRIER_ERROR
+ * @see TelephonyManager#PURCHASE_PREMIUM_CAPABILITY_RESULT_ENTITLEMENT_CHECK_FAILED
+ */
+ public static final String
+ KEY_PREMIUM_CAPABILITY_PURCHASE_CONDITION_BACKOFF_HYSTERESIS_TIME_MILLIS_LONG =
+ "premium_capability_purchase_condition_backoff_hysteresis_time_millis_long";
+
+ /**
+ * The amount of time in milliseconds within which the network must set up a slicing
+ * configuration for the premium capability after
+ * {@link TelephonyManager#purchasePremiumCapability(int, Executor, Consumer)}
+ * returns {@link TelephonyManager#PURCHASE_PREMIUM_CAPABILITY_RESULT_SUCCESS}.
+ * During the setup time, calls to
+ * {@link TelephonyManager#purchasePremiumCapability(int, Executor, Consumer)} will return
+ * {@link TelephonyManager#PURCHASE_PREMIUM_CAPABILITY_RESULT_PENDING_NETWORK_SETUP}.
+ * If the network fails to set up a slicing configuration for the premium capability within the
+ * setup time, subsequent purchase requests will be allowed to go through again.
+ *
+ * The default value is 5 minutes.
+ */
+ public static final String KEY_PREMIUM_CAPABILITY_NETWORK_SETUP_TIME_MILLIS_LONG =
+ "premium_capability_network_setup_time_millis_long";
+
+ /**
+ * The URL to redirect to when the user clicks on the notification for a performance boost via
+ * premium capabilities after applications call
+ * {@link TelephonyManager#purchasePremiumCapability(int, Executor, Consumer)}.
+ * If the URL is empty or invalid, the purchase request will return
+ * {@link TelephonyManager#PURCHASE_PREMIUM_CAPABILITY_RESULT_FEATURE_NOT_SUPPORTED}.
+ *
+ * This is empty by default.
+ */
+ public static final String KEY_PREMIUM_CAPABILITY_PURCHASE_URL_STRING =
+ "premium_capability_purchase_url_string";
+
+ /**
+ * Whether to allow premium capabilities to be purchased when the device is connected to LTE.
+ * If this is {@code true}, applications can call
+ * {@link TelephonyManager#purchasePremiumCapability(int, Executor, Consumer)}
+ * when connected to {@link TelephonyManager#NETWORK_TYPE_LTE} to purchase and use
+ * premium capabilities.
+ * If this is {@code false}, applications can only purchase and use premium capabilities when
+ * connected to {@link TelephonyManager#NETWORK_TYPE_NR}.
+ *
+ * This is {@code false} by default.
+ */
+ public static final String KEY_PREMIUM_CAPABILITY_SUPPORTED_ON_LTE_BOOL =
+ "premium_capability_supported_on_lte_bool";
+
+ /**
* IWLAN handover rules that determine whether handover is allowed or disallowed between
* cellular and IWLAN.
*
@@ -8705,7 +9717,7 @@ public class CarrierConfigManager {
* or EIMS-->
* <item value="source=EUTRAN, target=IWLAN, type=disallowed, capabilities=IMS|EIMS"/>
* <!-- Handover is always allowed in any condition. -->
- * <item value="source=GERAN|UTRAN|EUTRAN|NGRAN|IWLAN,
+ * <item value="source=GERAN|UTRAN|EUTRAN|NGRAN|IWLAN|UNKNOWN,
* target=GERAN|UTRAN|EUTRAN|NGRAN|IWLAN, type=allowed"/>
* </string-array>
*
@@ -8719,7 +9731,7 @@ public class CarrierConfigManager {
"iwlan_handover_policy_string_array";
/** The default value for every variable. */
- private final static PersistableBundle sDefaults;
+ private static final PersistableBundle sDefaults;
static {
sDefaults = new PersistableBundle();
@@ -8829,17 +9841,17 @@ public class CarrierConfigManager {
sDefaults.putBoolean(KEY_REQUIRE_ENTITLEMENT_CHECKS_BOOL, true);
sDefaults.putBoolean(KEY_CARRIER_SUPPORTS_TETHERING_BOOL, true);
sDefaults.putBoolean(KEY_RESTART_RADIO_ON_PDP_FAIL_REGULAR_DEACTIVATION_BOOL, false);
- sDefaults.putIntArray(KEY_RADIO_RESTART_FAILURE_CAUSES_INT_ARRAY, new int[]{});
+ sDefaults.putIntArray(KEY_RADIO_RESTART_FAILURE_CAUSES_INT_ARRAY, new int[0]);
sDefaults.putInt(KEY_VOLTE_REPLACEMENT_RAT_INT, 0);
sDefaults.putString(KEY_DEFAULT_SIM_CALL_MANAGER_STRING, "");
sDefaults.putString(KEY_VVM_DESTINATION_NUMBER_STRING, "");
sDefaults.putInt(KEY_VVM_PORT_NUMBER_INT, 0);
sDefaults.putString(KEY_VVM_TYPE_STRING, "");
sDefaults.putBoolean(KEY_VVM_CELLULAR_DATA_REQUIRED_BOOL, false);
- sDefaults.putString(KEY_VVM_CLIENT_PREFIX_STRING,"//VVM");
- sDefaults.putBoolean(KEY_VVM_SSL_ENABLED_BOOL,false);
+ sDefaults.putString(KEY_VVM_CLIENT_PREFIX_STRING, "//VVM");
+ sDefaults.putBoolean(KEY_VVM_SSL_ENABLED_BOOL, false);
sDefaults.putStringArray(KEY_VVM_DISABLED_CAPABILITIES_STRING_ARRAY, null);
- sDefaults.putBoolean(KEY_VVM_LEGACY_MODE_ENABLED_BOOL,false);
+ sDefaults.putBoolean(KEY_VVM_LEGACY_MODE_ENABLED_BOOL, false);
sDefaults.putBoolean(KEY_VVM_PREFETCH_BOOL, true);
sDefaults.putString(KEY_CARRIER_VVM_PACKAGE_NAME_STRING, "");
sDefaults.putStringArray(KEY_CARRIER_VVM_PACKAGE_NAME_STRING_ARRAY, null);
@@ -8996,7 +10008,6 @@ public class CarrierConfigManager {
sDefaults.putStringArray(KEY_CARRIER_APP_NO_WAKE_SIGNAL_CONFIG_STRING_ARRAY, null);
sDefaults.putBoolean(KEY_CARRIER_APP_REQUIRED_DURING_SIM_SETUP_BOOL, false);
-
// Default carrier app configurations
sDefaults.putStringArray(KEY_CARRIER_DEFAULT_ACTIONS_ON_REDIRECTION_STRING_ARRAY,
new String[]{
@@ -9010,9 +10021,10 @@ public class CarrierConfigManager {
//6: CARRIER_ACTION_CANCEL_ALL_NOTIFICATIONS
//8: CARRIER_ACTION_DISABLE_DEFAULT_URL_HANDLER
});
- sDefaults.putStringArray(KEY_CARRIER_DEFAULT_ACTIONS_ON_DEFAULT_NETWORK_AVAILABLE, new String[] {
- String.valueOf(false) + ": 7", //7: CARRIER_ACTION_ENABLE_DEFAULT_URL_HANDLER
- String.valueOf(true) + ": 8" //8: CARRIER_ACTION_DISABLE_DEFAULT_URL_HANDLER
+ sDefaults.putStringArray(KEY_CARRIER_DEFAULT_ACTIONS_ON_DEFAULT_NETWORK_AVAILABLE,
+ new String[] {
+ false + ": 7", //7: CARRIER_ACTION_ENABLE_DEFAULT_URL_HANDLER
+ true + ": 8" //8: CARRIER_ACTION_DISABLE_DEFAULT_URL_HANDLER
});
sDefaults.putStringArray(KEY_CARRIER_DEFAULT_REDIRECTION_URL_STRING_ARRAY, null);
@@ -9026,9 +10038,9 @@ public class CarrierConfigManager {
// Rat families: {GPRS, EDGE}, {EVDO, EVDO_A, EVDO_B}, {UMTS, HSPA, HSDPA, HSUPA, HSPAP},
// {LTE, LTE_CA}
- // Order is important - lowest precidence first
+ // Order is important - lowest precedence first
sDefaults.putStringArray(KEY_RATCHET_RAT_FAMILIES,
- new String[]{"1,2","7,8,12","3,11,9,10,15","14,19"});
+ new String[]{"1,2", "7,8,12", "3,11,9,10,15", "14,19"});
sDefaults.putBoolean(KEY_TREAT_DOWNGRADED_VIDEO_CALLS_AS_VIDEO_CALLS_BOOL, false);
sDefaults.putBoolean(KEY_DROP_VIDEO_CALL_WHEN_ANSWERING_AUDIO_CALL_BOOL, false);
sDefaults.putBoolean(KEY_ALLOW_MERGE_WIFI_CALLS_WHEN_VOWIFI_OFF_BOOL, true);
@@ -9059,8 +10071,7 @@ public class CarrierConfigManager {
sDefaults.putBoolean(KEY_NOTIFY_INTERNATIONAL_CALL_ON_WFC_BOOL, false);
sDefaults.putBoolean(KEY_HIDE_PRESET_APN_DETAILS_BOOL, false);
sDefaults.putBoolean(KEY_SHOW_VIDEO_CALL_CHARGES_ALERT_DIALOG_BOOL, false);
- sDefaults.putStringArray(KEY_CALL_FORWARDING_BLOCKS_WHILE_ROAMING_STRING_ARRAY,
- null);
+ sDefaults.putStringArray(KEY_CALL_FORWARDING_BLOCKS_WHILE_ROAMING_STRING_ARRAY, null);
sDefaults.putBoolean(KEY_SUPPORT_IMS_CALL_FORWARDING_WHILE_ROAMING_BOOL, true);
sDefaults.putInt(KEY_LTE_EARFCNS_RSRP_BOOST_INT, 0);
sDefaults.putStringArray(KEY_BOOSTED_LTE_EARFCNS_STRING_ARRAY, null);
@@ -9096,9 +10107,11 @@ public class CarrierConfigManager {
sDefaults.putString(KEY_OPERATOR_NAME_FILTER_PATTERN_STRING, "");
sDefaults.putString(KEY_SHOW_CARRIER_DATA_ICON_PATTERN_STRING, "");
sDefaults.putBoolean(KEY_HIDE_LTE_PLUS_DATA_ICON_BOOL, true);
+ sDefaults.putBoolean(KEY_SHOW_5G_SLICE_ICON_BOOL, true);
sDefaults.putInt(KEY_LTE_PLUS_THRESHOLD_BANDWIDTH_KHZ_INT, 20000);
sDefaults.putInt(KEY_NR_ADVANCED_THRESHOLD_BANDWIDTH_KHZ_INT, 0);
sDefaults.putBoolean(KEY_INCLUDE_LTE_FOR_NR_ADVANCED_THRESHOLD_BANDWIDTH_BOOL, false);
+ sDefaults.putBoolean(KEY_RATCHET_NR_ADVANCED_BANDWIDTH_IF_RRC_IDLE_BOOL, true);
sDefaults.putIntArray(KEY_CARRIER_NR_AVAILABILITIES_INT_ARRAY,
new int[]{CARRIER_NR_AVAILABILITY_NSA, CARRIER_NR_AVAILABILITY_SA});
sDefaults.putBoolean(KEY_LTE_ENABLED_BOOL, true);
@@ -9111,6 +10124,7 @@ public class CarrierConfigManager {
sDefaults.putBoolean(KEY_CHECK_PRICING_WITH_CARRIER_FOR_DATA_ROAMING_BOOL, false);
sDefaults.putBoolean(KEY_SHOW_DATA_CONNECTED_ROAMING_NOTIFICATION_BOOL, false);
sDefaults.putIntArray(KEY_LTE_RSRP_THRESHOLDS_INT_ARRAY,
+ // Boundaries: [-140 dBm, -44 dBm]
new int[] {
-128, /* SIGNAL_STRENGTH_POOR */
-118, /* SIGNAL_STRENGTH_MODERATE */
@@ -9118,6 +10132,7 @@ public class CarrierConfigManager {
-98, /* SIGNAL_STRENGTH_GREAT */
});
sDefaults.putIntArray(KEY_LTE_RSRQ_THRESHOLDS_INT_ARRAY,
+ // Boundaries: [-34 dB, 3 dB]
new int[] {
-20, /* SIGNAL_STRENGTH_POOR */
-17, /* SIGNAL_STRENGTH_MODERATE */
@@ -9125,6 +10140,7 @@ public class CarrierConfigManager {
-11 /* SIGNAL_STRENGTH_GREAT */
});
sDefaults.putIntArray(KEY_LTE_RSSNR_THRESHOLDS_INT_ARRAY,
+ // Boundaries: [-20 dBm, 30 dBm]
new int[] {
-3, /* SIGNAL_STRENGTH_POOR */
1, /* SIGNAL_STRENGTH_MODERATE */
@@ -9132,18 +10148,29 @@ public class CarrierConfigManager {
13 /* SIGNAL_STRENGTH_GREAT */
});
sDefaults.putIntArray(KEY_WCDMA_RSCP_THRESHOLDS_INT_ARRAY,
+ // Boundaries: [-120 dBm, -25 dBm]
new int[] {
- -115, /* SIGNAL_STRENGTH_POOR */
+ -115, /* SIGNAL_STRENGTH_POOR */
-105, /* SIGNAL_STRENGTH_MODERATE */
- -95, /* SIGNAL_STRENGTH_GOOD */
- -85 /* SIGNAL_STRENGTH_GREAT */
+ -95, /* SIGNAL_STRENGTH_GOOD */
+ -85 /* SIGNAL_STRENGTH_GREAT */
+ });
+ // TODO(b/249896055): On enabling ECNO measurement part for Signal Bar level indication
+ // system functionality, below values to be rechecked.
+ sDefaults.putIntArray(KEY_WCDMA_ECNO_THRESHOLDS_INT_ARRAY,
+ // Boundaries: [-24 dBm, 1 dBm]
+ new int[] {
+ -24, /* SIGNAL_STRENGTH_POOR */
+ -14, /* SIGNAL_STRENGTH_MODERATE */
+ -6, /* SIGNAL_STRENGTH_GOOD */
+ 1 /* SIGNAL_STRENGTH_GREAT */
});
sDefaults.putIntArray(KEY_5G_NR_SSRSRP_THRESHOLDS_INT_ARRAY,
// Boundaries: [-140 dB, -44 dB]
new int[] {
-110, /* SIGNAL_STRENGTH_POOR */
- -90, /* SIGNAL_STRENGTH_MODERATE */
- -80, /* SIGNAL_STRENGTH_GOOD */
+ -90, /* SIGNAL_STRENGTH_MODERATE */
+ -80, /* SIGNAL_STRENGTH_GOOD */
-65, /* SIGNAL_STRENGTH_GREAT */
});
sDefaults.putIntArray(KEY_5G_NR_SSRSRQ_THRESHOLDS_INT_ARRAY,
@@ -9151,17 +10178,26 @@ public class CarrierConfigManager {
new int[] {
-31, /* SIGNAL_STRENGTH_POOR */
-19, /* SIGNAL_STRENGTH_MODERATE */
- -7, /* SIGNAL_STRENGTH_GOOD */
- 6 /* SIGNAL_STRENGTH_GREAT */
+ -7, /* SIGNAL_STRENGTH_GOOD */
+ 6 /* SIGNAL_STRENGTH_GREAT */
});
sDefaults.putIntArray(KEY_5G_NR_SSSINR_THRESHOLDS_INT_ARRAY,
// Boundaries: [-23 dB, 40 dB]
new int[] {
-5, /* SIGNAL_STRENGTH_POOR */
- 5, /* SIGNAL_STRENGTH_MODERATE */
+ 5, /* SIGNAL_STRENGTH_MODERATE */
15, /* SIGNAL_STRENGTH_GOOD */
30 /* SIGNAL_STRENGTH_GREAT */
});
+ sDefaults.putInt(KEY_GERAN_RSSI_HYSTERESIS_DB_INT, 2);
+ sDefaults.putInt(KEY_UTRAN_RSCP_HYSTERESIS_DB_INT, 2);
+ sDefaults.putInt(KEY_EUTRAN_RSRP_HYSTERESIS_DB_INT, 2);
+ sDefaults.putInt(KEY_EUTRAN_RSRQ_HYSTERESIS_DB_INT, 2);
+ sDefaults.putInt(KEY_EUTRAN_RSSNR_HYSTERESIS_DB_INT, 2);
+ sDefaults.putInt(KEY_NGRAN_SSRSRP_HYSTERESIS_DB_INT, 2);
+ sDefaults.putInt(KEY_NGRAN_SSRSRQ_HYSTERESIS_DB_INT, 2);
+ sDefaults.putInt(KEY_NGRAN_SSSINR_HYSTERESIS_DB_INT, 2);
+ sDefaults.putInt(KEY_UTRAN_ECNO_HYSTERESIS_DB_INT, 2);
sDefaults.putInt(KEY_PARAMETERS_USE_FOR_5G_NR_SIGNAL_BAR_INT,
CellSignalStrengthNr.USE_SSRSRP);
sDefaults.putBoolean(KEY_SIGNAL_STRENGTH_NR_NSA_USE_LTE_AS_PRIMARY_BOOL, true);
@@ -9236,8 +10272,7 @@ public class CarrierConfigManager {
sDefaults.putLong(KEY_OPPORTUNISTIC_NETWORK_MAX_BACKOFF_TIME_LONG, 60000);
sDefaults.putBoolean(KEY_ENABLE_4G_OPPORTUNISTIC_NETWORK_SCAN_BOOL, true);
sDefaults.putLong(KEY_TIME_TO_SWITCH_BACK_TO_PRIMARY_IF_OPPORTUNISTIC_OOS_LONG, 60000L);
- sDefaults.putLong(
- KEY_OPPORTUNISTIC_TIME_TO_SCAN_AFTER_CAPABILITY_SWITCH_TO_PRIMARY_LONG,
+ sDefaults.putLong(KEY_OPPORTUNISTIC_TIME_TO_SCAN_AFTER_CAPABILITY_SWITCH_TO_PRIMARY_LONG,
120000L);
sDefaults.putAll(ImsServiceEntitlement.getDefaults());
sDefaults.putAll(Gps.getDefaults());
@@ -9259,7 +10294,7 @@ public class CarrierConfigManager {
new int[] {
-107, /* SIGNAL_STRENGTH_POOR */
-103, /* SIGNAL_STRENGTH_MODERATE */
- -97, /* SIGNAL_STRENGTH_GOOD */
+ -97, /* SIGNAL_STRENGTH_GOOD */
-89, /* SIGNAL_STRENGTH_GREAT */
});
sDefaults.putBoolean(KEY_SUPPORT_WPS_OVER_IMS_BOOL, true);
@@ -9352,6 +10387,20 @@ public class CarrierConfigManager {
sDefaults.putBoolean(KEY_VONR_SETTING_VISIBILITY_BOOL, true);
sDefaults.putBoolean(KEY_VONR_ENABLED_BOOL, false);
sDefaults.putBoolean(KEY_VONR_ON_BY_DEFAULT_BOOL, true);
+ sDefaults.putIntArray(KEY_SUPPORTED_PREMIUM_CAPABILITIES_INT_ARRAY, new int[0]);
+ sDefaults.putLong(KEY_PREMIUM_CAPABILITY_NOTIFICATION_DISPLAY_TIMEOUT_MILLIS_LONG,
+ TimeUnit.MINUTES.toMillis(30));
+ sDefaults.putLong(KEY_PREMIUM_CAPABILITY_NOTIFICATION_BACKOFF_HYSTERESIS_TIME_MILLIS_LONG,
+ TimeUnit.MINUTES.toMillis(30));
+ sDefaults.putInt(KEY_PREMIUM_CAPABILITY_MAXIMUM_DAILY_NOTIFICATION_COUNT_INT, 2);
+ sDefaults.putInt(KEY_PREMIUM_CAPABILITY_MAXIMUM_MONTHLY_NOTIFICATION_COUNT_INT, 10);
+ sDefaults.putLong(
+ KEY_PREMIUM_CAPABILITY_PURCHASE_CONDITION_BACKOFF_HYSTERESIS_TIME_MILLIS_LONG,
+ TimeUnit.MINUTES.toMillis(30));
+ sDefaults.putLong(KEY_PREMIUM_CAPABILITY_NETWORK_SETUP_TIME_MILLIS_LONG,
+ TimeUnit.MINUTES.toMillis(5));
+ sDefaults.putString(KEY_PREMIUM_CAPABILITY_PURCHASE_URL_STRING, null);
+ sDefaults.putBoolean(KEY_PREMIUM_CAPABILITY_SUPPORTED_ON_LTE_BOOL, false);
sDefaults.putStringArray(KEY_IWLAN_HANDOVER_POLICY_STRING_ARRAY, new String[]{
"source=GERAN|UTRAN|EUTRAN|NGRAN|IWLAN, "
+ "target=GERAN|UTRAN|EUTRAN|NGRAN|IWLAN, type=allowed"});
@@ -9409,7 +10458,6 @@ public class CarrierConfigManager {
public static final String KEY_AVOID_5GHZ_WIFI_DIRECT_FOR_LAA_BOOL =
KEY_PREFIX + "avoid_5ghz_wifi_direct_for_laa_bool";
-
private static PersistableBundle getDefaults() {
PersistableBundle defaults = new PersistableBundle();
defaults.putInt(KEY_HOTSPOT_MAX_CLIENT_COUNT, 0);
@@ -9456,8 +10504,7 @@ public class CarrierConfigManager {
return loader.getConfigForSubIdWithFeature(subId, mContext.getOpPackageName(),
mContext.getAttributionTag());
} catch (RemoteException ex) {
- Rlog.e(TAG, "Error getting config for subId " + subId + ": "
- + ex.toString());
+ Rlog.e(TAG, "Error getting config for subId " + subId + ": " + ex);
}
return null;
}
@@ -9483,7 +10530,7 @@ public class CarrierConfigManager {
* {@link TelephonyManager#hasCarrierPrivileges()}).
*
* @param subId The subscription ID on which the carrier config should be retrieved.
- * @param keys The carrier config keys to retrieve values.
+ * @param keys The carrier config keys to retrieve values.
* @return A {@link PersistableBundle} with key/value mapping for the specified configuration
* on success, or an empty (but never null) bundle on failure (for example, when the calling app
* has no permission).
@@ -9574,8 +10621,7 @@ public class CarrierConfigManager {
}
loader.overrideConfig(subscriptionId, overrideValues, persistent);
} catch (RemoteException ex) {
- Rlog.e(TAG, "Error setting config for subId " + subscriptionId + ": "
- + ex.toString());
+ Rlog.e(TAG, "Error setting config for subId " + subscriptionId + ": " + ex);
}
}
@@ -9688,7 +10734,7 @@ public class CarrierConfigManager {
}
loader.notifyConfigChangedForSubId(subId);
} catch (RemoteException ex) {
- Rlog.e(TAG, "Error reloading config for subId=" + subId + ": " + ex.toString());
+ Rlog.e(TAG, "Error reloading config for subId=" + subId + ": " + ex);
}
}
@@ -9712,7 +10758,7 @@ public class CarrierConfigManager {
}
loader.updateConfigForPhoneId(phoneId, simState);
} catch (RemoteException ex) {
- Rlog.e(TAG, "Error updating config for phoneId=" + phoneId + ": " + ex.toString());
+ Rlog.e(TAG, "Error updating config for phoneId=" + phoneId + ": " + ex);
}
}
@@ -9734,8 +10780,7 @@ public class CarrierConfigManager {
}
return loader.getDefaultCarrierServicePackageName();
} catch (RemoteException ex) {
- Rlog.e(TAG, "getDefaultCarrierServicePackageName ICarrierConfigLoader is null"
- + ex.toString());
+ Rlog.e(TAG, "getDefaultCarrierServicePackageName ICarrierConfigLoader is null" + ex);
ex.rethrowAsRuntimeException();
}
return "";
diff --git a/telephony/java/android/telephony/CarrierRestrictionRules.java b/telephony/java/android/telephony/CarrierRestrictionRules.java
index c13801887572..eac4d1682aa9 100644
--- a/telephony/java/android/telephony/CarrierRestrictionRules.java
+++ b/telephony/java/android/telephony/CarrierRestrictionRules.java
@@ -27,6 +27,7 @@ import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
import java.util.List;
+import java.util.Locale;
import java.util.Objects;
/**
@@ -103,12 +104,15 @@ public final class CarrierRestrictionRules implements Parcelable {
private int mCarrierRestrictionDefault;
@MultiSimPolicy
private int mMultiSimPolicy;
+ @TelephonyManager.CarrierRestrictionStatus
+ private int mCarrierRestrictionStatus;
private CarrierRestrictionRules() {
mAllowedCarriers = new ArrayList<CarrierIdentifier>();
mExcludedCarriers = new ArrayList<CarrierIdentifier>();
mCarrierRestrictionDefault = CARRIER_RESTRICTION_DEFAULT_NOT_ALLOWED;
mMultiSimPolicy = MULTISIM_POLICY_NONE;
+ mCarrierRestrictionStatus = TelephonyManager.CARRIER_RESTRICTION_STATUS_UNKNOWN;
}
private CarrierRestrictionRules(Parcel in) {
@@ -119,6 +123,7 @@ public final class CarrierRestrictionRules implements Parcelable {
in.readTypedList(mExcludedCarriers, CarrierIdentifier.CREATOR);
mCarrierRestrictionDefault = in.readInt();
mMultiSimPolicy = in.readInt();
+ mCarrierRestrictionStatus = in.readInt();
}
/**
@@ -276,8 +281,8 @@ public final class CarrierRestrictionRules implements Parcelable {
if (str.length() != pattern.length()) {
return false;
}
- String lowerCaseStr = str.toLowerCase();
- String lowerCasePattern = pattern.toLowerCase();
+ String lowerCaseStr = str.toLowerCase(Locale.ROOT);
+ String lowerCasePattern = pattern.toLowerCase(Locale.ROOT);
for (int i = 0; i < lowerCasePattern.length(); i++) {
if (lowerCasePattern.charAt(i) != lowerCaseStr.charAt(i)
@@ -288,6 +293,11 @@ public final class CarrierRestrictionRules implements Parcelable {
return true;
}
+ /** @hide */
+ public int getCarrierRestrictionStatus() {
+ return mCarrierRestrictionStatus;
+ }
+
/**
* {@link Parcelable#writeToParcel}
*/
@@ -297,6 +307,7 @@ public final class CarrierRestrictionRules implements Parcelable {
out.writeTypedList(mExcludedCarriers);
out.writeInt(mCarrierRestrictionDefault);
out.writeInt(mMultiSimPolicy);
+ out.writeInt(mCarrierRestrictionStatus);
}
/**
@@ -398,5 +409,17 @@ public final class CarrierRestrictionRules implements Parcelable {
mRules.mMultiSimPolicy = multiSimPolicy;
return this;
}
+
+ /**
+ * Set the device's carrier restriction status
+ *
+ * @param carrierRestrictionStatus device restriction status
+ * @hide
+ */
+ public @NonNull
+ Builder setCarrierRestrictionStatus(int carrierRestrictionStatus) {
+ mRules.mCarrierRestrictionStatus = carrierRestrictionStatus;
+ return this;
+ }
}
}
diff --git a/telephony/java/android/telephony/CellBroadcastIdRange.aidl b/telephony/java/android/telephony/CellBroadcastIdRange.aidl
new file mode 100644
index 000000000000..ddaceffc19cb
--- /dev/null
+++ b/telephony/java/android/telephony/CellBroadcastIdRange.aidl
@@ -0,0 +1,19 @@
+/*
+ * Copyright (c) 2022, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.telephony;
+
+parcelable CellBroadcastIdRange;
diff --git a/telephony/java/android/telephony/CellBroadcastIdRange.java b/telephony/java/android/telephony/CellBroadcastIdRange.java
new file mode 100644
index 000000000000..abee80f76f83
--- /dev/null
+++ b/telephony/java/android/telephony/CellBroadcastIdRange.java
@@ -0,0 +1,165 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.telephony;
+
+import android.annotation.IntRange;
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.util.Objects;
+
+/**
+ * Describes a particular cell broadcast message identifier range.
+ * @hide
+ */
+@SystemApi
+public final class CellBroadcastIdRange implements Parcelable {
+
+ @IntRange(from = 0, to = 0xFFFF)
+ private int mStartId;
+ @IntRange(from = 0, to = 0xFFFF)
+ private int mEndId;
+ private int mType;
+ private boolean mIsEnabled;
+
+ /**
+ * Create a new CellBroacastRange
+ *
+ * @param startId first message identifier as specified in TS 23.041 (3GPP)
+ * or C.R1001-G (3GPP2). The value must be between 0 and 0xFFFF.
+ * @param endId last message identifier as specified in TS 23.041 (3GPP)
+ * or C.R1001-G (3GPP2). The value must be between 0 and 0xFFFF.
+ * @param type the message format as defined in {@link SmsCbMessage}
+ * @param isEnabled whether the range is enabled
+ *
+ * @throws IllegalArgumentException if endId < startId or invalid value
+ */
+ public CellBroadcastIdRange(@IntRange(from = 0, to = 0xFFFF) int startId,
+ @IntRange(from = 0, to = 0xFFFF) int endId,
+ @android.telephony.SmsCbMessage.MessageFormat int type, boolean isEnabled)
+ throws IllegalArgumentException {
+ if (startId < 0 || endId < 0 || startId > 0xFFFF || endId > 0xFFFF) {
+ throw new IllegalArgumentException("invalid id");
+ }
+ if (endId < startId) {
+ throw new IllegalArgumentException("endId must be greater than or equal to startId");
+ }
+ mStartId = startId;
+ mEndId = endId;
+ mType = type;
+ mIsEnabled = isEnabled;
+ }
+
+ /**
+ * Return the first message identifier of this range as specified in TS 23.041 (3GPP)
+ * or C.R1001-G (3GPP2)
+ */
+ @IntRange(from = 0, to = 0xFFFF)
+ public int getStartId() {
+ return mStartId;
+ }
+
+ /**
+ * Return the last message identifier of this range as specified in TS 23.041 (3GPP)
+ * or C.R1001-G (3GPP2)
+ */
+ @IntRange(from = 0, to = 0xFFFF)
+ public int getEndId() {
+ return mEndId;
+ }
+
+ /**
+ * Return the message format of this range as defined in {@link SmsCbMessage}
+ */
+ public @android.telephony.SmsCbMessage.MessageFormat int getType() {
+ return mType;
+ }
+
+ /**
+ * Return whether the range is enabled
+ */
+ public boolean isEnabled() {
+ return mIsEnabled;
+ }
+
+ /**
+ * {@link Parcelable#writeToParcel}
+ */
+ @Override
+ public void writeToParcel(@NonNull Parcel out, int flags) {
+ out.writeInt(mStartId);
+ out.writeInt(mEndId);
+ out.writeInt(mType);
+ out.writeBoolean(mIsEnabled);
+ }
+
+ /**
+ * {@link Parcelable.Creator}
+ *
+ */
+ public static final @NonNull Parcelable.Creator<CellBroadcastIdRange> CREATOR =
+ new Creator<CellBroadcastIdRange>() {
+ @NonNull
+ @Override
+ public CellBroadcastIdRange createFromParcel(Parcel in) {
+ int startId = in.readInt();
+ int endId = in.readInt();
+ int type = in.readInt();
+ boolean isEnabled = in.readBoolean();
+
+ return new CellBroadcastIdRange(startId, endId, type, isEnabled);
+ }
+
+ @NonNull
+ @Override
+ public CellBroadcastIdRange[] newArray(int size) {
+ return new CellBroadcastIdRange[size];
+ }
+ };
+
+ /**
+ * {@link Parcelable#describeContents}
+ */
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(mStartId, mEndId, mType, mIsEnabled);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (!(obj instanceof CellBroadcastIdRange)) {
+ return false;
+ }
+
+ CellBroadcastIdRange other = (CellBroadcastIdRange) obj;
+
+ return mStartId == other.mStartId && mEndId == other.mEndId && mType == other.mType
+ && mIsEnabled == other.mIsEnabled;
+ }
+
+ @Override
+ public String toString() {
+ return "CellBroadcastIdRange[" + mStartId + ", " + mEndId + ", " + mType + ", "
+ + mIsEnabled + "]";
+ }
+}
diff --git a/telephony/java/android/telephony/CellIdentityCdma.java b/telephony/java/android/telephony/CellIdentityCdma.java
index ba3a192074bc..5eace5433128 100644
--- a/telephony/java/android/telephony/CellIdentityCdma.java
+++ b/telephony/java/android/telephony/CellIdentityCdma.java
@@ -23,6 +23,9 @@ import android.annotation.Nullable;
import android.os.Parcel;
import android.telephony.cdma.CdmaCellLocation;
+import com.android.internal.telephony.util.TelephonyUtils;
+import com.android.telephony.Rlog;
+
import java.util.Objects;
/**
@@ -242,8 +245,8 @@ public final class CellIdentityCdma extends CellIdentity {
.append(":{ mNetworkId=").append(mNetworkId)
.append(" mSystemId=").append(mSystemId)
.append(" mBasestationId=").append(mBasestationId)
- .append(" mLongitude=").append(mLongitude)
- .append(" mLatitude=").append(mLatitude)
+ .append(" mLongitude=").append(Rlog.pii(TelephonyUtils.IS_DEBUGGABLE, mLongitude))
+ .append(" mLatitude=").append(Rlog.pii(TelephonyUtils.IS_DEBUGGABLE, mLatitude))
.append(" mAlphaLong=").append(mAlphaLong)
.append(" mAlphaShort=").append(mAlphaShort)
.append("}").toString();
diff --git a/telephony/java/android/telephony/CellSignalStrengthNr.java b/telephony/java/android/telephony/CellSignalStrengthNr.java
index 297940e9c8c6..03519a364a36 100644
--- a/telephony/java/android/telephony/CellSignalStrengthNr.java
+++ b/telephony/java/android/telephony/CellSignalStrengthNr.java
@@ -155,6 +155,16 @@ public final class CellSignalStrengthNr extends CellSignalStrength implements Pa
*/
private int mParametersUseForLevel;
+ /**
+ * Timing advance value for a one way trip from cell to device in microseconds.
+ * Approximate distance is calculated using 300m/us * timingAdvance.
+ *
+ * Reference: 3GPP TS 36.213 section 4.2.3.
+ *
+ * Range: [0, 1282]
+ */
+ private int mTimingAdvance;
+
/** @hide */
public CellSignalStrengthNr() {
setDefaultValues();
@@ -169,10 +179,11 @@ public final class CellSignalStrengthNr extends CellSignalStrength implements Pa
* @param ssRsrp SS reference signal received power.
* @param ssRsrq SS reference signal received quality.
* @param ssSinr SS signal-to-noise and interference ratio.
+ * @param timingAdvance Timing advance.
* @hide
*/
public CellSignalStrengthNr(int csiRsrp, int csiRsrq, int csiSinr, int csiCqiTableIndex,
- List<Byte> csiCqiReport, int ssRsrp, int ssRsrq, int ssSinr) {
+ List<Byte> csiCqiReport, int ssRsrp, int ssRsrq, int ssSinr, int timingAdvance) {
mCsiRsrp = inRangeOrUnavailable(csiRsrp, -156, -31);
mCsiRsrq = inRangeOrUnavailable(csiRsrq, -20, -3);
mCsiSinr = inRangeOrUnavailable(csiSinr, -23, 23);
@@ -183,6 +194,7 @@ public final class CellSignalStrengthNr extends CellSignalStrength implements Pa
mSsRsrp = inRangeOrUnavailable(ssRsrp, -156, -31);
mSsRsrq = inRangeOrUnavailable(ssRsrq, -43, 20);
mSsSinr = inRangeOrUnavailable(ssSinr, -23, 40);
+ mTimingAdvance = inRangeOrUnavailable(timingAdvance, 0, 1282);
updateLevel(null, null);
}
@@ -198,7 +210,7 @@ public final class CellSignalStrengthNr extends CellSignalStrength implements Pa
public CellSignalStrengthNr(
int csiRsrp, int csiRsrq, int csiSinr, int ssRsrp, int ssRsrq, int ssSinr) {
this(csiRsrp, csiRsrq, csiSinr, CellInfo.UNAVAILABLE, Collections.emptyList(),
- ssRsrp, ssRsrq, ssSinr);
+ ssRsrp, ssRsrq, ssSinr, CellInfo.UNAVAILABLE);
}
/**
@@ -302,6 +314,22 @@ public final class CellSignalStrengthNr extends CellSignalStrength implements Pa
return mCsiCqiReport;
}
+ /**
+ * Get the timing advance value for a one way trip from cell to device for NR in microseconds.
+ * {@link android.telephony.CellInfo#UNAVAILABLE} is reported when there is no
+ * active RRC connection.
+ *
+ * Reference: 3GPP TS 36.213 section 4.2.3.
+ * Range: 0 us to 1282 us.
+ *
+ * @return the NR timing advance if available or
+ * {@link android.telephony.CellInfo#UNAVAILABLE} if unavailable.
+ */
+ @IntRange(from = 0, to = 1282)
+ public int getTimingAdvanceMicros() {
+ return mTimingAdvance;
+ }
+
@Override
public int describeContents() {
return 0;
@@ -319,6 +347,7 @@ public final class CellSignalStrengthNr extends CellSignalStrength implements Pa
dest.writeInt(mSsRsrq);
dest.writeInt(mSsSinr);
dest.writeInt(mLevel);
+ dest.writeInt(mTimingAdvance);
}
private CellSignalStrengthNr(Parcel in) {
@@ -331,6 +360,7 @@ public final class CellSignalStrengthNr extends CellSignalStrength implements Pa
mSsRsrq = in.readInt();
mSsSinr = in.readInt();
mLevel = in.readInt();
+ mTimingAdvance = in.readInt();
}
/** @hide */
@@ -346,6 +376,7 @@ public final class CellSignalStrengthNr extends CellSignalStrength implements Pa
mSsSinr = CellInfo.UNAVAILABLE;
mLevel = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
mParametersUseForLevel = USE_SSRSRP;
+ mTimingAdvance = CellInfo.UNAVAILABLE;
}
/** {@inheritDoc} */
@@ -495,6 +526,7 @@ public final class CellSignalStrengthNr extends CellSignalStrength implements Pa
mSsSinr = s.mSsSinr;
mLevel = s.mLevel;
mParametersUseForLevel = s.mParametersUseForLevel;
+ mTimingAdvance = s.mTimingAdvance;
}
/** @hide */
@@ -506,7 +538,7 @@ public final class CellSignalStrengthNr extends CellSignalStrength implements Pa
@Override
public int hashCode() {
return Objects.hash(mCsiRsrp, mCsiRsrq, mCsiSinr, mCsiCqiTableIndex,
- mCsiCqiReport, mSsRsrp, mSsRsrq, mSsSinr, mLevel);
+ mCsiCqiReport, mSsRsrp, mSsRsrq, mSsSinr, mLevel, mTimingAdvance);
}
private static final CellSignalStrengthNr sInvalid = new CellSignalStrengthNr();
@@ -525,7 +557,7 @@ public final class CellSignalStrengthNr extends CellSignalStrength implements Pa
&& mCsiCqiTableIndex == o.mCsiCqiTableIndex
&& mCsiCqiReport.equals(o.mCsiCqiReport)
&& mSsRsrp == o.mSsRsrp && mSsRsrq == o.mSsRsrq && mSsSinr == o.mSsSinr
- && mLevel == o.mLevel;
+ && mLevel == o.mLevel && mTimingAdvance == o.mTimingAdvance;
}
return false;
}
@@ -543,6 +575,7 @@ public final class CellSignalStrengthNr extends CellSignalStrength implements Pa
.append(" ssSinr = " + mSsSinr)
.append(" level = " + mLevel)
.append(" parametersUseForLevel = " + mParametersUseForLevel)
+ .append(" timingAdvance = " + mTimingAdvance)
.append(" }")
.toString();
}
diff --git a/telephony/java/android/telephony/DataSpecificRegistrationInfo.java b/telephony/java/android/telephony/DataSpecificRegistrationInfo.java
index ca6dc2d55da3..5e5e028625b6 100644
--- a/telephony/java/android/telephony/DataSpecificRegistrationInfo.java
+++ b/telephony/java/android/telephony/DataSpecificRegistrationInfo.java
@@ -16,6 +16,7 @@
package android.telephony;
+import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
@@ -24,6 +25,8 @@ import android.os.Parcelable;
import com.android.internal.annotations.VisibleForTesting;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
import java.util.Objects;
@@ -33,6 +36,69 @@ import java.util.Objects;
*/
@SystemApi
public final class DataSpecificRegistrationInfo implements Parcelable {
+
+ /** @hide */
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef(
+ prefix = "LTE_ATTACH_TYPE_",
+ value = {
+ LTE_ATTACH_TYPE_UNKNOWN,
+ LTE_ATTACH_TYPE_EPS_ONLY,
+ LTE_ATTACH_TYPE_COMBINED,
+ })
+ public @interface LteAttachResultType {}
+
+ /**
+ * Default value.
+ * Attach type is unknown.
+ */
+ public static final int LTE_ATTACH_TYPE_UNKNOWN = 0;
+
+ /**
+ * LTE is attached with EPS only.
+ *
+ * Reference: 3GPP TS 24.301 9.9.3 EMM information elements.
+ */
+ public static final int LTE_ATTACH_TYPE_EPS_ONLY = 1;
+
+ /**
+ * LTE combined EPS and IMSI attach.
+ *
+ * Reference: 3GPP TS 24.301 9.9.3 EMM information elements.
+ */
+ public static final int LTE_ATTACH_TYPE_COMBINED = 2;
+
+ /** @hide */
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef(flag = true, prefix = {"LTE_ATTACH_EXTRA_INFO_"},
+ value = {
+ LTE_ATTACH_EXTRA_INFO_NONE,
+ LTE_ATTACH_EXTRA_INFO_CSFB_NOT_PREFERRED,
+ LTE_ATTACH_EXTRA_INFO_SMS_ONLY
+ })
+ public @interface LteAttachExtraInfo {}
+
+ /**
+ * Default value.
+ */
+ public static final int LTE_ATTACH_EXTRA_INFO_NONE = 0;
+
+ /**
+ * CSFB is not preferred.
+ * Applicable for LTE only.
+ *
+ * Reference: 3GPP TS 24.301 9.9.3 EMM information elements.
+ */
+ public static final int LTE_ATTACH_EXTRA_INFO_CSFB_NOT_PREFERRED = 1 << 0;
+
+ /**
+ * Attached for SMS only.
+ * Applicable for LTE only.
+ *
+ * Reference: 3GPP TS 24.301 9.9.3 EMM information elements.
+ */
+ public static final int LTE_ATTACH_EXTRA_INFO_SMS_ONLY = 1 << 1;
+
/**
* @hide
* The maximum number of simultaneous Data Calls that
@@ -75,6 +141,22 @@ public final class DataSpecificRegistrationInfo implements Parcelable {
@Nullable
private final VopsSupportInfo mVopsSupportInfo;
+ /** The type of network attachment */
+ private final @LteAttachResultType int mLteAttachResultType;
+
+ /** LTE attach extra info */
+ private final @LteAttachExtraInfo int mLteAttachExtraInfo;
+
+ private DataSpecificRegistrationInfo(Builder builder) {
+ this.maxDataCalls = builder.mMaxDataCalls;
+ this.isDcNrRestricted = builder.mIsDcNrRestricted;
+ this.isNrAvailable = builder.mIsNrAvailable;
+ this.isEnDcAvailable = builder.mIsEnDcAvailable;
+ this.mVopsSupportInfo = builder.mVopsSupportInfo;
+ this.mLteAttachResultType = builder.mLteAttachResultType;
+ this.mLteAttachExtraInfo = builder.mLteAttachExtraInfo;
+ }
+
/**
* @hide
*/
@@ -87,6 +169,8 @@ public final class DataSpecificRegistrationInfo implements Parcelable {
this.isNrAvailable = isNrAvailable;
this.isEnDcAvailable = isEnDcAvailable;
this.mVopsSupportInfo = vops;
+ this.mLteAttachResultType = LTE_ATTACH_TYPE_UNKNOWN;
+ this.mLteAttachExtraInfo = LTE_ATTACH_EXTRA_INFO_NONE;
}
/**
@@ -101,6 +185,8 @@ public final class DataSpecificRegistrationInfo implements Parcelable {
isNrAvailable = dsri.isNrAvailable;
isEnDcAvailable = dsri.isEnDcAvailable;
mVopsSupportInfo = dsri.mVopsSupportInfo;
+ mLteAttachResultType = dsri.mLteAttachResultType;
+ mLteAttachExtraInfo = dsri.mLteAttachExtraInfo;
}
private DataSpecificRegistrationInfo(/* @NonNull */ Parcel source) {
@@ -109,6 +195,8 @@ public final class DataSpecificRegistrationInfo implements Parcelable {
isNrAvailable = source.readBoolean();
isEnDcAvailable = source.readBoolean();
mVopsSupportInfo = source.readParcelable(VopsSupportInfo.class.getClassLoader(), android.telephony.VopsSupportInfo.class);
+ mLteAttachResultType = source.readInt();
+ mLteAttachExtraInfo = source.readInt();
}
@Override
@@ -118,6 +206,8 @@ public final class DataSpecificRegistrationInfo implements Parcelable {
dest.writeBoolean(isNrAvailable);
dest.writeBoolean(isEnDcAvailable);
dest.writeParcelable(mVopsSupportInfo, flags);
+ dest.writeInt(mLteAttachResultType);
+ dest.writeInt(mLteAttachExtraInfo);
}
@Override
@@ -134,6 +224,8 @@ public final class DataSpecificRegistrationInfo implements Parcelable {
.append(" isDcNrRestricted = " + isDcNrRestricted)
.append(" isNrAvailable = " + isNrAvailable)
.append(" isEnDcAvailable = " + isEnDcAvailable)
+ .append(" mLteAttachResultType = " + mLteAttachResultType)
+ .append(" mLteAttachExtraInfo = " + mLteAttachExtraInfo)
.append(" " + mVopsSupportInfo)
.append(" }")
.toString();
@@ -142,7 +234,8 @@ public final class DataSpecificRegistrationInfo implements Parcelable {
@Override
public int hashCode() {
return Objects.hash(maxDataCalls, isDcNrRestricted, isNrAvailable,
- isEnDcAvailable, mVopsSupportInfo);
+ isEnDcAvailable, mVopsSupportInfo,
+ mLteAttachResultType, mLteAttachExtraInfo);
}
@Override
@@ -156,7 +249,9 @@ public final class DataSpecificRegistrationInfo implements Parcelable {
&& this.isDcNrRestricted == other.isDcNrRestricted
&& this.isNrAvailable == other.isNrAvailable
&& this.isEnDcAvailable == other.isEnDcAvailable
- && Objects.equals(mVopsSupportInfo, other.mVopsSupportInfo);
+ && Objects.equals(mVopsSupportInfo, other.mVopsSupportInfo)
+ && this.mLteAttachResultType == other.mLteAttachResultType
+ && this.mLteAttachExtraInfo == other.mLteAttachExtraInfo;
}
public static final @NonNull Parcelable.Creator<DataSpecificRegistrationInfo> CREATOR =
@@ -196,4 +291,105 @@ public final class DataSpecificRegistrationInfo implements Parcelable {
public VopsSupportInfo getVopsSupportInfo() {
return mVopsSupportInfo;
}
+
+ /**
+ * Provides the LTE attach type.
+ */
+ public @LteAttachResultType int getLteAttachResultType() {
+ return mLteAttachResultType;
+ }
+
+ /**
+ * Provides the extra information of LTE attachment.
+ *
+ * @return the bitwise OR of {@link LteAttachExtraInfo}.
+ */
+ public @LteAttachExtraInfo int getLteAttachExtraInfo() {
+ return mLteAttachExtraInfo;
+ }
+
+ /**
+ * Builds {@link DataSpecificRegistrationInfo} instances, which may include optional parameters.
+ * @hide
+ */
+ public static final class Builder {
+ private final int mMaxDataCalls;
+
+ private boolean mIsDcNrRestricted;
+ private boolean mIsNrAvailable;
+ private boolean mIsEnDcAvailable;
+ private @Nullable VopsSupportInfo mVopsSupportInfo;
+ private @LteAttachResultType int mLteAttachResultType = LTE_ATTACH_TYPE_UNKNOWN;
+ private @LteAttachExtraInfo int mLteAttachExtraInfo = LTE_ATTACH_EXTRA_INFO_NONE;
+
+ public Builder(int maxDataCalls) {
+ mMaxDataCalls = maxDataCalls;
+ }
+
+ /**
+ * Ses whether the use of dual connectivity with NR is restricted.
+ * @param isDcNrRestricted {@code true} if the use of dual connectivity with NR is
+ * restricted.
+ */
+ public @NonNull Builder setDcNrRestricted(boolean isDcNrRestricted) {
+ mIsDcNrRestricted = isDcNrRestricted;
+ return this;
+ }
+
+ /**
+ * Sets whether NR is supported by the selected PLMN.
+ * @param isNrAvailable {@code true} if NR is supported.
+ */
+ public @NonNull Builder setNrAvailable(boolean isNrAvailable) {
+ mIsNrAvailable = isNrAvailable;
+ return this;
+ }
+
+ /**
+ * Sets whether E-UTRA-NR Dual Connectivity (EN-DC) is supported by the primary serving
+ * cell.
+ * @param isEnDcAvailable {@code true} if EN_DC is supported.
+ */
+ public @NonNull Builder setEnDcAvailable(boolean isEnDcAvailable) {
+ mIsEnDcAvailable = isEnDcAvailable;
+ return this;
+ }
+
+ /**
+ * Sets the network support info for VoPS and Emergency bearer support.
+ * @param vops The network support info for VoPS and Emergency bearer support.
+ */
+ @Nullable
+ public @NonNull Builder setVopsSupportInfo(VopsSupportInfo vops) {
+ mVopsSupportInfo = vops;
+ return this;
+ }
+
+ /**
+ * Sets the LTE attach type.
+ * @param lteAttachResultType the Lte attach type
+ */
+ public @NonNull Builder setLteAttachResultType(
+ @LteAttachResultType int lteAttachResultType) {
+ mLteAttachResultType = lteAttachResultType;
+ return this;
+ }
+
+ /**
+ * Sets the extra information of LTE attachment.
+ * @param lteAttachExtraInfo the extra information of LTE attachment.
+ */
+ public @NonNull Builder setLteAttachExtraInfo(
+ @LteAttachExtraInfo int lteAttachExtraInfo) {
+ mLteAttachExtraInfo = lteAttachExtraInfo;
+ return this;
+ }
+
+ /**
+ * @return a built {@link DataSpecificRegistrationInfo} instance.
+ */
+ public @NonNull DataSpecificRegistrationInfo build() {
+ return new DataSpecificRegistrationInfo(this);
+ }
+ }
}
diff --git a/telephony/java/android/telephony/DisconnectCause.java b/telephony/java/android/telephony/DisconnectCause.java
index 2704418935d9..6997f3c79bc3 100644
--- a/telephony/java/android/telephony/DisconnectCause.java
+++ b/telephony/java/android/telephony/DisconnectCause.java
@@ -360,6 +360,11 @@ public final class DisconnectCause {
*/
public static final int INCOMING_AUTO_REJECTED = 81;
+ /**
+ * Indicates that the call was unable to be made because the satellite modem is enabled.
+ * @hide
+ */
+ public static final int SATELLITE_ENABLED = 82;
//*********************************************************************************************
// When adding a disconnect type:
@@ -379,168 +384,170 @@ public final class DisconnectCause {
@UnsupportedAppUsage
public static @NonNull String toString(int cause) {
switch (cause) {
- case NOT_DISCONNECTED:
- return "NOT_DISCONNECTED";
- case INCOMING_MISSED:
- return "INCOMING_MISSED";
- case NORMAL:
- return "NORMAL";
- case LOCAL:
- return "LOCAL";
- case BUSY:
- return "BUSY";
- case CONGESTION:
- return "CONGESTION";
- case INVALID_NUMBER:
- return "INVALID_NUMBER";
- case NUMBER_UNREACHABLE:
- return "NUMBER_UNREACHABLE";
- case SERVER_UNREACHABLE:
- return "SERVER_UNREACHABLE";
- case INVALID_CREDENTIALS:
- return "INVALID_CREDENTIALS";
- case OUT_OF_NETWORK:
- return "OUT_OF_NETWORK";
- case SERVER_ERROR:
- return "SERVER_ERROR";
- case TIMED_OUT:
- return "TIMED_OUT";
- case LOST_SIGNAL:
- return "LOST_SIGNAL";
- case LIMIT_EXCEEDED:
- return "LIMIT_EXCEEDED";
- case INCOMING_REJECTED:
- return "INCOMING_REJECTED";
- case POWER_OFF:
- return "POWER_OFF";
- case OUT_OF_SERVICE:
- return "OUT_OF_SERVICE";
- case ICC_ERROR:
- return "ICC_ERROR";
- case CALL_BARRED:
- return "CALL_BARRED";
- case FDN_BLOCKED:
- return "FDN_BLOCKED";
- case CS_RESTRICTED:
- return "CS_RESTRICTED";
- case CS_RESTRICTED_NORMAL:
- return "CS_RESTRICTED_NORMAL";
- case CS_RESTRICTED_EMERGENCY:
- return "CS_RESTRICTED_EMERGENCY";
- case UNOBTAINABLE_NUMBER:
- return "UNOBTAINABLE_NUMBER";
- case CDMA_LOCKED_UNTIL_POWER_CYCLE:
- return "CDMA_LOCKED_UNTIL_POWER_CYCLE";
- case CDMA_DROP:
- return "CDMA_DROP";
- case CDMA_INTERCEPT:
- return "CDMA_INTERCEPT";
- case CDMA_REORDER:
- return "CDMA_REORDER";
- case CDMA_SO_REJECT:
- return "CDMA_SO_REJECT";
- case CDMA_RETRY_ORDER:
- return "CDMA_RETRY_ORDER";
- case CDMA_ACCESS_FAILURE:
- return "CDMA_ACCESS_FAILURE";
- case CDMA_PREEMPTED:
- return "CDMA_PREEMPTED";
- case CDMA_NOT_EMERGENCY:
- return "CDMA_NOT_EMERGENCY";
- case CDMA_ACCESS_BLOCKED:
- return "CDMA_ACCESS_BLOCKED";
- case EMERGENCY_ONLY:
- return "EMERGENCY_ONLY";
- case NO_PHONE_NUMBER_SUPPLIED:
- return "NO_PHONE_NUMBER_SUPPLIED";
- case DIALED_MMI:
- return "DIALED_MMI";
- case VOICEMAIL_NUMBER_MISSING:
- return "VOICEMAIL_NUMBER_MISSING";
- case CDMA_CALL_LOST:
- return "CDMA_CALL_LOST";
- case EXITED_ECM:
- return "EXITED_ECM";
- case DIAL_MODIFIED_TO_USSD:
- return "DIAL_MODIFIED_TO_USSD";
- case DIAL_MODIFIED_TO_SS:
- return "DIAL_MODIFIED_TO_SS";
- case DIAL_MODIFIED_TO_DIAL:
- return "DIAL_MODIFIED_TO_DIAL";
- case DIAL_MODIFIED_TO_DIAL_VIDEO:
- return "DIAL_MODIFIED_TO_DIAL_VIDEO";
- case DIAL_VIDEO_MODIFIED_TO_SS:
- return "DIAL_VIDEO_MODIFIED_TO_SS";
- case DIAL_VIDEO_MODIFIED_TO_USSD:
- return "DIAL_VIDEO_MODIFIED_TO_USSD";
- case DIAL_VIDEO_MODIFIED_TO_DIAL:
- return "DIAL_VIDEO_MODIFIED_TO_DIAL";
- case DIAL_VIDEO_MODIFIED_TO_DIAL_VIDEO:
- return "DIAL_VIDEO_MODIFIED_TO_DIAL_VIDEO";
- case ERROR_UNSPECIFIED:
- return "ERROR_UNSPECIFIED";
- case OUTGOING_FAILURE:
- return "OUTGOING_FAILURE";
- case OUTGOING_CANCELED:
- return "OUTGOING_CANCELED";
- case IMS_MERGED_SUCCESSFULLY:
- return "IMS_MERGED_SUCCESSFULLY";
- case CDMA_ALREADY_ACTIVATED:
- return "CDMA_ALREADY_ACTIVATED";
- case VIDEO_CALL_NOT_ALLOWED_WHILE_TTY_ENABLED:
- return "VIDEO_CALL_NOT_ALLOWED_WHILE_TTY_ENABLED";
- case CALL_PULLED:
- return "CALL_PULLED";
- case ANSWERED_ELSEWHERE:
- return "ANSWERED_ELSEWHERE";
- case MAXIMUM_NUMBER_OF_CALLS_REACHED:
- return "MAXIMUM_NUMER_OF_CALLS_REACHED";
- case DATA_DISABLED:
- return "DATA_DISABLED";
- case DATA_LIMIT_REACHED:
- return "DATA_LIMIT_REACHED";
- case DIALED_CALL_FORWARDING_WHILE_ROAMING:
- return "DIALED_CALL_FORWARDING_WHILE_ROAMING";
- case IMEI_NOT_ACCEPTED:
- return "IMEI_NOT_ACCEPTED";
- case WIFI_LOST:
- return "WIFI_LOST";
- case IMS_ACCESS_BLOCKED:
- return "IMS_ACCESS_BLOCKED";
- case LOW_BATTERY:
- return "LOW_BATTERY";
- case DIAL_LOW_BATTERY:
- return "DIAL_LOW_BATTERY";
- case EMERGENCY_TEMP_FAILURE:
- return "EMERGENCY_TEMP_FAILURE";
- case EMERGENCY_PERM_FAILURE:
- return "EMERGENCY_PERM_FAILURE";
- case NORMAL_UNSPECIFIED:
- return "NORMAL_UNSPECIFIED";
- case IMS_SIP_ALTERNATE_EMERGENCY_CALL:
- return "IMS_SIP_ALTERNATE_EMERGENCY_CALL";
- case ALREADY_DIALING:
- return "ALREADY_DIALING";
- case CANT_CALL_WHILE_RINGING:
- return "CANT_CALL_WHILE_RINGING";
- case CALLING_DISABLED:
- return "CALLING_DISABLED";
- case TOO_MANY_ONGOING_CALLS:
- return "TOO_MANY_ONGOING_CALLS";
- case OTASP_PROVISIONING_IN_PROCESS:
- return "OTASP_PROVISIONING_IN_PROCESS";
- case MEDIA_TIMEOUT:
- return "MEDIA_TIMEOUT";
- case EMERGENCY_CALL_OVER_WFC_NOT_AVAILABLE:
- return "EMERGENCY_CALL_OVER_WFC_NOT_AVAILABLE";
- case WFC_SERVICE_NOT_AVAILABLE_IN_THIS_LOCATION:
- return "WFC_SERVICE_NOT_AVAILABLE_IN_THIS_LOCATION";
- case OUTGOING_EMERGENCY_CALL_PLACED:
- return "OUTGOING_EMERGENCY_CALL_PLACED";
+ case NOT_DISCONNECTED:
+ return "NOT_DISCONNECTED";
+ case INCOMING_MISSED:
+ return "INCOMING_MISSED";
+ case NORMAL:
+ return "NORMAL";
+ case LOCAL:
+ return "LOCAL";
+ case BUSY:
+ return "BUSY";
+ case CONGESTION:
+ return "CONGESTION";
+ case INVALID_NUMBER:
+ return "INVALID_NUMBER";
+ case NUMBER_UNREACHABLE:
+ return "NUMBER_UNREACHABLE";
+ case SERVER_UNREACHABLE:
+ return "SERVER_UNREACHABLE";
+ case INVALID_CREDENTIALS:
+ return "INVALID_CREDENTIALS";
+ case OUT_OF_NETWORK:
+ return "OUT_OF_NETWORK";
+ case SERVER_ERROR:
+ return "SERVER_ERROR";
+ case TIMED_OUT:
+ return "TIMED_OUT";
+ case LOST_SIGNAL:
+ return "LOST_SIGNAL";
+ case LIMIT_EXCEEDED:
+ return "LIMIT_EXCEEDED";
+ case INCOMING_REJECTED:
+ return "INCOMING_REJECTED";
+ case POWER_OFF:
+ return "POWER_OFF";
+ case OUT_OF_SERVICE:
+ return "OUT_OF_SERVICE";
+ case ICC_ERROR:
+ return "ICC_ERROR";
+ case CALL_BARRED:
+ return "CALL_BARRED";
+ case FDN_BLOCKED:
+ return "FDN_BLOCKED";
+ case CS_RESTRICTED:
+ return "CS_RESTRICTED";
+ case CS_RESTRICTED_NORMAL:
+ return "CS_RESTRICTED_NORMAL";
+ case CS_RESTRICTED_EMERGENCY:
+ return "CS_RESTRICTED_EMERGENCY";
+ case UNOBTAINABLE_NUMBER:
+ return "UNOBTAINABLE_NUMBER";
+ case CDMA_LOCKED_UNTIL_POWER_CYCLE:
+ return "CDMA_LOCKED_UNTIL_POWER_CYCLE";
+ case CDMA_DROP:
+ return "CDMA_DROP";
+ case CDMA_INTERCEPT:
+ return "CDMA_INTERCEPT";
+ case CDMA_REORDER:
+ return "CDMA_REORDER";
+ case CDMA_SO_REJECT:
+ return "CDMA_SO_REJECT";
+ case CDMA_RETRY_ORDER:
+ return "CDMA_RETRY_ORDER";
+ case CDMA_ACCESS_FAILURE:
+ return "CDMA_ACCESS_FAILURE";
+ case CDMA_PREEMPTED:
+ return "CDMA_PREEMPTED";
+ case CDMA_NOT_EMERGENCY:
+ return "CDMA_NOT_EMERGENCY";
+ case CDMA_ACCESS_BLOCKED:
+ return "CDMA_ACCESS_BLOCKED";
+ case EMERGENCY_ONLY:
+ return "EMERGENCY_ONLY";
+ case NO_PHONE_NUMBER_SUPPLIED:
+ return "NO_PHONE_NUMBER_SUPPLIED";
+ case DIALED_MMI:
+ return "DIALED_MMI";
+ case VOICEMAIL_NUMBER_MISSING:
+ return "VOICEMAIL_NUMBER_MISSING";
+ case CDMA_CALL_LOST:
+ return "CDMA_CALL_LOST";
+ case EXITED_ECM:
+ return "EXITED_ECM";
+ case DIAL_MODIFIED_TO_USSD:
+ return "DIAL_MODIFIED_TO_USSD";
+ case DIAL_MODIFIED_TO_SS:
+ return "DIAL_MODIFIED_TO_SS";
+ case DIAL_MODIFIED_TO_DIAL:
+ return "DIAL_MODIFIED_TO_DIAL";
+ case DIAL_MODIFIED_TO_DIAL_VIDEO:
+ return "DIAL_MODIFIED_TO_DIAL_VIDEO";
+ case DIAL_VIDEO_MODIFIED_TO_SS:
+ return "DIAL_VIDEO_MODIFIED_TO_SS";
+ case DIAL_VIDEO_MODIFIED_TO_USSD:
+ return "DIAL_VIDEO_MODIFIED_TO_USSD";
+ case DIAL_VIDEO_MODIFIED_TO_DIAL:
+ return "DIAL_VIDEO_MODIFIED_TO_DIAL";
+ case DIAL_VIDEO_MODIFIED_TO_DIAL_VIDEO:
+ return "DIAL_VIDEO_MODIFIED_TO_DIAL_VIDEO";
+ case ERROR_UNSPECIFIED:
+ return "ERROR_UNSPECIFIED";
+ case OUTGOING_FAILURE:
+ return "OUTGOING_FAILURE";
+ case OUTGOING_CANCELED:
+ return "OUTGOING_CANCELED";
+ case IMS_MERGED_SUCCESSFULLY:
+ return "IMS_MERGED_SUCCESSFULLY";
+ case CDMA_ALREADY_ACTIVATED:
+ return "CDMA_ALREADY_ACTIVATED";
+ case VIDEO_CALL_NOT_ALLOWED_WHILE_TTY_ENABLED:
+ return "VIDEO_CALL_NOT_ALLOWED_WHILE_TTY_ENABLED";
+ case CALL_PULLED:
+ return "CALL_PULLED";
+ case ANSWERED_ELSEWHERE:
+ return "ANSWERED_ELSEWHERE";
+ case MAXIMUM_NUMBER_OF_CALLS_REACHED:
+ return "MAXIMUM_NUMER_OF_CALLS_REACHED";
+ case DATA_DISABLED:
+ return "DATA_DISABLED";
+ case DATA_LIMIT_REACHED:
+ return "DATA_LIMIT_REACHED";
+ case DIALED_CALL_FORWARDING_WHILE_ROAMING:
+ return "DIALED_CALL_FORWARDING_WHILE_ROAMING";
+ case IMEI_NOT_ACCEPTED:
+ return "IMEI_NOT_ACCEPTED";
+ case WIFI_LOST:
+ return "WIFI_LOST";
+ case IMS_ACCESS_BLOCKED:
+ return "IMS_ACCESS_BLOCKED";
+ case LOW_BATTERY:
+ return "LOW_BATTERY";
+ case DIAL_LOW_BATTERY:
+ return "DIAL_LOW_BATTERY";
+ case EMERGENCY_TEMP_FAILURE:
+ return "EMERGENCY_TEMP_FAILURE";
+ case EMERGENCY_PERM_FAILURE:
+ return "EMERGENCY_PERM_FAILURE";
+ case NORMAL_UNSPECIFIED:
+ return "NORMAL_UNSPECIFIED";
+ case IMS_SIP_ALTERNATE_EMERGENCY_CALL:
+ return "IMS_SIP_ALTERNATE_EMERGENCY_CALL";
+ case ALREADY_DIALING:
+ return "ALREADY_DIALING";
+ case CANT_CALL_WHILE_RINGING:
+ return "CANT_CALL_WHILE_RINGING";
+ case CALLING_DISABLED:
+ return "CALLING_DISABLED";
+ case TOO_MANY_ONGOING_CALLS:
+ return "TOO_MANY_ONGOING_CALLS";
+ case OTASP_PROVISIONING_IN_PROCESS:
+ return "OTASP_PROVISIONING_IN_PROCESS";
+ case MEDIA_TIMEOUT:
+ return "MEDIA_TIMEOUT";
+ case EMERGENCY_CALL_OVER_WFC_NOT_AVAILABLE:
+ return "EMERGENCY_CALL_OVER_WFC_NOT_AVAILABLE";
+ case WFC_SERVICE_NOT_AVAILABLE_IN_THIS_LOCATION:
+ return "WFC_SERVICE_NOT_AVAILABLE_IN_THIS_LOCATION";
+ case OUTGOING_EMERGENCY_CALL_PLACED:
+ return "OUTGOING_EMERGENCY_CALL_PLACED";
case INCOMING_AUTO_REJECTED:
return "INCOMING_AUTO_REJECTED";
- default:
- return "INVALID: " + cause;
+ case SATELLITE_ENABLED:
+ return "SATELLITE_ENABLED";
+ default:
+ return "INVALID: " + cause;
}
}
}
diff --git a/telephony/java/android/telephony/DomainSelectionService.aidl b/telephony/java/android/telephony/DomainSelectionService.aidl
new file mode 100644
index 000000000000..b9d2ba89eca9
--- /dev/null
+++ b/telephony/java/android/telephony/DomainSelectionService.aidl
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package android.telephony;
+
+parcelable DomainSelectionService.SelectionAttributes;
diff --git a/telephony/java/android/telephony/DomainSelectionService.java b/telephony/java/android/telephony/DomainSelectionService.java
new file mode 100644
index 000000000000..abcce5f61aee
--- /dev/null
+++ b/telephony/java/android/telephony/DomainSelectionService.java
@@ -0,0 +1,864 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.telephony;
+
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SuppressLint;
+import android.app.Service;
+import android.content.Intent;
+import android.os.Build;
+import android.os.CancellationSignal;
+import android.os.IBinder;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.os.RemoteException;
+import android.telephony.Annotation.DisconnectCauses;
+import android.telephony.Annotation.PreciseDisconnectCauses;
+import android.telephony.ims.ImsReasonInfo;
+import android.text.TextUtils;
+import android.util.Log;
+
+import com.android.internal.telephony.IDomainSelectionServiceController;
+import com.android.internal.telephony.IDomainSelector;
+import com.android.internal.telephony.ITransportSelectorCallback;
+import com.android.internal.telephony.ITransportSelectorResultCallback;
+import com.android.internal.telephony.IWwanSelectorCallback;
+import com.android.internal.telephony.IWwanSelectorResultCallback;
+import com.android.internal.telephony.util.TelephonyUtils;
+import com.android.telephony.Rlog;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.ref.WeakReference;
+import java.util.List;
+import java.util.Objects;
+import java.util.concurrent.CancellationException;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.CompletionException;
+import java.util.concurrent.Executor;
+import java.util.function.Consumer;
+
+/**
+ * Main domain selection implementation for various telephony features.
+ *
+ * The telephony framework will bind to the {@link DomainSelectionService}.
+ *
+ * @hide
+ */
+public class DomainSelectionService extends Service {
+
+ private static final String LOG_TAG = "DomainSelectionService";
+
+ /**
+ * The intent that must be defined as an intent-filter in the AndroidManifest of the
+ * {@link DomainSelectionService}.
+ *
+ * @hide
+ */
+ public static final String SERVICE_INTERFACE = "android.telephony.DomainSelectionService";
+
+ /** @hide */
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef(prefix = "SELECTOR_TYPE_",
+ value = {
+ SELECTOR_TYPE_CALLING,
+ SELECTOR_TYPE_SMS,
+ SELECTOR_TYPE_UT})
+ public @interface SelectorType {}
+
+ /** Indicates the domain selector type for calling. */
+ public static final int SELECTOR_TYPE_CALLING = 1;
+ /** Indicates the domain selector type for sms. */
+ public static final int SELECTOR_TYPE_SMS = 2;
+ /** Indicates the domain selector type for supplementary services. */
+ public static final int SELECTOR_TYPE_UT = 3;
+
+ /** Indicates that the modem can scan for emergency service as per modem’s implementation. */
+ public static final int SCAN_TYPE_NO_PREFERENCE = 0;
+
+ /** Indicates that the modem will scan for emergency service in limited service mode. */
+ public static final int SCAN_TYPE_LIMITED_SERVICE = 1;
+
+ /** Indicates that the modem will scan for emergency service in full service mode. */
+ public static final int SCAN_TYPE_FULL_SERVICE = 2;
+
+ /** @hide */
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef(prefix = "SCAN_TYPE_",
+ value = {
+ SCAN_TYPE_NO_PREFERENCE,
+ SCAN_TYPE_LIMITED_SERVICE,
+ SCAN_TYPE_FULL_SERVICE})
+ public @interface EmergencyScanType {}
+
+ /**
+ * Contains attributes required to determine the domain for a telephony service.
+ */
+ public static final class SelectionAttributes implements Parcelable {
+
+ private static final String TAG = "SelectionAttributes";
+
+ private int mSlotId;
+ private int mSubId;
+ private @Nullable String mCallId;
+ private @Nullable String mNumber;
+ private @SelectorType int mSelectorType;
+ private boolean mIsVideoCall;
+ private boolean mIsEmergency;
+ private boolean mIsExitedFromAirplaneMode;
+ //private @Nullable UtAttributes mUtAttributes;
+ private @Nullable ImsReasonInfo mImsReasonInfo;
+ private @PreciseDisconnectCauses int mCause;
+ private @Nullable EmergencyRegResult mEmergencyRegResult;
+
+ /**
+ * @param slotId The slot identifier.
+ * @param subId The subscription identifier.
+ * @param callId The call identifier.
+ * @param number The dialed number.
+ * @param selectorType Indicates the requested domain selector type.
+ * @param video Indicates it's a video call.
+ * @param emergency Indicates it's emergency service.
+ * @param exited {@code true} if the request caused the device to move out of airplane mode.
+ * @param imsReasonInfo The reason why the last PS attempt failed.
+ * @param cause The reason why the last CS attempt failed.
+ * @param regResult The current registration result for emergency services.
+ */
+ private SelectionAttributes(int slotId, int subId, @Nullable String callId,
+ @Nullable String number, @SelectorType int selectorType,
+ boolean video, boolean emergency, boolean exited,
+ /*UtAttributes attr,*/
+ @Nullable ImsReasonInfo imsReasonInfo, @PreciseDisconnectCauses int cause,
+ @Nullable EmergencyRegResult regResult) {
+ mSlotId = slotId;
+ mSubId = subId;
+ mCallId = callId;
+ mNumber = number;
+ mSelectorType = selectorType;
+ mIsVideoCall = video;
+ mIsEmergency = emergency;
+ mIsExitedFromAirplaneMode = exited;
+ //mUtAttributes = attr;
+ mImsReasonInfo = imsReasonInfo;
+ mCause = cause;
+ mEmergencyRegResult = regResult;
+ }
+
+ /**
+ * Copy constructor.
+ *
+ * @param s Source selection attributes.
+ * @hide
+ */
+ public SelectionAttributes(@NonNull SelectionAttributes s) {
+ mSlotId = s.mSlotId;
+ mSubId = s.mSubId;
+ mCallId = s.mCallId;
+ mNumber = s.mNumber;
+ mSelectorType = s.mSelectorType;
+ mIsEmergency = s.mIsEmergency;
+ mIsExitedFromAirplaneMode = s.mIsExitedFromAirplaneMode;
+ //mUtAttributes = s.mUtAttributes;
+ mImsReasonInfo = s.mImsReasonInfo;
+ mCause = s.mCause;
+ mEmergencyRegResult = s.mEmergencyRegResult;
+ }
+
+ /**
+ * Constructs a SelectionAttributes object from the given parcel.
+ */
+ private SelectionAttributes(@NonNull Parcel in) {
+ readFromParcel(in);
+ }
+
+ /**
+ * @return The slot identifier.
+ */
+ public int getSlotId() {
+ return mSlotId;
+ }
+
+ /**
+ * @return The subscription identifier.
+ */
+ public int getSubId() {
+ return mSubId;
+ }
+
+ /**
+ * @return The call identifier.
+ */
+ public @Nullable String getCallId() {
+ return mCallId;
+ }
+
+ /**
+ * @return The dialed number.
+ */
+ public @Nullable String getNumber() {
+ return mNumber;
+ }
+
+ /**
+ * @return The domain selector type.
+ */
+ public @SelectorType int getSelectorType() {
+ return mSelectorType;
+ }
+
+ /**
+ * @return {@code true} if the request is for a video call.
+ */
+ public boolean isVideoCall() {
+ return mIsVideoCall;
+ }
+
+ /**
+ * @return {@code true} if the request is for emergency services.
+ */
+ public boolean isEmergency() {
+ return mIsEmergency;
+ }
+
+ /**
+ * @return {@code true} if the request caused the device to move out of airplane mode.
+ */
+ public boolean isExitedFromAirplaneMode() {
+ return mIsExitedFromAirplaneMode;
+ }
+
+ /*
+ public @Nullable UtAttributes getUtAttributes();
+ return mUtAttributes;
+ }
+ */
+
+ /**
+ * @return The PS disconnect cause if trying over PS resulted in a failure and
+ * reselection is required.
+ */
+ public @Nullable ImsReasonInfo getPsDisconnectCause() {
+ return mImsReasonInfo;
+ }
+
+ /**
+ * @return The CS disconnect cause if trying over CS resulted in a failure and
+ * reselection is required.
+ */
+ public @PreciseDisconnectCauses int getCsDisconnectCause() {
+ return mCause;
+ }
+
+ /**
+ * @return The current registration state of cellular network.
+ */
+ public @Nullable EmergencyRegResult getEmergencyRegResult() {
+ return mEmergencyRegResult;
+ }
+
+ @Override
+ public @NonNull String toString() {
+ return "{ slotId=" + mSlotId
+ + ", subId=" + mSubId
+ + ", callId=" + mCallId
+ + ", number=" + (Build.IS_DEBUGGABLE ? mNumber : "***")
+ + ", type=" + mSelectorType
+ + ", videoCall=" + mIsVideoCall
+ + ", emergency=" + mIsEmergency
+ + ", airplaneMode=" + mIsExitedFromAirplaneMode
+ + ", reasonInfo=" + mImsReasonInfo
+ + ", cause=" + mCause
+ + ", regResult=" + mEmergencyRegResult
+ + " }";
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ SelectionAttributes that = (SelectionAttributes) o;
+ return mSlotId == that.mSlotId && mSubId == that.mSubId
+ && TextUtils.equals(mCallId, that.mCallId)
+ && TextUtils.equals(mNumber, that.mNumber)
+ && mSelectorType == that.mSelectorType && mIsVideoCall == that.mIsVideoCall
+ && mIsEmergency == that.mIsEmergency
+ && mIsExitedFromAirplaneMode == that.mIsExitedFromAirplaneMode
+ //&& equalsHandlesNulls(mUtAttributes, that.mUtAttributes)
+ && equalsHandlesNulls(mImsReasonInfo, that.mImsReasonInfo)
+ && mCause == that.mCause
+ && equalsHandlesNulls(mEmergencyRegResult, that.mEmergencyRegResult);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(mCallId, mNumber, mImsReasonInfo,
+ mIsVideoCall, mIsEmergency, mIsExitedFromAirplaneMode, mEmergencyRegResult,
+ mSlotId, mSubId, mSelectorType, mCause);
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(@NonNull Parcel out, int flags) {
+ out.writeInt(mSlotId);
+ out.writeInt(mSubId);
+ out.writeString8(mCallId);
+ out.writeString8(mNumber);
+ out.writeInt(mSelectorType);
+ out.writeBoolean(mIsVideoCall);
+ out.writeBoolean(mIsEmergency);
+ out.writeBoolean(mIsExitedFromAirplaneMode);
+ //out.writeParcelable(mUtAttributes, 0);
+ out.writeParcelable(mImsReasonInfo, 0);
+ out.writeInt(mCause);
+ out.writeParcelable(mEmergencyRegResult, 0);
+ }
+
+ private void readFromParcel(@NonNull Parcel in) {
+ mSlotId = in.readInt();
+ mSubId = in.readInt();
+ mCallId = in.readString8();
+ mNumber = in.readString8();
+ mSelectorType = in.readInt();
+ mIsVideoCall = in.readBoolean();
+ mIsEmergency = in.readBoolean();
+ mIsExitedFromAirplaneMode = in.readBoolean();
+ //mUtAttributes = s.mUtAttributes;
+ mImsReasonInfo = in.readParcelable(ImsReasonInfo.class.getClassLoader(),
+ android.telephony.ims.ImsReasonInfo.class);
+ mCause = in.readInt();
+ mEmergencyRegResult = in.readParcelable(EmergencyRegResult.class.getClassLoader(),
+ EmergencyRegResult.class);
+ }
+
+ public static final @NonNull Creator<SelectionAttributes> CREATOR =
+ new Creator<SelectionAttributes>() {
+ @Override
+ public SelectionAttributes createFromParcel(@NonNull Parcel in) {
+ return new SelectionAttributes(in);
+ }
+
+ @Override
+ public SelectionAttributes[] newArray(int size) {
+ return new SelectionAttributes[size];
+ }
+ };
+
+ private static boolean equalsHandlesNulls(Object a, Object b) {
+ return (a == null) ? (b == null) : a.equals(b);
+ }
+
+ /**
+ * Builder class creating a new instance.
+ */
+ public static final class Builder {
+ private final int mSlotId;
+ private final int mSubId;
+ private @Nullable String mCallId;
+ private @Nullable String mNumber;
+ private final @SelectorType int mSelectorType;
+ private boolean mIsVideoCall;
+ private boolean mIsEmergency;
+ private boolean mIsExitedFromAirplaneMode;
+ //private @Nullable UtAttributes mUtAttributes;
+ private @Nullable ImsReasonInfo mImsReasonInfo;
+ private @PreciseDisconnectCauses int mCause;
+ private @Nullable EmergencyRegResult mEmergencyRegResult;
+
+ /**
+ * Default constructor for Builder.
+ */
+ public Builder(int slotId, int subId, @SelectorType int selectorType) {
+ mSlotId = slotId;
+ mSubId = subId;
+ mSelectorType = selectorType;
+ }
+
+ /**
+ * Sets the call identifier.
+ *
+ * @param callId The call identifier.
+ * @return The same instance of the builder.
+ */
+ public @NonNull Builder setCallId(@NonNull String callId) {
+ mCallId = callId;
+ return this;
+ }
+
+ /**
+ * Sets the dialed number.
+ *
+ * @param number The dialed number.
+ * @return The same instance of the builder.
+ */
+ public @NonNull Builder setNumber(@NonNull String number) {
+ mNumber = number;
+ return this;
+ }
+
+ /**
+ * Sets whether it's a video call or not.
+ *
+ * @param video Indicates it's a video call.
+ * @return The same instance of the builder.
+ */
+ public @NonNull Builder setVideoCall(boolean video) {
+ mIsVideoCall = video;
+ return this;
+ }
+
+ /**
+ * Sets whether it's an emergency service or not.
+ *
+ * @param emergency Indicates it's emergency service.
+ * @return The same instance of the builder.
+ */
+ public @NonNull Builder setEmergency(boolean emergency) {
+ mIsEmergency = emergency;
+ return this;
+ }
+
+ /**
+ * Sets whether the request caused the device to move out of airplane mode.
+ *
+ * @param exited {@code true} if the request caused the device to move out of
+ * airplane mode.
+ * @return The same instance of the builder.
+ */
+ public @NonNull Builder setExitedFromAirplaneMode(boolean exited) {
+ mIsExitedFromAirplaneMode = exited;
+ return this;
+ }
+
+ /**
+ * Sets the Ut service attributes.
+ * Only applicable for SELECTOR_TYPE_UT
+ *
+ * @param attr Ut services attributes.
+ * @return The same instance of the builder.
+ */
+ /*
+ public @NonNull Builder setUtAttributes(@NonNull UtAttributes attr);
+ mUtAttributes = attr;
+ return this;
+ }
+ */
+
+ /**
+ * Sets an optional reason why the last PS attempt failed.
+ *
+ * @param info The reason why the last PS attempt failed.
+ * @return The same instance of the builder.
+ */
+ public @NonNull Builder setPsDisconnectCause(@NonNull ImsReasonInfo info) {
+ mImsReasonInfo = info;
+ return this;
+ }
+
+ /**
+ * Sets an optional reason why the last CS attempt failed.
+ *
+ * @param cause The reason why the last CS attempt failed.
+ * @return The same instance of the builder.
+ */
+ public @NonNull Builder setCsDisconnectCause(@PreciseDisconnectCauses int cause) {
+ mCause = cause;
+ return this;
+ }
+
+ /**
+ * Sets the current registration result for emergency services.
+ *
+ * @param regResult The current registration result for emergency services.
+ * @return The same instance of the builder.
+ */
+ public @NonNull Builder setEmergencyRegResult(@NonNull EmergencyRegResult regResult) {
+ mEmergencyRegResult = regResult;
+ return this;
+ }
+
+ /**
+ * Build the SelectionAttributes.
+ * @return The SelectionAttributes object.
+ */
+ public @NonNull SelectionAttributes build() {
+ return new SelectionAttributes(mSlotId, mSubId, mCallId, mNumber, mSelectorType,
+ mIsVideoCall, mIsEmergency, mIsExitedFromAirplaneMode, /*mUtAttributes,*/
+ mImsReasonInfo, mCause, mEmergencyRegResult);
+ }
+ }
+ }
+
+ /**
+ * A wrapper class for ITransportSelectorCallback interface.
+ */
+ private final class TransportSelectorCallbackWrapper implements TransportSelectorCallback {
+ private static final String TAG = "TransportSelectorCallbackWrapper";
+
+ private final @NonNull ITransportSelectorCallback mCallback;
+ private final @NonNull Executor mExecutor;
+
+ private @Nullable ITransportSelectorResultCallbackAdapter mResultCallback;
+ private @Nullable DomainSelectorWrapper mSelectorWrapper;
+
+ TransportSelectorCallbackWrapper(@NonNull ITransportSelectorCallback cb,
+ @NonNull Executor executor) {
+ mCallback = cb;
+ mExecutor = executor;
+ }
+
+ @Override
+ public void onCreated(@NonNull DomainSelector selector) {
+ try {
+ mSelectorWrapper = new DomainSelectorWrapper(selector, mExecutor);
+ mCallback.onCreated(mSelectorWrapper.getCallbackBinder());
+ } catch (Exception e) {
+ Rlog.e(TAG, "onCreated e=" + e);
+ }
+ }
+
+ @Override
+ public void onWlanSelected(boolean useEmergencyPdn) {
+ try {
+ mCallback.onWlanSelected(useEmergencyPdn);
+ } catch (Exception e) {
+ Rlog.e(TAG, "onWlanSelected e=" + e);
+ }
+ }
+
+ @Override
+ public @NonNull WwanSelectorCallback onWwanSelected() {
+ WwanSelectorCallback callback = null;
+ try {
+ IWwanSelectorCallback cb = mCallback.onWwanSelected();
+ callback = new WwanSelectorCallbackWrapper(cb, mExecutor);
+ } catch (Exception e) {
+ Rlog.e(TAG, "onWwanSelected e=" + e);
+ }
+
+ return callback;
+ }
+
+ @Override
+ public void onWwanSelected(Consumer<WwanSelectorCallback> consumer) {
+ try {
+ mResultCallback = new ITransportSelectorResultCallbackAdapter(consumer, mExecutor);
+ mCallback.onWwanSelectedAsync(mResultCallback);
+ } catch (Exception e) {
+ Rlog.e(TAG, "onWwanSelected e=" + e);
+ executeMethodAsyncNoException(mExecutor,
+ () -> consumer.accept(null), TAG, "onWwanSelectedAsync-Exception");
+ }
+ }
+
+ @Override
+ public void onSelectionTerminated(@DisconnectCauses int cause) {
+ try {
+ mCallback.onSelectionTerminated(cause);
+ mSelectorWrapper = null;
+ } catch (Exception e) {
+ Rlog.e(TAG, "onSelectionTerminated e=" + e);
+ }
+ }
+
+ private class ITransportSelectorResultCallbackAdapter
+ extends ITransportSelectorResultCallback.Stub {
+ private final @NonNull Consumer<WwanSelectorCallback> mConsumer;
+ private final @NonNull Executor mExecutor;
+
+ ITransportSelectorResultCallbackAdapter(
+ @NonNull Consumer<WwanSelectorCallback> consumer,
+ @NonNull Executor executor) {
+ mConsumer = consumer;
+ mExecutor = executor;
+ }
+
+ @Override
+ public void onCompleted(@NonNull IWwanSelectorCallback cb) {
+ if (mConsumer == null) return;
+
+ WwanSelectorCallback callback = new WwanSelectorCallbackWrapper(cb, mExecutor);
+ executeMethodAsyncNoException(mExecutor,
+ () -> mConsumer.accept(callback), TAG, "onWwanSelectedAsync-Completed");
+ }
+ }
+ }
+
+ /**
+ * A wrapper class for IDomainSelector interface.
+ */
+ private final class DomainSelectorWrapper {
+ private static final String TAG = "DomainSelectorWrapper";
+
+ private @NonNull IDomainSelector mCallbackBinder;
+
+ DomainSelectorWrapper(@NonNull DomainSelector cb, @NonNull Executor executor) {
+ mCallbackBinder = new IDomainSelectorAdapter(cb, executor);
+ }
+
+ private class IDomainSelectorAdapter extends IDomainSelector.Stub {
+ private final @NonNull WeakReference<DomainSelector> mDomainSelectorWeakRef;
+ private final @NonNull Executor mExecutor;
+
+ IDomainSelectorAdapter(@NonNull DomainSelector domainSelector,
+ @NonNull Executor executor) {
+ mDomainSelectorWeakRef =
+ new WeakReference<DomainSelector>(domainSelector);
+ mExecutor = executor;
+ }
+
+ @Override
+ public void cancelSelection() {
+ final DomainSelector domainSelector = mDomainSelectorWeakRef.get();
+ if (domainSelector == null) return;
+
+ executeMethodAsyncNoException(mExecutor,
+ () -> domainSelector.cancelSelection(), TAG, "cancelSelection");
+ }
+
+ @Override
+ public void reselectDomain(@NonNull SelectionAttributes attr) {
+ final DomainSelector domainSelector = mDomainSelectorWeakRef.get();
+ if (domainSelector == null) return;
+
+ executeMethodAsyncNoException(mExecutor,
+ () -> domainSelector.reselectDomain(attr), TAG, "reselectDomain");
+ }
+
+ @Override
+ public void finishSelection() {
+ final DomainSelector domainSelector = mDomainSelectorWeakRef.get();
+ if (domainSelector == null) return;
+
+ executeMethodAsyncNoException(mExecutor,
+ () -> domainSelector.finishSelection(), TAG, "finishSelection");
+ }
+ }
+
+ public @NonNull IDomainSelector getCallbackBinder() {
+ return mCallbackBinder;
+ }
+ }
+
+ /**
+ * A wrapper class for IWwanSelectorCallback and IWwanSelectorResultCallback.
+ */
+ private final class WwanSelectorCallbackWrapper
+ implements WwanSelectorCallback, CancellationSignal.OnCancelListener {
+ private static final String TAG = "WwanSelectorCallbackWrapper";
+
+ private final @NonNull IWwanSelectorCallback mCallback;
+ private final @NonNull Executor mExecutor;
+
+ private @Nullable IWwanSelectorResultCallbackAdapter mResultCallback;
+
+ WwanSelectorCallbackWrapper(@NonNull IWwanSelectorCallback cb,
+ @NonNull Executor executor) {
+ mCallback = cb;
+ mExecutor = executor;
+ }
+
+ @Override
+ public void onCancel() {
+ try {
+ mCallback.onCancel();
+ } catch (Exception e) {
+ Rlog.e(TAG, "onCancel e=" + e);
+ }
+ }
+
+ @Override
+ public void onRequestEmergencyNetworkScan(@NonNull List<Integer> preferredNetworks,
+ @EmergencyScanType int scanType, @NonNull CancellationSignal signal,
+ @NonNull Consumer<EmergencyRegResult> consumer) {
+ try {
+ if (signal != null) signal.setOnCancelListener(this);
+ mResultCallback = new IWwanSelectorResultCallbackAdapter(consumer, mExecutor);
+ mCallback.onRequestEmergencyNetworkScan(
+ preferredNetworks.stream().mapToInt(Integer::intValue).toArray(),
+ scanType, mResultCallback);
+ } catch (Exception e) {
+ Rlog.e(TAG, "onRequestEmergencyNetworkScan e=" + e);
+ }
+ }
+
+ @Override
+ public void onDomainSelected(@NetworkRegistrationInfo.Domain int domain,
+ boolean useEmergencyPdn) {
+ try {
+ mCallback.onDomainSelected(domain, useEmergencyPdn);
+ } catch (Exception e) {
+ Rlog.e(TAG, "onDomainSelected e=" + e);
+ }
+ }
+
+ private class IWwanSelectorResultCallbackAdapter
+ extends IWwanSelectorResultCallback.Stub {
+ private final @NonNull Consumer<EmergencyRegResult> mConsumer;
+ private final @NonNull Executor mExecutor;
+
+ IWwanSelectorResultCallbackAdapter(@NonNull Consumer<EmergencyRegResult> consumer,
+ @NonNull Executor executor) {
+ mConsumer = consumer;
+ mExecutor = executor;
+ }
+
+ @Override
+ public void onComplete(@NonNull EmergencyRegResult result) {
+ if (mConsumer == null) return;
+
+ executeMethodAsyncNoException(mExecutor,
+ () -> mConsumer.accept(result), TAG, "onScanComplete");
+ }
+ }
+ }
+
+ private final Object mExecutorLock = new Object();
+
+ /** Executor used to execute methods called remotely by the framework. */
+ private @NonNull Executor mExecutor;
+
+ /**
+ * Selects a domain for the given operation.
+ *
+ * @param attr Required to determine the domain.
+ * @param callback The callback instance being registered.
+ */
+ public void onDomainSelection(@NonNull SelectionAttributes attr,
+ @NonNull TransportSelectorCallback callback) {
+ }
+
+ /**
+ * Notifies the change in {@link ServiceState} for a specific slot.
+ *
+ * @param slotId For which the state changed.
+ * @param subId For which the state changed.
+ * @param serviceState Updated {@link ServiceState}.
+ */
+ public void onServiceStateUpdated(int slotId, int subId, @NonNull ServiceState serviceState) {
+ }
+
+ /**
+ * Notifies the change in {@link BarringInfo} for a specific slot.
+ *
+ * @param slotId For which the state changed.
+ * @param subId For which the state changed.
+ * @param info Updated {@link BarringInfo}.
+ */
+ public void onBarringInfoUpdated(int slotId, int subId, @NonNull BarringInfo info) {
+ }
+
+ private final IBinder mDomainSelectionServiceController =
+ new IDomainSelectionServiceController.Stub() {
+ @Override
+ public void selectDomain(@NonNull SelectionAttributes attr,
+ @NonNull ITransportSelectorCallback callback) throws RemoteException {
+ executeMethodAsync(getCachedExecutor(),
+ () -> DomainSelectionService.this.onDomainSelection(attr,
+ new TransportSelectorCallbackWrapper(callback, getCachedExecutor())),
+ LOG_TAG, "onDomainSelection");
+ }
+
+ @Override
+ public void updateServiceState(int slotId, int subId, @NonNull ServiceState serviceState) {
+ executeMethodAsyncNoException(getCachedExecutor(),
+ () -> DomainSelectionService.this.onServiceStateUpdated(slotId,
+ subId, serviceState), LOG_TAG, "onServiceStateUpdated");
+ }
+
+ @Override
+ public void updateBarringInfo(int slotId, int subId, @NonNull BarringInfo info) {
+ executeMethodAsyncNoException(getCachedExecutor(),
+ () -> DomainSelectionService.this.onBarringInfoUpdated(slotId, subId, info),
+ LOG_TAG, "onBarringInfoUpdated");
+ }
+ };
+
+ private static void executeMethodAsync(@NonNull Executor executor, @NonNull Runnable r,
+ @NonNull String tag, @NonNull String errorLogName) throws RemoteException {
+ try {
+ CompletableFuture.runAsync(
+ () -> TelephonyUtils.runWithCleanCallingIdentity(r), executor).join();
+ } catch (CancellationException | CompletionException e) {
+ Rlog.w(tag, "Binder - " + errorLogName + " exception: " + e.getMessage());
+ throw new RemoteException(e.getMessage());
+ }
+ }
+
+ private void executeMethodAsyncNoException(@NonNull Executor executor, @NonNull Runnable r,
+ @NonNull String tag, @NonNull String errorLogName) {
+ try {
+ CompletableFuture.runAsync(
+ () -> TelephonyUtils.runWithCleanCallingIdentity(r), executor).join();
+ } catch (CancellationException | CompletionException e) {
+ Rlog.w(tag, "Binder - " + errorLogName + " exception: " + e.getMessage());
+ }
+ }
+
+ /** @hide */
+ @Override
+ public IBinder onBind(Intent intent) {
+ if (SERVICE_INTERFACE.equals(intent.getAction())) {
+ Log.i(LOG_TAG, "DomainSelectionService Bound.");
+ return mDomainSelectionServiceController;
+ }
+ return null;
+ }
+
+ /**
+ * The DomainSelectionService will be able to define an {@link Executor} that the service
+ * can use to execute the methods. It has set the default executor as Runnable::run,
+ *
+ * @return An {@link Executor} to be used.
+ */
+ @SuppressLint("OnNameExpected")
+ public @NonNull Executor getExecutor() {
+ return Runnable::run;
+ }
+
+ /**
+ * Gets the {@link Executor} which executes methods of this service.
+ * This method should be private when this service is implemented in a separated process
+ * other than telephony framework.
+ * @return {@link Executor} instance.
+ * @hide
+ */
+ public @NonNull Executor getCachedExecutor() {
+ synchronized (mExecutorLock) {
+ if (mExecutor == null) {
+ Executor e = getExecutor();
+ mExecutor = (e != null) ? e : Runnable::run;
+ }
+ return mExecutor;
+ }
+ }
+
+ /**
+ * Returns a string representation of the domain.
+ * @param domain The domain.
+ * @return The name of the domain.
+ * @hide
+ */
+ public static @NonNull String getDomainName(@NetworkRegistrationInfo.Domain int domain) {
+ return NetworkRegistrationInfo.domainToString(domain);
+ }
+}
diff --git a/telephony/java/android/telephony/DomainSelector.java b/telephony/java/android/telephony/DomainSelector.java
new file mode 100644
index 000000000000..087183122670
--- /dev/null
+++ b/telephony/java/android/telephony/DomainSelector.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.telephony;
+
+import android.annotation.NonNull;
+import android.telephony.DomainSelectionService.SelectionAttributes;
+
+/**
+ * Implemented as part of the {@link DomainSelectionService} to implement domain selection
+ * for a specific use case.
+ * @hide
+ */
+public interface DomainSelector {
+ /**
+ * Cancel an ongoing selection operation. It is up to the DomainSelectionService
+ * to clean up all ongoing operations with the framework.
+ */
+ void cancelSelection();
+
+ /**
+ * Reselect a domain due to the call not setting up properly.
+ *
+ * @param attr attributes required to select the domain.
+ */
+ void reselectDomain(@NonNull SelectionAttributes attr);
+
+ /**
+ * Finish the selection procedure and clean everything up.
+ */
+ void finishSelection();
+}
diff --git a/telephony/java/android/telephony/EmergencyRegResult.aidl b/telephony/java/android/telephony/EmergencyRegResult.aidl
new file mode 100644
index 000000000000..f7229621c0c1
--- /dev/null
+++ b/telephony/java/android/telephony/EmergencyRegResult.aidl
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package android.telephony;
+
+parcelable EmergencyRegResult;
diff --git a/telephony/java/android/telephony/EmergencyRegResult.java b/telephony/java/android/telephony/EmergencyRegResult.java
new file mode 100644
index 000000000000..5aed41254cf6
--- /dev/null
+++ b/telephony/java/android/telephony/EmergencyRegResult.java
@@ -0,0 +1,318 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.telephony;
+
+import android.annotation.NonNull;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.text.TextUtils;
+
+import java.util.Objects;
+
+/**
+ * Contains attributes required to determine the domain for a telephony service
+ * @hide
+ */
+public final class EmergencyRegResult implements Parcelable {
+
+ /**
+ * Indicates the cellular network type of the acquired system.
+ */
+ private @AccessNetworkConstants.RadioAccessNetworkType int mAccessNetworkType;
+
+ /**
+ * Registration state of the acquired system.
+ */
+ private @NetworkRegistrationInfo.RegistrationState int mRegState;
+
+ /**
+ * EMC domain indicates the current domain of the acquired system.
+ */
+ private @NetworkRegistrationInfo.Domain int mDomain;
+
+ /**
+ * Indicates whether the network supports voice over PS network.
+ */
+ private boolean mIsVopsSupported;
+
+ /**
+ * This indicates if camped network support VoLTE emergency bearers.
+ * This should only be set if the UE is in LTE mode.
+ */
+ private boolean mIsEmcBearerSupported;
+
+ /**
+ * The value of the network provided EMC in 5G Registration ACCEPT.
+ * This should be set only if the UE is in 5G mode.
+ */
+ private int mNwProvidedEmc;
+
+ /**
+ * The value of the network provided EMF(EPS Fallback) in 5G Registration ACCEPT.
+ * This should be set only if the UE is in 5G mode.
+ */
+ private int mNwProvidedEmf;
+
+ /** 3-digit Mobile Country Code, 000..999, empty string if unknown. */
+ private @NonNull String mMcc;
+
+ /** 2 or 3-digit Mobile Network Code, 00..999, empty string if unknown. */
+ private @NonNull String mMnc;
+
+ /**
+ * The ISO-3166-1 alpha-2 country code equivalent for the network's country code,
+ * empty string if unknown.
+ */
+ private @NonNull String mIso;
+
+ /**
+ * Constructor
+ * @param accessNetwork Indicates the network type of the acquired system.
+ * @param regState Indicates the registration state of the acquired system.
+ * @param domain Indicates the current domain of the acquired system.
+ * @param isVopsSupported Indicates whether the network supports voice over PS network.
+ * @param isEmcBearerSupported Indicates if camped network support VoLTE emergency bearers.
+ * @param emc The value of the network provided EMC in 5G Registration ACCEPT.
+ * @param emf The value of the network provided EMF(EPS Fallback) in 5G Registration ACCEPT.
+ * @param mcc Mobile country code, empty string if unknown.
+ * @param mnc Mobile network code, empty string if unknown.
+ * @param iso The ISO-3166-1 alpha-2 country code equivalent, empty string if unknown.
+ * @hide
+ */
+ public EmergencyRegResult(
+ @AccessNetworkConstants.RadioAccessNetworkType int accessNetwork,
+ @NetworkRegistrationInfo.RegistrationState int regState,
+ @NetworkRegistrationInfo.Domain int domain,
+ boolean isVopsSupported, boolean isEmcBearerSupported, int emc, int emf,
+ @NonNull String mcc, @NonNull String mnc, @NonNull String iso) {
+ mAccessNetworkType = accessNetwork;
+ mRegState = regState;
+ mDomain = domain;
+ mIsVopsSupported = isVopsSupported;
+ mIsEmcBearerSupported = isEmcBearerSupported;
+ mNwProvidedEmc = emc;
+ mNwProvidedEmf = emf;
+ mMcc = mcc;
+ mMnc = mnc;
+ mIso = iso;
+ }
+
+ /**
+ * Copy constructors
+ *
+ * @param s Source emergency scan result
+ * @hide
+ */
+ public EmergencyRegResult(@NonNull EmergencyRegResult s) {
+ mAccessNetworkType = s.mAccessNetworkType;
+ mRegState = s.mRegState;
+ mDomain = s.mDomain;
+ mIsVopsSupported = s.mIsVopsSupported;
+ mIsEmcBearerSupported = s.mIsEmcBearerSupported;
+ mNwProvidedEmc = s.mNwProvidedEmc;
+ mNwProvidedEmf = s.mNwProvidedEmf;
+ mMcc = s.mMcc;
+ mMnc = s.mMnc;
+ mIso = s.mIso;
+ }
+
+ /**
+ * Construct a EmergencyRegResult object from the given parcel.
+ */
+ private EmergencyRegResult(@NonNull Parcel in) {
+ readFromParcel(in);
+ }
+
+ /**
+ * Returns the cellular access network type of the acquired system.
+ *
+ * @return the cellular network type.
+ */
+ public @AccessNetworkConstants.RadioAccessNetworkType int getAccessNetwork() {
+ return mAccessNetworkType;
+ }
+
+ /**
+ * Returns the registration state of the acquired system.
+ *
+ * @return the registration state.
+ */
+ public @NetworkRegistrationInfo.RegistrationState int getRegState() {
+ return mRegState;
+ }
+
+ /**
+ * Returns the current domain of the acquired system.
+ *
+ * @return the current domain.
+ */
+ public @NetworkRegistrationInfo.Domain int getDomain() {
+ return mDomain;
+ }
+
+ /**
+ * Returns whether the network supports voice over PS network.
+ *
+ * @return {@code true} if the network supports voice over PS network.
+ */
+ public boolean isVopsSupported() {
+ return mIsVopsSupported;
+ }
+
+ /**
+ * Returns whether camped network support VoLTE emergency bearers.
+ * This is not valid if the UE is not in LTE mode.
+ *
+ * @return {@code true} if the network supports VoLTE emergency bearers.
+ */
+ public boolean isEmcBearerSupported() {
+ return mIsEmcBearerSupported;
+ }
+
+ /**
+ * Returns the value of the network provided EMC in 5G Registration ACCEPT.
+ * This is not valid if UE is not in 5G mode.
+ *
+ * @return the value of the network provided EMC.
+ */
+ public int getNwProvidedEmc() {
+ return mNwProvidedEmc;
+ }
+
+ /**
+ * Returns the value of the network provided EMF(EPS Fallback) in 5G Registration ACCEPT.
+ * This is not valid if UE is not in 5G mode.
+ *
+ * @return the value of the network provided EMF.
+ */
+ public int getNwProvidedEmf() {
+ return mNwProvidedEmf;
+ }
+
+ /**
+ * Returns 3-digit Mobile Country Code.
+ *
+ * @return Mobile Country Code.
+ */
+ public @NonNull String getMcc() {
+ return mMcc;
+ }
+
+ /**
+ * Returns 2 or 3-digit Mobile Network Code.
+ *
+ * @return Mobile Network Code.
+ */
+ public @NonNull String getMnc() {
+ return mMnc;
+ }
+
+ /**
+ * Returns the ISO-3166-1 alpha-2 country code is provided in lowercase 2 character format.
+ *
+ * @return Country code.
+ */
+ public @NonNull String getIso() {
+ return mIso;
+ }
+
+ @Override
+ public @NonNull String toString() {
+ return "{ accessNetwork="
+ + AccessNetworkConstants.AccessNetworkType.toString(mAccessNetworkType)
+ + ", regState=" + NetworkRegistrationInfo.registrationStateToString(mRegState)
+ + ", domain=" + NetworkRegistrationInfo.domainToString(mDomain)
+ + ", vops=" + mIsVopsSupported
+ + ", emcBearer=" + mIsEmcBearerSupported
+ + ", emc=" + mNwProvidedEmc
+ + ", emf=" + mNwProvidedEmf
+ + ", mcc=" + mMcc
+ + ", mnc=" + mMnc
+ + ", iso=" + mIso
+ + " }";
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ EmergencyRegResult that = (EmergencyRegResult) o;
+ return mAccessNetworkType == that.mAccessNetworkType
+ && mRegState == that.mRegState
+ && mDomain == that.mDomain
+ && mIsVopsSupported == that.mIsVopsSupported
+ && mIsEmcBearerSupported == that.mIsEmcBearerSupported
+ && mNwProvidedEmc == that.mNwProvidedEmc
+ && mNwProvidedEmf == that.mNwProvidedEmf
+ && TextUtils.equals(mMcc, that.mMcc)
+ && TextUtils.equals(mMnc, that.mMnc)
+ && TextUtils.equals(mIso, that.mIso);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(mAccessNetworkType, mRegState, mDomain,
+ mIsVopsSupported, mIsEmcBearerSupported,
+ mNwProvidedEmc, mNwProvidedEmf,
+ mMcc, mMnc, mIso);
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(@NonNull Parcel out, int flags) {
+ out.writeInt(mAccessNetworkType);
+ out.writeInt(mRegState);
+ out.writeInt(mDomain);
+ out.writeBoolean(mIsVopsSupported);
+ out.writeBoolean(mIsEmcBearerSupported);
+ out.writeInt(mNwProvidedEmc);
+ out.writeInt(mNwProvidedEmf);
+ out.writeString8(mMcc);
+ out.writeString8(mMnc);
+ out.writeString8(mIso);
+ }
+
+ private void readFromParcel(@NonNull Parcel in) {
+ mAccessNetworkType = in.readInt();
+ mRegState = in.readInt();
+ mDomain = in.readInt();
+ mIsVopsSupported = in.readBoolean();
+ mIsEmcBearerSupported = in.readBoolean();
+ mNwProvidedEmc = in.readInt();
+ mNwProvidedEmf = in.readInt();
+ mMcc = in.readString8();
+ mMnc = in.readString8();
+ mIso = in.readString8();
+ }
+
+ public static final @NonNull Creator<EmergencyRegResult> CREATOR =
+ new Creator<EmergencyRegResult>() {
+ @Override
+ public EmergencyRegResult createFromParcel(@NonNull Parcel in) {
+ return new EmergencyRegResult(in);
+ }
+
+ @Override
+ public EmergencyRegResult[] newArray(int size) {
+ return new EmergencyRegResult[size];
+ }
+ };
+}
diff --git a/telephony/java/android/telephony/ModemActivityInfo.java b/telephony/java/android/telephony/ModemActivityInfo.java
index 2d0135ae1c99..64b3c0a203e3 100644
--- a/telephony/java/android/telephony/ModemActivityInfo.java
+++ b/telephony/java/android/telephony/ModemActivityInfo.java
@@ -567,14 +567,14 @@ public final class ModemActivityInfo implements Parcelable {
/** @hide */
@TestApi
public boolean isEmpty() {
- boolean isTxPowerEmpty = false;
- boolean isRxPowerEmpty = false;
+ boolean isTxPowerEmpty = true;
+ boolean isRxPowerEmpty = true;
for (int i = 0; i < getSpecificInfoLength(); i++) {
- if (mActivityStatsTechSpecificInfo[i].isTxPowerEmpty()) {
- isTxPowerEmpty = true;
+ if (!mActivityStatsTechSpecificInfo[i].isTxPowerEmpty()) {
+ isTxPowerEmpty = false;
}
- if (mActivityStatsTechSpecificInfo[i].isRxPowerEmpty()) {
- isRxPowerEmpty = true;
+ if (!mActivityStatsTechSpecificInfo[i].isRxPowerEmpty()) {
+ isRxPowerEmpty = false;
}
}
return isTxPowerEmpty
diff --git a/telephony/java/android/telephony/NetworkRegistrationInfo.java b/telephony/java/android/telephony/NetworkRegistrationInfo.java
index f1f13bc6bb55..b0552b4a18a3 100644
--- a/telephony/java/android/telephony/NetworkRegistrationInfo.java
+++ b/telephony/java/android/telephony/NetworkRegistrationInfo.java
@@ -20,6 +20,9 @@ import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
+import android.app.compat.CompatChanges;
+import android.compat.annotation.ChangeId;
+import android.compat.annotation.EnabledSince;
import android.os.Build;
import android.os.Parcel;
import android.os.Parcelable;
@@ -39,6 +42,16 @@ import java.util.stream.Collectors;
* Description of a mobile network registration info
*/
public final class NetworkRegistrationInfo implements Parcelable {
+
+ /**
+ * A new registration state, REGISTRATION_STATE_EMERGENCY, is added to
+ * {@link NetworkRegistrationInfo}. This change will affect the result of getRegistration().
+ * @hide
+ */
+ @ChangeId
+ @EnabledSince(targetSdkVersion = android.os.Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
+ public static final long RETURN_REGISTRATION_STATE_EMERGENCY = 255938466L;
+
/**
* Network domain
* @hide
@@ -64,7 +77,8 @@ public final class NetworkRegistrationInfo implements Parcelable {
@IntDef(prefix = "REGISTRATION_STATE_",
value = {REGISTRATION_STATE_NOT_REGISTERED_OR_SEARCHING, REGISTRATION_STATE_HOME,
REGISTRATION_STATE_NOT_REGISTERED_SEARCHING, REGISTRATION_STATE_DENIED,
- REGISTRATION_STATE_UNKNOWN, REGISTRATION_STATE_ROAMING})
+ REGISTRATION_STATE_UNKNOWN, REGISTRATION_STATE_ROAMING,
+ REGISTRATION_STATE_EMERGENCY})
public @interface RegistrationState {}
/**
@@ -103,6 +117,18 @@ public final class NetworkRegistrationInfo implements Parcelable {
*/
@SystemApi
public static final int REGISTRATION_STATE_ROAMING = 5;
+ /**
+ * Emergency attached in EPS or in 5GS.
+ * IMS service will skip emergency registration if the device is in
+ * emergency attached state. {@link #mEmergencyOnly} can be true
+ * even in case it's not in emergency attached state.
+ *
+ * Reference: 3GPP TS 24.301 9.9.3.11 EPS attach type.
+ * Reference: 3GPP TS 24.501 9.11.3.6 5GS registration result.
+ * @hide
+ */
+ @SystemApi
+ public static final int REGISTRATION_STATE_EMERGENCY = 6;
/** @hide */
@Retention(RetentionPolicy.SOURCE)
@@ -313,8 +339,12 @@ public final class NetworkRegistrationInfo implements Parcelable {
@Nullable VopsSupportInfo vopsSupportInfo) {
this(domain, transportType, registrationState, accessNetworkTechnology, rejectCause,
emergencyOnly, availableServices, cellIdentity, rplmn, null,
- new DataSpecificRegistrationInfo(maxDataCalls, isDcNrRestricted, isNrAvailable,
- isEndcAvailable, vopsSupportInfo));
+ new DataSpecificRegistrationInfo.Builder(maxDataCalls)
+ .setDcNrRestricted(isDcNrRestricted)
+ .setNrAvailable(isNrAvailable)
+ .setEnDcAvailable(isEndcAvailable)
+ .setVopsSupportInfo(vopsSupportInfo)
+ .build());
}
private NetworkRegistrationInfo(Parcel source) {
@@ -411,6 +441,15 @@ public final class NetworkRegistrationInfo implements Parcelable {
@Deprecated
@SystemApi
public @RegistrationState int getRegistrationState() {
+ if (mRegistrationState == REGISTRATION_STATE_EMERGENCY) {
+ if (!CompatChanges.isChangeEnabled(RETURN_REGISTRATION_STATE_EMERGENCY)) {
+ if (mAccessNetworkTechnology == TelephonyManager.NETWORK_TYPE_LTE) {
+ return REGISTRATION_STATE_DENIED;
+ } else if (mAccessNetworkTechnology == TelephonyManager.NETWORK_TYPE_NR) {
+ return REGISTRATION_STATE_NOT_REGISTERED_OR_SEARCHING;
+ }
+ }
+ }
return mRegistrationState;
}
@@ -676,6 +715,7 @@ public final class NetworkRegistrationInfo implements Parcelable {
case REGISTRATION_STATE_DENIED: return "DENIED";
case REGISTRATION_STATE_UNKNOWN: return "UNKNOWN";
case REGISTRATION_STATE_ROAMING: return "ROAMING";
+ case REGISTRATION_STATE_EMERGENCY: return "EMERGENCY";
}
return "Unknown reg state " + registrationState;
}
diff --git a/telephony/java/android/telephony/PhoneCapability.java b/telephony/java/android/telephony/PhoneCapability.java
index 63e3468ac19b..48170dfd0e54 100644
--- a/telephony/java/android/telephony/PhoneCapability.java
+++ b/telephony/java/android/telephony/PhoneCapability.java
@@ -90,7 +90,9 @@ public final class PhoneCapability implements Parcelable {
/**
* mMaxActiveVoiceSubscriptions defines the maximum subscriptions that can support
* simultaneous voice calls. For a dual sim dual standby (DSDS) device it would be one, but
- * for a dual sim dual active device it would be 2.
+ * for a dual sim dual active (DSDA) device, or a DSDS device that supports "virtual DSDA" (
+ * using the data line of 1 SIM to temporarily provide IMS voice connectivity to the other SIM)
+ * it would be 2.
*
* @hide
*/
@@ -99,7 +101,7 @@ public final class PhoneCapability implements Parcelable {
/**
* mMaxActiveDataSubscriptions defines the maximum subscriptions that can support
* simultaneous data connections.
- * For example, for L+L device it should be 2.
+ * For example, for dual sim dual active L+L device it should be 2.
*
* @hide
*/
@@ -114,14 +116,20 @@ public final class PhoneCapability implements Parcelable {
*/
private final boolean mNetworkValidationBeforeSwitchSupported;
- /** @hide */
+ /**
+ * List of logical modem information.
+ *
+ * @hide
+ */
+ @NonNull
private final List<ModemInfo> mLogicalModemList;
/**
- * List of logical modem information.
+ * Device NR capabilities.
*
* @hide
*/
+ @NonNull
private final int[] mDeviceNrCapabilities;
/** @hide */
@@ -136,6 +144,18 @@ public final class PhoneCapability implements Parcelable {
this.mDeviceNrCapabilities = deviceNrCapabilities;
}
+ private PhoneCapability(@NonNull Builder builder) {
+ this.mMaxActiveVoiceSubscriptions = builder.mMaxActiveVoiceSubscriptions;
+ this.mMaxActiveDataSubscriptions = builder.mMaxActiveDataSubscriptions;
+ // Make sure it's not null.
+ this.mLogicalModemList = builder.mLogicalModemList == null ? new ArrayList<>()
+ : builder.mLogicalModemList;
+ this.mNetworkValidationBeforeSwitchSupported =
+ builder.mNetworkValidationBeforeSwitchSupported;
+ this.mDeviceNrCapabilities = builder.mDeviceNrCapabilities;
+
+ }
+
@Override
public String toString() {
return "mMaxActiveVoiceSubscriptions=" + mMaxActiveVoiceSubscriptions
@@ -264,4 +284,121 @@ public final class PhoneCapability implements Parcelable {
public @NonNull @DeviceNrCapability int[] getDeviceNrCapabilities() {
return mDeviceNrCapabilities == null ? (new int[0]) : mDeviceNrCapabilities;
}
+
+
+ /**
+ * Builder for {@link PhoneCapability}.
+ *
+ * @hide
+ */
+ public static class Builder {
+ /**
+ * mMaxActiveVoiceSubscriptions defines the maximum subscriptions that can support
+ * simultaneous voice calls. For a dual sim dual standby (DSDS) device it would be one, but
+ * for a dual sim dual active (DSDA) device, or a DSDS device that supports "virtual DSDA"
+ * (using the data line of 1 SIM to temporarily provide IMS voice connectivity to the other
+ * SIM) it would be 2.
+ *
+ * @hide
+ */
+ private int mMaxActiveVoiceSubscriptions = 0;
+
+ /**
+ * mMaxActiveDataSubscriptions defines the maximum subscriptions that can support
+ * simultaneous data connections. For example, for L+L device it should be 2.
+ *
+ * @hide
+ */
+ private int mMaxActiveDataSubscriptions = 0;
+
+ /**
+ * Whether modem supports both internet PDN up so that we can do ping test before tearing
+ * down the other one.
+ *
+ * @hide
+ */
+ private boolean mNetworkValidationBeforeSwitchSupported = false;
+
+ /**
+ * List of logical modem information.
+ *
+ * @hide
+ */
+ @NonNull
+ private List<ModemInfo> mLogicalModemList = new ArrayList<>();
+
+ /**
+ * Device NR capabilities.
+ *
+ * @hide
+ */
+ @NonNull
+ private int[] mDeviceNrCapabilities = new int[0];
+
+ /**
+ * Default constructor.
+ */
+ public Builder() {
+ }
+
+ public Builder(@NonNull PhoneCapability phoneCapability) {
+ mMaxActiveVoiceSubscriptions = phoneCapability.mMaxActiveVoiceSubscriptions;
+ mMaxActiveDataSubscriptions = phoneCapability.mMaxActiveDataSubscriptions;
+ mNetworkValidationBeforeSwitchSupported =
+ phoneCapability.mNetworkValidationBeforeSwitchSupported;
+ mLogicalModemList = phoneCapability.mLogicalModemList;
+ mDeviceNrCapabilities = phoneCapability.mDeviceNrCapabilities;
+ }
+
+ /**
+ * Sets the max active voice subscriptions supported by the device.
+ */
+ public Builder setMaxActiveVoiceSubscriptions(int maxActiveVoiceSubscriptions) {
+ mMaxActiveVoiceSubscriptions = maxActiveVoiceSubscriptions;
+ return this;
+ }
+
+ /**
+ * Sets the max active voice subscriptions supported by the device.
+ */
+ public Builder setMaxActiveDataSubscriptions(int maxActiveDataSubscriptions) {
+ mMaxActiveDataSubscriptions = maxActiveDataSubscriptions;
+ return this;
+ }
+
+ /**
+ * Sets the max active data subscriptions supported by the device. Can be fewer than the
+ * active voice subscriptions.
+ */
+ public Builder setNetworkValidationBeforeSwitchSupported(
+ boolean networkValidationBeforeSwitchSupported) {
+ mNetworkValidationBeforeSwitchSupported = networkValidationBeforeSwitchSupported;
+ return this;
+ }
+
+ /**
+ * Sets the logical modem list of the device.
+ */
+ public Builder setLogicalModemList(@NonNull List<ModemInfo> logicalModemList) {
+ mLogicalModemList = logicalModemList;
+ return this;
+ }
+
+ /**
+ * Sets the NR capabilities supported by the device.
+ */
+ public Builder setDeviceNrCapabilities(@NonNull int[] deviceNrCapabilities) {
+ mDeviceNrCapabilities = deviceNrCapabilities;
+ return this;
+ }
+
+ /**
+ * Build the {@link PhoneCapability}.
+ *
+ * @return The {@link PhoneCapability} instance.
+ */
+ public PhoneCapability build() {
+ return new PhoneCapability(this);
+ }
+ }
}
diff --git a/telephony/java/android/telephony/PhoneNumberUtils.java b/telephony/java/android/telephony/PhoneNumberUtils.java
index 1273aa3abbc9..cf0561db2ae3 100644
--- a/telephony/java/android/telephony/PhoneNumberUtils.java
+++ b/telephony/java/android/telephony/PhoneNumberUtils.java
@@ -27,7 +27,6 @@ import android.content.Intent;
import android.content.res.Resources;
import android.database.Cursor;
import android.net.Uri;
-import android.os.Build;
import android.os.PersistableBundle;
import android.provider.Contacts;
import android.provider.ContactsContract;
@@ -1527,10 +1526,14 @@ public class PhoneNumberUtils {
* Formats the specified {@code phoneNumber} to the E.164 representation.
*
* @param phoneNumber the phone number to format.
- * @param defaultCountryIso the ISO 3166-1 two letters country code.
+ * @param defaultCountryIso the ISO 3166-1 two letters country code in UPPER CASE.
* @return the E.164 representation, or null if the given phone number is not valid.
*/
public static String formatNumberToE164(String phoneNumber, String defaultCountryIso) {
+ if (defaultCountryIso != null) {
+ defaultCountryIso = defaultCountryIso.toUpperCase(Locale.ROOT);
+ }
+
return formatNumberInternal(phoneNumber, defaultCountryIso, PhoneNumberFormat.E164);
}
@@ -1538,10 +1541,14 @@ public class PhoneNumberUtils {
* Formats the specified {@code phoneNumber} to the RFC3966 representation.
*
* @param phoneNumber the phone number to format.
- * @param defaultCountryIso the ISO 3166-1 two letters country code.
+ * @param defaultCountryIso the ISO 3166-1 two letters country code in UPPER CASE.
* @return the RFC3966 representation, or null if the given phone number is not valid.
*/
public static String formatNumberToRFC3966(String phoneNumber, String defaultCountryIso) {
+ if (defaultCountryIso != null) {
+ defaultCountryIso = defaultCountryIso.toUpperCase(Locale.ROOT);
+ }
+
return formatNumberInternal(phoneNumber, defaultCountryIso, PhoneNumberFormat.RFC3966);
}
@@ -1592,6 +1599,10 @@ public class PhoneNumberUtils {
return false;
}
+ if (defaultCountryIso != null) {
+ defaultCountryIso = defaultCountryIso.toUpperCase(Locale.ROOT);
+ }
+
PhoneNumberUtil util = PhoneNumberUtil.getInstance();
try {
PhoneNumber pn = util.parseAndKeepRawInput(phoneNumber, defaultCountryIso);
@@ -1620,6 +1631,10 @@ public class PhoneNumberUtils {
return phoneNumber;
}
+ if (defaultCountryIso != null) {
+ defaultCountryIso = defaultCountryIso.toUpperCase(Locale.ROOT);
+ }
+
PhoneNumberUtil util = PhoneNumberUtil.getInstance();
String result = null;
try {
@@ -1672,6 +1687,10 @@ public class PhoneNumberUtils {
*/
public static String formatNumber(
String phoneNumber, String phoneNumberE164, String defaultCountryIso) {
+ if (defaultCountryIso != null) {
+ defaultCountryIso = defaultCountryIso.toUpperCase(Locale.ROOT);
+ }
+
int len = phoneNumber.length();
for (int i = 0; i < len; i++) {
if (!isDialable(phoneNumber.charAt(i))) {
@@ -1782,266 +1801,21 @@ public class PhoneNumberUtils {
public static boolean isEmergencyNumber(int subId, String number) {
// Return true only if the specified number *exactly* matches
// one of the emergency numbers listed by the RIL / SIM.
- return isEmergencyNumberInternal(subId, number, true /* useExactMatch */);
- }
-
- /**
- * Checks if given number might *potentially* result in
- * a call to an emergency service on the current network.
- *
- * Specifically, this method will return true if the specified number
- * is an emergency number according to the list managed by the RIL or
- * SIM, *or* if the specified number simply starts with the same
- * digits as any of the emergency numbers listed in the RIL / SIM.
- *
- * This method is intended for internal use by the phone app when
- * deciding whether to allow ACTION_CALL intents from 3rd party apps
- * (where we're required to *not* allow emergency calls to be placed.)
- *
- * @param number the number to look up.
- * @return true if the number is in the list of emergency numbers
- * listed in the RIL / SIM, *or* if the number starts with the
- * same digits as any of those emergency numbers.
- *
- * @deprecated Please use {@link TelephonyManager#isPotentialEmergencyNumber(String)}
- * instead.
- *
- * @hide
- */
- @Deprecated
- public static boolean isPotentialEmergencyNumber(String number) {
- return isPotentialEmergencyNumber(getDefaultVoiceSubId(), number);
- }
-
- /**
- * Checks if given number might *potentially* result in
- * a call to an emergency service on the current network.
- *
- * Specifically, this method will return true if the specified number
- * is an emergency number according to the list managed by the RIL or
- * SIM, *or* if the specified number simply starts with the same
- * digits as any of the emergency numbers listed in the RIL / SIM.
- *
- * This method is intended for internal use by the phone app when
- * deciding whether to allow ACTION_CALL intents from 3rd party apps
- * (where we're required to *not* allow emergency calls to be placed.)
- *
- * @param subId the subscription id of the SIM.
- * @param number the number to look up.
- * @return true if the number is in the list of emergency numbers
- * listed in the RIL / SIM, *or* if the number starts with the
- * same digits as any of those emergency numbers.
- *
- * @deprecated Please use {@link TelephonyManager#isPotentialEmergencyNumber(String)}
- * instead.
- *
- * @hide
- */
- @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
- @Deprecated
- public static boolean isPotentialEmergencyNumber(int subId, String number) {
- // Check against the emergency numbers listed by the RIL / SIM,
- // and *don't* require an exact match.
- return isEmergencyNumberInternal(subId, number, false /* useExactMatch */);
- }
-
- /**
- * Helper function for isEmergencyNumber(String) and
- * isPotentialEmergencyNumber(String).
- *
- * @param number the number to look up.
- *
- * @param useExactMatch if true, consider a number to be an emergency
- * number only if it *exactly* matches a number listed in
- * the RIL / SIM. If false, a number is considered to be an
- * emergency number if it simply starts with the same digits
- * as any of the emergency numbers listed in the RIL / SIM.
- * (Setting useExactMatch to false allows you to identify
- * number that could *potentially* result in emergency calls
- * since many networks will actually ignore trailing digits
- * after a valid emergency number.)
- *
- * @return true if the number is in the list of emergency numbers
- * listed in the RIL / sim, otherwise return false.
- */
- private static boolean isEmergencyNumberInternal(String number, boolean useExactMatch) {
- return isEmergencyNumberInternal(getDefaultVoiceSubId(), number, useExactMatch);
- }
-
- /**
- * Helper function for isEmergencyNumber(String) and
- * isPotentialEmergencyNumber(String).
- *
- * @param subId the subscription id of the SIM.
- * @param number the number to look up.
- *
- * @param useExactMatch if true, consider a number to be an emergency
- * number only if it *exactly* matches a number listed in
- * the RIL / SIM. If false, a number is considered to be an
- * emergency number if it simply starts with the same digits
- * as any of the emergency numbers listed in the RIL / SIM.
- * (Setting useExactMatch to false allows you to identify
- * number that could *potentially* result in emergency calls
- * since many networks will actually ignore trailing digits
- * after a valid emergency number.)
- *
- * @return true if the number is in the list of emergency numbers
- * listed in the RIL / sim, otherwise return false.
- */
- private static boolean isEmergencyNumberInternal(int subId, String number,
- boolean useExactMatch) {
- return isEmergencyNumberInternal(subId, number, null, useExactMatch);
- }
-
- /**
- * Checks if a given number is an emergency number for a specific country.
- *
- * @param number the number to look up.
- * @param defaultCountryIso the specific country which the number should be checked against
- * @return if the number is an emergency number for the specific country, then return true,
- * otherwise false
- *
- * @deprecated Please use {@link TelephonyManager#isEmergencyNumber(String)}
- * instead.
- *
- * @hide
- */
- @Deprecated
- @UnsupportedAppUsage
- public static boolean isEmergencyNumber(String number, String defaultCountryIso) {
- return isEmergencyNumber(getDefaultVoiceSubId(), number, defaultCountryIso);
- }
-
- /**
- * Checks if a given number is an emergency number for a specific country.
- *
- * @param subId the subscription id of the SIM.
- * @param number the number to look up.
- * @param defaultCountryIso the specific country which the number should be checked against
- * @return if the number is an emergency number for the specific country, then return true,
- * otherwise false
- *
- * @deprecated Please use {@link TelephonyManager#isEmergencyNumber(String)}
- * instead.
- *
- * @hide
- */
- @Deprecated
- public static boolean isEmergencyNumber(int subId, String number, String defaultCountryIso) {
- return isEmergencyNumberInternal(subId, number,
- defaultCountryIso,
- true /* useExactMatch */);
- }
-
- /**
- * Checks if a given number might *potentially* result in a call to an
- * emergency service, for a specific country.
- *
- * Specifically, this method will return true if the specified number
- * is an emergency number in the specified country, *or* if the number
- * simply starts with the same digits as any emergency number for that
- * country.
- *
- * This method is intended for internal use by the phone app when
- * deciding whether to allow ACTION_CALL intents from 3rd party apps
- * (where we're required to *not* allow emergency calls to be placed.)
- *
- * @param number the number to look up.
- * @param defaultCountryIso the specific country which the number should be checked against
- * @return true if the number is an emergency number for the specific
- * country, *or* if the number starts with the same digits as
- * any of those emergency numbers.
- *
- * @deprecated Please use {@link TelephonyManager#isPotentialEmergencyNumber(String)}
- * instead.
- *
- * @hide
- */
- @Deprecated
- public static boolean isPotentialEmergencyNumber(String number, String defaultCountryIso) {
- return isPotentialEmergencyNumber(getDefaultVoiceSubId(), number, defaultCountryIso);
- }
-
- /**
- * Checks if a given number might *potentially* result in a call to an
- * emergency service, for a specific country.
- *
- * Specifically, this method will return true if the specified number
- * is an emergency number in the specified country, *or* if the number
- * simply starts with the same digits as any emergency number for that
- * country.
- *
- * This method is intended for internal use by the phone app when
- * deciding whether to allow ACTION_CALL intents from 3rd party apps
- * (where we're required to *not* allow emergency calls to be placed.)
- *
- * @param subId the subscription id of the SIM.
- * @param number the number to look up.
- * @param defaultCountryIso the specific country which the number should be checked against
- * @return true if the number is an emergency number for the specific
- * country, *or* if the number starts with the same digits as
- * any of those emergency numbers.
- *
- * @deprecated Please use {@link TelephonyManager#isPotentialEmergencyNumber(String)}
- * instead.
- *
- * @hide
- */
- @Deprecated
- public static boolean isPotentialEmergencyNumber(int subId, String number,
- String defaultCountryIso) {
- return isEmergencyNumberInternal(subId, number,
- defaultCountryIso,
- false /* useExactMatch */);
- }
-
- /**
- * Helper function for isEmergencyNumber(String, String) and
- * isPotentialEmergencyNumber(String, String).
- *
- * @param number the number to look up.
- * @param defaultCountryIso the specific country which the number should be checked against
- * @param useExactMatch if true, consider a number to be an emergency
- * number only if it *exactly* matches a number listed in
- * the RIL / SIM. If false, a number is considered to be an
- * emergency number if it simply starts with the same digits
- * as any of the emergency numbers listed in the RIL / SIM.
- *
- * @return true if the number is an emergency number for the specified country.
- */
- private static boolean isEmergencyNumberInternal(String number,
- String defaultCountryIso,
- boolean useExactMatch) {
- return isEmergencyNumberInternal(getDefaultVoiceSubId(), number, defaultCountryIso,
- useExactMatch);
+ return isEmergencyNumberInternal(subId, number);
}
/**
- * Helper function for isEmergencyNumber(String, String) and
- * isPotentialEmergencyNumber(String, String).
+ * Helper function for isEmergencyNumber(String, String) and.
*
* @param subId the subscription id of the SIM.
* @param number the number to look up.
- * @param defaultCountryIso the specific country which the number should be checked against
- * @param useExactMatch if true, consider a number to be an emergency
- * number only if it *exactly* matches a number listed in
- * the RIL / SIM. If false, a number is considered to be an
- * emergency number if it simply starts with the same digits
- * as any of the emergency numbers listed in the RIL / SIM.
- *
* @return true if the number is an emergency number for the specified country.
* @hide
*/
- private static boolean isEmergencyNumberInternal(int subId, String number,
- String defaultCountryIso,
- boolean useExactMatch) {
- // TODO: clean up all the callers that pass in a defaultCountryIso, since it's ignored now.
+ private static boolean isEmergencyNumberInternal(int subId, String number) {
+ //TODO: remove subid later. Keep it for now in case we need it later.
try {
- if (useExactMatch) {
return TelephonyManager.getDefault().isEmergencyNumber(number);
- } else {
- return TelephonyManager.getDefault().isPotentialEmergencyNumber(number);
- }
} catch (RuntimeException ex) {
Rlog.e(LOG_TAG, "isEmergencyNumberInternal: RuntimeException: " + ex);
}
@@ -2061,143 +1835,7 @@ public class PhoneNumberUtils {
*/
@Deprecated
public static boolean isLocalEmergencyNumber(Context context, String number) {
- return isLocalEmergencyNumber(context, getDefaultVoiceSubId(), number);
- }
-
- /**
- * Checks if a given number is an emergency number for the country that the user is in.
- *
- * @param subId the subscription id of the SIM.
- * @param number the number to look up.
- * @param context the specific context which the number should be checked against
- * @return true if the specified number is an emergency number for the country the user
- * is currently in.
- *
- * @deprecated Please use {@link TelephonyManager#isEmergencyNumber(String)}
- * instead.
- *
- * @hide
- */
- @Deprecated
- @UnsupportedAppUsage
- public static boolean isLocalEmergencyNumber(Context context, int subId, String number) {
- return isLocalEmergencyNumberInternal(subId, number,
- context,
- true /* useExactMatch */);
- }
-
- /**
- * Checks if a given number might *potentially* result in a call to an
- * emergency service, for the country that the user is in. The current
- * country is determined using the CountryDetector.
- *
- * Specifically, this method will return true if the specified number
- * is an emergency number in the current country, *or* if the number
- * simply starts with the same digits as any emergency number for the
- * current country.
- *
- * This method is intended for internal use by the phone app when
- * deciding whether to allow ACTION_CALL intents from 3rd party apps
- * (where we're required to *not* allow emergency calls to be placed.)
- *
- * @param number the number to look up.
- * @param context the specific context which the number should be checked against
- * @return true if the specified number is an emergency number for a local country, based on the
- * CountryDetector.
- *
- * @see android.location.CountryDetector
- *
- * @deprecated Please use {@link TelephonyManager#isPotentialEmergencyNumber(String)}
- * instead.
- *
- * @hide
- */
- @Deprecated
- @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
- public static boolean isPotentialLocalEmergencyNumber(Context context, String number) {
- return isPotentialLocalEmergencyNumber(context, getDefaultVoiceSubId(), number);
- }
-
- /**
- * Checks if a given number might *potentially* result in a call to an
- * emergency service, for the country that the user is in. The current
- * country is determined using the CountryDetector.
- *
- * Specifically, this method will return true if the specified number
- * is an emergency number in the current country, *or* if the number
- * simply starts with the same digits as any emergency number for the
- * current country.
- *
- * This method is intended for internal use by the phone app when
- * deciding whether to allow ACTION_CALL intents from 3rd party apps
- * (where we're required to *not* allow emergency calls to be placed.)
- *
- * @param subId the subscription id of the SIM.
- * @param number the number to look up.
- * @param context the specific context which the number should be checked against
- * @return true if the specified number is an emergency number for a local country, based on the
- * CountryDetector.
- *
- * @deprecated Please use {@link TelephonyManager#isPotentialEmergencyNumber(String)}
- * instead.
- *
- * @hide
- */
- @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
- @Deprecated
- public static boolean isPotentialLocalEmergencyNumber(Context context, int subId,
- String number) {
- return isLocalEmergencyNumberInternal(subId, number,
- context,
- false /* useExactMatch */);
- }
-
- /**
- * Helper function for isLocalEmergencyNumber() and
- * isPotentialLocalEmergencyNumber().
- *
- * @param number the number to look up.
- * @param context the specific context which the number should be checked against
- * @param useExactMatch if true, consider a number to be an emergency
- * number only if it *exactly* matches a number listed in
- * the RIL / SIM. If false, a number is considered to be an
- * emergency number if it simply starts with the same digits
- * as any of the emergency numbers listed in the RIL / SIM.
- *
- * @return true if the specified number is an emergency number for a
- * local country, based on the CountryDetector.
- *
- * @see android.location.CountryDetector
- * @hide
- */
- private static boolean isLocalEmergencyNumberInternal(String number,
- Context context,
- boolean useExactMatch) {
- return isLocalEmergencyNumberInternal(getDefaultVoiceSubId(), number, context,
- useExactMatch);
- }
-
- /**
- * Helper function for isLocalEmergencyNumber() and
- * isPotentialLocalEmergencyNumber().
- *
- * @param subId the subscription id of the SIM.
- * @param number the number to look up.
- * @param context the specific context which the number should be checked against
- * @param useExactMatch if true, consider a number to be an emergency
- * number only if it *exactly* matches a number listed in
- * the RIL / SIM. If false, a number is considered to be an
- * emergency number if it simply starts with the same digits
- * as any of the emergency numbers listed in the RIL / SIM.
- *
- * @return true if the specified number is an emergency number for a
- * local country, based on the CountryDetector.
- * @hide
- */
- private static boolean isLocalEmergencyNumberInternal(int subId, String number,
- Context context,
- boolean useExactMatch) {
- return isEmergencyNumberInternal(subId, number, null /* unused */, useExactMatch);
+ return isEmergencyNumberInternal(getDefaultVoiceSubId(), number);
}
/**
@@ -3282,7 +2920,11 @@ public class PhoneNumberUtils {
PhoneNumberUtil util = PhoneNumberUtil.getInstance();
PhoneNumber n1;
PhoneNumber n2;
- defaultCountryIso = defaultCountryIso.toUpperCase();
+
+ if (defaultCountryIso != null) {
+ defaultCountryIso = defaultCountryIso.toUpperCase(Locale.ROOT);
+ }
+
try {
n1 = util.parseAndKeepRawInput(number1, defaultCountryIso);
n2 = util.parseAndKeepRawInput(number2, defaultCountryIso);
diff --git a/telephony/java/android/telephony/PreciseCallState.java b/telephony/java/android/telephony/PreciseCallState.java
index 98eeacf1a416..f4336096ed3b 100644
--- a/telephony/java/android/telephony/PreciseCallState.java
+++ b/telephony/java/android/telephony/PreciseCallState.java
@@ -66,6 +66,11 @@ public final class PreciseCallState implements Parcelable {
public static final int PRECISE_CALL_STATE_DISCONNECTED = 7;
/** Call state: Disconnecting. */
public static final int PRECISE_CALL_STATE_DISCONNECTING = 8;
+ /**
+ * Call state: Incoming in pre-alerting state i.e. prior to entering
+ * {@link #PRECISE_CALL_STATE_INCOMING}.
+ */
+ public static final int PRECISE_CALL_STATE_INCOMING_SETUP = 9;
private @PreciseCallStates int mRingingCallState = PRECISE_CALL_STATE_NOT_VALID;
private @PreciseCallStates int mForegroundCallState = PRECISE_CALL_STATE_NOT_VALID;
diff --git a/telephony/java/android/telephony/PreciseDisconnectCause.java b/telephony/java/android/telephony/PreciseDisconnectCause.java
index 3b4cf75e7919..1cfd22cc4d65 100644
--- a/telephony/java/android/telephony/PreciseDisconnectCause.java
+++ b/telephony/java/android/telephony/PreciseDisconnectCause.java
@@ -235,6 +235,23 @@ public final class PreciseDisconnectCause {
/** Call failed/dropped because of a network detach. */
public static final int NETWORK_DETACH = 261;
+ /**
+ * Dialing emergency calls is currently unavailable.
+ * The call should be redialed on the other subscription silently.
+ * If there is no other subscription available, the call may be redialed
+ * on this subscription again.
+ * @hide
+ */
+ public static final int EMERGENCY_TEMP_FAILURE = 325;
+ /**
+ * Dialing emergency calls is currently unavailable.
+ * The call should be redialed on the other subscription silently.
+ * Even if there is no other subscription available, the call should not
+ * be redialed on this subscription again.
+ * @hide
+ */
+ public static final int EMERGENCY_PERM_FAILURE = 326;
+
/** Mobile station (MS) is locked until next power cycle. */
public static final int CDMA_LOCKED_UNTIL_POWER_CYCLE = 1000;
/** Drop call. */
diff --git a/telephony/java/android/telephony/RadioAccessFamily.java b/telephony/java/android/telephony/RadioAccessFamily.java
index f1e90118a559..90d6f89553b7 100644
--- a/telephony/java/android/telephony/RadioAccessFamily.java
+++ b/telephony/java/android/telephony/RadioAccessFamily.java
@@ -24,6 +24,8 @@ import android.telephony.TelephonyManager.PrefNetworkMode;
import com.android.internal.telephony.RILConstants;
+import java.util.Locale;
+
/**
* Object to indicate the phone radio type and access technology.
@@ -367,7 +369,7 @@ public class RadioAccessFamily implements Parcelable {
}
public static int rafTypeFromString(String rafList) {
- rafList = rafList.toUpperCase();
+ rafList = rafList.toUpperCase(Locale.ROOT);
String[] rafs = rafList.split("\\|");
int result = 0;
for(String raf : rafs) {
diff --git a/telephony/java/android/telephony/ServiceState.java b/telephony/java/android/telephony/ServiceState.java
index 03e019d2edde..523d0b0e55f4 100644
--- a/telephony/java/android/telephony/ServiceState.java
+++ b/telephony/java/android/telephony/ServiceState.java
@@ -138,12 +138,11 @@ public class ServiceState implements Parcelable {
*/
public static final int FREQUENCY_RANGE_MMWAVE = 4;
- private static final List<Integer> FREQUENCY_RANGE_ORDER = Arrays.asList(
- FREQUENCY_RANGE_UNKNOWN,
- FREQUENCY_RANGE_LOW,
- FREQUENCY_RANGE_MID,
- FREQUENCY_RANGE_HIGH,
- FREQUENCY_RANGE_MMWAVE);
+ /**
+ * Number of frequency ranges.
+ * @hide
+ */
+ public static final int FREQUENCY_RANGE_COUNT = 5;
/** @hide */
@Retention(RetentionPolicy.SOURCE)
@@ -1214,13 +1213,8 @@ public class ServiceState implements Parcelable {
/**
* Initialize the service state. Set everything to the default value.
- *
- * @param legacyMode {@code true} if the device is on IWLAN legacy mode, where IWLAN is
- * considered as a RAT on WWAN {@link NetworkRegistrationInfo}. {@code false} if the device
- * is on AP-assisted mode, where IWLAN should be reported through WLAN.
- * {@link NetworkRegistrationInfo}.
*/
- private void init(boolean legacyMode) {
+ private void init() {
if (DBG) Rlog.d(LOG_TAG, "init");
mVoiceRegState = STATE_OUT_OF_SERVICE;
mDataRegState = STATE_OUT_OF_SERVICE;
@@ -1252,13 +1246,11 @@ public class ServiceState implements Parcelable {
.setTransportType(AccessNetworkConstants.TRANSPORT_TYPE_WWAN)
.setRegistrationState(NetworkRegistrationInfo.REGISTRATION_STATE_UNKNOWN)
.build());
- if (!legacyMode) {
- addNetworkRegistrationInfo(new NetworkRegistrationInfo.Builder()
- .setDomain(NetworkRegistrationInfo.DOMAIN_PS)
- .setTransportType(AccessNetworkConstants.TRANSPORT_TYPE_WLAN)
- .setRegistrationState(NetworkRegistrationInfo.REGISTRATION_STATE_UNKNOWN)
- .build());
- }
+ addNetworkRegistrationInfo(new NetworkRegistrationInfo.Builder()
+ .setDomain(NetworkRegistrationInfo.DOMAIN_PS)
+ .setTransportType(AccessNetworkConstants.TRANSPORT_TYPE_WLAN)
+ .setRegistrationState(NetworkRegistrationInfo.REGISTRATION_STATE_UNKNOWN)
+ .build());
}
mOperatorAlphaLongRaw = null;
mOperatorAlphaShortRaw = null;
@@ -1267,11 +1259,11 @@ public class ServiceState implements Parcelable {
}
public void setStateOutOfService() {
- init(true);
+ init();
}
public void setStateOff() {
- init(true);
+ init();
mVoiceRegState = STATE_POWER_OFF;
mDataRegState = STATE_POWER_OFF;
}
@@ -1279,14 +1271,11 @@ public class ServiceState implements Parcelable {
/**
* Set the service state to out-of-service
*
- * @param legacyMode {@code true} if the device is on IWLAN legacy mode, where IWLAN is
- * considered as a RAT on WWAN {@link NetworkRegistrationInfo}. {@code false} if the device
- * is on AP-assisted mode, where IWLAN should be reported through WLAN.
* @param powerOff {@code true} if this is a power off case (i.e. Airplane mode on).
* @hide
*/
- public void setOutOfService(boolean legacyMode, boolean powerOff) {
- init(legacyMode);
+ public void setOutOfService(boolean powerOff) {
+ init();
if (powerOff) {
mVoiceRegState = STATE_POWER_OFF;
mDataRegState = STATE_POWER_OFF;
@@ -1452,7 +1441,7 @@ public class ServiceState implements Parcelable {
*/
@UnsupportedAppUsage
private void setFromNotifierBundle(Bundle m) {
- ServiceState ssFromBundle = m.getParcelable(EXTRA_SERVICE_STATE);
+ ServiceState ssFromBundle = m.getParcelable(EXTRA_SERVICE_STATE, android.telephony.ServiceState.class);
if (ssFromBundle != null) {
copyFrom(ssFromBundle);
}
@@ -2115,15 +2104,6 @@ public class ServiceState implements Parcelable {
}
/**
- * @hide
- */
- public static final int getBetterNRFrequencyRange(int range1, int range2) {
- return FREQUENCY_RANGE_ORDER.indexOf(range1) > FREQUENCY_RANGE_ORDER.indexOf(range2)
- ? range1
- : range2;
- }
-
- /**
* Returns a copy of self with location-identifying information removed.
* Always clears the NetworkRegistrationInfo's CellIdentity fields, but if removeCoarseLocation
* is true, clears other info as well.
diff --git a/telephony/java/android/telephony/SignalStrength.java b/telephony/java/android/telephony/SignalStrength.java
index f74ef0fe764a..f1af68f5cfee 100644
--- a/telephony/java/android/telephony/SignalStrength.java
+++ b/telephony/java/android/telephony/SignalStrength.java
@@ -906,12 +906,12 @@ public class SignalStrength implements Parcelable {
@Deprecated
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
private void setFromNotifierBundle(Bundle m) {
- mCdma = m.getParcelable("Cdma");
- mGsm = m.getParcelable("Gsm");
- mWcdma = m.getParcelable("Wcdma");
- mTdscdma = m.getParcelable("Tdscdma");
- mLte = m.getParcelable("Lte");
- mNr = m.getParcelable("Nr");
+ mCdma = m.getParcelable("Cdma", android.telephony.CellSignalStrengthCdma.class);
+ mGsm = m.getParcelable("Gsm", android.telephony.CellSignalStrengthGsm.class);
+ mWcdma = m.getParcelable("Wcdma", android.telephony.CellSignalStrengthWcdma.class);
+ mTdscdma = m.getParcelable("Tdscdma", android.telephony.CellSignalStrengthTdscdma.class);
+ mLte = m.getParcelable("Lte", android.telephony.CellSignalStrengthLte.class);
+ mNr = m.getParcelable("Nr", android.telephony.CellSignalStrengthNr.class);
}
/**
diff --git a/telephony/java/android/telephony/SignalThresholdInfo.java b/telephony/java/android/telephony/SignalThresholdInfo.java
index 3c1824539d1f..80f1de1b2e8a 100644
--- a/telephony/java/android/telephony/SignalThresholdInfo.java
+++ b/telephony/java/android/telephony/SignalThresholdInfo.java
@@ -17,6 +17,7 @@
package android.telephony;
import android.annotation.IntDef;
+import android.annotation.IntRange;
import android.annotation.NonNull;
import android.os.Parcel;
import android.os.Parcelable;
@@ -100,24 +101,34 @@ public final class SignalThresholdInfo implements Parcelable {
*/
public static final int SIGNAL_MEASUREMENT_TYPE_SSSINR = 8;
+ /**
+ * The ratio between the received energy from the pilot signal CPICH per chip (Ec) to the
+ * noise density (No).
+ * Range: -24 dBm to 1 dBm.
+ * Used RAN: {@link AccessNetworkConstants.AccessNetworkType#UTRAN}
+ * Reference: 3GPP TS 25.215 5.1.5
+ */
+ public static final int SIGNAL_MEASUREMENT_TYPE_ECNO = 9;
+
/** @hide */
- @IntDef(prefix = {"SIGNAL_MEASUREMENT_TYPE_"}, value = {
- SIGNAL_MEASUREMENT_TYPE_UNKNOWN,
- SIGNAL_MEASUREMENT_TYPE_RSSI,
- SIGNAL_MEASUREMENT_TYPE_RSCP,
- SIGNAL_MEASUREMENT_TYPE_RSRP,
- SIGNAL_MEASUREMENT_TYPE_RSRQ,
- SIGNAL_MEASUREMENT_TYPE_RSSNR,
- SIGNAL_MEASUREMENT_TYPE_SSRSRP,
- SIGNAL_MEASUREMENT_TYPE_SSRSRQ,
- SIGNAL_MEASUREMENT_TYPE_SSSINR
- })
+ @IntDef(
+ prefix = {"SIGNAL_MEASUREMENT_TYPE_"},
+ value = {
+ SIGNAL_MEASUREMENT_TYPE_UNKNOWN,
+ SIGNAL_MEASUREMENT_TYPE_RSSI,
+ SIGNAL_MEASUREMENT_TYPE_RSCP,
+ SIGNAL_MEASUREMENT_TYPE_RSRP,
+ SIGNAL_MEASUREMENT_TYPE_RSRQ,
+ SIGNAL_MEASUREMENT_TYPE_RSSNR,
+ SIGNAL_MEASUREMENT_TYPE_SSRSRP,
+ SIGNAL_MEASUREMENT_TYPE_SSRSRQ,
+ SIGNAL_MEASUREMENT_TYPE_SSSINR,
+ SIGNAL_MEASUREMENT_TYPE_ECNO
+ })
@Retention(RetentionPolicy.SOURCE)
- public @interface SignalMeasurementType {
- }
+ public @interface SignalMeasurementType {}
- @SignalMeasurementType
- private final int mSignalMeasurementType;
+ @SignalMeasurementType private final int mSignalMeasurementType;
/**
* A hysteresis time in milliseconds to prevent flapping.
@@ -149,8 +160,7 @@ public final class SignalThresholdInfo implements Parcelable {
/**
* The radio access network type associated with the signal thresholds.
*/
- @AccessNetworkConstants.RadioAccessNetworkType
- private final int mRan;
+ @AccessNetworkConstants.RadioAccessNetworkType private final int mRan;
/**
* Indicates the hysteresisMs is disabled.
@@ -160,12 +170,18 @@ public final class SignalThresholdInfo implements Parcelable {
public static final int HYSTERESIS_MS_DISABLED = 0;
/**
- * Indicates the hysteresisDb is disabled.
+ * Indicates the default hysteresis value in dB.
*
* @hide
*/
- public static final int HYSTERESIS_DB_DISABLED = 0;
+ private static final int HYSTERESIS_DB_DEFAULT = 2;
+ /**
+ * Indicates the hysteresisDb value is not set and to be initialised to default value.
+ *
+ * @hide
+ */
+ public static final int HYSTERESIS_DB_MINIMUM = 0;
/**
* Minimum valid value for {@link #SIGNAL_MEASUREMENT_TYPE_RSSI}.
@@ -280,6 +296,20 @@ public final class SignalThresholdInfo implements Parcelable {
public static final int SIGNAL_SSSINR_MAX_VALUE = 40;
/**
+ * Minimum valid value for {@link #SIGNAL_MEASUREMENT_TYPE_ECNO}.
+ *
+ * @hide
+ */
+ public static final int SIGNAL_ECNO_MIN_VALUE = -24;
+
+ /**
+ * Maximum valid value for {@link #SIGNAL_MEASUREMENT_TYPE_ECNO}.
+ *
+ * @hide
+ */
+ public static final int SIGNAL_ECNO_MAX_VALUE = 1;
+
+ /**
* The minimum number of thresholds allowed in each SignalThresholdInfo.
*
* @hide
@@ -303,9 +333,13 @@ public final class SignalThresholdInfo implements Parcelable {
* @param thresholds threshold value
* @param isEnabled isEnabled
*/
- private SignalThresholdInfo(@AccessNetworkConstants.RadioAccessNetworkType int ran,
- @SignalMeasurementType int signalMeasurementType, int hysteresisMs, int hysteresisDb,
- @NonNull int[] thresholds, boolean isEnabled) {
+ private SignalThresholdInfo(
+ @AccessNetworkConstants.RadioAccessNetworkType int ran,
+ @SignalMeasurementType int signalMeasurementType,
+ int hysteresisMs,
+ int hysteresisDb,
+ @NonNull int[] thresholds,
+ boolean isEnabled) {
Objects.requireNonNull(thresholds, "thresholds must not be null");
validateRanWithMeasurementType(ran, signalMeasurementType);
validateThresholdRange(signalMeasurementType, thresholds);
@@ -313,7 +347,7 @@ public final class SignalThresholdInfo implements Parcelable {
mRan = ran;
mSignalMeasurementType = signalMeasurementType;
mHysteresisMs = hysteresisMs < 0 ? HYSTERESIS_MS_DISABLED : hysteresisMs;
- mHysteresisDb = hysteresisDb < 0 ? HYSTERESIS_DB_DISABLED : hysteresisDb;
+ mHysteresisDb = hysteresisDb;
mThresholds = thresholds;
mIsEnabled = isEnabled;
}
@@ -325,7 +359,7 @@ public final class SignalThresholdInfo implements Parcelable {
private int mRan = AccessNetworkConstants.AccessNetworkType.UNKNOWN;
private int mSignalMeasurementType = SIGNAL_MEASUREMENT_TYPE_UNKNOWN;
private int mHysteresisMs = HYSTERESIS_MS_DISABLED;
- private int mHysteresisDb = HYSTERESIS_DB_DISABLED;
+ private int mHysteresisDb = HYSTERESIS_DB_DEFAULT;
private int[] mThresholds = null;
private boolean mIsEnabled = false;
@@ -335,7 +369,8 @@ public final class SignalThresholdInfo implements Parcelable {
* @param ran The radio access network type
* @return the builder to facilitate the chaining
*/
- public @NonNull Builder setRadioAccessNetworkType(
+ @NonNull
+ public Builder setRadioAccessNetworkType(
@AccessNetworkConstants.RadioAccessNetworkType int ran) {
mRan = ran;
return this;
@@ -347,7 +382,8 @@ public final class SignalThresholdInfo implements Parcelable {
* @param signalMeasurementType The signal measurement type
* @return the builder to facilitate the chaining
*/
- public @NonNull Builder setSignalMeasurementType(
+ @NonNull
+ public Builder setSignalMeasurementType(
@SignalMeasurementType int signalMeasurementType) {
mSignalMeasurementType = signalMeasurementType;
return this;
@@ -361,20 +397,27 @@ public final class SignalThresholdInfo implements Parcelable {
* @return the builder to facilitate the chaining
* @hide
*/
- public @NonNull Builder setHysteresisMs(int hysteresisMs) {
+ @NonNull
+ public Builder setHysteresisMs(int hysteresisMs) {
mHysteresisMs = hysteresisMs;
return this;
}
/**
- * Set the interval in dB defining the required magnitude change between reports. A value of
- * zero disabled dB-based hysteresis restrictions.
+ * Set the interval in dB defining the required minimum magnitude change to report a
+ * signal strength change. A value of zero disables dB-based hysteresis restrictions.
+ * Note:
+ * <p>Default hysteresis db value is 2. Minimum hysteresis db value allowed to set is 0.
+ * If hysteresis db value is not set, default hysteresis db value of 2 will be used.
*
* @param hysteresisDb the interval in dB
* @return the builder to facilitate the chaining
- * @hide
*/
- public @NonNull Builder setHysteresisDb(int hysteresisDb) {
+ @NonNull
+ public Builder setHysteresisDb(@IntRange(from = 0) int hysteresisDb) {
+ if (hysteresisDb < 0) {
+ throw new IllegalArgumentException("hysteresis db value should not be less than 0");
+ }
mHysteresisDb = hysteresisDb;
return this;
}
@@ -399,9 +442,11 @@ public final class SignalThresholdInfo implements Parcelable {
* @see #SIGNAL_MEASUREMENT_TYPE_SSRSRP
* @see #SIGNAL_MEASUREMENT_TYPE_SSRSRQ
* @see #SIGNAL_MEASUREMENT_TYPE_SSSINR
+ * @see #SIGNAL_MEASUREMENT_TYPE_ECNO
* @see #getThresholds() for more details on signal strength thresholds
*/
- public @NonNull Builder setThresholds(@NonNull int[] thresholds) {
+ @NonNull
+ public Builder setThresholds(@NonNull int[] thresholds) {
return setThresholds(thresholds, false /*isSystem*/);
}
@@ -415,20 +460,23 @@ public final class SignalThresholdInfo implements Parcelable {
*
* @hide
*/
- public @NonNull Builder setThresholds(@NonNull int[] thresholds, boolean isSystem) {
+ @NonNull
+ public Builder setThresholds(@NonNull int[] thresholds, boolean isSystem) {
Objects.requireNonNull(thresholds, "thresholds must not be null");
- if (!isSystem && (thresholds.length < MINIMUM_NUMBER_OF_THRESHOLDS_ALLOWED
- || thresholds.length > MAXIMUM_NUMBER_OF_THRESHOLDS_ALLOWED)) {
+ if (!isSystem
+ && (thresholds.length < MINIMUM_NUMBER_OF_THRESHOLDS_ALLOWED
+ || thresholds.length > MAXIMUM_NUMBER_OF_THRESHOLDS_ALLOWED)) {
throw new IllegalArgumentException(
- "thresholds length must between " + MINIMUM_NUMBER_OF_THRESHOLDS_ALLOWED
- + " and " + MAXIMUM_NUMBER_OF_THRESHOLDS_ALLOWED);
+ "thresholds length must between "
+ + MINIMUM_NUMBER_OF_THRESHOLDS_ALLOWED
+ + " and "
+ + MAXIMUM_NUMBER_OF_THRESHOLDS_ALLOWED);
}
mThresholds = thresholds.clone();
Arrays.sort(mThresholds);
return this;
}
-
/**
* Set if the modem should trigger the report based on the criteria.
*
@@ -436,7 +484,8 @@ public final class SignalThresholdInfo implements Parcelable {
* @return the builder to facilitate the chaining
* @hide
*/
- public @NonNull Builder setIsEnabled(boolean isEnabled) {
+ @NonNull
+ public Builder setIsEnabled(boolean isEnabled) {
mIsEnabled = isEnabled;
return this;
}
@@ -450,9 +499,15 @@ public final class SignalThresholdInfo implements Parcelable {
* the thresholds is out of range, or the RAN is not allowed to set with the signal
* measurement type
*/
- public @NonNull SignalThresholdInfo build() {
- return new SignalThresholdInfo(mRan, mSignalMeasurementType, mHysteresisMs,
- mHysteresisDb, mThresholds, mIsEnabled);
+ @NonNull
+ public SignalThresholdInfo build() {
+ return new SignalThresholdInfo(
+ mRan,
+ mSignalMeasurementType,
+ mHysteresisMs,
+ mHysteresisDb,
+ mThresholds,
+ mIsEnabled);
}
}
@@ -461,7 +516,8 @@ public final class SignalThresholdInfo implements Parcelable {
*
* @return radio access network type
*/
- public @AccessNetworkConstants.RadioAccessNetworkType int getRadioAccessNetworkType() {
+ @AccessNetworkConstants.RadioAccessNetworkType
+ public int getRadioAccessNetworkType() {
return mRan;
}
@@ -470,7 +526,8 @@ public final class SignalThresholdInfo implements Parcelable {
*
* @return the SignalMeasurementType value
*/
- public @SignalMeasurementType int getSignalMeasurementType() {
+ @SignalMeasurementType
+ public int getSignalMeasurementType() {
return mSignalMeasurementType;
}
@@ -479,7 +536,11 @@ public final class SignalThresholdInfo implements Parcelable {
return mHysteresisMs;
}
- /** @hide */
+ /**
+ * Get measurement hysteresis db.
+ *
+ * @return hysteresis db value
+ */
public int getHysteresisDb() {
return mHysteresisDb;
}
@@ -508,8 +569,10 @@ public final class SignalThresholdInfo implements Parcelable {
* @see #SIGNAL_MEASUREMENT_TYPE_SSRSRP
* @see #SIGNAL_MEASUREMENT_TYPE_SSRSRQ
* @see #SIGNAL_MEASUREMENT_TYPE_SSSINR
+ * @see #SIGNAL_MEASUREMENT_TYPE_ECNO
*/
- public @NonNull int[] getThresholds() {
+ @NonNull
+ public int[] getThresholds() {
return mThresholds.clone();
}
@@ -574,11 +637,17 @@ public final class SignalThresholdInfo implements Parcelable {
@Override
public int hashCode() {
- return Objects.hash(mRan, mSignalMeasurementType, mHysteresisMs, mHysteresisDb,
- Arrays.hashCode(mThresholds), mIsEnabled);
+ return Objects.hash(
+ mRan,
+ mSignalMeasurementType,
+ mHysteresisMs,
+ mHysteresisDb,
+ Arrays.hashCode(mThresholds),
+ mIsEnabled);
}
- public static final @NonNull Parcelable.Creator<SignalThresholdInfo> CREATOR =
+ @NonNull
+ public static final Parcelable.Creator<SignalThresholdInfo> CREATOR =
new Parcelable.Creator<SignalThresholdInfo>() {
@Override
public SignalThresholdInfo createFromParcel(Parcel in) {
@@ -594,13 +663,20 @@ public final class SignalThresholdInfo implements Parcelable {
@Override
public String toString() {
return new StringBuilder("SignalThresholdInfo{")
- .append("mRan=").append(mRan)
- .append(" mSignalMeasurementType=").append(mSignalMeasurementType)
- .append(" mHysteresisMs=").append(mHysteresisMs)
- .append(" mHysteresisDb=").append(mHysteresisDb)
- .append(" mThresholds=").append(Arrays.toString(mThresholds))
- .append(" mIsEnabled=").append(mIsEnabled)
- .append("}").toString();
+ .append("mRan=")
+ .append(mRan)
+ .append(" mSignalMeasurementType=")
+ .append(mSignalMeasurementType)
+ .append(" mHysteresisMs=")
+ .append(mHysteresisMs)
+ .append(" mHysteresisDb=")
+ .append(mHysteresisDb)
+ .append(" mThresholds=")
+ .append(Arrays.toString(mThresholds))
+ .append(" mIsEnabled=")
+ .append(mIsEnabled)
+ .append("}")
+ .toString();
}
/**
@@ -624,6 +700,8 @@ public final class SignalThresholdInfo implements Parcelable {
return threshold >= SIGNAL_SSRSRQ_MIN_VALUE && threshold <= SIGNAL_SSRSRQ_MAX_VALUE;
case SIGNAL_MEASUREMENT_TYPE_SSSINR:
return threshold >= SIGNAL_SSSINR_MIN_VALUE && threshold <= SIGNAL_SSSINR_MAX_VALUE;
+ case SIGNAL_MEASUREMENT_TYPE_ECNO:
+ return threshold >= SIGNAL_ECNO_MIN_VALUE && threshold <= SIGNAL_ECNO_MAX_VALUE;
default:
return false;
}
@@ -640,6 +718,7 @@ public final class SignalThresholdInfo implements Parcelable {
return ran == AccessNetworkConstants.AccessNetworkType.GERAN
|| ran == AccessNetworkConstants.AccessNetworkType.CDMA2000;
case SIGNAL_MEASUREMENT_TYPE_RSCP:
+ case SIGNAL_MEASUREMENT_TYPE_ECNO:
return ran == AccessNetworkConstants.AccessNetworkType.UTRAN;
case SIGNAL_MEASUREMENT_TYPE_RSRP:
case SIGNAL_MEASUREMENT_TYPE_RSRQ:
@@ -663,13 +742,15 @@ public final class SignalThresholdInfo implements Parcelable {
}
}
- private void validateThresholdRange(@SignalMeasurementType int signalMeasurement,
- int[] thresholds) {
+ private void validateThresholdRange(
+ @SignalMeasurementType int signalMeasurement, int[] thresholds) {
for (int threshold : thresholds) {
if (!isValidThreshold(signalMeasurement, threshold)) {
throw new IllegalArgumentException(
- "invalid signal measurement type: " + signalMeasurement
- + " with threshold: " + threshold);
+ "invalid signal measurement type: "
+ + signalMeasurement
+ + " with threshold: "
+ + threshold);
}
}
}
diff --git a/telephony/java/android/telephony/SmsManager.java b/telephony/java/android/telephony/SmsManager.java
index 1cf2969ea9b5..40488b15a37c 100644
--- a/telephony/java/android/telephony/SmsManager.java
+++ b/telephony/java/android/telephony/SmsManager.java
@@ -46,6 +46,7 @@ import android.util.Pair;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.telephony.IIntegerConsumer;
+import com.android.internal.telephony.IPhoneSubInfo;
import com.android.internal.telephony.ISms;
import com.android.internal.telephony.ITelephony;
import com.android.internal.telephony.SmsRawData;
@@ -297,6 +298,106 @@ public final class SmsManager {
*/
public static final int SMS_MESSAGE_PERIOD_NOT_SPECIFIED = -1;
+ // RP-Cause Values For MO SMS as per TS 124 011, table 8.4.
+
+ /** @hide */
+ @IntDef(prefix = { "SMS_RP_CAUSE" }, value = {
+ SmsManager.SMS_RP_CAUSE_UNALLOCATED_NUMBER,
+ SmsManager.SMS_RP_CAUSE_OPERATOR_DETERMINED_BARRING,
+ SmsManager.SMS_RP_CAUSE_CALL_BARRING,
+ SmsManager.SMS_RP_CAUSE_RESERVED,
+ SmsManager.SMS_RP_CAUSE_SHORT_MESSAGE_TRANSFER_REJECTED,
+ SmsManager.SMS_RP_CAUSE_DESTINATION_OUT_OF_ORDER,
+ SmsManager.SMS_RP_CAUSE_UNIDENTIFIED_SUBSCRIBER,
+ SmsManager.SMS_RP_CAUSE_FACILITY_REJECTED,
+ SmsManager.SMS_RP_CAUSE_UNKNOWN_SUBSCRIBER,
+ SmsManager.SMS_RP_CAUSE_NETWORK_OUT_OF_ORDER,
+ SmsManager.SMS_RP_CAUSE_TEMPORARY_FAILURE,
+ SmsManager.SMS_RP_CAUSE_CONGESTION,
+ SmsManager.SMS_RP_CAUSE_RESOURCES_UNAVAILABLE,
+ SmsManager.SMS_RP_CAUSE_FACILITY_NOT_SUBSCRIBED,
+ SmsManager.SMS_RP_CAUSE_FACILITY_NOT_IMPLEMENTED,
+ SmsManager.SMS_RP_CAUSE_INVALID_MESSAGE_REFERENCE_VALUE,
+ SmsManager.SMS_RP_CAUSE_SEMANTICALLY_INCORRECT_MESSAGE,
+ SmsManager.SMS_RP_CAUSE_INVALID_MANDATORY_INFORMATION,
+ SmsManager.SMS_RP_CAUSE_MESSAGE_TYPE_NON_EXISTENT,
+ SmsManager.SMS_RP_CAUSE_MESSAGE_INCOMPATIBLE_WITH_PROTOCOL_STATE,
+ SmsManager.SMS_RP_CAUSE_INFORMATION_ELEMENT_NON_EXISTENT,
+ SmsManager.SMS_RP_CAUSE_PROTOCOL_ERROR,
+ SmsManager.SMS_RP_CAUSE_INTERWORKING_UNSPECIFIED
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface SMS_RP_CAUSE {}
+
+ /** Unallocated Number Cause */
+ public static final int SMS_RP_CAUSE_UNALLOCATED_NUMBER = 1;
+
+ /** RP-Cause for Operator Barring */
+ public static final int SMS_RP_CAUSE_OPERATOR_DETERMINED_BARRING = 8;
+
+ /** RP-Cause Value for Call Barring */
+ public static final int SMS_RP_CAUSE_CALL_BARRING = 10;
+
+ /** RP-Cause value for Reserved Number */
+ public static final int SMS_RP_CAUSE_RESERVED = 11;
+
+ /** RP-Cause Value for Message Transfer Rejected by Network */
+ public static final int SMS_RP_CAUSE_SHORT_MESSAGE_TRANSFER_REJECTED = 21;
+
+ /** RP-Cause Value for Destination is Out of Order */
+ public static final int SMS_RP_CAUSE_DESTINATION_OUT_OF_ORDER = 27;
+
+ /** RP-Cause Value when Subscriber is not Identified */
+ public static final int SMS_RP_CAUSE_UNIDENTIFIED_SUBSCRIBER = 28;
+
+ /** RP-Cause Value when SMS Facility if Rejected by Operator */
+ public static final int SMS_RP_CAUSE_FACILITY_REJECTED = 29;
+
+ /** RP-Cause Value when Subscriber is not Identified */
+ public static final int SMS_RP_CAUSE_UNKNOWN_SUBSCRIBER = 30;
+
+ /** RP-Cause Value when network is out of order*/
+ public static final int SMS_RP_CAUSE_NETWORK_OUT_OF_ORDER = 38;
+
+ /** RP-Cause Value For Temporary failure*/
+ public static final int SMS_RP_CAUSE_TEMPORARY_FAILURE = 41;
+
+ /** RP-Cause Value for SMS Failure due to Congestion in network*/
+ public static final int SMS_RP_CAUSE_CONGESTION = 42;
+
+ /** RP-Cause Value when Network Resources are unavailable */
+ public static final int SMS_RP_CAUSE_RESOURCES_UNAVAILABLE = 47;
+
+ /** RP-Cause Value when SMS Facilty is not subscribed by Reote device */
+ public static final int SMS_RP_CAUSE_FACILITY_NOT_SUBSCRIBED = 50;
+
+ /** RP-Cause Value when network does not provide the received service */
+ public static final int SMS_RP_CAUSE_FACILITY_NOT_IMPLEMENTED = 69;
+
+ /** RP-Cause Value when RP-MessageRefere */
+ public static final int SMS_RP_CAUSE_INVALID_MESSAGE_REFERENCE_VALUE = 81;
+
+ /** RP-Cause Value when network does not provide the received service */
+ public static final int SMS_RP_CAUSE_SEMANTICALLY_INCORRECT_MESSAGE = 95;
+
+ /** RP-Cause Value when network does not provide the received service */
+ public static final int SMS_RP_CAUSE_INVALID_MANDATORY_INFORMATION = 96;
+
+ /** RP-Cause Value when network does not provide the received service */
+ public static final int SMS_RP_CAUSE_MESSAGE_TYPE_NON_EXISTENT = 97;
+
+ /** RP-Cause Value when network does not provide the received service */
+ public static final int SMS_RP_CAUSE_MESSAGE_INCOMPATIBLE_WITH_PROTOCOL_STATE = 98;
+
+ /** RP-Cause Value when network does not provide the received service */
+ public static final int SMS_RP_CAUSE_INFORMATION_ELEMENT_NON_EXISTENT = 99;
+
+ /** RP-Cause Value when network does not provide the received service */
+ public static final int SMS_RP_CAUSE_PROTOCOL_ERROR = 111;
+
+ /** RP-Cause Value when network does not provide the received service */
+ public static final int SMS_RP_CAUSE_INTERWORKING_UNSPECIFIED = 127;
+
/** @hide */
@IntDef(prefix = { "PREMIUM_SMS_CONSENT" }, value = {
SmsManager.PREMIUM_SMS_CONSENT_UNKNOWN,
@@ -1914,8 +2015,10 @@ public final class SmsManager {
* @see #disableCellBroadcastRange(int, int, int)
*
* @throws IllegalArgumentException if endMessageId < startMessageId
+ * @deprecated Use {@link TelephonyManager#setCellBroadcastIdRanges} instead.
* {@hide}
*/
+ @Deprecated
@SystemApi
public boolean enableCellBroadcastRange(int startMessageId, int endMessageId,
@android.telephony.SmsCbMessage.MessageFormat int ranType) {
@@ -1974,8 +2077,10 @@ public final class SmsManager {
* @see #enableCellBroadcastRange(int, int, int)
*
* @throws IllegalArgumentException if endMessageId < startMessageId
+ * @deprecated Use {@link TelephonyManager#setCellBroadcastIdRanges} instead.
* {@hide}
*/
+ @Deprecated
@SystemApi
public boolean disableCellBroadcastRange(int startMessageId, int endMessageId,
@android.telephony.SmsCbMessage.MessageFormat int ranType) {
@@ -2269,7 +2374,21 @@ public final class SmsManager {
RESULT_RIL_SIM_ABSENT,
RESULT_RIL_SIMULTANEOUS_SMS_AND_CALL_NOT_ALLOWED,
RESULT_RIL_ACCESS_BARRED,
- RESULT_RIL_BLOCKED_DUE_TO_CALL
+ RESULT_RIL_BLOCKED_DUE_TO_CALL,
+ RESULT_RIL_GENERIC_ERROR,
+ RESULT_RIL_INVALID_RESPONSE,
+ RESULT_RIL_SIM_PIN2,
+ RESULT_RIL_SIM_PUK2,
+ RESULT_RIL_SUBSCRIPTION_NOT_AVAILABLE,
+ RESULT_RIL_SIM_ERROR,
+ RESULT_RIL_INVALID_SIM_STATE,
+ RESULT_RIL_NO_SMS_TO_ACK,
+ RESULT_RIL_SIM_BUSY,
+ RESULT_RIL_SIM_FULL,
+ RESULT_RIL_NO_SUBSCRIPTION,
+ RESULT_RIL_NO_NETWORK_FOUND,
+ RESULT_RIL_DEVICE_IN_USE,
+ RESULT_RIL_ABORTED
})
@Retention(RetentionPolicy.SOURCE)
public @interface Result {}
@@ -2428,8 +2547,6 @@ public final class SmsManager {
/**
* User is not associated with the subscription.
- * TODO(b/263279115): Make this error code public.
- * @hide
*/
public static final int RESULT_USER_NOT_ALLOWED = 33;
@@ -2542,7 +2659,7 @@ public final class SmsManager {
public static final int RESULT_RIL_SIM_ABSENT = 120;
/**
- * 1X voice and SMS are not allowed simulteneously.
+ * 1X voice and SMS are not allowed simultaneously.
*/
public static final int RESULT_RIL_SIMULTANEOUS_SMS_AND_CALL_NOT_ALLOWED = 121;
@@ -2561,6 +2678,73 @@ public final class SmsManager {
*/
public static final int RESULT_RIL_GENERIC_ERROR = 124;
+ /**
+ * A RIL internal error when one of the RIL layers receives an unrecognized response from a
+ * lower layer.
+ */
+ public static final int RESULT_RIL_INVALID_RESPONSE = 125;
+
+ /**
+ * Operation requires SIM PIN2 to be entered
+ */
+ public static final int RESULT_RIL_SIM_PIN2 = 126;
+
+ /**
+ * Operation requires SIM PUK2 to be entered
+ */
+ public static final int RESULT_RIL_SIM_PUK2 = 127;
+
+ /**
+ * Fail to find CDMA subscription from specified location
+ */
+ public static final int RESULT_RIL_SUBSCRIPTION_NOT_AVAILABLE = 128;
+
+ /**
+ * Received error from SIM card
+ */
+ public static final int RESULT_RIL_SIM_ERROR = 129;
+
+ /**
+ * Cannot process the request in current SIM state
+ */
+ public static final int RESULT_RIL_INVALID_SIM_STATE = 130;
+
+ /**
+ * ACK received when there is no SMS to ack
+ */
+ public static final int RESULT_RIL_NO_SMS_TO_ACK = 131;
+
+ /**
+ * SIM is busy
+ */
+ public static final int RESULT_RIL_SIM_BUSY = 132;
+
+ /**
+ * The target EF is full
+ */
+ public static final int RESULT_RIL_SIM_FULL = 133;
+
+ /**
+ * Device does not have subscription
+ */
+ public static final int RESULT_RIL_NO_SUBSCRIPTION = 134;
+
+ /**
+ * Network cannot be found
+ */
+ public static final int RESULT_RIL_NO_NETWORK_FOUND = 135;
+
+ /**
+ * Operation cannot be performed because the device is currently in use
+ */
+ public static final int RESULT_RIL_DEVICE_IN_USE = 136;
+
+ /**
+ * Operation aborted
+ */
+ public static final int RESULT_RIL_ABORTED = 137;
+
+
// SMS receiving results sent as a "result" extra in {@link Intents.SMS_REJECTED_ACTION}
/**
@@ -3052,6 +3236,43 @@ public final class SmsManager {
}
}
+ /**
+ * Set Storage Availability in SmsStorageMonitor
+ * @param storageAvailable storage availability to be set true or false
+ * @hide
+ */
+ @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
+ @TestApi
+ public void setStorageMonitorMemoryStatusOverride(boolean storageAvailable) {
+ try {
+ ISms iccISms = getISmsServiceOrThrow();
+ if (iccISms != null) {
+ iccISms.setStorageMonitorMemoryStatusOverride(getSubscriptionId(),
+ storageAvailable);
+ }
+ } catch (RemoteException ex) {
+ ex.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * Clear the memory status override set by
+ * {@link #setStorageMonitorMemoryStatusOverride(boolean)}
+ * @hide
+ */
+ @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
+ @TestApi
+ public void clearStorageMonitorMemoryStatusOverride() {
+ try {
+ ISms iccISms = getISmsServiceOrThrow();
+ if (iccISms != null) {
+ iccISms.clearStorageMonitorMemoryStatusOverride(getSubscriptionId());
+ }
+ } catch (RemoteException ex) {
+ ex.rethrowFromSystemServer();
+ }
+ }
+
/** @hide */
@Retention(RetentionPolicy.SOURCE)
@IntDef(prefix = {"SMS_CATEGORY_"},
@@ -3264,8 +3485,10 @@ public final class SmsManager {
/**
* Reset all cell broadcast ranges. Previously enabled ranges will become invalid after this.
+ * @deprecated Use {@link TelephonyManager#setCellBroadcastIdRanges} with empty list instead
* @hide
*/
+ @Deprecated
@SystemApi
@RequiresPermission(android.Manifest.permission.MODIFY_CELL_BROADCASTS)
public void resetAllCellBroadcastRanges() {
@@ -3284,4 +3507,41 @@ public final class SmsManager {
private static String formatCrossStackMessageId(long id) {
return "{x-message-id:" + id + "}";
}
+
+ /**
+ * Fetches the EF_PSISMSC value from the UICC that contains the Public Service Identity of
+ * the SM-SC (either a SIP URI or tel URI). The EF_PSISMSC of ISIM and USIM can be found in
+ * DF_TELECOM.
+ * The EF_PSISMSC value is used by the ME to submit SMS over IP as defined in 24.341 [55].
+ *
+ * @return Uri : Public Service Identity of SM-SC from the ISIM or USIM if the ISIM is not
+ * available.
+ * @throws SecurityException if the caller does not have the required permission/privileges.
+ * @throws IllegalStateException in case of telephony service is not available.
+ * @hide
+ */
+ @NonNull
+ @SystemApi
+ @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
+ @RequiresFeature(PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION)
+ public Uri getSmscIdentity() {
+ Uri smscUri = Uri.EMPTY;
+ try {
+ IPhoneSubInfo info = TelephonyManager.getSubscriberInfoService();
+ if (info == null) {
+ Rlog.e(TAG, "getSmscIdentity(): IPhoneSubInfo instance is NULL");
+ throw new IllegalStateException("Telephony service is not available");
+ }
+ /** Fetches the SIM EF_PSISMSC value based on subId and appType */
+ smscUri = info.getSmscIdentity(getSubscriptionId(), TelephonyManager.APPTYPE_ISIM);
+ if (Uri.EMPTY.equals(smscUri)) {
+ /** Fallback in case where ISIM is not available */
+ smscUri = info.getSmscIdentity(getSubscriptionId(), TelephonyManager.APPTYPE_USIM);
+ }
+ } catch (RemoteException ex) {
+ Rlog.e(TAG, "getSmscIdentity(): Exception : " + ex);
+ ex.rethrowAsRuntimeException();
+ }
+ return smscUri;
+ }
}
diff --git a/telephony/java/android/telephony/SubscriptionInfo.java b/telephony/java/android/telephony/SubscriptionInfo.java
index 2ddc98aca90c..faf97b57594e 100644
--- a/telephony/java/android/telephony/SubscriptionInfo.java
+++ b/telephony/java/android/telephony/SubscriptionInfo.java
@@ -947,29 +947,30 @@ public class SubscriptionInfo implements Parcelable {
}
/**
- * Get ICCID stripped PII information on user build.
+ * Get stripped PII information from the id.
*
- * @param iccId The original ICCID.
+ * @param id The raw id (e.g. ICCID, IMSI, etc...).
* @return The stripped string.
*
* @hide
*/
- public static String givePrintableIccid(String iccId) {
- String iccIdToPrint = null;
- if (iccId != null) {
- if (iccId.length() > 9 && !TelephonyUtils.IS_DEBUGGABLE) {
- iccIdToPrint = iccId.substring(0, 9) + Rlog.pii(false, iccId.substring(9));
+ @Nullable
+ public static String getPrintableId(@Nullable String id) {
+ String idToPrint = null;
+ if (id != null) {
+ if (id.length() > 9 && !TelephonyUtils.IS_DEBUGGABLE) {
+ idToPrint = id.substring(0, 9) + Rlog.pii(false, id.substring(9));
} else {
- iccIdToPrint = iccId;
+ idToPrint = id;
}
}
- return iccIdToPrint;
+ return idToPrint;
}
@Override
public String toString() {
- String iccIdToPrint = givePrintableIccid(mIccId);
- String cardStringToPrint = givePrintableIccid(mCardString);
+ String iccIdToPrint = getPrintableId(mIccId);
+ String cardStringToPrint = getPrintableId(mCardString);
return "[SubscriptionInfo: id=" + mId
+ " iccId=" + iccIdToPrint
+ " simSlotIndex=" + mSimSlotIndex
@@ -1536,7 +1537,7 @@ public class SubscriptionInfo implements Parcelable {
*/
@NonNull
public Builder setGroupUuid(@Nullable String groupUuid) {
- mGroupUuid = groupUuid == null ? null : ParcelUuid.fromString(groupUuid);
+ mGroupUuid = TextUtils.isEmpty(groupUuid) ? null : ParcelUuid.fromString(groupUuid);
return this;
}
diff --git a/telephony/java/android/telephony/SubscriptionManager.java b/telephony/java/android/telephony/SubscriptionManager.java
index 96dc44a5f9fa..64e43568e4d6 100644
--- a/telephony/java/android/telephony/SubscriptionManager.java
+++ b/telephony/java/android/telephony/SubscriptionManager.java
@@ -91,8 +91,7 @@ import java.util.function.Consumer;
import java.util.stream.Collectors;
/**
- * SubscriptionManager is the application interface to SubscriptionController
- * and provides information about the current Telephony Subscriptions.
+ * Subscription manager provides the mobile subscription information.
*/
@SystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE)
@RequiresFeature(PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION)
@@ -119,13 +118,12 @@ public class SubscriptionManager {
public static final int DEFAULT_SUBSCRIPTION_ID = Integer.MAX_VALUE;
/**
- * Indicates the caller wants the default phone id.
- * Used in SubscriptionController and Phone but do we really need it???
+ * Indicates the default phone id.
* @hide
*/
public static final int DEFAULT_PHONE_INDEX = Integer.MAX_VALUE;
- /** Indicates the caller wants the default slot id. NOT used remove? */
+ /** Indicates the default slot index. */
/** @hide */
public static final int DEFAULT_SIM_SLOT_INDEX = Integer.MAX_VALUE;
@@ -141,29 +139,10 @@ public class SubscriptionManager {
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
public static final Uri CONTENT_URI = SimInfo.CONTENT_URI;
- private static final String CACHE_KEY_DEFAULT_SUB_ID_PROPERTY =
- "cache_key.telephony.get_default_sub_id";
-
- private static final String CACHE_KEY_DEFAULT_DATA_SUB_ID_PROPERTY =
- "cache_key.telephony.get_default_data_sub_id";
-
- private static final String CACHE_KEY_DEFAULT_SMS_SUB_ID_PROPERTY =
- "cache_key.telephony.get_default_sms_sub_id";
-
- private static final String CACHE_KEY_ACTIVE_DATA_SUB_ID_PROPERTY =
- "cache_key.telephony.get_active_data_sub_id";
-
- private static final String CACHE_KEY_SLOT_INDEX_PROPERTY =
- "cache_key.telephony.get_slot_index";
-
/** The IPC cache key shared by all subscription manager service cacheable properties. */
private static final String CACHE_KEY_SUBSCRIPTION_MANAGER_SERVICE_PROPERTY =
"cache_key.telephony.subscription_manager_service";
- /** The temporarily cache key to indicate whether subscription manager service is enabled. */
- private static final String CACHE_KEY_SUBSCRIPTION_MANAGER_SERVICE_ENABLED_PROPERTY =
- "cache_key.telephony.subscription_manager_service_enabled";
-
/** @hide */
public static final String GET_SIM_SPECIFIC_SETTINGS_METHOD_NAME = "getSimSpecificSettings";
@@ -199,13 +178,24 @@ public class SubscriptionManager {
}
@Override
- public T recompute(Void aVoid) {
+ public T recompute(Void query) {
+ // This always throws on any error. The exceptions must be handled outside
+ // the cache.
+ try {
+ return mInterfaceMethod.applyOrThrow(TelephonyManager.getSubscriptionService());
+ } catch (Exception re) {
+ throw new RuntimeException(re);
+ }
+ }
+
+ @Override
+ public T query(Void query) {
T result = mDefaultValue;
try {
ISub iSub = TelephonyManager.getSubscriptionService();
if (iSub != null) {
- result = mInterfaceMethod.applyOrThrow(iSub);
+ result = super.query(query);
}
} catch (Exception ex) {
Rlog.w(LOG_TAG, "Failed to recompute cache key for " + mCacheKeyProperty);
@@ -234,12 +224,24 @@ public class SubscriptionManager {
@Override
public T recompute(Integer query) {
+ // This always throws on any error. The exceptions must be handled outside
+ // the cache.
+ try {
+ return mInterfaceMethod.applyOrThrow(
+ TelephonyManager.getSubscriptionService(), query);
+ } catch (Exception re) {
+ throw new RuntimeException(re);
+ }
+ }
+
+ @Override
+ public T query(Integer query) {
T result = mDefaultValue;
try {
ISub iSub = TelephonyManager.getSubscriptionService();
if (iSub != null) {
- result = mInterfaceMethod.applyOrThrow(iSub, query);
+ result = super.query(query);
}
} catch (Exception ex) {
Rlog.w(LOG_TAG, "Failed to recompute cache key for " + mCacheKeyProperty);
@@ -250,83 +252,41 @@ public class SubscriptionManager {
}
}
- private static VoidPropertyInvalidatedCache<Integer> sDefaultSubIdCache =
- new VoidPropertyInvalidatedCache<>(ISub::getDefaultSubId,
- CACHE_KEY_DEFAULT_SUB_ID_PROPERTY,
- INVALID_SUBSCRIPTION_ID);
-
private static VoidPropertyInvalidatedCache<Integer> sGetDefaultSubIdCache =
new VoidPropertyInvalidatedCache<>(ISub::getDefaultSubId,
CACHE_KEY_SUBSCRIPTION_MANAGER_SERVICE_PROPERTY,
INVALID_SUBSCRIPTION_ID);
- private static VoidPropertyInvalidatedCache<Integer> sDefaultDataSubIdCache =
- new VoidPropertyInvalidatedCache<>(ISub::getDefaultDataSubId,
- CACHE_KEY_DEFAULT_DATA_SUB_ID_PROPERTY,
- INVALID_SUBSCRIPTION_ID);
-
private static VoidPropertyInvalidatedCache<Integer> sGetDefaultDataSubIdCache =
new VoidPropertyInvalidatedCache<>(ISub::getDefaultDataSubId,
CACHE_KEY_SUBSCRIPTION_MANAGER_SERVICE_PROPERTY,
INVALID_SUBSCRIPTION_ID);
- private static VoidPropertyInvalidatedCache<Integer> sDefaultSmsSubIdCache =
- new VoidPropertyInvalidatedCache<>(ISub::getDefaultSmsSubId,
- CACHE_KEY_DEFAULT_SMS_SUB_ID_PROPERTY,
- INVALID_SUBSCRIPTION_ID);
-
private static VoidPropertyInvalidatedCache<Integer> sGetDefaultSmsSubIdCache =
new VoidPropertyInvalidatedCache<>(ISub::getDefaultSmsSubId,
CACHE_KEY_SUBSCRIPTION_MANAGER_SERVICE_PROPERTY,
INVALID_SUBSCRIPTION_ID);
- private static VoidPropertyInvalidatedCache<Integer> sActiveDataSubIdCache =
- new VoidPropertyInvalidatedCache<>(ISub::getActiveDataSubscriptionId,
- CACHE_KEY_ACTIVE_DATA_SUB_ID_PROPERTY,
- INVALID_SUBSCRIPTION_ID);
-
private static VoidPropertyInvalidatedCache<Integer> sGetActiveDataSubscriptionIdCache =
new VoidPropertyInvalidatedCache<>(ISub::getActiveDataSubscriptionId,
CACHE_KEY_SUBSCRIPTION_MANAGER_SERVICE_PROPERTY,
INVALID_SUBSCRIPTION_ID);
- private static IntegerPropertyInvalidatedCache<Integer> sSlotIndexCache =
- new IntegerPropertyInvalidatedCache<>(ISub::getSlotIndex,
- CACHE_KEY_SLOT_INDEX_PROPERTY,
- INVALID_SIM_SLOT_INDEX);
-
private static IntegerPropertyInvalidatedCache<Integer> sGetSlotIndexCache =
new IntegerPropertyInvalidatedCache<>(ISub::getSlotIndex,
CACHE_KEY_SUBSCRIPTION_MANAGER_SERVICE_PROPERTY,
INVALID_SIM_SLOT_INDEX);
- private static IntegerPropertyInvalidatedCache<Integer> sSubIdCache =
- new IntegerPropertyInvalidatedCache<>(ISub::getSubId,
- CACHE_KEY_SLOT_INDEX_PROPERTY,
- INVALID_SUBSCRIPTION_ID);
-
private static IntegerPropertyInvalidatedCache<Integer> sGetSubIdCache =
new IntegerPropertyInvalidatedCache<>(ISub::getSubId,
CACHE_KEY_SUBSCRIPTION_MANAGER_SERVICE_PROPERTY,
INVALID_SUBSCRIPTION_ID);
- /** Cache depends on getDefaultSubId, so we use the defaultSubId cache key */
- private static IntegerPropertyInvalidatedCache<Integer> sPhoneIdCache =
- new IntegerPropertyInvalidatedCache<>(ISub::getPhoneId,
- CACHE_KEY_DEFAULT_SUB_ID_PROPERTY,
- INVALID_PHONE_INDEX);
-
private static IntegerPropertyInvalidatedCache<Integer> sGetPhoneIdCache =
new IntegerPropertyInvalidatedCache<>(ISub::getPhoneId,
CACHE_KEY_SUBSCRIPTION_MANAGER_SERVICE_PROPERTY,
INVALID_PHONE_INDEX);
- //TODO: Removed before U AOSP public release.
- private static VoidPropertyInvalidatedCache<Boolean> sIsSubscriptionManagerServiceEnabled =
- new VoidPropertyInvalidatedCache<>(ISub::isSubscriptionManagerServiceEnabled,
- CACHE_KEY_SUBSCRIPTION_MANAGER_SERVICE_ENABLED_PROPERTY,
- false);
-
/**
* Generates a content {@link Uri} used to receive updates on simInfo change
* on the given subscriptionId
@@ -1432,17 +1392,6 @@ public class SubscriptionManager {
mContext = context;
}
- /**
- * @return {@code true} if the new subscription manager service is used. This is temporary and
- * will be removed before Android 14 release.
- *
- * @hide
- */
- //TODO: Removed before U AOSP public release.
- public static boolean isSubscriptionManagerServiceEnabled() {
- return sIsSubscriptionManagerServiceEnabled.query(null);
- }
-
private NetworkPolicyManager getNetworkPolicyManager() {
return (NetworkPolicyManager) mContext
.getSystemService(Context.NETWORK_POLICY_SERVICE);
@@ -1497,7 +1446,7 @@ public class SubscriptionManager {
+ " listener=" + listener);
}
// We use the TelephonyRegistry as it runs in the system and thus is always
- // available. Where as SubscriptionController could crash and not be available
+ // available.
TelephonyRegistryManager telephonyRegistryManager = (TelephonyRegistryManager)
mContext.getSystemService(Context.TELEPHONY_REGISTRY_SERVICE);
if (telephonyRegistryManager != null) {
@@ -1527,7 +1476,7 @@ public class SubscriptionManager {
+ " listener=" + listener);
}
// We use the TelephonyRegistry as it runs in the system and thus is always
- // available where as SubscriptionController could crash and not be available
+ // available.
TelephonyRegistryManager telephonyRegistryManager = (TelephonyRegistryManager)
mContext.getSystemService(Context.TELEPHONY_REGISTRY_SERVICE);
if (telephonyRegistryManager != null) {
@@ -1585,7 +1534,7 @@ public class SubscriptionManager {
}
// We use the TelephonyRegistry as it runs in the system and thus is always
- // available where as SubscriptionController could crash and not be available
+ // available.
TelephonyRegistryManager telephonyRegistryManager = (TelephonyRegistryManager)
mContext.getSystemService(Context.TELEPHONY_REGISTRY_SERVICE);
if (telephonyRegistryManager != null) {
@@ -2126,9 +2075,9 @@ public class SubscriptionManager {
Log.e(LOG_TAG, "[removeSubscriptionInfoRecord]- ISub service is null");
return;
}
- int result = iSub.removeSubInfo(uniqueId, subscriptionType);
- if (result < 0) {
- Log.e(LOG_TAG, "Removal of subscription didn't succeed: error = " + result);
+ boolean result = iSub.removeSubInfo(uniqueId, subscriptionType);
+ if (!result) {
+ Log.e(LOG_TAG, "Removal of subscription didn't succeed");
} else {
logd("successfully removed subscription");
}
@@ -2213,8 +2162,7 @@ public class SubscriptionManager {
* subscriptionId doesn't have an associated slot index.
*/
public static int getSlotIndex(int subscriptionId) {
- if (isSubscriptionManagerServiceEnabled()) return sGetSlotIndexCache.query(subscriptionId);
- return sSlotIndexCache.query(subscriptionId);
+ return sGetSlotIndexCache.query(subscriptionId);
}
/**
@@ -2271,15 +2219,13 @@ public class SubscriptionManager {
return SubscriptionManager.INVALID_SUBSCRIPTION_ID;
}
- if (isSubscriptionManagerServiceEnabled()) return sGetSubIdCache.query(slotIndex);
- return sSubIdCache.query(slotIndex);
+ return sGetSubIdCache.query(slotIndex);
}
/** @hide */
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
public static int getPhoneId(int subId) {
- if (isSubscriptionManagerServiceEnabled()) return sGetPhoneIdCache.query(subId);
- return sPhoneIdCache.query(subId);
+ return sGetPhoneIdCache.query(subId);
}
private static void logd(String msg) {
@@ -2300,8 +2246,7 @@ public class SubscriptionManager {
* @return the "system" default subscription id.
*/
public static int getDefaultSubscriptionId() {
- if (isSubscriptionManagerServiceEnabled()) return sGetDefaultSubIdCache.query(null);
- return sDefaultSubIdCache.query(null);
+ return sGetDefaultSubIdCache.query(null);
}
/**
@@ -2389,8 +2334,7 @@ public class SubscriptionManager {
* @return the default SMS subscription Id.
*/
public static int getDefaultSmsSubscriptionId() {
- if (isSubscriptionManagerServiceEnabled()) return sGetDefaultSmsSubIdCache.query(null);
- return sDefaultSmsSubIdCache.query(null);
+ return sGetDefaultSmsSubIdCache.query(null);
}
/**
@@ -2424,8 +2368,7 @@ public class SubscriptionManager {
* @return the default data subscription Id.
*/
public static int getDefaultDataSubscriptionId() {
- if (isSubscriptionManagerServiceEnabled()) return sGetDefaultDataSubIdCache.query(null);
- return sDefaultDataSubIdCache.query(null);
+ return sGetDefaultDataSubIdCache.query(null);
}
/**
@@ -2663,10 +2606,10 @@ public class SubscriptionManager {
* @param columnName Column name in subscription database.
*
* @return Value in string format associated with {@code subscriptionId} and {@code columnName}
- * from the database.
+ * from the database. Empty string if the {@code subscriptionId} is invalid (for backward
+ * compatible).
*
- * @throws IllegalArgumentException if {@code subscriptionId} is invalid, or the field is not
- * exposed.
+ * @throws IllegalArgumentException if the field is not exposed.
*
* @see android.provider.Telephony.SimInfo for all the columns.
*
@@ -3119,10 +3062,10 @@ public class SubscriptionManager {
*
* Only supported for embedded subscriptions (if {@link SubscriptionInfo#isEmbedded} returns
* true). To check for permissions for non-embedded subscription as well,
+ * see {@link android.telephony.TelephonyManager#hasCarrierPrivileges}.
*
* @param info The subscription to check.
* @return whether the app is authorized to manage this subscription per its metadata.
- *
* @see android.telephony.TelephonyManager#hasCarrierPrivileges
*/
public boolean canManageSubscription(SubscriptionInfo info) {
@@ -3136,12 +3079,12 @@ public class SubscriptionManager {
*
* Only supported for embedded subscriptions (if {@link SubscriptionInfo#isEmbedded} returns
* true). To check for permissions for non-embedded subscription as well,
+ * see {@link android.telephony.TelephonyManager#hasCarrierPrivileges}.
*
* @param info The subscription to check.
* @param packageName Package name of the app to check.
*
* @return whether the app is authorized to manage this subscription per its access rules.
- *
* @see android.telephony.TelephonyManager#hasCarrierPrivileges
* @hide
*/
@@ -3298,12 +3241,13 @@ public class SubscriptionManager {
* @param subId sub id
* @param callbackIntent pending intent that will be sent after operation is done.
*
- * to-be-deprecated this API is a duplicate of {@link EuiccManager#switchToSubscription(int,
+ * @deprecated this API is a duplicate of {@link EuiccManager#switchToSubscription(int,
* PendingIntent)} and does not support Multiple Enabled Profile(MEP). Apps should use
* {@link EuiccManager#switchToSubscription(int, PendingIntent)} or
* {@link EuiccManager#switchToSubscription(int, int, PendingIntent)} instead.
*/
@RequiresPermission(android.Manifest.permission.WRITE_EMBEDDED_SUBSCRIPTIONS)
+ @Deprecated
public void switchToSubscription(int subId, @NonNull PendingIntent callbackIntent) {
Preconditions.checkNotNull(callbackIntent, "callbackIntent cannot be null");
EuiccManager euiccManager = new EuiccManager(mContext);
@@ -3507,8 +3451,8 @@ public class SubscriptionManager {
* or carrier privilege permission on the subscription.
* {@link TelephonyManager#hasCarrierPrivileges()}
*
- * <p>Starting with API level 33, this method will return an empty List if the caller does
- * not have access to device identifiers.
+ * <p>Starting with API level 33, the caller also needs permission to access device identifiers
+ * to get the list of subscriptions associated with a group UUID.
* This method can be invoked if one of the following requirements is met:
* <ul>
* <li>If the app has carrier privilege permission.
@@ -3888,10 +3832,7 @@ public class SubscriptionManager {
* @see TelephonyCallback.ActiveDataSubscriptionIdListener
*/
public static int getActiveDataSubscriptionId() {
- if (isSubscriptionManagerServiceEnabled()) {
- return sGetActiveDataSubscriptionIdCache.query(null);
- }
- return sActiveDataSubIdCache.query(null);
+ return sGetActiveDataSubscriptionIdCache.query(null);
}
/**
@@ -3910,56 +3851,16 @@ public class SubscriptionManager {
}
/** @hide */
- public static void invalidateDefaultSubIdCaches() {
- PropertyInvalidatedCache.invalidateCache(CACHE_KEY_DEFAULT_SUB_ID_PROPERTY);
- }
-
- /** @hide */
- public static void invalidateDefaultDataSubIdCaches() {
- PropertyInvalidatedCache.invalidateCache(CACHE_KEY_DEFAULT_DATA_SUB_ID_PROPERTY);
- }
-
- /** @hide */
- public static void invalidateDefaultSmsSubIdCaches() {
- PropertyInvalidatedCache.invalidateCache(CACHE_KEY_DEFAULT_SMS_SUB_ID_PROPERTY);
- }
-
- /** @hide */
- public static void invalidateActiveDataSubIdCaches() {
- PropertyInvalidatedCache.invalidateCache(CACHE_KEY_ACTIVE_DATA_SUB_ID_PROPERTY);
- }
-
- /** @hide */
- public static void invalidateSlotIndexCaches() {
- PropertyInvalidatedCache.invalidateCache(CACHE_KEY_SLOT_INDEX_PROPERTY);
- }
-
- /** @hide */
public static void invalidateSubscriptionManagerServiceCaches() {
PropertyInvalidatedCache.invalidateCache(CACHE_KEY_SUBSCRIPTION_MANAGER_SERVICE_PROPERTY);
}
- /** @hide */
- //TODO: Removed before U AOSP public release.
- public static void invalidateSubscriptionManagerServiceEnabledCaches() {
- PropertyInvalidatedCache.invalidateCache(
- CACHE_KEY_SUBSCRIPTION_MANAGER_SERVICE_ENABLED_PROPERTY);
- }
-
/**
* Allows a test process to disable client-side caching operations.
*
* @hide
*/
public static void disableCaching() {
- sDefaultSubIdCache.disableLocal();
- sDefaultDataSubIdCache.disableLocal();
- sActiveDataSubIdCache.disableLocal();
- sDefaultSmsSubIdCache.disableLocal();
- sSlotIndexCache.disableLocal();
- sSubIdCache.disableLocal();
- sPhoneIdCache.disableLocal();
-
sGetDefaultSubIdCache.disableLocal();
sGetDefaultDataSubIdCache.disableLocal();
sGetActiveDataSubscriptionIdCache.disableLocal();
@@ -3967,8 +3868,6 @@ public class SubscriptionManager {
sGetSlotIndexCache.disableLocal();
sGetSubIdCache.disableLocal();
sGetPhoneIdCache.disableLocal();
-
- sIsSubscriptionManagerServiceEnabled.disableLocal();
}
/**
@@ -3976,14 +3875,6 @@ public class SubscriptionManager {
*
* @hide */
public static void clearCaches() {
- sDefaultSubIdCache.clear();
- sDefaultDataSubIdCache.clear();
- sActiveDataSubIdCache.clear();
- sDefaultSmsSubIdCache.clear();
- sSlotIndexCache.clear();
- sSubIdCache.clear();
- sPhoneIdCache.clear();
-
sGetDefaultSubIdCache.clear();
sGetDefaultDataSubIdCache.clear();
sGetActiveDataSubscriptionIdCache.clear();
@@ -3991,8 +3882,6 @@ public class SubscriptionManager {
sGetSlotIndexCache.clear();
sGetSubIdCache.clear();
sGetPhoneIdCache.clear();
-
- sIsSubscriptionManagerServiceEnabled.clear();
}
/**
@@ -4331,7 +4220,6 @@ public class SubscriptionManager {
*
* @hide
*/
- @SystemApi
@RequiresPermission(Manifest.permission.MANAGE_SUBSCRIPTION_USER_ASSOCIATION)
public void setSubscriptionUserHandle(int subscriptionId, @Nullable UserHandle userHandle) {
if (!isValidSubscriptionId(subscriptionId)) {
@@ -4363,11 +4251,9 @@ public class SubscriptionManager {
*
* @throws IllegalArgumentException if subscription is invalid.
* @throws SecurityException if the caller doesn't have permissions required.
- * @throws IllegalStateException if subscription service is not available.
*
* @hide
*/
- @SystemApi
@RequiresPermission(Manifest.permission.MANAGE_SUBSCRIPTION_USER_ASSOCIATION)
public @Nullable UserHandle getSubscriptionUserHandle(int subscriptionId) {
if (!isValidSubscriptionId(subscriptionId)) {
@@ -4380,8 +4266,7 @@ public class SubscriptionManager {
if (iSub != null) {
return iSub.getSubscriptionUserHandle(subscriptionId);
} else {
- throw new IllegalStateException("[getSubscriptionUserHandle]: "
- + "subscription service unavailable");
+ Log.e(LOG_TAG, "[getSubscriptionUserHandle]: subscription service unavailable");
}
} catch (RemoteException ex) {
ex.rethrowAsRuntimeException();
@@ -4400,7 +4285,6 @@ public class SubscriptionManager {
*
* @throws IllegalArgumentException if subscription is invalid.
* @throws SecurityException if the caller doesn't have permissions required.
- * @throws IllegalStateException if subscription service is not available.
*
* @hide
*/
@@ -4417,8 +4301,8 @@ public class SubscriptionManager {
if (iSub != null) {
return iSub.isSubscriptionAssociatedWithUser(subscriptionId, userHandle);
} else {
- throw new IllegalStateException("[isSubscriptionAssociatedWithUser]: "
- + "subscription service unavailable");
+ Log.e(LOG_TAG, "[isSubscriptionAssociatedWithUser]: subscription service "
+ + "unavailable");
}
} catch (RemoteException ex) {
ex.rethrowAsRuntimeException();
@@ -4445,7 +4329,7 @@ public class SubscriptionManager {
if (iSub != null) {
return iSub.getSubscriptionInfoListAssociatedWithUser(userHandle);
} else {
- throw new IllegalStateException("[getSubscriptionInfoListAssociatedWithUser]: "
+ Log.e(LOG_TAG, "[getSubscriptionInfoListAssociatedWithUser]: "
+ "subscription service unavailable");
}
} catch (RemoteException ex) {
@@ -4454,4 +4338,3 @@ public class SubscriptionManager {
return new ArrayList<>();
}
}
-
diff --git a/telephony/java/android/telephony/TelephonyFrameworkInitializer.java b/telephony/java/android/telephony/TelephonyFrameworkInitializer.java
index 8308821b59ff..c2f5b8f3e7da 100644
--- a/telephony/java/android/telephony/TelephonyFrameworkInitializer.java
+++ b/telephony/java/android/telephony/TelephonyFrameworkInitializer.java
@@ -23,6 +23,7 @@ import android.os.TelephonyServiceManager;
import android.telephony.euicc.EuiccCardManager;
import android.telephony.euicc.EuiccManager;
import android.telephony.ims.ImsManager;
+import android.telephony.satellite.SatelliteManager;
import com.android.internal.util.Preconditions;
@@ -98,6 +99,11 @@ public class TelephonyFrameworkInitializer {
context -> SmsManager.getSmsManagerForContextAndSubscriptionId(context,
SubscriptionManager.DEFAULT_SUBSCRIPTION_ID)
);
+ SystemServiceRegistry.registerContextAwareService(
+ Context.SATELLITE_SERVICE,
+ SatelliteManager.class,
+ context -> new SatelliteManager(context)
+ );
}
/** @hide */
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index fa60031f2a66..2a6099a18fab 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -54,6 +54,7 @@ import android.content.Intent;
import android.content.pm.PackageManager;
import android.database.Cursor;
import android.net.ConnectivityManager;
+import android.net.NetworkCapabilities;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Binder;
@@ -125,7 +126,6 @@ import com.android.internal.telephony.IccLogicalChannelRequest;
import com.android.internal.telephony.OperatorInfo;
import com.android.internal.telephony.PhoneConstants;
import com.android.internal.telephony.RILConstants;
-import com.android.internal.telephony.SmsApplication;
import com.android.telephony.Rlog;
import java.io.IOException;
@@ -140,6 +140,7 @@ import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
@@ -234,6 +235,54 @@ public class TelephonyManager {
public static final int NETWORK_SELECTION_MODE_AUTO = 1;
public static final int NETWORK_SELECTION_MODE_MANUAL = 2;
+ /**
+ * Reasons for Radio being powered off.
+ *
+ * @hide
+ */
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef(prefix = {"RADIO_POWER_REASON_"},
+ value = {
+ RADIO_POWER_REASON_USER,
+ RADIO_POWER_REASON_THERMAL,
+ RADIO_POWER_REASON_CARRIER,
+ RADIO_POWER_REASON_NEARBY_DEVICE})
+ public @interface RadioPowerReason {}
+
+ /**
+ * This reason is used when users want to turn off radio, e.g., users turn on airplane mode.
+ *
+ * @hide
+ */
+ @SystemApi
+ public static final int RADIO_POWER_REASON_USER = 0;
+ /**
+ * This reason is used when radio needs to be turned off due to thermal.
+ *
+ * @hide
+ */
+ @SystemApi
+ public static final int RADIO_POWER_REASON_THERMAL = 1;
+ /**
+ * This reason is used when carriers want to turn off radio. A privileged app can request to
+ * turn off radio via the system service
+ * {@link com.android.carrierdefaultapp.CaptivePortalLoginActivity}, which subsequently calls
+ * the system APIs {@link requestRadioPowerOffForReason} and
+ * {@link clearRadioPowerOffForReason}.
+ *
+ * @hide
+ */
+ @SystemApi
+ public static final int RADIO_POWER_REASON_CARRIER = 2;
+ /**
+ * Used to reduce power on a battery-constrained device when Telephony services are available
+ * via a paired device which is nearby.
+ *
+ * @hide
+ */
+ @SystemApi
+ public static final int RADIO_POWER_REASON_NEARBY_DEVICE = 3;
+
/** The otaspMode passed to PhoneStateListener#onOtaspChanged */
/** @hide */
static public final int OTASP_UNINITIALIZED = 0;
@@ -364,6 +413,9 @@ public class TelephonyManager {
/** @hide */
public static final int INVALID_PORT_INDEX = -1;
+ /** @hide */
+ public static final String PROPERTY_ENABLE_NULL_CIPHER_TOGGLE = "enable_null_cipher_toggle";
+
private final Context mContext;
private final int mSubId;
@UnsupportedAppUsage
@@ -2909,7 +2961,11 @@ public class TelephonyManager {
public static final int NETWORK_TYPE_HSUPA = TelephonyProtoEnums.NETWORK_TYPE_HSUPA; // = 9.
/** Current network is HSPA */
public static final int NETWORK_TYPE_HSPA = TelephonyProtoEnums.NETWORK_TYPE_HSPA; // = 10.
- /** Current network is iDen */
+ /**
+ * Current network is iDen
+ * @deprecated Legacy network type no longer being used starting in Android U.
+ */
+ @Deprecated
public static final int NETWORK_TYPE_IDEN = TelephonyProtoEnums.NETWORK_TYPE_IDEN; // = 11.
/** Current network is EVDO revision B*/
public static final int NETWORK_TYPE_EVDO_B = TelephonyProtoEnums.NETWORK_TYPE_EVDO_B; // = 12.
@@ -3257,15 +3313,14 @@ public class TelephonyManager {
case NETWORK_TYPE_TD_SCDMA:
return NETWORK_TYPE_BITMASK_TD_SCDMA;
case NETWORK_TYPE_LTE:
- return NETWORK_TYPE_BITMASK_LTE;
case NETWORK_TYPE_LTE_CA:
- return NETWORK_TYPE_BITMASK_LTE_CA;
+ return NETWORK_TYPE_BITMASK_LTE;
case NETWORK_TYPE_NR:
return NETWORK_TYPE_BITMASK_NR;
case NETWORK_TYPE_IWLAN:
return NETWORK_TYPE_BITMASK_IWLAN;
case NETWORK_TYPE_IDEN:
- return (1 << (NETWORK_TYPE_IDEN - 1));
+ return NETWORK_TYPE_BITMASK_IDEN;
default:
return NETWORK_TYPE_BITMASK_UNKNOWN;
}
@@ -3456,7 +3511,15 @@ public class TelephonyManager {
public static final String ACTION_SECRET_CODE = "android.telephony.action.SECRET_CODE";
/**
- * @return true if a ICC card is present
+ * This API is used to check if there is an ICC card present in the device.
+ *
+ * An ICC card is a smart card that contains a subscriber identity module (SIM) and is used
+ * to identify and authenticate users to a mobile network.
+ *
+ * Note: In case of embedded SIM there is an ICC card always present irrespective
+ * of whether an active SIM profile is present or not so this API would always return true.
+ *
+ * @return true if a ICC card is present.
*/
@RequiresFeature(PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION)
public boolean hasIccCard() {
@@ -4847,7 +4910,7 @@ public class TelephonyManager {
return;
}
ParcelUuid resultUuid =
- result.getParcelable(KEY_CALL_COMPOSER_PICTURE_HANDLE);
+ result.getParcelable(KEY_CALL_COMPOSER_PICTURE_HANDLE, android.os.ParcelUuid.class);
if (resultUuid == null) {
Log.e(TAG, "Got null uuid without an error"
+ " while uploading call composer pic");
@@ -5945,6 +6008,7 @@ public class TelephonyManager {
* Returns the IMS private user identity (IMPI) that was loaded from the ISIM.
* @return the IMPI, or null if not present or not loaded
* @hide
+ * @deprecated use {@link #getImsPrivateUserIdentity()}
*/
@UnsupportedAppUsage
public String getIsimImpi() {
@@ -5963,6 +6027,35 @@ public class TelephonyManager {
}
/**
+ * Returns the IMS private user identity (IMPI) of the subscription that was loaded from the
+ * ISIM records {@link #APPTYPE_ISIM}. This value is fetched from the Elementary file EF_IMPI.
+ * The contents of the file is a <b>Ip Multimedia Service Private User Identity</b> of the user
+ * as defined in the section 4.2.2 of 3GPP TS 131 103.
+ *
+ * @return IMPI (IMS private user identity) of type string.
+ * @throws IllegalStateException in case the ISIM has’t been loaded
+ * @throws SecurityException if the caller does not have the required permission/privileges
+ * @hide
+ */
+ @NonNull
+ @RequiresPermission(android.Manifest.permission.USE_ICC_AUTH_WITH_DEVICE_IDENTIFIER)
+ @RequiresFeature(PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION)
+ public String getImsPrivateUserIdentity() {
+ try {
+ IPhoneSubInfo info = getSubscriberInfoService();
+ if (info == null) {
+ Rlog.e(TAG, "getImsPrivateUserIdentity(): IPhoneSubInfo instance is NULL");
+ throw new RuntimeException("IMPI error: Subscriber Info is null");
+ }
+ return info.getImsPrivateUserIdentity(getSubId(), getOpPackageName(),
+ getAttributionTag());
+ } catch (RemoteException | NullPointerException | IllegalArgumentException ex) {
+ Rlog.e(TAG, "getImsPrivateUserIdentity() Exception = " + ex);
+ throw new RuntimeException(ex.getMessage());
+ }
+ }
+
+ /**
* Returns the IMS home network domain name that was loaded from the ISIM {@see #APPTYPE_ISIM}.
* @return the IMS domain name. Returns {@code null} if ISIM hasn't been loaded or IMS domain
* hasn't been loaded or isn't present on the ISIM.
@@ -5995,6 +6088,7 @@ public class TelephonyManager {
* @return an array of IMPU strings, with one IMPU per string, or null if
* not present or not loaded
* @hide
+ * @deprecated use {@link #getImsPublicUserIdentities()}
*/
@UnsupportedAppUsage
@Nullable
@@ -6015,6 +6109,39 @@ public class TelephonyManager {
}
/**
+ * Returns the IMS public user identities (IMPU) of the subscription that was loaded from the
+ * ISIM records {@link #APPTYPE_ISIM}. This value is fetched from the Elementary file EF_IMPU.
+ * The contents of the file are <b>Ip Multimedia Service Public User Identities</b> of the user
+ * as defined in the section 4.2.4 of 3GPP TS 131 103. It contains one or more records.
+ *
+ * @return List of public user identities of type android.net.Uri or empty list if
+ * EF_IMPU is not available.
+ * @throws IllegalStateException in case the ISIM hasn’t been loaded
+ * @throws SecurityException if the caller does not have the required permission/privilege
+ * @hide
+ */
+ @NonNull
+ @RequiresPermission(anyOf = {android.Manifest.permission.READ_PHONE_NUMBERS,
+ android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE})
+ @RequiresFeature(PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION)
+ public List<Uri> getImsPublicUserIdentities() {
+ try {
+ IPhoneSubInfo info = getSubscriberInfoService();
+ if (info == null) {
+ throw new RuntimeException("IMPU error: Subscriber Info is null");
+ }
+ return info.getImsPublicUserIdentities(getSubId(), getOpPackageName(),
+ getAttributionTag());
+ } catch (IllegalArgumentException | NullPointerException ex) {
+ Rlog.e(TAG, "getImsPublicUserIdentities Exception = " + ex);
+ } catch (RemoteException ex) {
+ Rlog.e(TAG, "getImsPublicUserIdentities Exception = " + ex);
+ ex.rethrowAsRuntimeException();
+ }
+ return Collections.EMPTY_LIST;
+ }
+
+ /**
* Device call state: No activity.
*/
public static final int CALL_STATE_IDLE = 0;
@@ -6784,11 +6911,11 @@ public class TelephonyManager {
*
* @hide
*/
- public void setCellInfoListRate(int rateInMillis) {
+ public void setCellInfoListRate(int rateInMillis, int subId) {
try {
ITelephony telephony = getITelephony();
if (telephony != null)
- telephony.setCellInfoListRate(rateInMillis);
+ telephony.setCellInfoListRate(rateInMillis, subId);
} catch (RemoteException ex) {
} catch (NullPointerException ex) {
}
@@ -7684,7 +7811,7 @@ public class TelephonyManager {
* app has carrier privileges (see {@link #hasCarrierPrivileges}).
*
* TODO: remove this one. use {@link #rebootModem()} for reset type 1 and
- * {@link #resetRadioConfig()} for reset type 3
+ * {@link #resetRadioConfig()} for reset type 3 (b/116476729)
*
* @param resetType reset type: 1: reload NV reset, 2: erase NV reset, 3: factory NV reset
* @return true on success; false on any failure.
@@ -8184,6 +8311,37 @@ public class TelephonyManager {
public static final int AUTHTYPE_EAP_SIM = PhoneConstants.AUTH_CONTEXT_EAP_SIM;
/** Authentication type for UICC challenge is EAP AKA. See RFC 4187 for details. */
public static final int AUTHTYPE_EAP_AKA = PhoneConstants.AUTH_CONTEXT_EAP_AKA;
+ /**
+ * Authentication type for GBA Bootstrap Challenge.
+ * Pass this authentication type into the {@link #getIccAuthentication} API to perform a GBA
+ * Bootstrap challenge (BSF), with {@code data} (generated according to the procedure defined in
+ * 3GPP 33.220 Section 5.3.2 step.4) in base64 encoding.
+ * This method will return the Bootstrapping response in base64 encoding when ICC authentication
+ * is completed.
+ * Ref 3GPP 33.220 Section 5.3.2.
+ */
+ public static final int AUTHTYPE_GBA_BOOTSTRAP = PhoneConstants.AUTH_CONTEXT_GBA_BOOTSTRAP;
+ /**
+ * Authentication type for GBA Network Application Functions (NAF) key External Challenge.
+ * Pass this authentication type into the {@link #getIccAuthentication} API to perform a GBA
+ * Network Applications Functions (NAF) key External challenge using the NAF_ID parameter
+ * as the {@code data} in base64 encoding.
+ * This method will return the Ks_Ext_Naf key in base64 encoding when ICC authentication
+ * is completed.
+ * Ref 3GPP 33.220 Section 5.3.2.
+ */
+ public static final int AUTHTYPE_GBA_NAF_KEY_EXTERNAL =
+ PhoneConstants.AUTHTYPE_GBA_NAF_KEY_EXTERNAL;
+
+ /** @hide */
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef({
+ AUTHTYPE_EAP_SIM,
+ AUTHTYPE_EAP_AKA,
+ AUTHTYPE_GBA_BOOTSTRAP,
+ AUTHTYPE_GBA_NAF_KEY_EXTERNAL
+ })
+ public @interface AuthType {}
/**
* Returns the response of authentication for the default subscription.
@@ -8198,8 +8356,9 @@ public class TelephonyManager {
* </ul>
*
* @param appType the icc application type, like {@link #APPTYPE_USIM}
- * @param authType the authentication type, {@link #AUTHTYPE_EAP_AKA} or
- * {@link #AUTHTYPE_EAP_SIM}
+ * @param authType the authentication type, any one of {@link #AUTHTYPE_EAP_AKA} or
+ * {@link #AUTHTYPE_EAP_SIM} or {@link #AUTHTYPE_GBA_BOOTSTRAP} or
+ * {@link #AUTHTYPE_GBA_NAF_KEY_EXTERNAL}
* @param data authentication challenge data, base64 encoded.
* See 3GPP TS 31.102 7.1.2 for more details.
* @return the response of authentication. This value will be null in the following cases:
@@ -8213,7 +8372,7 @@ public class TelephonyManager {
// READ_PRIVILEGED_PHONE_STATE. It certainly shouldn't reference the permission in Javadoc since
// it's not public API.
@RequiresFeature(PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION)
- public String getIccAuthentication(int appType, int authType, String data) {
+ public String getIccAuthentication(int appType,@AuthType int authType, String data) {
return getIccAuthentication(getSubId(), appType, authType, data);
}
@@ -8226,8 +8385,9 @@ public class TelephonyManager {
*
* @param subId subscription ID used for authentication
* @param appType the icc application type, like {@link #APPTYPE_USIM}
- * @param authType the authentication type, {@link #AUTHTYPE_EAP_AKA} or
- * {@link #AUTHTYPE_EAP_SIM}
+ * @param authType the authentication type, any one of {@link #AUTHTYPE_EAP_AKA} or
+ * {@link #AUTHTYPE_EAP_SIM} or {@link #AUTHTYPE_GBA_BOOTSTRAP} or
+ * {@link #AUTHTYPE_GBA_NAF_KEY_EXTERNAL}
* @param data authentication challenge data, base64 encoded.
* See 3GPP TS 31.102 7.1.2 for more details.
* @return the response of authentication. This value will be null in the following cases only
@@ -8240,7 +8400,7 @@ public class TelephonyManager {
* @hide
*/
@UnsupportedAppUsage
- public String getIccAuthentication(int subId, int appType, int authType, String data) {
+ public String getIccAuthentication(int subId, int appType,@AuthType int authType, String data) {
try {
IPhoneSubInfo info = getSubscriberInfoService();
if (info == null)
@@ -8333,6 +8493,51 @@ public class TelephonyManager {
}
/**
+ * Fetches the sim service table from the EFUST/EFIST based on the application type
+ * {@link #APPTYPE_USIM} or {@link #APPTYPE_ISIM}. The return value is hexaString format
+ * representing X bytes (x >= 1). Each bit of every byte indicates which optional services
+ * are available for the given application type.
+ * The USIM service table EF is described in as per Section 4.2.8 of 3GPP TS 31.102.
+ * The ISIM service table EF is described in as per Section 4.2.7 of 3GPP TS 31.103.
+ * The list of services mapped to the exact nth byte of response as mentioned in Section 4.2
+ * .7 of 3GPP TS 31.103. Eg. Service n°1: Local Phone Book, Service n°2: Fixed Dialling
+ * Numbers (FDN) - Bit 1 and 2 of the 1st Byte represent service Local Phone Book and Fixed
+ * Dialling Numbers (FDN)respectively. The coding format for each service type should be
+ * interpreted as bit = 1: service available;bit = 0:service not available.
+ *
+ * @param appType of type int of either {@link #APPTYPE_USIM} or {@link #APPTYPE_ISIM}.
+ * @return HexString represents sim service table else null.
+ * @throws SecurityException if the caller does not have the required permission/privileges
+ * @hide
+ */
+
+ @Nullable
+ @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
+ @RequiresFeature(PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION)
+ public String getSimServiceTable(int appType) {
+ try {
+ IPhoneSubInfo info = getSubscriberInfoService();
+ if (info == null) {
+ Rlog.e(TAG, "getSimServiceTable(): IPhoneSubInfo is null");
+ return null;
+ }
+ //Fetches the sim service table based on subId and appType
+ if (appType == APPTYPE_ISIM) {
+ return info.getIsimIst(getSubId());
+ } else if ((appType == APPTYPE_USIM)) {
+ return info.getSimServiceTable(getSubId(), APPTYPE_USIM);
+ } else {
+ return null;
+ }
+ } catch (RemoteException ex) {
+ Rlog.e(TAG, "getSimServiceTable(): RemoteException=" + ex.getMessage());
+ } catch (NullPointerException ex) {
+ Rlog.e(TAG, "getSimServiceTable(): NullPointerException=" + ex.getMessage());
+ }
+ return null;
+ }
+
+ /**
* Resets the {@link android.telephony.ims.ImsService} associated with the specified sim slot.
* Used by diagnostic apps to force the IMS stack to be disabled and re-enabled in an effort to
* recover from scenarios where the {@link android.telephony.ims.ImsService} gets in to a bad
@@ -9299,7 +9504,6 @@ public class TelephonyManager {
ALLOWED_NETWORK_TYPES_REASON_POWER,
ALLOWED_NETWORK_TYPES_REASON_CARRIER,
ALLOWED_NETWORK_TYPES_REASON_ENABLE_2G,
- ALLOWED_NETWORK_TYPES_REASON_USER_RESTRICTIONS,
})
@Retention(RetentionPolicy.SOURCE)
public @interface AllowedNetworkTypesReason {
@@ -9338,15 +9542,6 @@ public class TelephonyManager {
public static final int ALLOWED_NETWORK_TYPES_REASON_ENABLE_2G = 3;
/**
- * To indicate allowed network type change is requested by an update to the
- * {@link android.os.UserManager.DISALLOW_CELLULAR_2G} user restriction.
- *
- * @hide
- */
- @SystemApi
- public static final int ALLOWED_NETWORK_TYPES_REASON_USER_RESTRICTIONS = 4;
-
- /**
* Set the allowed network types of the device and provide the reason triggering the allowed
* network change.
* <p>Requires permission: {@link android.Manifest.permission#MODIFY_PHONE_STATE} or
@@ -9370,7 +9565,6 @@ public class TelephonyManager {
* {@link android.Manifest.permission#MODIFY_PHONE_STATE} permissions.
* <ol>
* <li>{@code TelephonyManager.ALLOWED_NETWORK_TYPES_REASON_ENABLE_2G}</li>
- * <li>{@code TelephonyManager.ALLOWED_NETWORK_TYPES_REASON_USER_RESTRICTIONS}</li>
* </ol>
*/
@RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
@@ -9445,7 +9639,6 @@ public class TelephonyManager {
case TelephonyManager.ALLOWED_NETWORK_TYPES_REASON_POWER:
case TelephonyManager.ALLOWED_NETWORK_TYPES_REASON_CARRIER:
case TelephonyManager.ALLOWED_NETWORK_TYPES_REASON_ENABLE_2G:
- case ALLOWED_NETWORK_TYPES_REASON_USER_RESTRICTIONS:
return true;
}
return false;
@@ -10312,7 +10505,7 @@ public class TelephonyManager {
protected void onReceiveResult(int resultCode, Bundle ussdResponse) {
Rlog.d(TAG, "USSD:" + resultCode);
checkNotNull(ussdResponse, "ussdResponse cannot be null.");
- UssdResponse response = ussdResponse.getParcelable(USSD_RESPONSE);
+ UssdResponse response = ussdResponse.getParcelable(USSD_RESPONSE, android.telephony.UssdResponse.class);
if (resultCode == USSD_RETURN_SUCCESS) {
callback.onReceiveUssdResponse(telephonyManager, response.getUssdRequest(),
@@ -10398,34 +10591,155 @@ public class TelephonyManager {
}
}
- /** @hide */
+ /**
+ * @deprecated - use the APIs {@link requestRadioPowerOffForReason} and
+ * {@link clearRadioPowerOffForReason}.
+ *
+ * @hide
+ */
+ @Deprecated
@SystemApi
@RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
@RequiresFeature(PackageManager.FEATURE_TELEPHONY_RADIO_ACCESS)
public boolean setRadio(boolean turnOn) {
+ boolean result = true;
+ try {
+ if (turnOn) {
+ clearRadioPowerOffForReason(RADIO_POWER_REASON_USER);
+ } else {
+ requestRadioPowerOffForReason(RADIO_POWER_REASON_USER);
+ }
+ } catch (Exception e) {
+ String calledFunction =
+ turnOn ? "clearRadioPowerOffForReason" : "requestRadioPowerOffForReason";
+ Log.e(TAG, "Error calling " + calledFunction, e);
+ result = false;
+ }
+ return result;
+ }
+
+ /**
+ * @deprecated - use the APIs {@link requestRadioPowerOffForReason} and
+ * {@link clearRadioPowerOffForReason}.
+ *
+ * @hide
+ */
+ @Deprecated
+ @SystemApi
+ @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
+ @RequiresFeature(PackageManager.FEATURE_TELEPHONY_RADIO_ACCESS)
+ public boolean setRadioPower(boolean turnOn) {
+ boolean result = true;
+ try {
+ if (turnOn) {
+ clearRadioPowerOffForReason(RADIO_POWER_REASON_USER);
+ } else {
+ requestRadioPowerOffForReason(RADIO_POWER_REASON_USER);
+ }
+ } catch (Exception e) {
+ String calledFunction =
+ turnOn ? "clearRadioPowerOffForReason" : "requestRadioPowerOffForReason";
+ Log.e(TAG, "Error calling " + calledFunction, e);
+ result = false;
+ }
+ return result;
+ }
+
+ /**
+ * Vote on powering off the radio for a reason. The radio will be turned on only when there is
+ * no reason to power it off. When any of the voters want to power it off, it will be turned
+ * off. In case of emergency, the radio will be turned on even if there are some reasons for
+ * powering it off, and these radio off votes will be cleared.
+ * Multiple apps can vote for the same reason and the last vote will take effect. Each app is
+ * responsible for its vote. A powering-off vote of a reason will be maintained until it is
+ * cleared by calling {@link clearRadioPowerOffForReason} for that reason, or an emergency call
+ * is made, or the device is rebooted. When an app comes backup from a crash, it needs to make
+ * sure if its vote is as expected. An app can use the API {@link getRadioPowerOffReasons} to
+ * check its vote.
+ *
+ * @param reason The reason for powering off radio.
+ * @throws SecurityException if the caller does not have MODIFY_PHONE_STATE permission.
+ * @throws IllegalStateException if the Telephony service is not currently available.
+ *
+ * @hide
+ */
+ @SystemApi
+ @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
+ @RequiresFeature(PackageManager.FEATURE_TELEPHONY_RADIO_ACCESS)
+ public void requestRadioPowerOffForReason(@RadioPowerReason int reason) {
try {
ITelephony telephony = getITelephony();
- if (telephony != null)
- return telephony.setRadio(turnOn);
+ if (telephony != null) {
+ if (!telephony.requestRadioPowerOffForReason(getSubId(), reason)) {
+ throw new IllegalStateException("Telephony service is not available.");
+ }
+ } else {
+ throw new IllegalStateException("Telephony service is null.");
+ }
} catch (RemoteException e) {
- Log.e(TAG, "Error calling ITelephony#setRadio", e);
+ Log.e(TAG, "Error calling ITelephony#requestRadioPowerOffForReason", e);
+ e.rethrowAsRuntimeException();
}
- return false;
}
- /** @hide */
+ /**
+ * Remove the vote on powering off the radio for a reason, as requested by
+ * {@link requestRadioPowerOffForReason}.
+ *
+ * @param reason The reason for powering off radio.
+ * @throws SecurityException if the caller does not have MODIFY_PHONE_STATE permission.
+ * @throws IllegalStateException if the Telephony service is not currently available.
+ *
+ * @hide
+ */
@SystemApi
@RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
@RequiresFeature(PackageManager.FEATURE_TELEPHONY_RADIO_ACCESS)
- public boolean setRadioPower(boolean turnOn) {
+ public void clearRadioPowerOffForReason(@RadioPowerReason int reason) {
try {
ITelephony telephony = getITelephony();
- if (telephony != null)
- return telephony.setRadioPower(turnOn);
+ if (telephony != null) {
+ if (!telephony.clearRadioPowerOffForReason(getSubId(), reason)) {
+ throw new IllegalStateException("Telephony service is not available.");
+ }
+ } else {
+ throw new IllegalStateException("Telephony service is null.");
+ }
} catch (RemoteException e) {
- Log.e(TAG, "Error calling ITelephony#setRadioPower", e);
+ Log.e(TAG, "Error calling ITelephony#clearRadioPowerOffForReason", e);
+ e.rethrowAsRuntimeException();
}
- return false;
+ }
+
+ /**
+ * Get reasons for powering off radio, as requested by {@link requestRadioPowerOffForReason}.
+ * If the reason set is empty, the radio is on in all cases.
+ *
+ * @return Set of reasons for powering off radio.
+ * @throws SecurityException if the caller does not have READ_PRIVILEGED_PHONE_STATE permission.
+ * @throws IllegalStateException if the Telephony service is not currently available.
+ *
+ * @hide
+ */
+ @SystemApi
+ @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
+ @RequiresFeature(PackageManager.FEATURE_TELEPHONY_RADIO_ACCESS)
+ @NonNull
+ public Set<Integer> getRadioPowerOffReasons() {
+ Set<Integer> result = new HashSet<>();
+ try {
+ ITelephony telephony = getITelephony();
+ if (telephony != null) {
+ result.addAll(telephony.getRadioPowerOffReasons(getSubId(),
+ mContext.getOpPackageName(), mContext.getAttributionTag()));
+ } else {
+ throw new IllegalStateException("Telephony service is null.");
+ }
+ } catch (RemoteException e) {
+ Log.e(TAG, "Error calling ITelephony#getRadioPowerOffReasons", e);
+ e.rethrowAsRuntimeException();
+ }
+ return result;
}
/**
@@ -11703,8 +12017,9 @@ public class TelephonyManager {
}
/**
- * Gets the default Respond Via Message application, updating the cache if there is no
- * respond-via-message application currently configured.
+ * Get the component name of the default app to direct respond-via-message intent for the
+ * user associated with this subscription, update the cache if there is no respond-via-message
+ * application currently configured for this user.
* @return component name of the app and class to direct Respond Via Message intent to, or
* {@code null} if the functionality is not supported.
* @hide
@@ -11713,11 +12028,20 @@ public class TelephonyManager {
@RequiresPermission(Manifest.permission.INTERACT_ACROSS_USERS)
@RequiresFeature(PackageManager.FEATURE_TELEPHONY_MESSAGING)
public @Nullable ComponentName getAndUpdateDefaultRespondViaMessageApplication() {
- return SmsApplication.getDefaultRespondViaMessageApplication(mContext, true);
+ try {
+ ITelephony telephony = getITelephony();
+ if (telephony != null) {
+ return telephony.getDefaultRespondViaMessageApplication(getSubId(), true);
+ }
+ } catch (RemoteException e) {
+ Log.e(TAG, "Error in getAndUpdateDefaultRespondViaMessageApplication: " + e);
+ }
+ return null;
}
/**
- * Gets the default Respond Via Message application.
+ * Get the component name of the default app to direct respond-via-message intent for the
+ * user associated with this subscription.
* @return component name of the app and class to direct Respond Via Message intent to, or
* {@code null} if the functionality is not supported.
* @hide
@@ -11726,7 +12050,15 @@ public class TelephonyManager {
@RequiresPermission(Manifest.permission.INTERACT_ACROSS_USERS)
@RequiresFeature(PackageManager.FEATURE_TELEPHONY_MESSAGING)
public @Nullable ComponentName getDefaultRespondViaMessageApplication() {
- return SmsApplication.getDefaultRespondViaMessageApplication(mContext, false);
+ try {
+ ITelephony telephony = getITelephony();
+ if (telephony != null) {
+ return telephony.getDefaultRespondViaMessageApplication(getSubId(), false);
+ }
+ } catch (RemoteException e) {
+ Log.e(TAG, "Error in getDefaultRespondViaMessageApplication: " + e);
+ }
+ return null;
}
/**
@@ -12890,6 +13222,104 @@ public class TelephonyManager {
}
/**
+ * Carrier restriction status value is unknown, in case modem did not provide any
+ * information about carrier restriction status.
+ */
+ public static final int CARRIER_RESTRICTION_STATUS_UNKNOWN = 0;
+
+ /** The device is not restricted to a carrier */
+ public static final int CARRIER_RESTRICTION_STATUS_NOT_RESTRICTED = 1;
+
+ /** The device is restricted to a carrier. */
+ public static final int CARRIER_RESTRICTION_STATUS_RESTRICTED = 2;
+
+ /** The device is restricted to the carrier of the calling application. */
+ public static final int CARRIER_RESTRICTION_STATUS_RESTRICTED_TO_CALLER = 3;
+
+ /** @hide */
+ @IntDef(prefix = {"CARRIER_RESTRICTION_STATUS_"}, value = {
+ CARRIER_RESTRICTION_STATUS_UNKNOWN,
+ CARRIER_RESTRICTION_STATUS_NOT_RESTRICTED,
+ CARRIER_RESTRICTION_STATUS_RESTRICTED,
+ CARRIER_RESTRICTION_STATUS_RESTRICTED_TO_CALLER
+ })
+
+ public @interface CarrierRestrictionStatus {
+ }
+
+ /**
+ * Get the carrier restriction status of the device.
+ * <p>To fetch the carrier restriction status of the device the calling application needs to be
+ * allowlisted to Android at <a href="https://android.googlesource.com/platform/packages/services/Telephony/+/master/assets/CarrierRestrictionOperatorDetails.json">here</a>.
+ * The calling application also needs the READ_PHONE_STATE permission.
+ * The return value of the API is as follows.
+ * <ul>
+ * <li>return {@link #CARRIER_RESTRICTION_STATUS_RESTRICTED_TO_CALLER} if the caller
+ * and the device locked by the network are same</li>
+ * <li>return {@link #CARRIER_RESTRICTION_STATUS_RESTRICTED} if the caller and the
+ * device locked by the network are different</li>
+ * <li>return {@link #CARRIER_RESTRICTION_STATUS_NOT_RESTRICTED} if the device is
+ * not locked</li>
+ * <li>return {@link #CARRIER_RESTRICTION_STATUS_UNKNOWN} if the device locking
+ * state is unavailable or radio does not supports the feature</li>
+ * </ul>
+ *
+ * @param executor The executor on which the result listener will be called.
+ * @param resultListener {@link Consumer} that will be called with the result fetched
+ * from the radio of type {@link CarrierRestrictionStatus}
+ * @throws SecurityException if the caller does not have the required permission/privileges or
+ * if the caller is not pre-registered.
+ */
+ @RequiresFeature(PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION)
+ @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
+ public void getCarrierRestrictionStatus(@NonNull Executor executor,
+ @NonNull @CarrierRestrictionStatus
+ Consumer<Integer> resultListener) {
+ Objects.requireNonNull(executor);
+ Objects.requireNonNull(resultListener);
+
+ IIntegerConsumer internalCallback = new IIntegerConsumer.Stub() {
+ @Override
+ public void accept(@CarrierRestrictionStatus int result) {
+ executor.execute(() -> Binder.withCleanCallingIdentity(
+ () -> resultListener.accept(result)));
+ }
+ };
+ try {
+ ITelephony service = getITelephony();
+ if (service != null) {
+ service.getCarrierRestrictionStatus(internalCallback, getOpPackageName());
+ }
+ } catch (RemoteException ex) {
+ Rlog.e(TAG, "getCarrierRestrictionStatus: RemoteException = " + ex);
+ throw ex.rethrowAsRuntimeException();
+ }
+ }
+
+ /**
+ * Test API to verify carrier restriction status allow list i.e.
+ * packages/services/Telephony/assets/CarrierRestrictionOperatorDetails.json.
+ *
+ * @param pkgName : packaga name of the entry to verify
+ * @param carrierId : carrier Id of the entry
+ * @return {@code List<String>} : list of registered shaIds
+ * @hide
+ */
+ @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
+ public List<String> getShaIdFromAllowList(String pkgName, int carrierId) {
+ try {
+ ITelephony service = getITelephony();
+ if (service != null) {
+ return service.getShaIdFromAllowList(pkgName, carrierId);
+ }
+ } catch (RemoteException ex) {
+ Rlog.e(TAG, "getShaIdFromAllowList: RemoteException = " + ex);
+ throw ex.rethrowAsRuntimeException();
+ }
+ return Collections.EMPTY_LIST;
+ }
+
+ /**
* Used to enable or disable carrier data by the system based on carrier signalling or
* carrier privileged apps. Different from {@link #setDataEnabled(boolean)} which is linked to
* user settings, carrier data on/off won't affect user settings but will bypass the
@@ -12929,20 +13359,21 @@ public class TelephonyManager {
*
* @param enabled control enable or disable radio.
* @see #resetAllCarrierActions()
+ *
+ * @deprecated - use the APIs {@link requestRadioPowerOffForReason} and
+ * {@link clearRadioPowerOffForReason}.
+ *
* @hide
*/
+ @Deprecated
@SystemApi
@RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
@RequiresFeature(PackageManager.FEATURE_TELEPHONY_RADIO_ACCESS)
public void setRadioEnabled(boolean enabled) {
- try {
- ITelephony service = getITelephony();
- if (service != null) {
- service.carrierActionSetRadioEnabled(
- getSubId(SubscriptionManager.getDefaultDataSubscriptionId()), enabled);
- }
- } catch (RemoteException e) {
- Log.e(TAG, "Error calling ITelephony#carrierActionSetRadioEnabled", e);
+ if (enabled) {
+ clearRadioPowerOffForReason(RADIO_POWER_REASON_CARRIER);
+ } else {
+ requestRadioPowerOffForReason(RADIO_POWER_REASON_CARRIER);
}
}
@@ -13628,7 +14059,8 @@ public class TelephonyManager {
NETWORK_TYPE_BITMASK_LTE,
NETWORK_TYPE_BITMASK_LTE_CA,
NETWORK_TYPE_BITMASK_NR,
- NETWORK_TYPE_BITMASK_IWLAN
+ NETWORK_TYPE_BITMASK_IWLAN,
+ NETWORK_TYPE_BITMASK_IDEN
})
public @interface NetworkTypeBitMask {}
@@ -13688,6 +14120,11 @@ public class TelephonyManager {
*/
public static final long NETWORK_TYPE_BITMASK_HSPA = (1 << (NETWORK_TYPE_HSPA -1));
/**
+ * network type bitmask indicating the support of radio tech iDen.
+ * @hide
+ */
+ public static final long NETWORK_TYPE_BITMASK_IDEN = (1 << (NETWORK_TYPE_IDEN - 1));
+ /**
* network type bitmask indicating the support of radio tech HSPAP.
*/
public static final long NETWORK_TYPE_BITMASK_HSPAP = (1 << (NETWORK_TYPE_HSPAP -1));
@@ -13705,12 +14142,13 @@ public class TelephonyManager {
*/
public static final long NETWORK_TYPE_BITMASK_LTE = (1 << (NETWORK_TYPE_LTE -1));
/**
- * NOT USED; this bitmask is exposed accidentally, will be deprecated in U.
+ * NOT USED; this bitmask is exposed accidentally.
* If used, will be converted to {@link #NETWORK_TYPE_BITMASK_LTE}.
* network type bitmask indicating the support of radio tech LTE CA (carrier aggregation).
*
- * @see #NETWORK_TYPE_BITMASK_LTE
+ * @deprecated Please use {@link #NETWORK_TYPE_BITMASK_LTE} instead. Deprecated in Android U.
*/
+ @Deprecated
public static final long NETWORK_TYPE_BITMASK_LTE_CA = (1 << (NETWORK_TYPE_LTE_CA -1));
/**
@@ -14088,8 +14526,11 @@ public class TelephonyManager {
* network; {@code false} if it is not; or throw an SecurityException if the caller does not
* have the required permission/privileges
* @throws IllegalStateException if the Telephony process is not currently available.
+ *
+ * @deprecated Please use {@link TelephonyManager#isEmergencyNumber(String)} instead.
* @hide
*/
+ @Deprecated
@SystemApi
@RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
@RequiresFeature(PackageManager.FEATURE_TELEPHONY_CALLING)
@@ -14484,7 +14925,10 @@ public class TelephonyManager {
/**
* The extra used with an {@link #ACTION_NETWORK_COUNTRY_CHANGED} to specify the
- * the country code in ISO-3166-1 alpha-2 format.
+ * the country code in ISO-3166-1 alpha-2 format. This is the same country code returned by
+ * {@link #getNetworkCountryIso()}. This might be an empty string when the country code is not
+ * available.
+ *
* <p class="note">
* Retrieve with {@link android.content.Intent#getStringExtra(String)}.
*/
@@ -14493,11 +14937,11 @@ public class TelephonyManager {
/**
* The extra used with an {@link #ACTION_NETWORK_COUNTRY_CHANGED} to specify the
- * last known the country code in ISO-3166-1 alpha-2 format.
+ * last known the country code in ISO-3166-1 alpha-2 format. This might be an empty string when
+ * the country code was never available. The last known country code persists across reboot.
+ *
* <p class="note">
* Retrieve with {@link android.content.Intent#getStringExtra(String)}.
- *
- * @hide
*/
public static final String EXTRA_LAST_KNOWN_NETWORK_COUNTRY =
"android.telephony.extra.LAST_KNOWN_NETWORK_COUNTRY";
@@ -14650,21 +15094,132 @@ public class TelephonyManager {
* @return a Pair of (major version, minor version) or (-1,-1) if unknown.
*
* @hide
+ *
+ * @deprecated Use {@link #getHalVersion} instead.
*/
+ @Deprecated
@UnsupportedAppUsage
@TestApi
public Pair<Integer, Integer> getRadioHalVersion() {
+ return getHalVersion(HAL_SERVICE_RADIO);
+ }
+
+ /** @hide */
+ public static final int HAL_SERVICE_RADIO = 0;
+
+ /**
+ * HAL service type that supports the HAL APIs implementation of IRadioData
+ * {@link RadioDataProxy}
+ * @hide
+ */
+ @TestApi
+ public static final int HAL_SERVICE_DATA = 1;
+
+ /**
+ * HAL service type that supports the HAL APIs implementation of IRadioMessaging
+ * {@link RadioMessagingProxy}
+ * @hide
+ */
+ @TestApi
+ public static final int HAL_SERVICE_MESSAGING = 2;
+
+ /**
+ * HAL service type that supports the HAL APIs implementation of IRadioModem
+ * {@link RadioModemProxy}
+ * @hide
+ */
+ @TestApi
+ public static final int HAL_SERVICE_MODEM = 3;
+
+ /**
+ * HAL service type that supports the HAL APIs implementation of IRadioNetwork
+ * {@link RadioNetworkProxy}
+ * @hide
+ */
+ @TestApi
+ public static final int HAL_SERVICE_NETWORK = 4;
+
+ /**
+ * HAL service type that supports the HAL APIs implementation of IRadioSim
+ * {@link RadioSimProxy}
+ * @hide
+ */
+ @TestApi
+ public static final int HAL_SERVICE_SIM = 5;
+
+ /**
+ * HAL service type that supports the HAL APIs implementation of IRadioVoice
+ * {@link RadioVoiceProxy}
+ * @hide
+ */
+ @TestApi
+ public static final int HAL_SERVICE_VOICE = 6;
+
+ /**
+ * HAL service type that supports the HAL APIs implementation of IRadioIms
+ * {@link RadioImsProxy}
+ * @hide
+ */
+ @TestApi
+ public static final int HAL_SERVICE_IMS = 7;
+
+ /** @hide */
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef(prefix = {"HAL_SERVICE_"},
+ value = {
+ HAL_SERVICE_RADIO,
+ HAL_SERVICE_DATA,
+ HAL_SERVICE_MESSAGING,
+ HAL_SERVICE_MODEM,
+ HAL_SERVICE_NETWORK,
+ HAL_SERVICE_SIM,
+ HAL_SERVICE_VOICE,
+ HAL_SERVICE_IMS,
+ })
+ public @interface HalService {}
+
+ /**
+ * The HAL Version indicating that the version is unknown or invalid.
+ * @hide
+ */
+ @TestApi
+ public static final Pair HAL_VERSION_UNKNOWN = new Pair(-1, -1);
+
+ /**
+ * The HAL Version indicating that the version is unsupported.
+ * @hide
+ */
+ @TestApi
+ public static final Pair HAL_VERSION_UNSUPPORTED = new Pair(-2, -2);
+
+ /**
+ * Retrieve the HAL Version of a specific service for this device.
+ *
+ * Get the HAL version for a specific HAL interface for test purposes.
+ *
+ * @param halService the service id to query.
+ * @return a Pair of (major version, minor version), HAL_VERSION_UNKNOWN if unknown
+ * or HAL_VERSION_UNSUPPORTED if unsupported.
+ *
+ * @hide
+ */
+ @TestApi
+ public @NonNull Pair<Integer, Integer> getHalVersion(@HalService int halService) {
try {
ITelephony service = getITelephony();
if (service != null) {
- int version = service.getRadioHalVersion();
- if (version == -1) return new Pair<Integer, Integer>(-1, -1);
- return new Pair<Integer, Integer>(version / 100, version % 100);
+ int version = service.getHalVersion(halService);
+ if (version != -1) {
+ return new Pair<Integer, Integer>(version / 100, version % 100);
+ }
+ } else {
+ throw new IllegalStateException("telephony service is null.");
}
} catch (RemoteException e) {
- Log.e(TAG, "getRadioHalVersion() RemoteException", e);
+ Log.e(TAG, "getHalVersion() RemoteException", e);
+ e.rethrowAsRuntimeException();
}
- return new Pair<Integer, Integer>(-1, -1);
+ return HAL_VERSION_UNKNOWN;
}
/**
@@ -15354,6 +15909,7 @@ public class TelephonyManager {
* This policy can be enabled and disabled via {@link #setMobileDataPolicyEnabled}.
* @hide
*/
+ @SystemApi
public static final int MOBILE_DATA_POLICY_AUTO_DATA_SWITCH = 3;
/**
@@ -15875,9 +16431,33 @@ public class TelephonyManager {
}
/**
- * Whether device can connect to 5G network when two SIMs are active.
+ * Setup sIPhoneSubInfo for testing.
+ *
+ * @hide
+ */
+ @VisibleForTesting
+ public static void setupIPhoneSubInfoForTest(IPhoneSubInfo iPhoneSubInfo) {
+ synchronized (sCacheLock) {
+ sIPhoneSubInfo = iPhoneSubInfo;
+ }
+ }
+
+ /**
+ * Setup sISub for testing.
+ *
* @hide
- * TODO b/153669716: remove or make system API.
+ */
+ @VisibleForTesting
+ public static void setupISubForTest(ISub iSub) {
+ synchronized (sCacheLock) {
+ sISub = iSub;
+ }
+ }
+
+ /**
+ * Whether device can connect to 5G network when two SIMs are active.
+ *
+ * @hide TODO b/153669716: remove or make system API.
*/
public boolean canConnectTo5GInDsdsMode() {
ITelephony telephony = getITelephony();
@@ -16192,7 +16772,8 @@ public class TelephonyManager {
* may encounter an {@link IllegalStateException} when trying to register more callbacks.
*
* @param executor The executor of where the callback will execute.
- * @param callback The {@link TelephonyCallback} object to register.
+ * @param callback The {@link TelephonyCallback} object to register. The caller should hold a
+ * reference to the callback. The framework only holds a weak reference.
*/
public void registerTelephonyCallback(@NonNull @CallbackExecutor Executor executor,
@NonNull TelephonyCallback callback) {
@@ -16287,7 +16868,8 @@ public class TelephonyManager {
* @param includeLocationData Specifies if the caller would like to receive
* location related information.
* @param executor The executor of where the callback will execute.
- * @param callback The {@link TelephonyCallback} object to register.
+ * @param callback The {@link TelephonyCallback} object to register. The caller should hold a
+ * reference to the callback. The framework only holds a weak reference.
*/
public void registerTelephonyCallback(@IncludeLocationData int includeLocationData,
@NonNull @CallbackExecutor Executor executor,
@@ -16824,7 +17406,7 @@ public class TelephonyManager {
}
NetworkSlicingConfig slicingConfig =
- result.getParcelable(KEY_SLICING_CONFIG_HANDLE);
+ result.getParcelable(KEY_SLICING_CONFIG_HANDLE, android.telephony.data.NetworkSlicingConfig.class);
executor.execute(() -> callback.onResult(slicingConfig));
}
});
@@ -16834,6 +17416,307 @@ public class TelephonyManager {
}
/**
+ * A premium capability that boosts the network to allow for real-time interactive traffic
+ * by prioritizing low latency communication.
+ * Corresponds to {@link NetworkCapabilities#NET_CAPABILITY_PRIORITIZE_LATENCY}.
+ */
+ public static final int PREMIUM_CAPABILITY_PRIORITIZE_LATENCY =
+ NetworkCapabilities.NET_CAPABILITY_PRIORITIZE_LATENCY;
+
+ /**
+ * Purchasable premium capabilities.
+ * @hide
+ */
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef(prefix = { "PREMIUM_CAPABILITY_" }, value = {
+ PREMIUM_CAPABILITY_PRIORITIZE_LATENCY})
+ public @interface PremiumCapability {}
+
+ /**
+ * Returns the premium capability {@link PremiumCapability} as a String.
+ *
+ * @param capability The premium capability.
+ * @return The premium capability as a String.
+ * @hide
+ */
+ public static String convertPremiumCapabilityToString(@PremiumCapability int capability) {
+ switch (capability) {
+ case PREMIUM_CAPABILITY_PRIORITIZE_LATENCY:
+ return "PRIORITIZE_LATENCY";
+ default:
+ return "UNKNOWN (" + capability + ")";
+ }
+ }
+
+ /**
+ * Check whether the given premium capability is available for purchase from the carrier.
+ * If this is {@code true}, the capability can be purchased from the carrier using
+ * {@link #purchasePremiumCapability(int, Executor, Consumer)}.
+ *
+ * @param capability The premium capability to check.
+ * @return Whether the given premium capability is available to purchase.
+ * @throws SecurityException if the caller does not hold permission READ_BASIC_PHONE_STATE.
+ */
+ @RequiresPermission(android.Manifest.permission.READ_BASIC_PHONE_STATE)
+ public boolean isPremiumCapabilityAvailableForPurchase(@PremiumCapability int capability) {
+ try {
+ ITelephony telephony = getITelephony();
+ if (telephony == null) {
+ throw new IllegalStateException("telephony service is null.");
+ }
+ return telephony.isPremiumCapabilityAvailableForPurchase(capability, getSubId());
+ } catch (RemoteException ex) {
+ ex.rethrowAsRuntimeException();
+ }
+ return false;
+ }
+
+ /**
+ * Purchase premium capability request was successful.
+ * Once the purchase result is successful, the network must set up a slicing configuration
+ * for the purchased premium capability within the timeout specified by
+ * {@link CarrierConfigManager#KEY_PREMIUM_CAPABILITY_NETWORK_SETUP_TIME_MILLIS_LONG}.
+ * During the setup time, subsequent attempts will return
+ * {@link #PURCHASE_PREMIUM_CAPABILITY_RESULT_PENDING_NETWORK_SETUP}.
+ * After setup is complete, subsequent attempts will return
+ * {@link #PURCHASE_PREMIUM_CAPABILITY_RESULT_ALREADY_PURCHASED} until the boost expires.
+ * The expiry time is determined by the type or duration of boost purchased from the carrier,
+ * provided at {@link CarrierConfigManager#KEY_PREMIUM_CAPABILITY_PURCHASE_URL_STRING}.
+ */
+ public static final int PURCHASE_PREMIUM_CAPABILITY_RESULT_SUCCESS = 1;
+
+ /**
+ * Purchase premium capability failed because the request is throttled.
+ * If purchasing premium capabilities is throttled, it will be for the amount of time
+ * specified by {@link CarrierConfigManager
+ * #KEY_PREMIUM_CAPABILITY_PURCHASE_CONDITION_BACKOFF_HYSTERESIS_TIME_MILLIS_LONG}.
+ * If displaying the performance boost notification is throttled, it will be for the amount of
+ * time specified by {@link CarrierConfigManager
+ * #KEY_PREMIUM_CAPABILITY_NOTIFICATION_BACKOFF_HYSTERESIS_TIME_MILLIS_LONG}.
+ * We will show the performance boost notification to the user up to the daily and monthly
+ * maximum number of times specified by
+ * {@link CarrierConfigManager#KEY_PREMIUM_CAPABILITY_MAXIMUM_DAILY_NOTIFICATION_COUNT_INT} and
+ * {@link CarrierConfigManager#KEY_PREMIUM_CAPABILITY_MAXIMUM_MONTHLY_NOTIFICATION_COUNT_INT}.
+ * Subsequent attempts will return the same error until the request is no longer throttled
+ * or throttling conditions change.
+ */
+ public static final int PURCHASE_PREMIUM_CAPABILITY_RESULT_THROTTLED = 2;
+
+ /**
+ * Purchase premium capability failed because it is already purchased and available.
+ * Subsequent attempts will return the same error until the performance boost expires.
+ */
+ public static final int PURCHASE_PREMIUM_CAPABILITY_RESULT_ALREADY_PURCHASED = 3;
+
+ /**
+ * Purchase premium capability failed because a request was already made and is in progress.
+ * This may have been requested by either the same app or another app.
+ * Subsequent attempts will return the same error until the previous request completes.
+ */
+ public static final int PURCHASE_PREMIUM_CAPABILITY_RESULT_ALREADY_IN_PROGRESS = 4;
+
+ /**
+ * Purchase premium capability failed because the requesting application is not in the
+ * foreground. Subsequent attempts will return the same error until the requesting application
+ * moves to the foreground.
+ */
+ public static final int PURCHASE_PREMIUM_CAPABILITY_RESULT_NOT_FOREGROUND = 5;
+
+ /**
+ * Purchase premium capability failed because the user canceled the operation.
+ * Subsequent attempts will be throttled for the amount of time specified by
+ * {@link CarrierConfigManager
+ * #KEY_PREMIUM_CAPABILITY_NOTIFICATION_BACKOFF_HYSTERESIS_TIME_MILLIS_LONG}
+ * and return {@link #PURCHASE_PREMIUM_CAPABILITY_RESULT_THROTTLED}.
+ */
+ public static final int PURCHASE_PREMIUM_CAPABILITY_RESULT_USER_CANCELED = 6;
+
+ /**
+ * Purchase premium capability failed because the carrier disabled or does not support
+ * the capability, as specified in
+ * {@link CarrierConfigManager#KEY_SUPPORTED_PREMIUM_CAPABILITIES_INT_ARRAY}.
+ * Subsequent attempts will return the same error until the carrier enables the feature.
+ */
+ public static final int PURCHASE_PREMIUM_CAPABILITY_RESULT_CARRIER_DISABLED = 7;
+
+ /**
+ * Purchase premium capability failed because the carrier app did not indicate success.
+ * Subsequent attempts will be throttled for the amount of time specified by
+ * {@link CarrierConfigManager
+ * #KEY_PREMIUM_CAPABILITY_PURCHASE_CONDITION_BACKOFF_HYSTERESIS_TIME_MILLIS_LONG}
+ * and return {@link #PURCHASE_PREMIUM_CAPABILITY_RESULT_THROTTLED}.
+ */
+ public static final int PURCHASE_PREMIUM_CAPABILITY_RESULT_CARRIER_ERROR = 8;
+
+ /**
+ * Purchase premium capability failed because we did not receive a response from the user
+ * for the performance boost notification within the time specified by
+ * {@link CarrierConfigManager#KEY_PREMIUM_CAPABILITY_NOTIFICATION_DISPLAY_TIMEOUT_MILLIS_LONG}.
+ * The performance boost notification will be automatically dismissed and subsequent attempts
+ * will be throttled for the amount of time specified by
+ * {@link CarrierConfigManager
+ * #KEY_PREMIUM_CAPABILITY_NOTIFICATION_BACKOFF_HYSTERESIS_TIME_MILLIS_LONG}
+ * and return {@link #PURCHASE_PREMIUM_CAPABILITY_RESULT_THROTTLED}.
+ */
+ public static final int PURCHASE_PREMIUM_CAPABILITY_RESULT_TIMEOUT = 9;
+
+ /**
+ * Purchase premium capability failed because the device does not support the feature.
+ * Subsequent attempts will return the same error.
+ */
+ public static final int PURCHASE_PREMIUM_CAPABILITY_RESULT_FEATURE_NOT_SUPPORTED = 10;
+
+ /**
+ * Purchase premium capability failed because the telephony service is unavailable
+ * or there was an error in the phone process.
+ * Subsequent attempts will return the same error until request conditions are satisfied.
+ */
+ public static final int PURCHASE_PREMIUM_CAPABILITY_RESULT_REQUEST_FAILED = 11;
+
+ /**
+ * Purchase premium capability failed because the network is not available.
+ * Subsequent attempts will return the same error until network conditions change.
+ */
+ public static final int PURCHASE_PREMIUM_CAPABILITY_RESULT_NETWORK_NOT_AVAILABLE = 12;
+
+ /**
+ * Purchase premium capability failed because the entitlement check failed.
+ * Subsequent attempts will be throttled for the amount of time specified by
+ * {@link CarrierConfigManager
+ * #KEY_PREMIUM_CAPABILITY_PURCHASE_CONDITION_BACKOFF_HYSTERESIS_TIME_MILLIS_LONG}
+ * and return {@link #PURCHASE_PREMIUM_CAPABILITY_RESULT_THROTTLED}.
+ * Throttling will be reevaluated when the network is no longer congested.
+ */
+ public static final int PURCHASE_PREMIUM_CAPABILITY_RESULT_ENTITLEMENT_CHECK_FAILED = 13;
+
+ /**
+ * Purchase premium capability failed because the request was not made on the default data
+ * subscription, indicated by {@link SubscriptionManager#getDefaultDataSubscriptionId()}.
+ * Subsequent attempts will return the same error until the request is made on the default
+ * data subscription.
+ */
+ public static final int PURCHASE_PREMIUM_CAPABILITY_RESULT_NOT_DEFAULT_DATA_SUBSCRIPTION = 14;
+
+ /**
+ * Purchase premium capability was successful and is waiting for the network to setup the
+ * slicing configuration. If the setup is complete within the time specified by
+ * {@link CarrierConfigManager#KEY_PREMIUM_CAPABILITY_NETWORK_SETUP_TIME_MILLIS_LONG},
+ * subsequent requests will return {@link #PURCHASE_PREMIUM_CAPABILITY_RESULT_ALREADY_PURCHASED}
+ * until the purchase expires. If the setup is not complete within the time specified above,
+ * applications can request the premium capability again.
+ */
+ public static final int PURCHASE_PREMIUM_CAPABILITY_RESULT_PENDING_NETWORK_SETUP = 15;
+
+ /**
+ * Results of the purchase premium capability request.
+ * @hide
+ */
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef(prefix = { "PURCHASE_PREMIUM_CAPABILITY_RESULT_" }, value = {
+ PURCHASE_PREMIUM_CAPABILITY_RESULT_SUCCESS,
+ PURCHASE_PREMIUM_CAPABILITY_RESULT_THROTTLED,
+ PURCHASE_PREMIUM_CAPABILITY_RESULT_ALREADY_PURCHASED,
+ PURCHASE_PREMIUM_CAPABILITY_RESULT_ALREADY_IN_PROGRESS,
+ PURCHASE_PREMIUM_CAPABILITY_RESULT_NOT_FOREGROUND,
+ PURCHASE_PREMIUM_CAPABILITY_RESULT_USER_CANCELED,
+ PURCHASE_PREMIUM_CAPABILITY_RESULT_CARRIER_DISABLED,
+ PURCHASE_PREMIUM_CAPABILITY_RESULT_CARRIER_ERROR,
+ PURCHASE_PREMIUM_CAPABILITY_RESULT_TIMEOUT,
+ PURCHASE_PREMIUM_CAPABILITY_RESULT_FEATURE_NOT_SUPPORTED,
+ PURCHASE_PREMIUM_CAPABILITY_RESULT_NETWORK_NOT_AVAILABLE,
+ PURCHASE_PREMIUM_CAPABILITY_RESULT_ENTITLEMENT_CHECK_FAILED,
+ PURCHASE_PREMIUM_CAPABILITY_RESULT_NOT_DEFAULT_DATA_SUBSCRIPTION,
+ PURCHASE_PREMIUM_CAPABILITY_RESULT_PENDING_NETWORK_SETUP})
+ public @interface PurchasePremiumCapabilityResult {}
+
+ /**
+ * Returns the purchase result {@link PurchasePremiumCapabilityResult} as a String.
+ *
+ * @param result The purchase premium capability result.
+ * @return The purchase result as a String.
+ * @hide
+ */
+ public static String convertPurchaseResultToString(
+ @PurchasePremiumCapabilityResult int result) {
+ switch (result) {
+ case PURCHASE_PREMIUM_CAPABILITY_RESULT_SUCCESS:
+ return "SUCCESS";
+ case PURCHASE_PREMIUM_CAPABILITY_RESULT_THROTTLED:
+ return "THROTTLED";
+ case PURCHASE_PREMIUM_CAPABILITY_RESULT_ALREADY_PURCHASED:
+ return "ALREADY_PURCHASED";
+ case PURCHASE_PREMIUM_CAPABILITY_RESULT_ALREADY_IN_PROGRESS:
+ return "ALREADY_IN_PROGRESS";
+ case PURCHASE_PREMIUM_CAPABILITY_RESULT_NOT_FOREGROUND:
+ return "NOT_FOREGROUND";
+ case PURCHASE_PREMIUM_CAPABILITY_RESULT_USER_CANCELED:
+ return "USER_CANCELED";
+ case PURCHASE_PREMIUM_CAPABILITY_RESULT_CARRIER_DISABLED:
+ return "CARRIER_DISABLED";
+ case PURCHASE_PREMIUM_CAPABILITY_RESULT_CARRIER_ERROR:
+ return "CARRIER_ERROR";
+ case PURCHASE_PREMIUM_CAPABILITY_RESULT_TIMEOUT:
+ return "TIMEOUT";
+ case PURCHASE_PREMIUM_CAPABILITY_RESULT_FEATURE_NOT_SUPPORTED:
+ return "FEATURE_NOT_SUPPORTED";
+ case PURCHASE_PREMIUM_CAPABILITY_RESULT_REQUEST_FAILED:
+ return "REQUEST_FAILED";
+ case PURCHASE_PREMIUM_CAPABILITY_RESULT_NETWORK_NOT_AVAILABLE:
+ return "NETWORK_NOT_AVAILABLE";
+ case PURCHASE_PREMIUM_CAPABILITY_RESULT_ENTITLEMENT_CHECK_FAILED:
+ return "ENTITLEMENT_CHECK_FAILED";
+ case PURCHASE_PREMIUM_CAPABILITY_RESULT_NOT_DEFAULT_DATA_SUBSCRIPTION:
+ return "NOT_DEFAULT_DATA_SUBSCRIPTION";
+ case PURCHASE_PREMIUM_CAPABILITY_RESULT_PENDING_NETWORK_SETUP:
+ return "PENDING_NETWORK_SETUP";
+ default:
+ return "UNKNOWN (" + result + ")";
+ }
+ }
+
+ /**
+ * Purchase the given premium capability from the carrier.
+ * This requires user action to purchase the boost from the carrier.
+ * If this returns {@link #PURCHASE_PREMIUM_CAPABILITY_RESULT_SUCCESS} or
+ * {@link #PURCHASE_PREMIUM_CAPABILITY_RESULT_ALREADY_PURCHASED}, applications can request
+ * the premium capability via {@link ConnectivityManager#requestNetwork}.
+ *
+ * @param capability The premium capability to purchase.
+ * @param executor The callback executor for the response.
+ * @param callback The result of the purchase request.
+ * One of {@link PurchasePremiumCapabilityResult}.
+ * @throws SecurityException if the caller does not hold permissions
+ * READ_BASIC_PHONE_STATE or INTERNET.
+ * @see #isPremiumCapabilityAvailableForPurchase(int) to check whether the capability is valid.
+ */
+ @RequiresPermission(allOf = {android.Manifest.permission.READ_BASIC_PHONE_STATE,
+ android.Manifest.permission.INTERNET})
+ public void purchasePremiumCapability(@PremiumCapability int capability,
+ @NonNull @CallbackExecutor Executor executor,
+ @NonNull @PurchasePremiumCapabilityResult Consumer<Integer> callback) {
+ Objects.requireNonNull(executor);
+ Objects.requireNonNull(callback);
+
+ IIntegerConsumer internalCallback = new IIntegerConsumer.Stub() {
+ @Override
+ public void accept(int result) {
+ executor.execute(() -> callback.accept(result));
+ }
+ };
+
+ try {
+ ITelephony telephony = getITelephony();
+ if (telephony == null) {
+ callback.accept(PURCHASE_PREMIUM_CAPABILITY_RESULT_REQUEST_FAILED);
+ return;
+ }
+ telephony.purchasePremiumCapability(capability, internalCallback, getSubId());
+ } catch (RemoteException ex) {
+ callback.accept(PURCHASE_PREMIUM_CAPABILITY_RESULT_REQUEST_FAILED);
+ }
+ }
+
+ /**
* Get last known cell identity.
* Require {@link android.Manifest.permission#ACCESS_FINE_LOCATION} and
* com.android.phone.permission.ACCESS_LAST_KNOWN_CELL_ID, otherwise throws SecurityException.
@@ -17054,6 +17937,411 @@ public class TelephonyManager {
}
/**
+ * Captures parameters for collection of emergency
+ * call diagnostic data
+ * @hide
+ */
+ public static class EmergencyCallDiagnosticParams {
+
+ private boolean mCollectTelecomDumpSys;
+ private boolean mCollectTelephonyDumpsys;
+ private boolean mCollectLogcat;
+
+ //logcat lines with this time or greater are collected
+ //how much is collected is dependent on internal implementation.
+ //Time represented as milliseconds since January 1, 1970 UTC
+ private long mLogcatStartTimeMillis;
+
+
+ public boolean isTelecomDumpSysCollectionEnabled() {
+ return mCollectTelecomDumpSys;
+ }
+
+ public void setTelecomDumpSysCollection(boolean collectTelecomDumpSys) {
+ mCollectTelecomDumpSys = collectTelecomDumpSys;
+ }
+
+ public boolean isTelephonyDumpSysCollectionEnabled() {
+ return mCollectTelephonyDumpsys;
+ }
+
+ public void setTelephonyDumpSysCollection(boolean collectTelephonyDumpsys) {
+ mCollectTelephonyDumpsys = collectTelephonyDumpsys;
+ }
+
+ public boolean isLogcatCollectionEnabled() {
+ return mCollectLogcat;
+ }
+
+ public long getLogcatStartTime()
+ {
+ return mLogcatStartTimeMillis;
+ }
+
+ public void setLogcatCollection(boolean collectLogcat, long startTimeMillis) {
+ mCollectLogcat = collectLogcat;
+ if(mCollectLogcat)
+ {
+ mLogcatStartTimeMillis = startTimeMillis;
+ }
+ }
+
+ @Override
+ public String toString() {
+ return "EmergencyCallDiagnosticParams{" +
+ "mCollectTelecomDumpSys=" + mCollectTelecomDumpSys +
+ ", mCollectTelephonyDumpsys=" + mCollectTelephonyDumpsys +
+ ", mCollectLogcat=" + mCollectLogcat +
+ ", mLogcatStartTimeMillis=" + mLogcatStartTimeMillis +
+ '}';
+ }
+ }
+
+ /**
+ * Request telephony to persist state for debugging emergency call failures.
+ *
+ * @param dropboxTag Tag to use when persisting data to dropbox service.
+ *
+ * @see params Parameters controlling what is collected
+ *
+ * @hide
+ */
+ @RequiresPermission(android.Manifest.permission.DUMP)
+ public void persistEmergencyCallDiagnosticData(@NonNull String dropboxTag,
+ @NonNull EmergencyCallDiagnosticParams params) {
+ try {
+ ITelephony telephony = ITelephony.Stub.asInterface(
+ TelephonyFrameworkInitializer
+ .getTelephonyServiceManager()
+ .getTelephonyServiceRegisterer()
+ .get());
+ if (telephony != null) {
+ telephony.persistEmergencyCallDiagnosticData(dropboxTag,
+ params.isLogcatCollectionEnabled(),
+ params.getLogcatStartTime(),
+ params.isTelecomDumpSysCollectionEnabled(),
+ params.isTelephonyDumpSysCollectionEnabled());
+ }
+ } catch (RemoteException e) {
+ Log.e(TAG, "Error while persistEmergencyCallDiagnosticData: " + e);
+ }
+ }
+
+ /**
+ * Set the UE's ability to accept/reject null ciphered and null integrity-protected connections.
+ *
+ * The modem is required to ignore this in case of an emergency call.
+ *
+ * <p>Requires permission: android.Manifest.MODIFY_PHONE_STATE</p>
+ *
+ * @param enabled if null ciphered and null integrity protected connections are permitted
+ * @throws IllegalStateException if the Telephony process is not currently available
+ * @throws SecurityException if the caller does not have the required privileges
+ * @throws UnsupportedOperationException if the modem does not support disabling null ciphers.
+ * @hide
+ */
+ @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
+ public void setNullCipherAndIntegrityEnabled(boolean enabled) {
+ try {
+ ITelephony telephony = getITelephony();
+ if (telephony != null) {
+ telephony.setNullCipherAndIntegrityEnabled(enabled);
+ } else {
+ throw new IllegalStateException("telephony service is null.");
+ }
+ } catch (RemoteException ex) {
+ Rlog.e(TAG, "setNullCipherAndIntegrityEnabled RemoteException", ex);
+ ex.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * Get the value of the global preference for null cipher and integriy enablement.
+ * Note: This does not return the state of the modem, only the persisted global preference.
+ *
+ * <p>Requires permission: android.Manifest.READ_PHONE_STATE</p>
+ *
+ * @throws IllegalStateException if the Telephony process is not currently available
+ * @throws SecurityException if the caller does not have the required privileges
+ * @throws UnsupportedOperationException if the modem does not support disabling null ciphers.
+ * @hide
+ */
+ @RequiresPermission(Manifest.permission.READ_PHONE_STATE)
+ public boolean isNullCipherAndIntegrityPreferenceEnabled() {
+ try {
+ ITelephony telephony = getITelephony();
+ if (telephony != null) {
+ return telephony.isNullCipherAndIntegrityPreferenceEnabled();
+ } else {
+ throw new IllegalStateException("telephony service is null.");
+ }
+ } catch (RemoteException ex) {
+ Rlog.e(TAG, "isNullCipherAndIntegrityPreferenceEnabled RemoteException", ex);
+ ex.rethrowFromSystemServer();
+ }
+ return true;
+ }
+
+ /**
+ * Get current cell broadcast message identifier ranges.
+ *
+ * @throws SecurityException if the caller does not have the required permission
+ * @hide
+ */
+ @SystemApi
+ @RequiresPermission(android.Manifest.permission.MODIFY_CELL_BROADCASTS)
+ @NonNull
+ public List<CellBroadcastIdRange> getCellBroadcastIdRanges() {
+ try {
+ ITelephony telephony = getITelephony();
+ if (telephony != null) {
+ return telephony.getCellBroadcastIdRanges(getSubId());
+ } else {
+ throw new IllegalStateException("telephony service is null.");
+ }
+ } catch (RemoteException ex) {
+ ex.rethrowFromSystemServer();
+ }
+ return new ArrayList<>();
+ }
+
+ /** @hide */
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef(prefix = {"CELL_BROADCAST_RESULT_"}, value = {
+ CELL_BROADCAST_RESULT_UNKNOWN,
+ CELL_BROADCAST_RESULT_SUCCESS,
+ CELL_BROADCAST_RESULT_UNSUPPORTED,
+ CELL_BROADCAST_RESULT_FAIL_CONFIG,
+ CELL_BROADCAST_RESULT_FAIL_ACTIVATION})
+ public @interface CellBroadcastResult {}
+
+ /**
+ * The result of the cell broadcast request is unknown
+ * @hide
+ */
+ @SystemApi
+ public static final int CELL_BROADCAST_RESULT_UNKNOWN = -1;
+
+ /**
+ * The cell broadcast request is successful.
+ * @hide
+ */
+ @SystemApi
+ public static final int CELL_BROADCAST_RESULT_SUCCESS = 0;
+
+ /**
+ * The cell broadcast request is not supported.
+ * @hide
+ */
+ @SystemApi
+ public static final int CELL_BROADCAST_RESULT_UNSUPPORTED = 1;
+
+ /**
+ * The cell broadcast request is failed due to the error to set config
+ * @hide
+ */
+ @SystemApi
+ public static final int CELL_BROADCAST_RESULT_FAIL_CONFIG = 2;
+
+ /**
+ * The cell broadcast request is failed due to the error to set activation
+ * @hide
+ */
+ @SystemApi
+ public static final int CELL_BROADCAST_RESULT_FAIL_ACTIVATION = 3;
+
+ /**
+ * Callback mode type
+ * @hide
+ */
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef(prefix = {"EMERGENCY_CALLBACK_MODE_"}, value = {
+ EMERGENCY_CALLBACK_MODE_CALL,
+ EMERGENCY_CALLBACK_MODE_SMS})
+ public @interface EmergencyCallbackModeType {}
+
+ /**
+ * The callback mode is due to emergency call.
+ * @hide
+ */
+ public static final int EMERGENCY_CALLBACK_MODE_CALL = 1;
+
+ /**
+ * The callback mode is due to emergency SMS.
+ * @hide
+ */
+ public static final int EMERGENCY_CALLBACK_MODE_SMS = 2;
+
+ /**
+ * The reason for changing callback mode.
+ * @hide
+ */
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef(prefix = {"STOP_REASON_"},
+ value = {
+ STOP_REASON_UNKNOWN,
+ STOP_REASON_OUTGOING_NORMAL_CALL_INITIATED,
+ STOP_REASON_NORMAL_SMS_SENT,
+ STOP_REASON_OUTGOING_EMERGENCY_CALL_INITIATED,
+ STOP_REASON_EMERGENCY_SMS_SENT,
+ STOP_REASON_TIMER_EXPIRED,
+ STOP_REASON_USER_ACTION,
+ })
+ public @interface EmergencyCallbackModeStopReason {}
+
+ /**
+ * unknown reason.
+ * @hide
+ */
+ public static final int STOP_REASON_UNKNOWN = 0;
+
+ /**
+ * The call back mode is exited due to a new normal call is originated.
+ * @hide
+ */
+ public static final int STOP_REASON_OUTGOING_NORMAL_CALL_INITIATED = 1;
+
+ /**
+ * The call back mode is exited due to a new normal SMS is originated.
+ * @hide
+ */
+ public static final int STOP_REASON_NORMAL_SMS_SENT = 2;
+
+ /**
+ * The call back mode is exited due to a new emergency call is originated.
+ * @hide
+ */
+ public static final int STOP_REASON_OUTGOING_EMERGENCY_CALL_INITIATED = 3;
+
+ /**
+ * The call back mode is exited due to a new emergency SMS is originated.
+ * @hide
+ */
+ public static final int STOP_REASON_EMERGENCY_SMS_SENT = 4;
+
+ /**
+ * The call back mode is exited due to timer expiry.
+ * @hide
+ */
+ public static final int STOP_REASON_TIMER_EXPIRED = 5;
+
+ /**
+ * The call back mode is exited due to user action.
+ * @hide
+ */
+ public static final int STOP_REASON_USER_ACTION = 6;
+
+ /**
+ * Set reception of cell broadcast messages with the list of the given ranges
+ *
+ * <p>The ranges set previously will be overridden by the new one. Empty list
+ * can be used to clear the ranges.
+ *
+ * @param ranges the list of {@link CellBroadcastIdRange} to be set.
+ * @param executor The {@link Executor} that will be used to call the callback.
+ * @param callback A callback called on the supplied {@link Executor} to notify
+ * the result when the operation completes.
+ * @throws SecurityException if the caller does not have the required permission
+ * @throws IllegalArgumentException when the ranges are invalid.
+ * @hide
+ */
+ @SystemApi
+ @RequiresPermission(android.Manifest.permission.MODIFY_CELL_BROADCASTS)
+ public void setCellBroadcastIdRanges(@NonNull List<CellBroadcastIdRange> ranges,
+ @NonNull @CallbackExecutor Executor executor,
+ @NonNull Consumer<Integer> callback) {
+ IIntegerConsumer consumer = callback == null ? null : new IIntegerConsumer.Stub() {
+ @Override
+ public void accept(int result) {
+ final long identity = Binder.clearCallingIdentity();
+ try {
+ executor.execute(() -> callback.accept(result));
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
+ }
+ };
+
+ try {
+ ITelephony telephony = getITelephony();
+ if (telephony != null) {
+ telephony.setCellBroadcastIdRanges(getSubId(), ranges, consumer);
+ } else {
+ throw new IllegalStateException("telephony service is null.");
+ }
+ } catch (RemoteException ex) {
+ ex.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * Returns whether the domain selection service is supported.
+ *
+ * <p>Requires Permission:
+ * {@link android.Manifest.permission#READ_PRIVILEGED_PHONE_STATE READ_PRIVILEGED_PHONE_STATE}.
+ *
+ * @return {@code true} if the domain selection service is supported.
+ * @hide
+ */
+ @TestApi
+ @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
+ @RequiresFeature(PackageManager.FEATURE_TELEPHONY_CALLING)
+ public boolean isDomainSelectionSupported() {
+ try {
+ ITelephony telephony = getITelephony();
+ if (telephony != null) {
+ return telephony.isDomainSelectionSupported();
+ }
+ } catch (RemoteException ex) {
+ Rlog.w(TAG, "RemoteException", ex);
+ }
+ return false;
+ }
+
+ /**
+ * Returns the primary IMEI (International Mobile Equipment Identity) of the device as
+ * mentioned in GSMA TS.37. {@link #getImei(int)} returns the IMEI that belongs to the selected
+ * slotID whereas this API {@link #getPrimaryImei()} returns primary IMEI of the device.
+ * A single SIM device with only one IMEI will be set by default as primary IMEI.
+ * A multi-SIM device with multiple IMEIs will have one of the IMEIs set as primary as
+ * mentioned in GSMA TS37_2.2_REQ_8.
+ *
+ * <p>Requires one of the following permissions
+ * <ul>
+ * <li>If the calling app has been granted the READ_PRIVILEGED_PHONE_STATE permission; this
+ * is a privileged permission that can only be granted to apps preloaded on the device.
+ * <li>If the calling app is the device owner of a fully-managed device, a profile
+ * owner of an organization-owned device, or their delegates (see {@link
+ * android.app.admin.DevicePolicyManager#getEnrollmentSpecificId()}).
+ * <li>If the calling app has carrier privileges (see {@link #hasCarrierPrivileges}) on any
+ * active subscription.
+ * <li>If the calling app is the default SMS role holder (see {@link
+ * RoleManager#isRoleHeld(String)}).
+ * <li>If the calling app has been granted the
+ * {@link Manifest.permission#USE_ICC_AUTH_WITH_DEVICE_IDENTIFIER} permission.
+ * </ul>
+ *
+ * @return Primary IMEI of type string
+ * @throws UnsupportedOperationException if the radio doesn't support this feature.
+ * @throws SecurityException if the caller does not have the required permission/privileges
+ */
+ @NonNull
+ @RequiresFeature(PackageManager.FEATURE_TELEPHONY_GSM)
+ public String getPrimaryImei() {
+ try {
+ ITelephony telephony = getITelephony();
+ if (telephony == null) {
+ Rlog.e(TAG, "getPrimaryImei(): IPhoneSubInfo instance is NULL");
+ throw new IllegalStateException("Telephony service not available.");
+ }
+ return telephony.getPrimaryImei(getOpPackageName(), getAttributionTag());
+ } catch (RemoteException ex) {
+ Rlog.e(TAG, "getPrimaryImei() RemoteException : " + ex);
+ throw ex.rethrowAsRuntimeException();
+ }
+ }
+
+ /**
* Convert SIM state into string.
*
* @param state SIM state.
diff --git a/telephony/java/android/telephony/TransportSelectorCallback.java b/telephony/java/android/telephony/TransportSelectorCallback.java
new file mode 100644
index 000000000000..04752e418466
--- /dev/null
+++ b/telephony/java/android/telephony/TransportSelectorCallback.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.telephony;
+
+import android.annotation.NonNull;
+import android.telephony.Annotation.DisconnectCauses;
+
+import java.util.function.Consumer;
+
+/**
+ * A callback class used to receive the transport selection result.
+ * @hide
+ */
+public interface TransportSelectorCallback {
+ /**
+ * Notify that {@link DomainSelector} instance has been created for the selection request.
+ *
+ * @param selector the {@link DomainSelector} instance created.
+ */
+ void onCreated(@NonNull DomainSelector selector);
+
+ /**
+ * Notify that WLAN transport has been selected.
+ *
+ * @param useEmergencyPdn Indicates whether Wi-Fi emergency services use emergency PDN or not.
+ */
+ void onWlanSelected(boolean useEmergencyPdn);
+
+ /**
+ * Notify that WWAN transport has been selected.
+ */
+ @NonNull WwanSelectorCallback onWwanSelected();
+
+ /**
+ * Notify that WWAN transport has been selected.
+ *
+ * @param consumer The callback to receive the result.
+ */
+ void onWwanSelected(Consumer<WwanSelectorCallback> consumer);
+
+ /**
+ * Notify that selection has terminated because there is no decision that can be made
+ * or a timeout has occurred. The call should be terminated when this method is called.
+ *
+ * @param cause indicates the reason.
+ */
+ void onSelectionTerminated(@DisconnectCauses int cause);
+}
diff --git a/telephony/java/android/telephony/UiccCardInfo.java b/telephony/java/android/telephony/UiccCardInfo.java
index e5e8f0a41048..6c069d4ee843 100644
--- a/telephony/java/android/telephony/UiccCardInfo.java
+++ b/telephony/java/android/telephony/UiccCardInfo.java
@@ -166,7 +166,7 @@ public final class UiccCardInfo implements Parcelable {
+ " Please Use UiccPortInfo API instead");
}
//always return ICCID from first port.
- return getPorts().stream().findFirst().get().getIccId();
+ return mPortList.isEmpty() ? null : mPortList.get(0).getIccId();
}
/**
diff --git a/telephony/java/android/telephony/UiccPortInfo.java b/telephony/java/android/telephony/UiccPortInfo.java
index 6fb0470d6225..41e743c43272 100644
--- a/telephony/java/android/telephony/UiccPortInfo.java
+++ b/telephony/java/android/telephony/UiccPortInfo.java
@@ -165,7 +165,7 @@ public final class UiccPortInfo implements Parcelable{
return "UiccPortInfo (isActive="
+ mIsActive
+ ", iccId="
- + SubscriptionInfo.givePrintableIccid(mIccId)
+ + SubscriptionInfo.getPrintableId(mIccId)
+ ", portIndex="
+ mPortIndex
+ ", mLogicalSlotIndex="
diff --git a/telephony/java/android/telephony/UiccSlotInfo.java b/telephony/java/android/telephony/UiccSlotInfo.java
index 5e02532e85a8..dda73497e647 100644
--- a/telephony/java/android/telephony/UiccSlotInfo.java
+++ b/telephony/java/android/telephony/UiccSlotInfo.java
@@ -139,14 +139,16 @@ public class UiccSlotInfo implements Parcelable {
public UiccSlotInfo(boolean isEuicc, String cardId,
@CardStateInfo int cardStateInfo, boolean isExtendedApduSupported,
boolean isRemovable, @NonNull List<UiccPortInfo> portList) {
- this.mIsActive = portList.get(0).isActive();
this.mIsEuicc = isEuicc;
this.mCardId = cardId;
this.mCardStateInfo = cardStateInfo;
- this.mLogicalSlotIdx = portList.get(0).getLogicalSlotIndex();
this.mIsExtendedApduSupported = isExtendedApduSupported;
this.mIsRemovable = isRemovable;
this.mPortList = portList;
+ this.mIsActive = !portList.isEmpty() && portList.get(0).isActive();
+ this.mLogicalSlotIdx = portList.isEmpty()
+ ? SubscriptionManager.INVALID_PHONE_INDEX
+ : portList.get(0).getLogicalSlotIndex();
}
/**
@@ -164,8 +166,7 @@ public class UiccSlotInfo implements Parcelable {
throw new UnsupportedOperationException("getIsActive() is not supported by "
+ "UiccSlotInfo. Please Use UiccPortInfo API instead");
}
- //always return status from first port.
- return getPorts().stream().findFirst().get().isActive();
+ return mIsActive;
}
public boolean getIsEuicc() {
@@ -202,9 +203,7 @@ public class UiccSlotInfo implements Parcelable {
throw new UnsupportedOperationException("getLogicalSlotIdx() is not supported by "
+ "UiccSlotInfo. Please use UiccPortInfo API instead");
}
- //always return logical slot index from first port.
- //portList always have at least one element.
- return getPorts().stream().findFirst().get().getLogicalSlotIndex();
+ return mLogicalSlotIdx;
}
/**
@@ -281,7 +280,7 @@ public class UiccSlotInfo implements Parcelable {
+ ", mIsEuicc="
+ mIsEuicc
+ ", mCardId="
- + SubscriptionInfo.givePrintableIccid(mCardId)
+ + SubscriptionInfo.getPrintableId(mCardId)
+ ", cardState="
+ mCardStateInfo
+ ", mIsExtendedApduSupported="
diff --git a/telephony/java/android/telephony/VisualVoicemailService.java b/telephony/java/android/telephony/VisualVoicemailService.java
index fe30eb7bb005..a530917a271c 100644
--- a/telephony/java/android/telephony/VisualVoicemailService.java
+++ b/telephony/java/android/telephony/VisualVoicemailService.java
@@ -157,14 +157,14 @@ public abstract class VisualVoicemailService extends Service {
@Override
public void handleMessage(final Message msg) {
final PhoneAccountHandle handle = msg.getData()
- .getParcelable(DATA_PHONE_ACCOUNT_HANDLE);
+ .getParcelable(DATA_PHONE_ACCOUNT_HANDLE, android.telecom.PhoneAccountHandle.class);
VisualVoicemailTask task = new VisualVoicemailTask(msg.replyTo, msg.arg1);
switch (msg.what) {
case MSG_ON_CELL_SERVICE_CONNECTED:
onCellServiceConnected(task, handle);
break;
case MSG_ON_SMS_RECEIVED:
- VisualVoicemailSms sms = msg.getData().getParcelable(DATA_SMS);
+ VisualVoicemailSms sms = msg.getData().getParcelable(DATA_SMS, android.telephony.VisualVoicemailSms.class);
onSmsReceived(task, sms);
break;
case MSG_ON_SIM_REMOVED:
diff --git a/telephony/java/android/telephony/WwanSelectorCallback.java b/telephony/java/android/telephony/WwanSelectorCallback.java
new file mode 100644
index 000000000000..f9c2620cfaf8
--- /dev/null
+++ b/telephony/java/android/telephony/WwanSelectorCallback.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.telephony;
+
+import android.annotation.NonNull;
+import android.os.CancellationSignal;
+import android.telephony.DomainSelectionService.EmergencyScanType;
+
+import java.util.List;
+import java.util.function.Consumer;
+
+/**
+ * A callback class used to receive the domain selection result.
+ * @hide
+ */
+public interface WwanSelectorCallback {
+ /**
+ * Notify the framework that the {@link DomainSelectionService} has requested an emergency
+ * network scan as part of selection.
+ *
+ * @param preferredNetworks the ordered list of preferred networks to scan.
+ * @param scanType indicates the scan preference, such as full service or limited service.
+ * @param signal notifies when the operation is canceled.
+ * @param consumer the handler of the response.
+ */
+ void onRequestEmergencyNetworkScan(@NonNull List<Integer> preferredNetworks,
+ @EmergencyScanType int scanType,
+ @NonNull CancellationSignal signal, @NonNull Consumer<EmergencyRegResult> consumer);
+
+ /**
+ * Notifies the FW that the domain has been selected. After this method is called,
+ * this interface can be discarded.
+ *
+ * @param domain The selected domain.
+ * @param useEmergencyPdn Indicates whether emergency services use emergency PDN or not.
+ */
+ void onDomainSelected(@NetworkRegistrationInfo.Domain int domain, boolean useEmergencyPdn);
+}
diff --git a/telephony/java/android/telephony/cdma/CdmaCellLocation.java b/telephony/java/android/telephony/cdma/CdmaCellLocation.java
index d808cabaaa92..d4cb5ac8a64c 100644
--- a/telephony/java/android/telephony/cdma/CdmaCellLocation.java
+++ b/telephony/java/android/telephony/cdma/CdmaCellLocation.java
@@ -21,6 +21,9 @@ import android.os.Build;
import android.os.Bundle;
import android.telephony.CellLocation;
+import com.android.internal.telephony.util.TelephonyUtils;
+import com.android.telephony.Rlog;
+
/**
* Represents the cell location on a CDMA phone.
*
@@ -197,8 +200,8 @@ public class CdmaCellLocation extends CellLocation {
@Override
public String toString() {
return "[" + this.mBaseStationId + ","
- + this.mBaseStationLatitude + ","
- + this.mBaseStationLongitude + ","
+ + Rlog.pii(TelephonyUtils.IS_DEBUGGABLE, this.mBaseStationLatitude) + ","
+ + Rlog.pii(TelephonyUtils.IS_DEBUGGABLE, this.mBaseStationLongitude) + ","
+ this.mSystemId + ","
+ this.mNetworkId + "]";
}
diff --git a/telephony/java/android/telephony/data/ApnSetting.java b/telephony/java/android/telephony/data/ApnSetting.java
index b32f04633247..28ea5a681730 100644
--- a/telephony/java/android/telephony/data/ApnSetting.java
+++ b/telephony/java/android/telephony/data/ApnSetting.java
@@ -43,6 +43,7 @@ import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.List;
+import java.util.Locale;
import java.util.Map;
import java.util.Objects;
@@ -1337,6 +1338,14 @@ public class ApnSetting implements Parcelable {
public ContentValues toContentValues() {
ContentValues apnValue = new ContentValues();
apnValue.put(Telephony.Carriers.NUMERIC, nullToEmpty(mOperatorNumeric));
+ // If the APN is editable, the user may be able to set an invalid numeric. The numeric must
+ // always be 5 or 6 characters (depending on the length of the MNC), so skip if it is
+ // potentially invalid.
+ if (!TextUtils.isEmpty(mOperatorNumeric)
+ && (mOperatorNumeric.length() == 5 || mOperatorNumeric.length() == 6)) {
+ apnValue.put(Telephony.Carriers.MCC, mOperatorNumeric.substring(0, 3));
+ apnValue.put(Telephony.Carriers.MNC, mOperatorNumeric.substring(3));
+ }
apnValue.put(Telephony.Carriers.NAME, nullToEmpty(mEntryName));
apnValue.put(Telephony.Carriers.APN, nullToEmpty(mApnName));
apnValue.put(Telephony.Carriers.PROXY, nullToEmpty(mProxyAddress));
@@ -1356,6 +1365,7 @@ public class ApnSetting implements Parcelable {
getProtocolStringFromInt(mRoamingProtocol));
apnValue.put(Telephony.Carriers.CARRIER_ENABLED, mCarrierEnabled);
apnValue.put(Telephony.Carriers.MVNO_TYPE, getMvnoTypeStringFromInt(mMvnoType));
+ apnValue.put(Telephony.Carriers.MVNO_MATCH_DATA, nullToEmpty(mMvnoMatchData));
apnValue.put(Telephony.Carriers.NETWORK_TYPE_BITMASK, mNetworkTypeBitmask);
apnValue.put(Telephony.Carriers.LINGERING_NETWORK_TYPE_BITMASK,
mLingeringNetworkTypeBitmask);
@@ -1442,7 +1452,7 @@ public class ApnSetting implements Parcelable {
*/
@SystemApi
public static @ApnType int getApnTypeInt(@NonNull @ApnTypeString String apnType) {
- return APN_TYPE_STRING_MAP.getOrDefault(apnType.toLowerCase(), 0);
+ return APN_TYPE_STRING_MAP.getOrDefault(apnType.toLowerCase(Locale.ROOT), 0);
}
/**
@@ -1457,7 +1467,7 @@ public class ApnSetting implements Parcelable {
} else {
int result = 0;
for (String str : types.split(",")) {
- Integer type = APN_TYPE_STRING_MAP.get(str.toLowerCase());
+ Integer type = APN_TYPE_STRING_MAP.get(str.toLowerCase(Locale.ROOT));
if (type != null) {
result |= type;
}
@@ -1468,7 +1478,8 @@ public class ApnSetting implements Parcelable {
/** @hide */
public static int getMvnoTypeIntFromString(String mvnoType) {
- String mvnoTypeString = TextUtils.isEmpty(mvnoType) ? mvnoType : mvnoType.toLowerCase();
+ String mvnoTypeString = TextUtils.isEmpty(mvnoType)
+ ? mvnoType : mvnoType.toLowerCase(Locale.ROOT);
Integer mvnoTypeInt = MVNO_TYPE_STRING_MAP.get(mvnoTypeString);
return mvnoTypeInt == null ? UNSPECIFIED_INT : mvnoTypeInt;
}
diff --git a/telephony/java/android/telephony/data/IQualifiedNetworksService.aidl b/telephony/java/android/telephony/data/IQualifiedNetworksService.aidl
index ba2b62d14bec..8e2707735f63 100644
--- a/telephony/java/android/telephony/data/IQualifiedNetworksService.aidl
+++ b/telephony/java/android/telephony/data/IQualifiedNetworksService.aidl
@@ -27,4 +27,5 @@ interface IQualifiedNetworksService
oneway void createNetworkAvailabilityProvider(int slotId, IQualifiedNetworksServiceCallback callback);
oneway void removeNetworkAvailabilityProvider(int slotId);
oneway void reportThrottleStatusChanged(int slotId, in List<ThrottleStatus> statuses);
+ oneway void reportEmergencyDataNetworkPreferredTransportChanged (int slotId, int transportType);
}
diff --git a/telephony/java/android/telephony/data/QosBearerSession.java b/telephony/java/android/telephony/data/QosBearerSession.java
index dd080856d450..1668193e076c 100644
--- a/telephony/java/android/telephony/data/QosBearerSession.java
+++ b/telephony/java/android/telephony/data/QosBearerSession.java
@@ -102,12 +102,11 @@ public final class QosBearerSession implements Parcelable{
QosBearerSession other = (QosBearerSession) o;
return this.qosBearerSessionId == other.qosBearerSessionId
- && this.qos.equals(other.qos)
+ && Objects.equals(this.qos, other.qos)
&& this.qosBearerFilterList.size() == other.qosBearerFilterList.size()
&& this.qosBearerFilterList.containsAll(other.qosBearerFilterList);
}
-
public static final @NonNull Parcelable.Creator<QosBearerSession> CREATOR =
new Parcelable.Creator<QosBearerSession>() {
@Override
diff --git a/telephony/java/android/telephony/data/QualifiedNetworksService.java b/telephony/java/android/telephony/data/QualifiedNetworksService.java
index fb973361e398..56f0f9f13772 100644
--- a/telephony/java/android/telephony/data/QualifiedNetworksService.java
+++ b/telephony/java/android/telephony/data/QualifiedNetworksService.java
@@ -68,6 +68,7 @@ public abstract class QualifiedNetworksService extends Service {
private static final int QNS_REMOVE_ALL_NETWORK_AVAILABILITY_PROVIDERS = 3;
private static final int QNS_UPDATE_QUALIFIED_NETWORKS = 4;
private static final int QNS_APN_THROTTLE_STATUS_CHANGED = 5;
+ private static final int QNS_EMERGENCY_DATA_NETWORK_PREFERRED_TRANSPORT_CHANGED = 6;
private final HandlerThread mHandlerThread;
@@ -193,6 +194,20 @@ public abstract class QualifiedNetworksService extends Service {
}
/**
+ * The framework calls this method when the preferred transport type used to set up
+ * emergency data network is changed.
+ *
+ * This method is meant to be overridden.
+ *
+ * @param transportType transport type changed to be preferred
+ */
+ public void reportEmergencyDataNetworkPreferredTransportChanged(
+ @AccessNetworkConstants.TransportType int transportType) {
+ Log.d(TAG, "reportEmergencyDataNetworkPreferredTransportChanged: "
+ + AccessNetworkConstants.transportTypeToString(transportType));
+ }
+
+ /**
* Called when the qualified networks provider is removed. The extended class should
* implement this method to perform cleanup works.
*/
@@ -237,6 +252,13 @@ public abstract class QualifiedNetworksService extends Service {
}
break;
+ case QNS_EMERGENCY_DATA_NETWORK_PREFERRED_TRANSPORT_CHANGED:
+ if (provider != null) {
+ int transportType = (int) message.arg2;
+ provider.reportEmergencyDataNetworkPreferredTransportChanged(transportType);
+ }
+ break;
+
case QNS_REMOVE_NETWORK_AVAILABILITY_PROVIDER:
if (provider != null) {
provider.close();
@@ -332,6 +354,14 @@ public abstract class QualifiedNetworksService extends Service {
mHandler.obtainMessage(QNS_APN_THROTTLE_STATUS_CHANGED, slotIndex, 0, statuses)
.sendToTarget();
}
+
+ @Override
+ public void reportEmergencyDataNetworkPreferredTransportChanged(int slotIndex,
+ @AccessNetworkConstants.TransportType int transportType) {
+ mHandler.obtainMessage(
+ QNS_EMERGENCY_DATA_NETWORK_PREFERRED_TRANSPORT_CHANGED,
+ slotIndex, transportType).sendToTarget();
+ }
}
private void log(String s) {
diff --git a/telephony/java/android/telephony/emergency/EmergencyNumber.java b/telephony/java/android/telephony/emergency/EmergencyNumber.java
index d9d5c14735ea..64bcf7171ade 100644
--- a/telephony/java/android/telephony/emergency/EmergencyNumber.java
+++ b/telephony/java/android/telephony/emergency/EmergencyNumber.java
@@ -25,6 +25,8 @@ import android.os.Parcel;
import android.os.Parcelable;
import android.telephony.CarrierConfigManager;
import android.telephony.PhoneNumberUtils;
+import android.util.SparseArray;
+import android.util.SparseIntArray;
import com.android.telephony.Rlog;
@@ -247,6 +249,17 @@ public final class EmergencyNumber implements Parcelable, Comparable<EmergencyNu
private final List<String> mEmergencyUrns;
private final int mEmergencyNumberSourceBitmask;
private final int mEmergencyCallRouting;
+ /**
+ * The source of the EmergencyNumber in the order of precedence.
+ */
+ private static final int[] EMERGENCY_NUMBER_SOURCE_PRECEDENCE;
+ static {
+ EMERGENCY_NUMBER_SOURCE_PRECEDENCE = new int[4];
+ EMERGENCY_NUMBER_SOURCE_PRECEDENCE[0] = EMERGENCY_NUMBER_SOURCE_NETWORK_SIGNALING;
+ EMERGENCY_NUMBER_SOURCE_PRECEDENCE[1] = EMERGENCY_NUMBER_SOURCE_SIM;
+ EMERGENCY_NUMBER_SOURCE_PRECEDENCE[2] = EMERGENCY_NUMBER_SOURCE_DATABASE;
+ EMERGENCY_NUMBER_SOURCE_PRECEDENCE[3] = EMERGENCY_NUMBER_SOURCE_MODEM_CONFIG;
+ }
/** @hide */
public EmergencyNumber(@NonNull String number, @NonNull String countryIso, @NonNull String mnc,
@@ -601,19 +614,44 @@ public final class EmergencyNumber implements Parcelable, Comparable<EmergencyNu
*/
public static void mergeSameNumbersInEmergencyNumberList(
List<EmergencyNumber> emergencyNumberList) {
+ mergeSameNumbersInEmergencyNumberList(emergencyNumberList, false);
+ }
+
+ /**
+ * In-place merge same emergency numbers in the emergency number list.
+ *
+ * A unique EmergencyNumber has a unique combination of ‘number’, ‘mcc’ and 'mnc' fields.
+ * If mergeServiceCategoriesAndUrns is true ignore comparing of 'urns' and
+ * 'categories' fields and determine these fields from most precedent number. Else compare
+ * to get unique combination of EmergencyNumber.
+ * Multiple Emergency Number Sources should be merged into one bitfield for the
+ * same EmergencyNumber.
+ *
+ * @param emergencyNumberList the emergency number list to process
+ * @param mergeServiceCategoriesAndUrns {@code true} determine service category and urns
+ * from most precedent number. {@code false} compare those fields for determing duplicate.
+ *
+ * @hide
+ */
+ public static void mergeSameNumbersInEmergencyNumberList(
+ @NonNull List<EmergencyNumber> emergencyNumberList,
+ boolean mergeServiceCategoriesAndUrns) {
if (emergencyNumberList == null) {
return;
}
+
Set<Integer> duplicatedEmergencyNumberPosition = new HashSet<>();
for (int i = 0; i < emergencyNumberList.size(); i++) {
for (int j = 0; j < i; j++) {
- if (areSameEmergencyNumbers(
- emergencyNumberList.get(i), emergencyNumberList.get(j))) {
- Rlog.e(LOG_TAG, "Found unexpected duplicate numbers: "
- + emergencyNumberList.get(i) + " vs " + emergencyNumberList.get(j));
+ if (areSameEmergencyNumbers(emergencyNumberList.get(i),
+ emergencyNumberList.get(j), mergeServiceCategoriesAndUrns)) {
+ Rlog.e(LOG_TAG, "Found unexpected duplicate numbers "
+ + emergencyNumberList.get(i)
+ + " vs " + emergencyNumberList.get(j));
// Set the merged emergency number in the current position
- emergencyNumberList.set(i, mergeSameEmergencyNumbers(
- emergencyNumberList.get(i), emergencyNumberList.get(j)));
+ emergencyNumberList.set(i,
+ mergeSameEmergencyNumbers(emergencyNumberList.get(i),
+ emergencyNumberList.get(j), mergeServiceCategoriesAndUrns));
// Mark the emergency number has been merged
duplicatedEmergencyNumberPosition.add(j);
}
@@ -632,18 +670,24 @@ public final class EmergencyNumber implements Parcelable, Comparable<EmergencyNu
/**
* Check if two emergency numbers are the same.
*
- * A unique EmergencyNumber has a unique combination of ‘number’, ‘mcc’, 'mnc' and
- * 'categories', and 'routing' fields. Multiple Emergency Number Sources should be
+ * A unique EmergencyNumber has a unique combination of ‘number’, ‘mcc’, 'mnc' fields.
+ * If mergeServiceCategoriesAndUrns is true ignore comparing of 'urns' and
+ * 'categories' fields and determine these fields from most precedent number. Else compare
+ * to get unique combination of EmergencyNumber.
+ * Multiple Emergency Number Sources should be
* merged into one bitfield for the same EmergencyNumber.
*
* @param first first EmergencyNumber to compare
* @param second second EmergencyNumber to compare
+ * @param ignoreServiceCategoryAndUrns {@code true} Ignore comparing of service category
+ * and Urns so that they can be determined from most precedent number. {@code false} compare
+ * those fields for determing duplicate.
* @return true if they are the same EmergencyNumbers; false otherwise.
*
* @hide
*/
public static boolean areSameEmergencyNumbers(@NonNull EmergencyNumber first,
- @NonNull EmergencyNumber second) {
+ @NonNull EmergencyNumber second, boolean ignoreServiceCategoryAndUrns) {
if (!first.getNumber().equals(second.getNumber())) {
return false;
}
@@ -653,15 +697,14 @@ public final class EmergencyNumber implements Parcelable, Comparable<EmergencyNu
if (!first.getMnc().equals(second.getMnc())) {
return false;
}
- if (first.getEmergencyServiceCategoryBitmask()
- != second.getEmergencyServiceCategoryBitmask()) {
- return false;
- }
- if (!first.getEmergencyUrns().equals(second.getEmergencyUrns())) {
- return false;
- }
- if (first.getEmergencyCallRouting() != second.getEmergencyCallRouting()) {
- return false;
+ if (!ignoreServiceCategoryAndUrns) {
+ if (first.getEmergencyServiceCategoryBitmask()
+ != second.getEmergencyServiceCategoryBitmask()) {
+ return false;
+ }
+ if (!first.getEmergencyUrns().equals(second.getEmergencyUrns())) {
+ return false;
+ }
}
// Never merge two numbers if one of them is from test mode but the other one is not;
// This supports to remove a number from the test mode.
@@ -684,18 +727,133 @@ public final class EmergencyNumber implements Parcelable, Comparable<EmergencyNu
*/
public static EmergencyNumber mergeSameEmergencyNumbers(@NonNull EmergencyNumber first,
@NonNull EmergencyNumber second) {
- if (areSameEmergencyNumbers(first, second)) {
+ if (areSameEmergencyNumbers(first, second, false)) {
+ int routing = first.getEmergencyCallRouting();
+
+ if (second.isFromSources(EMERGENCY_NUMBER_SOURCE_DATABASE)) {
+ routing = second.getEmergencyCallRouting();
+ }
+
return new EmergencyNumber(first.getNumber(), first.getCountryIso(), first.getMnc(),
first.getEmergencyServiceCategoryBitmask(),
first.getEmergencyUrns(),
first.getEmergencyNumberSourceBitmask()
| second.getEmergencyNumberSourceBitmask(),
- first.getEmergencyCallRouting());
+ routing);
}
return null;
}
/**
+ * Get merged EmergencyUrns list from two same emergency numbers.
+ * By giving priority to the urns from first number.
+ *
+ * @param firstEmergencyUrns first number's Urns
+ * @param secondEmergencyUrns second number's Urns
+ * @return a merged Urns
+ *
+ * @hide
+ */
+ private static List<String> mergeEmergencyUrns(@NonNull List<String> firstEmergencyUrns,
+ @NonNull List<String> secondEmergencyUrns) {
+ List<String> mergedUrns = new ArrayList<String>();
+ mergedUrns.addAll(firstEmergencyUrns);
+ for (String urn : secondEmergencyUrns) {
+ if (!firstEmergencyUrns.contains(urn)) {
+ mergedUrns.add(urn);
+ }
+ }
+ return mergedUrns;
+ }
+
+ /**
+ * Get the highest precedence source of the given Emergency number. Then get service catergory
+ * and urns list fill in the respective map with key as source.
+ *
+ * @param num EmergencyNumber to get the source, service category & urns
+ * @param serviceCategoryArray Array to store the category of the given EmergencyNumber
+ * with key as highest precedence source
+ * @param urnsArray Array to store the list of Urns of the given EmergencyNumber
+ * with key as highest precedence source
+ *
+ * @hide
+ */
+ private static void fillServiceCategoryAndUrns(@NonNull EmergencyNumber num,
+ @NonNull SparseIntArray serviceCategoryArray,
+ @NonNull SparseArray<List<String>> urnsArray) {
+ int numberSrc = num.getEmergencyNumberSourceBitmask();
+ for (Integer source : EMERGENCY_NUMBER_SOURCE_PRECEDENCE) {
+ if ((numberSrc & source) == source) {
+ if (!num.isInEmergencyServiceCategories(EMERGENCY_SERVICE_CATEGORY_UNSPECIFIED)) {
+ serviceCategoryArray.put(source, num.getEmergencyServiceCategoryBitmask());
+ }
+ urnsArray.put(source, num.getEmergencyUrns());
+ break;
+ }
+ }
+ }
+
+ /**
+ * Get a merged EmergencyNumber from two same emergency numbers from
+ * Emergency number list. Two emergency numbers are the same if
+ * {@link #areSameEmergencyNumbers} returns {@code true}.
+ *
+ * @param first first EmergencyNumber to compare
+ * @param second second EmergencyNumber to compare
+ * @param mergeServiceCategoriesAndUrns {@code true} then determine service category and urns
+ * Service catetory : set from most precedence source number(N/W, SIM, DB, modem_cfg)
+ * Urns : merge from both with first priority from most precedence source number
+ * {@code false} then call {@link #mergeSameEmergencyNumbers} to merge.
+ * @return a merged EmergencyNumber or null if they are not the same EmergencyNumber
+ *
+ * @hide
+ */
+ public static @NonNull EmergencyNumber mergeSameEmergencyNumbers(
+ @NonNull EmergencyNumber first, @NonNull EmergencyNumber second,
+ boolean mergeServiceCategoriesAndUrns) {
+ if (!mergeServiceCategoriesAndUrns) {
+ return mergeSameEmergencyNumbers(first, second);
+ }
+
+ int routing = first.getEmergencyCallRouting();
+ int serviceCategory = first.getEmergencyServiceCategoryBitmask();
+ List<String> mergedEmergencyUrns = new ArrayList<String>();
+ //Maps to store the service category and urns of both the first and second emergency number
+ // with key as most precedent source
+ SparseIntArray serviceCategoryArray = new SparseIntArray(2);
+ SparseArray<List<String>> urnsArray = new SparseArray(2);
+
+ fillServiceCategoryAndUrns(first, serviceCategoryArray, urnsArray);
+ fillServiceCategoryAndUrns(second, serviceCategoryArray, urnsArray);
+
+ if (second.isFromSources(EMERGENCY_NUMBER_SOURCE_DATABASE)) {
+ routing = second.getEmergencyCallRouting();
+ }
+
+ // Determine serviceCategory of most precedence number
+ for (int sourceOfCategory : EMERGENCY_NUMBER_SOURCE_PRECEDENCE) {
+ if (serviceCategoryArray.indexOfKey(sourceOfCategory) >= 0) {
+ serviceCategory = serviceCategoryArray.get(sourceOfCategory);
+ break;
+ }
+ }
+
+ // Merge Urns in precedence number
+ for (int sourceOfUrn : EMERGENCY_NUMBER_SOURCE_PRECEDENCE) {
+ if (urnsArray.contains(sourceOfUrn)) {
+ mergedEmergencyUrns = mergeEmergencyUrns(mergedEmergencyUrns,
+ urnsArray.get(sourceOfUrn));
+ }
+ }
+
+ return new EmergencyNumber(first.getNumber(), first.getCountryIso(), first.getMnc(),
+ serviceCategory, mergedEmergencyUrns,
+ first.getEmergencyNumberSourceBitmask()
+ | second.getEmergencyNumberSourceBitmask(),
+ routing);
+ }
+
+ /**
* Validate Emergency Number address that only contains the dialable character
* {@link PhoneNumberUtils#isDialable(char)}
*
diff --git a/telephony/java/android/telephony/euicc/EuiccCardManager.java b/telephony/java/android/telephony/euicc/EuiccCardManager.java
index 2f8316e38363..611f97b70c8c 100644
--- a/telephony/java/android/telephony/euicc/EuiccCardManager.java
+++ b/telephony/java/android/telephony/euicc/EuiccCardManager.java
@@ -116,7 +116,10 @@ public class EuiccCardManager {
/** Resets the default SM-DP+ address. */
public static final int RESET_OPTION_RESET_DEFAULT_SMDP_ADDRESS = 1 << 2;
- /** Result code when the requested profile is not found */
+ /** Result code when the requested profile is not found.
+ * {@link #RESULT_PROFILE_NOT_FOUND} is not used in Android U+,
+ * use {@link #RESULT_PROFILE_DOES_NOT_EXIST} instead.
+ **/
public static final int RESULT_PROFILE_NOT_FOUND = 1;
/** Result code of execution with no error. */
@@ -131,6 +134,9 @@ public class EuiccCardManager {
/** Result code indicating the caller is not the active LPA. */
public static final int RESULT_CALLER_NOT_ALLOWED = -3;
+ /** Result code when the requested profile does not exist */
+ public static final int RESULT_PROFILE_DOES_NOT_EXIST = -4;
+
/**
* Callback to receive the result of an eUICC card API.
*
@@ -222,7 +228,7 @@ public class EuiccCardManager {
/**
* Requests the enabled profile for a given port on an eUicc. Callback with result code
- * {@link RESULT_PROFILE_NOT_FOUND} and {@code NULL} EuiccProfile if there is no enabled
+ * {@link RESULT_PROFILE_DOES_NOT_EXIST} and {@code NULL} EuiccProfile if there is no enabled
* profile on the target port.
*
* @param cardId The Id of the eUICC.
diff --git a/telephony/java/android/telephony/euicc/EuiccManager.java b/telephony/java/android/telephony/euicc/EuiccManager.java
index 1252dc178cb9..ed4627631dd5 100644
--- a/telephony/java/android/telephony/euicc/EuiccManager.java
+++ b/telephony/java/android/telephony/euicc/EuiccManager.java
@@ -48,6 +48,7 @@ import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.Collections;
import java.util.List;
+import java.util.Locale;
import java.util.stream.Collectors;
/**
@@ -81,6 +82,47 @@ public class EuiccManager {
public static final String ACTION_MANAGE_EMBEDDED_SUBSCRIPTIONS =
"android.telephony.euicc.action.MANAGE_EMBEDDED_SUBSCRIPTIONS";
+
+ /**
+ * Intent action to transfer an embedded subscriptions.
+ *
+ * <p> Action sent by apps (such as the Settings app) to the Telephony framework to transfer an
+ * embedded subscription.
+ *
+ * <p> Requires that the calling app has the
+ * {@code android.Manifest.permission#MODIFY_PHONE_STATE} permission.
+ *
+ * <p>The activity will immediately finish with {@link android.app.Activity#RESULT_CANCELED} if
+ * {@link #isEnabled} is false.
+ *
+ * @hide
+ */
+ @SystemApi
+ @SdkConstant(SdkConstant.SdkConstantType.ACTIVITY_INTENT_ACTION)
+ @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE)
+ public static final String ACTION_TRANSFER_EMBEDDED_SUBSCRIPTIONS =
+ "android.telephony.euicc.action.TRANSFER_EMBEDDED_SUBSCRIPTIONS";
+
+ /**
+ * Intent action to convert the physical subscription to an embedded subscription.
+ *
+ * <p> Action sent by apps (such as the Settings app) to the Telephony framework to convert
+ * physical sim to embedded sim.
+ *
+ * <p> Requires that the calling app has the
+ * {@code android.Manifest.permission#MODIFY_PHONE_STATE} permission.
+ *
+ * <p>The activity will immediately finish with {@link android.app.Activity#RESULT_CANCELED} if
+ * {@link #isEnabled} is false.
+ *
+ * @hide
+ */
+ @SystemApi
+ @SdkConstant(SdkConstant.SdkConstantType.ACTIVITY_INTENT_ACTION)
+ @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE)
+ public static final String ACTION_CONVERT_TO_EMBEDDED_SUBSCRIPTION =
+ "android.telephony.euicc.action.CONVERT_TO_EMBEDDED_SUBSCRIPTION";
+
/**
* Broadcast Action: The eUICC OTA status is changed.
* <p class="note">
@@ -840,6 +882,16 @@ public class EuiccManager {
@EnabledSince(targetSdkVersion = Build.VERSION_CODES.TIRAMISU)
public static final long SHOULD_RESOLVE_PORT_INDEX_FOR_APPS = 224562872L;
+ /**
+ * Starting with Android U, a port is available if it is active without an enabled profile
+ * on it or calling app can activate a new profile on the selected port without any user
+ * interaction.
+ * @hide
+ */
+ @ChangeId
+ @EnabledSince(targetSdkVersion = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
+ public static final long INACTIVE_PORT_AVAILABILITY_CHECK = 240273417L;
+
private final Context mContext;
private int mCardId;
@@ -1001,7 +1053,7 @@ public class EuiccManager {
public void startResolutionActivity(Activity activity, int requestCode, Intent resultIntent,
PendingIntent callbackIntent) throws IntentSender.SendIntentException {
PendingIntent resolutionIntent =
- resultIntent.getParcelableExtra(EXTRA_EMBEDDED_SUBSCRIPTION_RESOLUTION_INTENT);
+ resultIntent.getParcelableExtra(EXTRA_EMBEDDED_SUBSCRIPTION_RESOLUTION_INTENT, android.app.PendingIntent.class);
if (resolutionIntent == null) {
throw new IllegalArgumentException("Invalid result intent");
}
@@ -1032,7 +1084,7 @@ public class EuiccManager {
if (!isEnabled()) {
PendingIntent callbackIntent =
resolutionIntent.getParcelableExtra(
- EuiccManager.EXTRA_EMBEDDED_SUBSCRIPTION_RESOLUTION_CALLBACK_INTENT);
+ EuiccManager.EXTRA_EMBEDDED_SUBSCRIPTION_RESOLUTION_CALLBACK_INTENT, android.app.PendingIntent.class);
if (callbackIntent != null) {
sendUnavailableError(callbackIntent);
}
@@ -1524,7 +1576,7 @@ public class EuiccManager {
return false;
}
try {
- return getIEuiccController().isSupportedCountry(countryIso.toUpperCase());
+ return getIEuiccController().isSupportedCountry(countryIso.toUpperCase(Locale.ROOT));
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -1571,6 +1623,10 @@ public class EuiccManager {
* Returns whether the passing portIndex is available.
* A port is available if it is active without enabled profile on it or
* calling app has carrier privilege over the profile installed on the selected port.
+ *
+ * <p> From Android U, a port is available if it is active without an enabled profile on it or
+ * calling app can activate a new profile on the selected port without any user interaction.
+ *
* Always returns false if the cardId is a physical card.
*
* @param portIndex is an enumeration of the ports available on the UICC.
diff --git a/telephony/java/android/telephony/ims/ImsCallProfile.java b/telephony/java/android/telephony/ims/ImsCallProfile.java
index e6d7df34f755..d07edeb971ea 100644
--- a/telephony/java/android/telephony/ims/ImsCallProfile.java
+++ b/telephony/java/android/telephony/ims/ImsCallProfile.java
@@ -27,6 +27,7 @@ import android.os.Bundle;
import android.os.Parcel;
import android.os.Parcelable;
import android.telecom.VideoProfile;
+import android.telephony.CallState;
import android.telephony.emergency.EmergencyNumber;
import android.telephony.emergency.EmergencyNumber.EmergencyCallRouting;
import android.telephony.emergency.EmergencyNumber.EmergencyServiceCategories;
@@ -78,8 +79,11 @@ public final class ImsCallProfile implements Parcelable {
public static final int SERVICE_TYPE_EMERGENCY = 2;
/**
- * Call types
+ * This value is returned if there is no valid IMS call type defined for the call. For example,
+ * if an ongoing call is circuit-switched and {@link CallState#getImsCallType()} is called, this
+ * value will be returned.
*/
+ public static final int CALL_TYPE_NONE = 0;
/**
* IMSPhone to support IR.92 & IR.94 (voice + video upgrade/downgrade)
*/
diff --git a/telephony/java/android/telephony/ims/ImsCallSession.java b/telephony/java/android/telephony/ims/ImsCallSession.java
index d65286f26447..ecd703960d08 100755
--- a/telephony/java/android/telephony/ims/ImsCallSession.java
+++ b/telephony/java/android/telephony/ims/ImsCallSession.java
@@ -18,10 +18,12 @@ package android.telephony.ims;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.os.Bundle;
import android.os.Message;
import android.os.RemoteException;
import android.telephony.CallQuality;
import android.telephony.ims.aidl.IImsCallSessionListener;
+import android.telephony.ims.stub.ImsCallSessionImplBase;
import android.util.ArraySet;
import android.util.Log;
@@ -99,7 +101,6 @@ public class ImsCallSession {
* Listener for events relating to an IMS session, such as when a session is being
* recieved ("on ringing") or a call is outgoing ("on calling").
* <p>Many of these events are also received by {@link ImsCall.Listener}.</p>
- * @hide
*/
public static class Listener {
/**
@@ -519,20 +520,30 @@ public class ImsCallSession {
@NonNull Set<RtpHeaderExtension> extensions) {
// no-op
}
+
+ /**
+ * Called when radio to send ANBRQ message to the access network to query the desired
+ * bitrate.
+ */
+ public void callSessionSendAnbrQuery(int mediaType, int direction, int bitsPerSecond) {
+ // no-op
+ }
}
private final IImsCallSession miSession;
private boolean mClosed = false;
+ private String mCallId = null;
private Listener mListener;
private Executor mListenerExecutor = Runnable::run;
+ private IImsCallSessionListenerProxy mIImsCallSessionListenerProxy = null;
- /** @hide */
public ImsCallSession(IImsCallSession iSession) {
miSession = iSession;
+ mIImsCallSessionListenerProxy = new IImsCallSessionListenerProxy();
if (iSession != null) {
try {
- iSession.setListener(new IImsCallSessionListenerProxy());
+ iSession.setListener(mIImsCallSessionListenerProxy);
} catch (RemoteException e) {
}
} else {
@@ -540,13 +551,19 @@ public class ImsCallSession {
}
}
- /** @hide */
public ImsCallSession(IImsCallSession iSession, Listener listener, Executor executor) {
this(iSession);
setListener(listener, executor);
}
/**
+ * returns the IImsCallSessionListenerProxy for the ImsCallSession
+ */
+ public final IImsCallSessionListenerProxy getIImsCallSessionListenerProxy() {
+ return mIImsCallSessionListenerProxy;
+ }
+
+ /**
* Closes this object. This object is not usable after being closed.
*/
public void close() {
@@ -567,16 +584,34 @@ public class ImsCallSession {
* Gets the call ID of the session.
*
* @return the call ID
+ * If null is returned for getCallId, then that means that the call ID has not been set yet.
*/
public String getCallId() {
if (mClosed) {
return null;
}
- try {
- return miSession.getCallId();
- } catch (RemoteException e) {
- return null;
+ if (mCallId != null) {
+ return mCallId;
+ } else {
+ try {
+ return mCallId = miSession.getCallId();
+ } catch (RemoteException e) {
+ return null;
+ }
+ }
+ }
+
+ /**
+ * Sets the call ID of the session.
+ *
+ * @param callId Call ID of the session, which is transferred from
+ * {@link android.telephony.ims.feature.MmTelFeature#notifyIncomingCall(
+ * ImsCallSessionImplBase, String, Bundle)}
+ */
+ public void setCallId(String callId) {
+ if (callId != null) {
+ mCallId = callId;
}
}
@@ -635,7 +670,6 @@ public class ImsCallSession {
* Gets the video call provider for the session.
*
* @return The video call provider.
- * @hide
*/
public IImsVideoCallProvider getVideoCallProvider() {
if (mClosed) {
@@ -712,7 +746,6 @@ public class ImsCallSession {
/**
* Gets the native IMS call session.
- * @hide
*/
public IImsCallSession getSession() {
return miSession;
@@ -742,7 +775,6 @@ public class ImsCallSession {
*
* @param listener to listen to the session events of this object
* @param executor an Executor that will execute callbacks
- * @hide
*/
public void setListener(Listener listener, Executor executor) {
mListener = listener;
@@ -1201,6 +1233,27 @@ public class ImsCallSession {
}
/**
+ * Deliver the bitrate for the indicated media type, direction and bitrate to the upper layer.
+ *
+ * @param mediaType MediaType is used to identify media stream such as audio or video.
+ * @param direction Direction of this packet stream (e.g. uplink or downlink).
+ * @param bitsPerSecond This value is the bitrate received from the NW through the Recommended
+ * bitrate MAC Control Element message and ImsStack converts this value from MAC bitrate
+ * to audio/video codec bitrate (defined in TS26.114).
+ */
+ public void callSessionNotifyAnbr(int mediaType, int direction, int bitsPerSecond) {
+ if (mClosed) {
+ return;
+ }
+
+ try {
+ miSession.callSessionNotifyAnbr(mediaType, direction, bitsPerSecond);
+ } catch (RemoteException e) {
+ Log.e(TAG, "callSessionNotifyAnbr" + e);
+ }
+ }
+
+ /**
* A listener type for receiving notification on IMS call session events.
* When an event is generated for an {@link IImsCallSession},
* the application is notified by having one of the methods called on
@@ -1693,6 +1746,26 @@ public class ImsCallSession {
}
}, mListenerExecutor);
}
+
+ /**
+ * ANBR Query received.
+ *
+ * @param mediaType MediaType is used to identify media stream such as audio or video.
+ * @param direction Direction of this packet stream (e.g. uplink or downlink).
+ * @param bitsPerSecond This value is the bitrate requested by the other party UE through
+ * RTP CMR, RTCPAPP or TMMBR, and ImsStack converts this value to the MAC bitrate
+ * (defined in TS36.321, range: 0 ~ 8000 kbit/s).
+ */
+ @Override
+ public void callSessionSendAnbrQuery(int mediaType, int direction,
+ int bitsPerSecond) {
+ Log.d(TAG, "callSessionSendAnbrQuery in ImsCallSession");
+ TelephonyUtils.runWithCleanCallingIdentity(()-> {
+ if (mListener != null) {
+ mListener.callSessionSendAnbrQuery(mediaType, direction, bitsPerSecond);
+ }
+ }, mListenerExecutor);
+ }
}
/**
@@ -1706,10 +1779,8 @@ public class ImsCallSession {
StringBuilder sb = new StringBuilder();
sb.append("[ImsCallSession objId:");
sb.append(System.identityHashCode(this));
- sb.append(" state:");
- sb.append(State.toString(getState()));
sb.append(" callId:");
- sb.append(getCallId());
+ sb.append(mCallId != null ? mCallId : "[UNINITIALIZED]");
sb.append("]");
return sb.toString();
}
diff --git a/telephony/java/android/telephony/ims/ImsCallSessionListener.java b/telephony/java/android/telephony/ims/ImsCallSessionListener.java
index 3533c0907fac..5946535ce3af 100644
--- a/telephony/java/android/telephony/ims/ImsCallSessionListener.java
+++ b/telephony/java/android/telephony/ims/ImsCallSessionListener.java
@@ -16,6 +16,7 @@
package android.telephony.ims;
+import android.annotation.IntRange;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
@@ -25,6 +26,9 @@ import android.telephony.CallQuality;
import android.telephony.ServiceState;
import android.telephony.ims.aidl.IImsCallSessionListener;
import android.telephony.ims.stub.ImsCallSessionImplBase;
+import android.telephony.ims.stub.ImsCallSessionImplBase.MediaStreamDirection;
+import android.telephony.ims.stub.ImsCallSessionImplBase.MediaStreamType;
+import android.util.Log;
import com.android.ims.internal.IImsCallSession;
@@ -45,6 +49,7 @@ import java.util.concurrent.Executor;
// ImsCallSessionListenerConverter is also changed.
@SystemApi
public class ImsCallSessionListener {
+ private static final String TAG = "ImsCallSessionListener";
private final IImsCallSessionListener mListener;
private Executor mExecutor = null;
@@ -823,6 +828,30 @@ public class ImsCallSessionListener {
}
/**
+ * Access Network Bitrate Recommendation Query (ANBRQ), see 3GPP TS 26.114.
+ * This API triggers radio to send ANBRQ message to the access network to query the
+ * desired bitrate.
+ *
+ * @param mediaType {@link ImsCallSessionImplBase.MediaStreamType} is used to identify
+ * media stream such as audio or video.
+ * @param direction {@link ImsCallSessionImplBase.MediaStreamDirection} of this packet
+ * stream (e.g. uplink or downlink).
+ * @param bitsPerSecond This value is the bitrate requested by the other party UE through
+ * RTP CMR, RTCPAPP or TMMBR, and ImsStack converts this value to the MAC bitrate
+ * (defined in TS36.321, range: 0 ~ 8000 kbit/s).
+ * @hide
+ */
+ public final void callSessionSendAnbrQuery(@MediaStreamType int mediaType,
+ @MediaStreamDirection int direction, @IntRange(from = 0) int bitsPerSecond) {
+ Log.d(TAG, "callSessionSendAnbrQuery in imscallsessonListener");
+ try {
+ mListener.callSessionSendAnbrQuery(mediaType, direction, bitsPerSecond);
+ } catch (RemoteException e) {
+ e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
* Set default Executor from ImsService.
* @param executor The default executor to use when executing the methods by the vendor
* implementation of {@link ImsCallSessionImplBase} for conference call.
diff --git a/telephony/java/android/telephony/ims/ImsMmTelManager.java b/telephony/java/android/telephony/ims/ImsMmTelManager.java
index 883824ffc889..caee4e2ca277 100644
--- a/telephony/java/android/telephony/ims/ImsMmTelManager.java
+++ b/telephony/java/android/telephony/ims/ImsMmTelManager.java
@@ -549,7 +549,6 @@ public class ImsMmTelManager implements RegistrationManager {
* <li>The caller has carrier privileges (see
* {@link android.telephony.TelephonyManager#hasCarrierPrivileges}) on any
* active subscription.</li>
- * <li>The caller is the default SMS app for the device.</li>
* </ul>
* <p>The profile owner is an app that owns a managed profile on the device; for more details
* see <a href="https://developer.android.com/work/managed-profiles">Work profiles</a>.
@@ -611,7 +610,6 @@ public class ImsMmTelManager implements RegistrationManager {
* <li>The caller has carrier privileges (see
* {@link android.telephony.TelephonyManager#hasCarrierPrivileges}) on any
* active subscription.</li>
- * <li>The caller is the default SMS app for the device.</li>
* </ul>
* <p>The profile owner is an app that owns a managed profile on the device; for more details
* see <a href="https://developer.android.com/work/managed-profiles">Work profiles</a>.
@@ -659,7 +657,6 @@ public class ImsMmTelManager implements RegistrationManager {
* <li>The caller has carrier privileges (see
* {@link android.telephony.TelephonyManager#hasCarrierPrivileges}) on any
* active subscription.</li>
- * <li>The caller is the default SMS app for the device.</li>
* </ul>
* <p>The profile owner is an app that owns a managed profile on the device; for more details
* see <a href="https://developer.android.com/work/managed-profiles">Work profiles</a>.
@@ -872,7 +869,6 @@ public class ImsMmTelManager implements RegistrationManager {
* <li>The caller has carrier privileges (see
* {@link android.telephony.TelephonyManager#hasCarrierPrivileges}) on any
* active subscription.</li>
- * <li>The caller is the default SMS app for the device.</li>
* </ul>
* <p>The profile owner is an app that owns a managed profile on the device; for more details
* see <a href="https://developer.android.com/work/managed-profiles">Work profiles</a>.
@@ -947,7 +943,6 @@ public class ImsMmTelManager implements RegistrationManager {
* <li>The caller has carrier privileges (see
* {@link android.telephony.TelephonyManager#hasCarrierPrivileges}) on any
* active subscription.</li>
- * <li>The caller is the default SMS app for the device.</li>
* </ul>
* <p>The profile owner is an app that owns a managed profile on the device; for more details
* see <a href="https://developer.android.com/work/managed-profiles">Work profiles</a>.
@@ -1121,7 +1116,6 @@ public class ImsMmTelManager implements RegistrationManager {
* <li>The caller has carrier privileges (see
* {@link android.telephony.TelephonyManager#hasCarrierPrivileges}) on any
* active subscription.</li>
- * <li>The caller is the default SMS app for the device.</li>
* </ul>
* <p>The profile owner is an app that owns a managed profile on the device; for more details
* see <a href="https://developer.android.com/work/managed-profiles">Work profiles</a>.
@@ -1236,7 +1230,6 @@ public class ImsMmTelManager implements RegistrationManager {
* <li>The caller has carrier privileges (see
* {@link android.telephony.TelephonyManager#hasCarrierPrivileges}) on any
* active subscription.</li>
- * <li>The caller is the default SMS app for the device.</li>
* </ul>
* <p>The profile owner is an app that owns a managed profile on the device; for more details
* see <a href="https://developer.android.com/work/managed-profiles">Work profiles</a>.
@@ -1425,7 +1418,6 @@ public class ImsMmTelManager implements RegistrationManager {
* <li>The caller has carrier privileges (see
* {@link android.telephony.TelephonyManager#hasCarrierPrivileges}) on any
* active subscription.</li>
- * <li>The caller is the default SMS app for the device.</li>
* </ul>
* <p>The profile owner is an app that owns a managed profile on the device; for more details
* see <a href="https://developer.android.com/work/managed-profiles">Work profiles</a>.
diff --git a/telephony/java/android/telephony/ims/ImsRcsManager.java b/telephony/java/android/telephony/ims/ImsRcsManager.java
index e00ea0ea4d5e..4439e5c35d83 100644
--- a/telephony/java/android/telephony/ims/ImsRcsManager.java
+++ b/telephony/java/android/telephony/ims/ImsRcsManager.java
@@ -540,6 +540,8 @@ public class ImsRcsManager {
try {
return imsRcsController.isCapable(mSubId, capability, radioTech);
+ } catch (ServiceSpecificException e) {
+ throw new ImsException(e.getMessage(), e.errorCode);
} catch (RemoteException e) {
Log.w(TAG, "Error calling IImsRcsController#isCapable", e);
throw new ImsException("Remote IMS Service is not available",
@@ -577,6 +579,8 @@ public class ImsRcsManager {
try {
return imsRcsController.isAvailable(mSubId, capability, radioTech);
+ } catch (ServiceSpecificException e) {
+ throw new ImsException(e.getMessage(), e.errorCode);
} catch (RemoteException e) {
Log.w(TAG, "Error calling IImsRcsController#isAvailable", e);
throw new ImsException("Remote IMS Service is not available",
diff --git a/telephony/java/android/telephony/ims/ImsRegistrationAttributes.java b/telephony/java/android/telephony/ims/ImsRegistrationAttributes.java
index b77d3063e2cc..50c438c7678e 100644
--- a/telephony/java/android/telephony/ims/ImsRegistrationAttributes.java
+++ b/telephony/java/android/telephony/ims/ImsRegistrationAttributes.java
@@ -65,6 +65,7 @@ public final class ImsRegistrationAttributes implements Parcelable {
public static final class Builder {
private final int mRegistrationTech;
private Set<String> mFeatureTags = Collections.emptySet();
+ private @Nullable SipDetails mSipDetails;
/**
* Build a new instance of {@link ImsRegistrationAttributes}.
@@ -100,13 +101,22 @@ public final class ImsRegistrationAttributes implements Parcelable {
}
/**
+ * Set the SIP information.
+ * @param details The SIP information related to this IMS registration.
+ */
+ public @NonNull Builder setSipDetails(@NonNull SipDetails details) {
+ mSipDetails = details;
+ return this;
+ }
+
+ /**
* @return A new instance created from this builder.
*/
public @NonNull ImsRegistrationAttributes build() {
return new ImsRegistrationAttributes(mRegistrationTech,
RegistrationManager.getAccessType(mRegistrationTech),
getAttributeFlags(mRegistrationTech),
- mFeatureTags);
+ mFeatureTags, mSipDetails);
}
/**
@@ -125,6 +135,28 @@ public final class ImsRegistrationAttributes implements Parcelable {
private final int mTransportType;
private final int mImsAttributeFlags;
private final ArrayList<String> mFeatureTags;
+ private final @Nullable SipDetails mSipDetails;
+ /**
+ * Create a new {@link ImsRegistrationAttributes} instance.
+ * This is for backward compatibility.
+ *
+ * @param registrationTech The technology that IMS has been registered on.
+ * @param transportType The transport type that IMS has been registered on.
+ * @param imsAttributeFlags The attributes associated with the IMS registration.
+ * @param featureTags The feature tags included in the IMS registration.
+ * @hide
+ */
+ public ImsRegistrationAttributes(
+ @ImsRegistrationImplBase.ImsRegistrationTech int registrationTech,
+ @AccessNetworkConstants.TransportType int transportType,
+ @ImsAttributeFlag int imsAttributeFlags,
+ @Nullable Set<String> featureTags) {
+ mRegistrationTech = registrationTech;
+ mTransportType = transportType;
+ mImsAttributeFlags = imsAttributeFlags;
+ mFeatureTags = new ArrayList<>(featureTags);
+ mSipDetails = null;
+ }
/**
* Create a new {@link ImsRegistrationAttributes} instance.
@@ -133,6 +165,7 @@ public final class ImsRegistrationAttributes implements Parcelable {
* @param transportType The transport type that IMS has been registered on.
* @param imsAttributeFlags The attributes associated with the IMS registration.
* @param featureTags The feature tags included in the IMS registration.
+ * @param details The SIP information associated with the IMS registration.
* @see Builder
* @hide
*/
@@ -140,11 +173,13 @@ public final class ImsRegistrationAttributes implements Parcelable {
@ImsRegistrationImplBase.ImsRegistrationTech int registrationTech,
@AccessNetworkConstants.TransportType int transportType,
@ImsAttributeFlag int imsAttributeFlags,
- @Nullable Set<String> featureTags) {
+ @Nullable Set<String> featureTags,
+ @Nullable SipDetails details) {
mRegistrationTech = registrationTech;
mTransportType = transportType;
mImsAttributeFlags = imsAttributeFlags;
mFeatureTags = new ArrayList<>(featureTags);
+ mSipDetails = details;
}
/**@hide*/
@@ -154,6 +189,8 @@ public final class ImsRegistrationAttributes implements Parcelable {
mImsAttributeFlags = source.readInt();
mFeatureTags = new ArrayList<>();
source.readList(mFeatureTags, null /*classloader*/, java.lang.String.class);
+ mSipDetails = source.readParcelable(null /*loader*/,
+ android.telephony.ims.SipDetails.class);
}
/**
@@ -202,6 +239,13 @@ public final class ImsRegistrationAttributes implements Parcelable {
return new ArraySet<>(mFeatureTags);
}
+ /**
+ * @return The SIP information associated with the IMS registration.
+ */
+ public @Nullable SipDetails getSipDetails() {
+ return mSipDetails;
+ }
+
@Override
public int describeContents() {
return 0;
@@ -213,6 +257,7 @@ public final class ImsRegistrationAttributes implements Parcelable {
dest.writeInt(mTransportType);
dest.writeInt(mImsAttributeFlags);
dest.writeList(mFeatureTags);
+ dest.writeParcelable(mSipDetails, flags);
}
public static final @NonNull Creator<ImsRegistrationAttributes> CREATOR =
@@ -236,17 +281,20 @@ public final class ImsRegistrationAttributes implements Parcelable {
return mRegistrationTech == that.mRegistrationTech
&& mTransportType == that.mTransportType
&& mImsAttributeFlags == that.mImsAttributeFlags
- && Objects.equals(mFeatureTags, that.mFeatureTags);
+ && Objects.equals(mFeatureTags, that.mFeatureTags)
+ && Objects.equals(mSipDetails, that.mSipDetails);
}
@Override
public int hashCode() {
- return Objects.hash(mRegistrationTech, mTransportType, mImsAttributeFlags, mFeatureTags);
+ return Objects.hash(mRegistrationTech, mTransportType, mImsAttributeFlags, mFeatureTags,
+ mSipDetails);
}
@Override
public String toString() {
return "ImsRegistrationAttributes { transportType= " + mTransportType + ", attributeFlags="
- + mImsAttributeFlags + ", featureTags=[" + mFeatureTags + "]}";
+ + mImsAttributeFlags + ", featureTags=[" + mFeatureTags + "]"
+ + ",SipDetails=" + mSipDetails + "}";
}
}
diff --git a/telephony/java/android/telephony/ims/ImsService.java b/telephony/java/android/telephony/ims/ImsService.java
index 4477f81a378d..4c37f7d3184c 100644
--- a/telephony/java/android/telephony/ims/ImsService.java
+++ b/telephony/java/android/telephony/ims/ImsService.java
@@ -51,6 +51,7 @@ import com.android.internal.telephony.util.TelephonyUtils;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.Map;
+import java.util.NoSuchElementException;
import java.util.concurrent.CancellationException;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionException;
@@ -138,12 +139,25 @@ public class ImsService extends Service {
public static final long CAPABILITY_SIP_DELEGATE_CREATION = 1 << 1;
/**
+ * This ImsService supports the terminal based call waiting service.
+ * <p>
+ * In order for the IMS service to support the service, IMS service shall
+ * override {@link MmTelFeature#setTerminalBasedCallWaitingStatus}.
+ * If ImsService has this capability, Android platform will handle the synchronization
+ * between the network based call waiting service over circuit-switched networks and the
+ * terminal based call waiting service of IMS service, and will handle the received
+ * circuit-switched waiting calls. Otherwise, this functionality of Android platform shall
+ * be disabled.
+ */
+ public static final long CAPABILITY_TERMINAL_BASED_CALL_WAITING = 1 << 2;
+
+ /**
* 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_SIP_DELEGATE_CREATION);
+ Long.numberOfTrailingZeros(CAPABILITY_TERMINAL_BASED_CALL_WAITING);
/**
* @hide
@@ -154,7 +168,8 @@ public class ImsService extends Service {
// CAPABILITY_EMERGENCY_OVER_MMTEL is not included here because it is managed by
// whether or not ImsFeature.FEATURE_EMERGENCY_MMTEL feature is set and should
// not be set by users of ImsService.
- CAPABILITY_SIP_DELEGATE_CREATION
+ CAPABILITY_SIP_DELEGATE_CREATION,
+ CAPABILITY_TERMINAL_BASED_CALL_WAITING
})
@Retention(RetentionPolicy.SOURCE)
public @interface ImsServiceCapability {}
@@ -186,6 +201,8 @@ public class ImsService extends Service {
new SparseArray<>();
private IImsServiceControllerListener mListener;
+ private final Object mListenerLock = new Object();
+ private final Object mExecutorLock = new Object();
private Executor mExecutor;
/**
@@ -196,10 +213,6 @@ public class ImsService extends Service {
* vendor use Runnable::run.
*/
public ImsService() {
- mExecutor = ImsService.this.getExecutor();
- if (mExecutor == null) {
- mExecutor = Runnable::run;
- }
}
/**
@@ -223,7 +236,30 @@ public class ImsService extends Service {
protected final IBinder mImsServiceController = new IImsServiceController.Stub() {
@Override
public void setListener(IImsServiceControllerListener l) {
- mListener = l;
+ synchronized (mListenerLock) {
+ if (mListener != null && mListener.asBinder().isBinderAlive()) {
+ try {
+ mListener.asBinder().unlinkToDeath(mDeathRecipient, 0);
+ } catch (NoSuchElementException e) {
+ Log.w(LOG_TAG, "IImsServiceControllerListener does not exist");
+ }
+ }
+
+ mListener = l;
+ if (mListener == null) {
+ executeMethodAsync(() -> releaseResource(), "releaseResource");
+ return;
+ }
+
+ try {
+ mListener.asBinder().linkToDeath(mDeathRecipient, 0);
+ Log.i(LOG_TAG, "setListener: register linkToDeath");
+ } catch (RemoteException e) {
+ // RemoteException means target binder process was crashed
+ // release resource
+ executeMethodAsync(() -> releaseResource(), "releaseResource");
+ }
+ }
}
@Override
@@ -315,7 +351,7 @@ public class ImsService extends Service {
ImsConfigImplBase c =
ImsService.this.getConfigForSubscription(slotId, subId);
if (c != null) {
- c.setDefaultExecutor(mExecutor);
+ c.setDefaultExecutor(getCachedExecutor());
return c.getIImsConfig();
} else {
return null;
@@ -329,7 +365,7 @@ public class ImsService extends Service {
ImsRegistrationImplBase r =
ImsService.this.getRegistrationForSubscription(slotId, subId);
if (r != null) {
- r.setDefaultExecutor(mExecutor);
+ r.setDefaultExecutor(getCachedExecutor());
return r.getBinder();
} else {
return null;
@@ -342,7 +378,7 @@ public class ImsService extends Service {
return executeMethodAsyncForResult(() -> {
SipTransportImplBase s = ImsService.this.getSipTransport(slotId);
if (s != null) {
- s.setDefaultExecutor(mExecutor);
+ s.setDefaultExecutor(getCachedExecutor());
return s.getBinder();
} else {
return null;
@@ -362,28 +398,19 @@ public class ImsService extends Service {
ImsService.this.disableImsForSubscription(slotId, subId), "disableIms");
}
- // Call the methods with a clean calling identity on the executor and wait indefinitely for
- // the future to return.
- private void executeMethodAsync(Runnable r, String errorLogName) {
- try {
- CompletableFuture.runAsync(
- () -> TelephonyUtils.runWithCleanCallingIdentity(r), mExecutor).join();
- } catch (CancellationException | CompletionException e) {
- Log.w(LOG_TAG, "ImsService Binder - " + errorLogName + " exception: "
- + e.getMessage());
- }
+ @Override
+ public void resetIms(int slotId, int subId) {
+ executeMethodAsync(() ->
+ ImsService.this.resetImsInternal(slotId, subId), "resetIms");
}
+ };
- private <T> T executeMethodAsyncForResult(Supplier<T> r, String errorLogName) {
- CompletableFuture<T> future = CompletableFuture.supplyAsync(
- () -> TelephonyUtils.runWithCleanCallingIdentity(r), mExecutor);
- try {
- return future.get();
- } catch (ExecutionException | InterruptedException e) {
- Log.w(LOG_TAG, "ImsService Binder - " + errorLogName + " exception: "
- + e.getMessage());
- return null;
- }
+ private final IBinder.DeathRecipient mDeathRecipient = new IBinder.DeathRecipient() {
+ @Override
+ public void binderDied() {
+ Log.w(LOG_TAG,
+ "IImsServiceControllerListener binder to framework has died. Cleaning up");
+ executeMethodAsync(() -> releaseResource(), "releaseResource");
}
};
@@ -399,11 +426,21 @@ public class ImsService extends Service {
return null;
}
+ private Executor getCachedExecutor() {
+ synchronized (mExecutorLock) {
+ if (mExecutor == null) {
+ Executor e = ImsService.this.getExecutor();
+ mExecutor = (e != null) ? e : Runnable::run;
+ }
+ return mExecutor;
+ }
+ }
+
private IImsMmTelFeature createMmTelFeatureInternal(int slotId, int subscriptionId) {
MmTelFeature f = createMmTelFeatureForSubscription(slotId, subscriptionId);
if (f != null) {
setupFeature(f, slotId, ImsFeature.FEATURE_MMTEL);
- f.setDefaultExecutor(mExecutor);
+ f.setDefaultExecutor(getCachedExecutor());
return f.getBinder();
} else {
Log.e(LOG_TAG, "createMmTelFeatureInternal: null feature returned.");
@@ -415,7 +452,7 @@ public class ImsService extends Service {
MmTelFeature f = createEmergencyOnlyMmTelFeature(slotId);
if (f != null) {
setupFeature(f, slotId, ImsFeature.FEATURE_MMTEL);
- f.setDefaultExecutor(mExecutor);
+ f.setDefaultExecutor(getCachedExecutor());
return f.getBinder();
} else {
Log.e(LOG_TAG, "createEmergencyOnlyMmTelFeatureInternal: null feature returned.");
@@ -426,7 +463,7 @@ public class ImsService extends Service {
private IImsRcsFeature createRcsFeatureInternal(int slotId, int subId) {
RcsFeature f = createRcsFeatureForSubscription(slotId, subId);
if (f != null) {
- f.setDefaultExecutor(mExecutor);
+ f.setDefaultExecutor(getCachedExecutor());
setupFeature(f, slotId, ImsFeature.FEATURE_RCS);
return f.getBinder();
} else {
@@ -488,6 +525,9 @@ public class ImsService extends Service {
}
private void removeImsFeature(int slotId, int featureType) {
+ // clear cached data
+ notifySubscriptionRemoved(slotId);
+
synchronized (mFeaturesBySlot) {
// get ImsFeature associated with the slot/feature
SparseArray<ImsFeature> features = mFeaturesBySlot.get(slotId);
@@ -505,7 +545,6 @@ public class ImsService extends Service {
f.onFeatureRemoved();
features.remove(featureType);
}
-
}
/**
@@ -550,6 +589,63 @@ public class ImsService extends Service {
return createFlag;
}
+ private void releaseResource() {
+ Log.w(LOG_TAG, "cleaning up features");
+ synchronized (mFeaturesBySlot) {
+ SparseArray<ImsFeature> features;
+ ImsFeature imsFeature;
+
+ for (int i = 0; i < mFeaturesBySlot.size(); i++) {
+ features = mFeaturesBySlot.valueAt(i);
+ if (features == null) {
+ continue;
+ }
+
+ for (int index = 0; index < features.size(); index++) {
+ imsFeature = features.valueAt(index);
+ if (imsFeature != null) {
+ imsFeature.onFeatureRemoved();
+ }
+ }
+ features.clear();
+ }
+ mFeaturesBySlot.clear();
+ }
+ }
+
+ // Call the methods with a clean calling identity on the executor and wait indefinitely for
+ // the future to return.
+ private void executeMethodAsync(Runnable r, String errorLogName) {
+ try {
+ CompletableFuture.runAsync(
+ () -> TelephonyUtils.runWithCleanCallingIdentity(r),
+ getCachedExecutor()).join();
+ } catch (CancellationException | CompletionException e) {
+ Log.w(LOG_TAG, "ImsService Binder - " + errorLogName + " exception: "
+ + e.getMessage());
+ }
+ }
+
+ private <T> T executeMethodAsyncForResult(Supplier<T> r, String errorLogName) {
+ CompletableFuture<T> future = CompletableFuture.supplyAsync(
+ () -> TelephonyUtils.runWithCleanCallingIdentity(r), getCachedExecutor());
+ try {
+ return future.get();
+ } catch (ExecutionException | InterruptedException e) {
+ Log.w(LOG_TAG, "ImsService Binder - " + errorLogName + " exception: "
+ + e.getMessage());
+ return null;
+ }
+ }
+
+ private void resetImsInternal(int slotId, int subId) {
+ try {
+ resetIms(slotId);
+ } catch (UnsupportedOperationException e) {
+ disableImsForSubscription(slotId, subId);
+ }
+ }
+
/**
* When called, provide the {@link ImsFeatureConfiguration} that this {@link ImsService}
* currently supports. This will trigger the framework to set up the {@link ImsFeature}s that
@@ -572,10 +668,14 @@ public class ImsService extends Service {
*/
public final void onUpdateSupportedImsFeatures(ImsFeatureConfiguration c)
throws RemoteException {
- if (mListener == null) {
- throw new IllegalStateException("Framework is not ready");
+ IImsServiceControllerListener l;
+ synchronized (mListenerLock) {
+ if (mListener == null) {
+ throw new IllegalStateException("Framework is not ready");
+ }
+ l = mListener;
}
- mListener.onUpdateSupportedImsFeatures(c);
+ l.onUpdateSupportedImsFeatures(c);
}
/**
@@ -627,6 +727,24 @@ public class ImsService extends Service {
}
/**
+ * The subscription has removed. The ImsService should notify ImsRegistrationImplBase and
+ * ImsConfigImplBase the SIM state was changed.
+ * @param slotId The slot ID which has removed.
+ */
+ private void notifySubscriptionRemoved(int slotId) {
+ ImsRegistrationImplBase registrationImplBase =
+ getRegistration(slotId);
+ if (registrationImplBase != null) {
+ registrationImplBase.clearRegistrationCache();
+ }
+
+ ImsConfigImplBase imsConfigImplBase = getConfig(slotId);
+ if (imsConfigImplBase != null) {
+ imsConfigImplBase.clearConfigurationCache();
+ }
+ }
+
+ /**
* The framework has enabled IMS for the slot specified, the ImsService should register for IMS
* and perform all appropriate initialization to bring up all ImsFeatures.
* @deprecated Use {@link #enableImsForSubscription} instead.
@@ -645,6 +763,19 @@ public class ImsService extends Service {
}
/**
+ * The framework has reset IMS for the slot specified. The ImsService must deregister
+ * and release all resources for IMS. After resetIms is called, either
+ * {@link #enableImsForSubscription(int, int)} or {@link #disableImsForSubscription(int, int)}
+ * will be called for the same slotId.
+ *
+ * @param slotId The slot ID that IMS will be reset for.
+ * @hide
+ */
+ public void resetIms(int slotId) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
* When called, the framework is requesting that a new {@link MmTelFeature} is created for the
* specified subscription.
*
diff --git a/telephony/java/android/telephony/ims/MediaQualityStatus.aidl b/telephony/java/android/telephony/ims/MediaQualityStatus.aidl
new file mode 100644
index 000000000000..e570f6c906c3
--- /dev/null
+++ b/telephony/java/android/telephony/ims/MediaQualityStatus.aidl
@@ -0,0 +1,19 @@
+/*
+ * Copyright (c) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.telephony.ims;
+
+parcelable MediaQualityStatus; \ No newline at end of file
diff --git a/telephony/java/android/telephony/ims/MediaQualityStatus.java b/telephony/java/android/telephony/ims/MediaQualityStatus.java
new file mode 100644
index 000000000000..76394feaed66
--- /dev/null
+++ b/telephony/java/android/telephony/ims/MediaQualityStatus.java
@@ -0,0 +1,203 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.telephony.ims;
+
+import android.annotation.IntDef;
+import android.annotation.IntRange;
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.telephony.AccessNetworkConstants.TransportType;
+
+import java.util.Objects;
+
+/**
+ * A representation of Media quality status.
+ *
+ * @hide
+ */
+@SystemApi
+public final class MediaQualityStatus implements Parcelable {
+ public static final int MEDIA_SESSION_TYPE_AUDIO = 1;
+ public static final int MEDIA_SESSION_TYPE_VIDEO = 2;
+
+ private final String mImsCallSessionId;
+ private final int mMediaSessionType;
+ private final int mTransportType;
+ private final int mRtpPacketLossRate;
+ private final int mRtpJitterMillis;
+ private final long mRtpInactivityTimeMillis;
+
+ /** @hide */
+ @IntDef(
+ value = {
+ MEDIA_SESSION_TYPE_AUDIO,
+ MEDIA_SESSION_TYPE_VIDEO,
+ })
+ public @interface MediaSessionType {}
+
+ /**
+ * The constructor for MediaQualityStatus, which represents the media quality for each session
+ * type ({@link #MEDIA_SESSION_TYPE_AUDIO} or {@link #MEDIA_SESSION_TYPE_VIDEO}) of the IMS call
+ *
+ * @param imsCallSessionId IMS call session id of this quality status
+ * @param mediaSessionType media session type of this quality status
+ * @param transportType transport type of this quality status
+ * @param rtpPacketLossRate measured RTP packet loss rate in percentage
+ * @param rtpJitterMillis measured RTP jitter(RFC3550) in milliseconds
+ * @param rptInactivityTimeMillis measured RTP inactivity time in milliseconds
+ */
+ public MediaQualityStatus(@NonNull String imsCallSessionId,
+ @MediaSessionType int mediaSessionType, @TransportType int transportType,
+ @IntRange(from = 0, to = 100) int rtpPacketLossRate,
+ @IntRange(from = 0) int rtpJitterMillis,
+ @IntRange(from = 0) long rptInactivityTimeMillis) {
+ mImsCallSessionId = imsCallSessionId;
+ mMediaSessionType = mediaSessionType;
+ mTransportType = transportType;
+ mRtpPacketLossRate = rtpPacketLossRate;
+ mRtpJitterMillis = rtpJitterMillis;
+ mRtpInactivityTimeMillis = rptInactivityTimeMillis;
+ }
+
+ /**
+ * Retrieves call session ID for this quality status
+ */
+ @NonNull
+ public String getCallSessionId() {
+ return mImsCallSessionId;
+ }
+
+ /**
+ * Retrieves media session type of this quality status
+ */
+ public @MediaSessionType int getMediaSessionType() {
+ return mMediaSessionType;
+ }
+
+
+ /**
+ * Retrieves Transport type for which this media quality was measured.
+ */
+ public @TransportType int getTransportType() {
+ return mTransportType;
+ }
+
+ /**
+ * Retrieves measured RTP packet loss rate in percentage.
+ */
+ @IntRange(from = 0, to = 100)
+ public int getRtpPacketLossRate() {
+ return mRtpPacketLossRate;
+ }
+
+ /**
+ * Retrieves measured RTP jitter(RFC3550) value in milliseconds
+ */
+ @IntRange(from = 0)
+ public int getRtpJitterMillis() {
+ return mRtpJitterMillis;
+ }
+
+ /**
+ * Retrieves measured RTP inactivity time in milliseconds
+ */
+ @IntRange(from = 0)
+ public long getRtpInactivityMillis() {
+ return mRtpInactivityTimeMillis;
+ }
+
+ /**
+ * Creates a new instance of {@link MediaQualityStatus} from a parcel.
+ * @param in The parceled data to read.
+ */
+ private MediaQualityStatus(@NonNull Parcel in) {
+ mImsCallSessionId = in.readString();
+ mMediaSessionType = in.readInt();
+ mTransportType = in.readInt();
+ mRtpPacketLossRate = in.readInt();
+ mRtpJitterMillis = in.readInt();
+ mRtpInactivityTimeMillis = in.readLong();
+ }
+
+ @Override
+ public void writeToParcel(@NonNull Parcel dest, int flags) {
+ dest.writeString(mImsCallSessionId);
+ dest.writeInt(mMediaSessionType);
+ dest.writeInt(mTransportType);
+ dest.writeInt(mRtpPacketLossRate);
+ dest.writeInt(mRtpJitterMillis);
+ dest.writeLong(mRtpInactivityTimeMillis);
+ }
+
+ public static final @NonNull Creator<MediaQualityStatus> CREATOR =
+ new Creator<MediaQualityStatus>() {
+ @Override
+ public MediaQualityStatus createFromParcel(@NonNull Parcel in) {
+ return new MediaQualityStatus(in);
+ }
+
+ @Override
+ public MediaQualityStatus[] newArray(int size) {
+ return new MediaQualityStatus[size];
+ }
+ };
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ MediaQualityStatus that = (MediaQualityStatus) o;
+ return mImsCallSessionId != null && mImsCallSessionId.equals(that.mImsCallSessionId)
+ && mMediaSessionType == that.mMediaSessionType
+ && mTransportType == that.mTransportType
+ && mRtpPacketLossRate == that.mRtpPacketLossRate
+ && mRtpJitterMillis == that.mRtpJitterMillis
+ && mRtpInactivityTimeMillis == that.mRtpInactivityTimeMillis;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(mImsCallSessionId, mMediaSessionType, mTransportType,
+ mRtpPacketLossRate, mRtpJitterMillis, mRtpInactivityTimeMillis);
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder();
+ sb.append("MediaThreshold{mImsCallSessionId=");
+ sb.append(mImsCallSessionId);
+ sb.append(", mMediaSessionType=");
+ sb.append(mMediaSessionType);
+ sb.append(", mTransportType=");
+ sb.append(mTransportType);
+ sb.append(", mRtpPacketLossRate=");
+ sb.append(mRtpPacketLossRate);
+ sb.append(", mRtpJitterMillis=");
+ sb.append(mRtpJitterMillis);
+ sb.append(", mRtpInactivityTimeMillis=");
+ sb.append(mRtpInactivityTimeMillis);
+ sb.append("}");
+ return sb.toString();
+ }
+}
diff --git a/telephony/java/android/telephony/ims/MediaThreshold.aidl b/telephony/java/android/telephony/ims/MediaThreshold.aidl
new file mode 100644
index 000000000000..dede418fb0e2
--- /dev/null
+++ b/telephony/java/android/telephony/ims/MediaThreshold.aidl
@@ -0,0 +1,19 @@
+/*
+ * Copyright (c) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.telephony.ims;
+
+parcelable MediaThreshold; \ No newline at end of file
diff --git a/telephony/java/android/telephony/ims/MediaThreshold.java b/telephony/java/android/telephony/ims/MediaThreshold.java
new file mode 100644
index 000000000000..343aa4aab023
--- /dev/null
+++ b/telephony/java/android/telephony/ims/MediaThreshold.java
@@ -0,0 +1,333 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.telephony.ims;
+
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.telephony.ims.feature.MmTelFeature;
+
+import java.util.Arrays;
+import java.util.Objects;
+import java.util.TreeSet;
+
+/**
+ * A MediaThreshold represents a series of packet loss rate, jitter and rtp inactivity time
+ * thresholds which when crossed should result in a {@link MediaQualityStatus} report being
+ * generated by the {@link ImsService} via {@link MmTelFeature#notifyMediaQualityStatusChanged(
+ * MediaQualityStatus)}
+ *
+ * <p/>
+ * A {@link MediaQualityStatus} should be triggered when any of various
+ * attributes pass one of the thresholds defined here.
+ *
+ * @hide
+ */
+@SystemApi
+public final class MediaThreshold implements Parcelable {
+ private final int[] mRtpPacketLossRate;
+ private final int[] mRtpJitter;
+ private final long[] mRtpInactivityTimeMillis;
+
+ /**
+ * Retrieves threshold values for RTP packet loss rate in percentage.
+ *
+ * @return int array including threshold values for packet loss rate
+ *
+ * @hide
+ */
+ @NonNull
+ @SystemApi
+ public int[] getThresholdsRtpPacketLossRate() {
+ return mRtpPacketLossRate;
+ }
+
+ /**
+ * Retrieves threshold values for jitter(RFC3550) in milliseconds.
+ *
+ * @return int array including threshold values for RTP jitter.
+ */
+ @NonNull
+ public int[] getThresholdsRtpJitterMillis() {
+ return mRtpJitter;
+ }
+
+ /**
+ * Retrieves threshold values for RTP inactivity time in milliseconds.
+ *
+ * @return int array including threshold values for RTP inactivity time.
+ */
+ @NonNull
+ public long[] getThresholdsRtpInactivityTimeMillis() {
+ return mRtpInactivityTimeMillis;
+ }
+
+ private MediaThreshold(
+ int[] packetLossRateThresholds,
+ int[] jitterThresholds,
+ long[] inactivityTimeThresholds) {
+ mRtpPacketLossRate = packetLossRateThresholds;
+ mRtpJitter = jitterThresholds;
+ mRtpInactivityTimeMillis = inactivityTimeThresholds;
+ }
+
+ /**
+ * Creates a new instance of {@link MediaThreshold} from a parcel.
+ * @param in The parceled data to read.
+ */
+ private MediaThreshold(@NonNull Parcel in) {
+ mRtpPacketLossRate = in.createIntArray();
+ mRtpJitter = in.createIntArray();
+ mRtpInactivityTimeMillis = in.createLongArray();
+ }
+
+ @Override
+ public void writeToParcel(@NonNull Parcel dest, int flags) {
+ dest.writeIntArray(mRtpPacketLossRate);
+ dest.writeIntArray(mRtpJitter);
+ dest.writeLongArray(mRtpInactivityTimeMillis);
+ }
+
+ public static final @NonNull Creator<MediaThreshold> CREATOR =
+ new Creator<MediaThreshold>() {
+ @Override
+ public MediaThreshold createFromParcel(@NonNull Parcel in) {
+ return new MediaThreshold(in);
+ }
+
+ @Override
+ public MediaThreshold[] newArray(int size) {
+ return new MediaThreshold[size];
+ }
+ };
+
+ /**
+ * Returns whether the RTP packet loss rate threshold is valid or not.
+ *
+ * @param packetLossRate packet loss rate
+ * @return the threshold is valid or not.
+ * @hide
+ */
+ public static boolean isValidRtpPacketLossRate(int packetLossRate) {
+ return (packetLossRate >= 0 && packetLossRate <= 100);
+ }
+
+ /**
+ * Returns whether the RTP jitter threshold is valid or not.
+ *
+ * @param jitter jitter value in milliseconds
+ * @return the threshold is valid or not.
+ * @hide
+ */
+ public static boolean isValidJitterMillis(int jitter) {
+ return (jitter >= 0 && jitter <= 10000);
+ }
+
+ /**
+ * Returns whether the RTP packet loss rate threshold is valid or not.
+ *
+ * @param inactivityTime packet loss rate
+ * @return the threshold is valid or not.
+ * @hide
+ */
+ public static boolean isValidRtpInactivityTimeMillis(long inactivityTime) {
+ return (inactivityTime >= 0 && inactivityTime <= 60000);
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ MediaThreshold that = (MediaThreshold) o;
+ return Arrays.equals(mRtpPacketLossRate, that.mRtpPacketLossRate)
+ && Arrays.equals(mRtpJitter, that.mRtpJitter)
+ && Arrays.equals(mRtpInactivityTimeMillis, that.mRtpInactivityTimeMillis);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(Arrays.hashCode(mRtpPacketLossRate), Arrays.hashCode(mRtpJitter),
+ Arrays.hashCode(mRtpInactivityTimeMillis));
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder();
+ sb.append("MediaThreshold{mRtpPacketLossRate=");
+ for (int i : mRtpPacketLossRate) {
+ sb.append(" ").append(i);
+ }
+ sb.append(", mRtpJitter=");
+ for (int b : mRtpJitter) {
+ sb.append(" ").append(b);
+ }
+ sb.append(", mRtpInactivityTimeMillis=");
+ for (long i : mRtpInactivityTimeMillis) {
+ sb.append(" ").append(i);
+ }
+ sb.append("}");
+ return sb.toString();
+ }
+
+ /**
+ * Provides a convenient way to set the fields of an {@link MediaThreshold} when creating a
+ * new instance.
+ *
+ * <p>The example below shows how you might create a new {@code RtpThreshold}:
+ *
+ * <pre><code>
+ *
+ * RtpThreshold = new RtpThreshold.Builder()
+ * .setRtpSessionType({@link MediaQualityStatus#MEDIA_SESSION_TYPE_AUDIO} or
+ * {@link MediaQualityStatus#MEDIA_SESSION_TYPE_VIDEO})
+ * .setThresholdsRtpPacketLossRate(int[] packetLossRateThresholds)
+ * .setThresholdsRtpJitterMillis(int[] jitterThresholds)
+ * .setThresholdsRtpInactivityTimeMillis(int[] inactivityTimeThresholds)
+ * .build();
+ * </code></pre>
+ *
+ * @hide
+ */
+ public static final class Builder {
+ private int[] mRtpPacketLossRate = null;
+ private int[] mRtpJitter = null;
+ private long[] mRtpInactivityTimeMillis = null;
+
+ /**
+ * Default constructor for the Builder.
+ *
+ * @hide
+ */
+ public Builder() {
+ }
+
+ /**
+ * Set threshold values for RTP packet loss rate in percentage.
+ * <p/>
+ * The packet loss calculation should be done at least once per
+ * second. It should be calculated with at least the last 3 seconds
+ * of data.
+ *
+ * @param packetLossRateThresholds int array for threshold values.
+ * @return The same instance of the builder.
+ *
+ * @hide
+ */
+ @NonNull
+ public Builder setThresholdsRtpPacketLossRate(int[] packetLossRateThresholds) {
+ if (packetLossRateThresholds.length > 0) {
+ TreeSet<Integer> thresholds = new TreeSet<>();
+ for (Integer value : packetLossRateThresholds) {
+ if (isValidRtpPacketLossRate(value)) {
+ thresholds.add(value);
+ }
+ }
+ int[] targetArray = new int[thresholds.size()];
+ int i = 0;
+ for (int element : thresholds) {
+ targetArray[i++] = element;
+ }
+ this.mRtpPacketLossRate = targetArray;
+ } else {
+ this.mRtpPacketLossRate = packetLossRateThresholds;
+ }
+ return this;
+ }
+
+
+ /**
+ * Set threshold values for RTP jitter in Milliseconds.
+ *
+ * @param jitterThresholds int array including threshold values for Jitter.
+ * @return The same instance of the builder.
+ *
+ * @hide
+ */
+ @NonNull
+ public Builder setThresholdsRtpJitterMillis(int[] jitterThresholds) {
+ if (jitterThresholds.length > 0) {
+ TreeSet<Integer> thresholds = new TreeSet<>();
+ for (Integer value : jitterThresholds) {
+ if (isValidJitterMillis(value)) {
+ thresholds.add(value);
+ }
+ }
+ int[] targetArray = new int[thresholds.size()];
+ int i = 0;
+ for (int element : thresholds) {
+ targetArray[i++] = element;
+ }
+ this.mRtpJitter = targetArray;
+ } else {
+ this.mRtpJitter = jitterThresholds;
+ }
+ return this;
+ }
+
+ /**
+ * Set threshold values for RTP inactivity time.
+ *
+ * @param inactivityTimeThresholds int array including threshold
+ * values for RTP inactivity time.
+ * @return The same instance of the builder.
+ *
+ * @hide
+ */
+ @NonNull
+ public Builder setThresholdsRtpInactivityTimeMillis(long[] inactivityTimeThresholds) {
+ if (inactivityTimeThresholds.length > 0) {
+ TreeSet<Long> thresholds = new TreeSet<>();
+ for (Long value : inactivityTimeThresholds) {
+ if (isValidRtpInactivityTimeMillis(value)) {
+ thresholds.add(value);
+ }
+ }
+ long[] targetArray = new long[thresholds.size()];
+ int i = 0;
+ for (long element : thresholds) {
+ targetArray[i++] = element;
+ }
+ this.mRtpInactivityTimeMillis = targetArray;
+ } else {
+ this.mRtpInactivityTimeMillis = inactivityTimeThresholds;
+ }
+ return this;
+ }
+
+ /**
+ * Build the {@link MediaThreshold}
+ *
+ * @return the {@link MediaThreshold} object
+ *
+ * @hide
+ */
+ @NonNull
+ public MediaThreshold build() {
+ mRtpPacketLossRate = mRtpPacketLossRate != null ? mRtpPacketLossRate : new int[0];
+ mRtpJitter = mRtpJitter != null ? mRtpJitter : new int[0];
+ mRtpInactivityTimeMillis =
+ mRtpInactivityTimeMillis != null ? mRtpInactivityTimeMillis : new long[0];
+ return new MediaThreshold(mRtpPacketLossRate, mRtpJitter, mRtpInactivityTimeMillis);
+ }
+ }
+}
diff --git a/telephony/java/android/telephony/ims/ProvisioningManager.java b/telephony/java/android/telephony/ims/ProvisioningManager.java
index 945b0850d25e..37a6a7ebf953 100644
--- a/telephony/java/android/telephony/ims/ProvisioningManager.java
+++ b/telephony/java/android/telephony/ims/ProvisioningManager.java
@@ -54,6 +54,9 @@ import java.util.concurrent.Executor;
* IMS provisioning keys are defined per carrier or OEM using OMA-DM or other provisioning
* applications and may vary. It is up to the carrier and OEM applications to ensure that the
* correct provisioning keys are being used when integrating with a vendor's ImsService.
+ *
+ * Use {@link android.telephony.ims.ImsManager#getProvisioningManager(int)} to get an instance of
+ * this manager.
*/
@RequiresFeature(PackageManager.FEATURE_TELEPHONY_IMS)
public class ProvisioningManager {
@@ -1685,7 +1688,8 @@ public class ProvisioningManager {
/**
* Notify the framework that an RCS autoconfiguration XML file has been received for
- * provisioning.
+ * provisioning. This API is only valid if the device supports IMS, which can be checked using
+ * {@link PackageManager#hasSystemFeature}.
*
* <p>Requires Permission:
* <ul>
@@ -1923,7 +1927,8 @@ public class ProvisioningManager {
/**
* Reconfiguration triggered by the RCS application. Most likely cause
- * is the 403 forbidden to a HTTP request.
+ * is the 403 forbidden to a HTTP request. This API is only valid if the device supports IMS,
+ * which can be checked using {@link PackageManager#hasSystemFeature}
*
* <p>When this api is called, the RCS configuration for the associated
* subscription will be removed, and the application which has registered
diff --git a/telephony/java/android/telephony/ims/PublishAttributes.aidl b/telephony/java/android/telephony/ims/PublishAttributes.aidl
new file mode 100644
index 000000000000..c569cd75eadd
--- /dev/null
+++ b/telephony/java/android/telephony/ims/PublishAttributes.aidl
@@ -0,0 +1,19 @@
+/*
+ * Copyright (c) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.telephony.ims;
+
+parcelable PublishAttributes;
diff --git a/telephony/java/android/telephony/ims/PublishAttributes.java b/telephony/java/android/telephony/ims/PublishAttributes.java
new file mode 100644
index 000000000000..b987f1cb562d
--- /dev/null
+++ b/telephony/java/android/telephony/ims/PublishAttributes.java
@@ -0,0 +1,186 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.telephony.ims;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SystemApi;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.telephony.ims.RcsUceAdapter.PublishState;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Objects;
+
+/**
+ * This class provides detailed information related to publish state, SIP information and
+ * presence tuples in publication.
+ * This allows the application can check the detailed information of publication.
+ * @hide
+ */
+@SystemApi
+public final class PublishAttributes implements Parcelable {
+
+ private final @PublishState int mPublishState;
+ private List<RcsContactPresenceTuple> mPresenceTuples;
+ private @Nullable SipDetails mSipDetails;
+
+ /**
+ * Builder for creating {@link Builder} instances.
+ * @hide
+ */
+ public static final class Builder {
+ private PublishAttributes mAttributes;
+ /**
+ * Build a new instance of {@link PublishAttributes}.
+ *
+ * @param publishState The current publication state {@link RcsUceAdapter.PublishState}.
+ */
+ public Builder(@PublishState int publishState) {
+ mAttributes = new PublishAttributes(publishState);
+ }
+
+ /**
+ * Sets the SIP information in received response to a publish operation.
+ * @param details The {@link SipDetails} in received response.
+ * @return The same instance of the builder.
+ */
+ public @NonNull Builder setSipDetails(@Nullable SipDetails details) {
+ mAttributes.mSipDetails = details;
+ return this;
+ }
+
+ /**
+ * The tuple elements associated with the presence element portion of the PIDF document
+ * successfully sent to the network.
+ * @param tuples The list of the {@link RcsContactPresenceTuple} sent to the server.
+ * The contact URI should not be included in this tuples.
+ * @return this The same instance of the builder.
+ */
+ public @NonNull Builder setPresenceTuples(@NonNull List<RcsContactPresenceTuple> tuples) {
+ mAttributes.mPresenceTuples = tuples;
+ return this;
+ }
+
+ /**
+ * @return a new PublishAttributes from this Builder.
+ */
+ public @NonNull PublishAttributes build() {
+ return mAttributes;
+ }
+ }
+
+ /**
+ * Generate the attributes related to the publication.
+ *
+ * @param publishState The current publication state.
+ * See {@link RcsUceAdapter.PublishState}.
+ */
+ private PublishAttributes(@PublishState int publishState) {
+ mPublishState = publishState;
+ }
+
+ /**
+ * Get the current publication state when the publishing state has changed or
+ * the publishing operation has done.
+ * @return The current publication state. See {@link RcsUceAdapter.PublishState}.
+ */
+ public @PublishState int getPublishState() {
+ return mPublishState;
+ }
+
+ /**
+ * Get the presence tuples from the PIDF on which the publishing was successful.
+ * @return The list of the {@link RcsContactPresenceTuple} sent to the server. If publish is
+ * not successful yet, the value is empty.
+ */
+ public @NonNull List<RcsContactPresenceTuple> getPresenceTuples() {
+ if (mPresenceTuples == null) {
+ return Collections.emptyList();
+ }
+ return mPresenceTuples;
+ }
+
+ /**
+ * Get the SipDetails set in ImsService.
+ * @return The {@link SipDetails} received in response. This value may be null if
+ * the device doesn't support the collection of this information.
+ */
+ public @Nullable SipDetails getSipDetails() {
+ return mSipDetails;
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(@NonNull Parcel dest, int flags) {
+ dest.writeInt(mPublishState);
+ dest.writeList(mPresenceTuples);
+ dest.writeParcelable(mSipDetails, 0);
+ }
+
+ public static final @NonNull Creator<PublishAttributes> CREATOR =
+ new Creator<PublishAttributes>() {
+ @Override
+ public PublishAttributes createFromParcel(Parcel source) {
+ return new PublishAttributes(source);
+ }
+
+ @Override
+ public PublishAttributes[] newArray(int size) {
+ return new PublishAttributes[size];
+ }
+ };
+
+ /**
+ * Construct a PublishAttributes object from the given parcel.
+ */
+ private PublishAttributes(Parcel in) {
+ mPublishState = in.readInt();
+ mPresenceTuples = new ArrayList<>();
+ in.readList(mPresenceTuples, null, RcsContactPresenceTuple.class);
+ mSipDetails = in.readParcelable(SipDetails.class.getClassLoader(),
+ android.telephony.ims.SipDetails.class);
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ PublishAttributes that = (PublishAttributes) o;
+ return mPublishState == that.mPublishState
+ && Objects.equals(mPresenceTuples, that.mPresenceTuples)
+ && Objects.equals(mSipDetails, that.mSipDetails);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(mPublishState, mPresenceTuples, mSipDetails);
+ }
+
+ @Override
+ public String toString() {
+ return "PublishAttributes { publishState= " + mPublishState
+ + ", presenceTuples=[" + mPresenceTuples + "]" + "SipDetails=" + mSipDetails + "}";
+ }
+}
+
diff --git a/telephony/java/android/telephony/ims/RcsConfig.java b/telephony/java/android/telephony/ims/RcsConfig.java
index fd8d8a76353b..32d686d4e28c 100644
--- a/telephony/java/android/telephony/ims/RcsConfig.java
+++ b/telephony/java/android/telephony/ims/RcsConfig.java
@@ -36,6 +36,7 @@ import org.xmlpull.v1.XmlPullParserFactory;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
+import java.util.Locale;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
@@ -188,16 +189,17 @@ public final class RcsConfig {
String tag = null;
while (eventType != XmlPullParser.END_DOCUMENT && current != null) {
if (eventType == XmlPullParser.START_TAG) {
- tag = xpp.getName().trim().toLowerCase();
+ tag = xpp.getName().trim().toLowerCase(Locale.ROOT);
if (TAG_CHARACTERISTIC.equals(tag)) {
int count = xpp.getAttributeCount();
String type = null;
if (count > 0) {
for (int i = 0; i < count; i++) {
- String name = xpp.getAttributeName(i).trim().toLowerCase();
+ String name = xpp.getAttributeName(i).trim()
+ .toLowerCase(Locale.ROOT);
if (ATTRIBUTE_TYPE.equals(name)) {
type = xpp.getAttributeValue(xpp.getAttributeNamespace(i),
- name).trim().toLowerCase();
+ name).trim().toLowerCase(Locale.ROOT);
break;
}
}
@@ -211,10 +213,11 @@ public final class RcsConfig {
String value = null;
if (count > 1) {
for (int i = 0; i < count; i++) {
- String name = xpp.getAttributeName(i).trim().toLowerCase();
+ String name = xpp.getAttributeName(i).trim()
+ .toLowerCase(Locale.ROOT);
if (ATTRIBUTE_NAME.equals(name)) {
key = xpp.getAttributeValue(xpp.getAttributeNamespace(i),
- name).trim().toLowerCase();
+ name).trim().toLowerCase(Locale.ROOT);
} else if (ATTRIBUTE_VALUE.equals(name)) {
value = xpp.getAttributeValue(xpp.getAttributeNamespace(i),
name).trim();
@@ -226,7 +229,7 @@ public final class RcsConfig {
}
}
} else if (eventType == XmlPullParser.END_TAG) {
- tag = xpp.getName().trim().toLowerCase();
+ tag = xpp.getName().trim().toLowerCase(Locale.ROOT);
if (TAG_CHARACTERISTIC.equals(tag)) {
current = current.getParent();
}
@@ -254,7 +257,7 @@ public final class RcsConfig {
* @return Returns the config value if it exists, or defaultVal.
*/
public @Nullable String getString(@NonNull String tag, @Nullable String defaultVal) {
- String value = mCurrent.getParmValue(tag.trim().toLowerCase());
+ String value = mCurrent.getParmValue(tag.trim().toLowerCase(Locale.ROOT));
return value != null ? value : defaultVal;
}
@@ -296,21 +299,21 @@ public final class RcsConfig {
* @return Returns true if it exists, or false.
*/
public boolean hasConfig(@NonNull String tag) {
- return mCurrent.hasParm(tag.trim().toLowerCase());
+ return mCurrent.hasParm(tag.trim().toLowerCase(Locale.ROOT));
}
/**
* Return the Characteristic with the given type
*/
public @Nullable Characteristic getCharacteristic(@NonNull String type) {
- return mCurrent.getSubByType(type.trim().toLowerCase());
+ return mCurrent.getSubByType(type.trim().toLowerCase(Locale.ROOT));
}
/**
* Check whether the Characteristic with the given type exists
*/
public boolean hasCharacteristic(@NonNull String type) {
- return mCurrent.getSubByType(type.trim().toLowerCase()) != null;
+ return mCurrent.getSubByType(type.trim().toLowerCase(Locale.ROOT)) != null;
}
/**
diff --git a/telephony/java/android/telephony/ims/RcsUceAdapter.java b/telephony/java/android/telephony/ims/RcsUceAdapter.java
index 91dc38ff9ddb..3bb9be0252cd 100644
--- a/telephony/java/android/telephony/ims/RcsUceAdapter.java
+++ b/telephony/java/android/telephony/ims/RcsUceAdapter.java
@@ -20,6 +20,7 @@ import android.Manifest;
import android.annotation.CallbackExecutor;
import android.annotation.IntDef;
import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.annotation.RequiresPermission;
import android.annotation.SystemApi;
import android.content.Context;
@@ -382,8 +383,21 @@ public class RcsUceAdapter {
/**
* Notifies the callback when the publish state has changed.
* @param publishState The latest update to the publish state.
+ *
+ * @deprecated Replaced by {@link #onPublishStateChange}, deprecated for
+ * sip information.
*/
+ @Deprecated
void onPublishStateChange(@PublishState int publishState);
+
+ /**
+ * Notifies the callback when the publish state has changed or the publish operation is
+ * done.
+ * @param attributes The latest information related to the publish.
+ */
+ default void onPublishStateChange(@NonNull PublishAttributes attributes) {
+ onPublishStateChange(attributes.getPublishState());
+ };
}
/**
@@ -404,13 +418,13 @@ public class RcsUceAdapter {
}
@Override
- public void onPublishStateChanged(int publishState) {
+ public void onPublishUpdated(@NonNull PublishAttributes attributes) {
if (mPublishStateChangeListener == null) return;
final long callingIdentity = Binder.clearCallingIdentity();
try {
mExecutor.execute(() ->
- mPublishStateChangeListener.onPublishStateChange(publishState));
+ mPublishStateChangeListener.onPublishStateChange(attributes));
} finally {
restoreCallingIdentity(callingIdentity);
}
@@ -433,12 +447,12 @@ public class RcsUceAdapter {
/**
* A callback for the response to a UCE request. The method
* {@link CapabilitiesCallback#onCapabilitiesReceived} will be called zero or more times as the
- * capabilities are received for each requested contact.
+ * capabilities are fetched from multiple sources, both cached on the device and on the network.
* <p>
* This request will take a varying amount of time depending on if the contacts requested are
* cached or if it requires a network query. The timeout time of these requests can vary
* depending on the network, however in poor cases it could take up to a minute for a request
- * to timeout. In that time only a subset of capabilities may have been retrieved.
+ * to timeout. In that time, only a subset of capabilities may have been retrieved.
* <p>
* After {@link CapabilitiesCallback#onComplete} or {@link CapabilitiesCallback#onError} has
* been called, the reference to this callback will be discarded on the service side.
@@ -449,18 +463,29 @@ public class RcsUceAdapter {
public interface CapabilitiesCallback {
/**
- * Notify this application that the pending capability request has returned successfully
- * for one or more of the requested contacts.
+ * The pending capability request has completed successfully for one or more of the
+ * requested contacts.
+ * This may be called one or more times before the request is fully completed, as
+ * capabilities may need to be fetched from multiple sources both on device and on the
+ * network. Once the capabilities of all the requested contacts have been received,
+ * {@link #onComplete()} will be called. If there was an error during the capability
+ * exchange process, {@link #onError(int, long)} will be called instead.
* @param contactCapabilities List of capabilities associated with each contact requested.
*/
void onCapabilitiesReceived(@NonNull List<RcsContactUceCapability> contactCapabilities);
/**
- * The pending request has completed successfully due to all requested contacts information
- * being delivered. The callback {@link #onCapabilitiesReceived(List)}
- * for each contacts is required to be called before {@link #onComplete} is called.
+ * Called when the pending request has completed successfully due to all requested contacts
+ * information being delivered. The callback {@link #onCapabilitiesReceived(List)} will be
+ * called one or more times and will contain the contacts in the request that the device has
+ * received capabilities for.
+ *
+ * @see #onComplete(SipDetails) onComplete(SipDetails) provides more information related to
+ * the underlying SIP transaction used to perform the capabilities exchange. Either this
+ * method or the alternate method should be implemented to determine when the request has
+ * completed successfully.
*/
- void onComplete();
+ default void onComplete() {}
/**
* The pending request has resulted in an error and may need to be retried, depending on the
@@ -468,8 +493,50 @@ public class RcsUceAdapter {
* @param errorCode The reason for the framework being unable to process the request.
* @param retryIntervalMillis The time in milliseconds the requesting application should
* wait before retrying, if non-zero.
+ *
+ * @see #onError(int, long, SipDetails) onError(int, long, SipDetails) provides more
+ * information related to the underlying SIP transaction that resulted in an error. Either
+ * this method or the alternative method should be implemented to determine when the
+ * request has completed with an error.
*/
- void onError(@ErrorCode int errorCode, long retryIntervalMillis);
+ default void onError(@ErrorCode int errorCode, long retryIntervalMillis) {}
+
+ /**
+ * Called when the pending request has completed successfully due to all requested contacts
+ * information being delivered. The callback {@link #onCapabilitiesReceived(List)} will be
+ * called one or more times and will contain the contacts in the request that the device has
+ * received capabilities for.
+ *
+ * This method contains more information about the underlying SIP transaction if it exists.
+ * If this information is not needed, {@link #onComplete()} can be implemented
+ * instead.
+ *
+ * @param details The SIP information related to this request if the device supports
+ * supplying this information. This parameter will be {@code null} if this
+ * information is not available.
+ */
+ default void onComplete(@Nullable SipDetails details) {
+ onComplete();
+ };
+
+ /**
+ * The pending request has resulted in an error and may need to be retried, depending on the
+ * error code.
+ *
+ * This method contains more information about the underlying SIP transaction if it exists.
+ * If this information is not needed, {@link #onError(int, long)} can be implemented
+ * instead.
+ * @param errorCode The reason for the framework being unable to process the request.
+ * @param retryIntervalMillis The time in milliseconds the requesting application should
+ * wait before retrying, if non-zero.
+ * @param details The SIP information related to this request if the device supports
+ * supplying this information. This parameter will be {@code null} if this
+ * information is not available.
+ */
+ default void onError(@ErrorCode int errorCode, long retryIntervalMillis,
+ @Nullable SipDetails details) {
+ onError(errorCode, retryIntervalMillis);
+ };
}
private final Context mContext;
@@ -554,19 +621,20 @@ public class RcsUceAdapter {
}
}
@Override
- public void onComplete() {
+ public void onComplete(@Nullable SipDetails details) {
final long callingIdentity = Binder.clearCallingIdentity();
try {
- executor.execute(() -> c.onComplete());
+ executor.execute(() -> c.onComplete(details));
} finally {
restoreCallingIdentity(callingIdentity);
}
}
@Override
- public void onError(int errorCode, long retryAfterMilliseconds) {
+ public void onError(int errorCode, long retryAfterMilliseconds,
+ @Nullable SipDetails details) {
final long callingIdentity = Binder.clearCallingIdentity();
try {
- executor.execute(() -> c.onError(errorCode, retryAfterMilliseconds));
+ executor.execute(() -> c.onError(errorCode, retryAfterMilliseconds, details));
} finally {
restoreCallingIdentity(callingIdentity);
}
@@ -650,19 +718,20 @@ public class RcsUceAdapter {
}
}
@Override
- public void onComplete() {
+ public void onComplete(@Nullable SipDetails details) {
final long callingIdentity = Binder.clearCallingIdentity();
try {
- executor.execute(() -> c.onComplete());
+ executor.execute(() -> c.onComplete(details));
} finally {
restoreCallingIdentity(callingIdentity);
}
}
@Override
- public void onError(int errorCode, long retryAfterMilliseconds) {
+ public void onError(int errorCode, long retryAfterMilliseconds,
+ @Nullable SipDetails details) {
final long callingIdentity = Binder.clearCallingIdentity();
try {
- executor.execute(() -> c.onError(errorCode, retryAfterMilliseconds));
+ executor.execute(() -> c.onError(errorCode, retryAfterMilliseconds, details));
} finally {
restoreCallingIdentity(callingIdentity);
}
diff --git a/telephony/java/android/telephony/ims/RegistrationManager.java b/telephony/java/android/telephony/ims/RegistrationManager.java
index 9996b868afc7..873ce6064cca 100644
--- a/telephony/java/android/telephony/ims/RegistrationManager.java
+++ b/telephony/java/android/telephony/ims/RegistrationManager.java
@@ -23,6 +23,7 @@ import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.RequiresFeature;
import android.annotation.RequiresPermission;
+import android.annotation.SystemApi;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Binder;
@@ -36,7 +37,6 @@ import android.util.Log;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
-import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.Executor;
import java.util.function.Consumer;
@@ -75,6 +75,41 @@ public interface RegistrationManager {
*/
int REGISTRATION_STATE_REGISTERED = 2;
+ /** @hide */
+ @IntDef(prefix = {"SUGGESTED_ACTION_"},
+ value = {
+ SUGGESTED_ACTION_NONE,
+ SUGGESTED_ACTION_TRIGGER_PLMN_BLOCK,
+ SUGGESTED_ACTION_TRIGGER_PLMN_BLOCK_WITH_TIMEOUT
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface SuggestedAction {}
+
+ /**
+ * Default value. No action is suggested when IMS registration fails.
+ * @hide
+ */
+ @SystemApi
+ public static final int SUGGESTED_ACTION_NONE = 0;
+
+ /**
+ * Indicates that the IMS registration is failed with fatal error such as 403 or 404
+ * on all P-CSCF addresses. The radio shall block the current PLMN or disable
+ * the RAT as per the carrier requirements.
+ * @hide
+ */
+ @SystemApi
+ public static final int SUGGESTED_ACTION_TRIGGER_PLMN_BLOCK = 1;
+
+ /**
+ * Indicates that the IMS registration on current PLMN failed multiple times.
+ * The radio shall block the current PLMN or disable the RAT during EPS or 5GS mobility
+ * management timer value as per the carrier requirements.
+ * @hide
+ */
+ @SystemApi
+ public static final int SUGGESTED_ACTION_TRIGGER_PLMN_BLOCK_WITH_TIMEOUT = 2;
+
/**@hide*/
// Translate ImsRegistrationImplBase API to new AccessNetworkConstant because WLAN
// and WWAN are more accurate constants.
@@ -167,12 +202,32 @@ public interface RegistrationManager {
}
@Override
- public void onDeregistered(ImsReasonInfo info) {
+ public void onDeregistered(ImsReasonInfo info,
+ @SuggestedAction int suggestedAction,
+ @ImsRegistrationImplBase.ImsRegistrationTech int imsRadioTech) {
if (mLocalCallback == null) return;
final long callingIdentity = Binder.clearCallingIdentity();
try {
- mExecutor.execute(() -> mLocalCallback.onUnregistered(info));
+ mExecutor.execute(() -> mLocalCallback.onUnregistered(info,
+ suggestedAction, imsRadioTech));
+ } finally {
+ restoreCallingIdentity(callingIdentity);
+ }
+ }
+
+ @Override
+ public void onDeregisteredWithDetails(ImsReasonInfo info,
+ @SuggestedAction int suggestedAction,
+ @ImsRegistrationImplBase.ImsRegistrationTech int imsRadioTech,
+ @NonNull SipDetails details) {
+ if (mLocalCallback == null) return;
+
+ final long callingIdentity = Binder.clearCallingIdentity();
+ try {
+ mExecutor.execute(() -> mLocalCallback.onUnregistered(info, suggestedAction,
+ imsRadioTech));
+ mExecutor.execute(() -> mLocalCallback.onUnregistered(info, details));
} finally {
restoreCallingIdentity(callingIdentity);
}
@@ -258,6 +313,37 @@ public interface RegistrationManager {
}
/**
+ * Notifies the framework when the IMS Provider is unregistered from the IMS network.
+ *
+ * Since this callback is only required for the communication between telephony framework
+ * and ImsService, it is made hidden.
+ *
+ * @param info the {@link ImsReasonInfo} associated with why registration was disconnected.
+ * @param suggestedAction the expected behavior of radio protocol stack.
+ * @param imsRadioTech the network type on which IMS registration has failed.
+ * @hide
+ */
+ public void onUnregistered(@NonNull ImsReasonInfo info,
+ @SuggestedAction int suggestedAction,
+ @ImsRegistrationImplBase.ImsRegistrationTech int imsRadioTech) {
+ // Default impl to keep backwards compatibility with old implementations
+ onUnregistered(info);
+ }
+
+ /**
+ * Notifies the framework when the IMS Provider is unregistered from the IMS network.
+ *
+ * @param info the {@link ImsReasonInfo} associated with why registration was disconnected.
+ * @param details the {@link SipDetails} related to disconnected Ims registration.
+ *
+ * @hide
+ */
+ @SystemApi
+ public void onUnregistered(@NonNull ImsReasonInfo info,
+ @NonNull SipDetails details) {
+ }
+
+ /**
* A failure has occurred when trying to handover registration to another technology type.
*
* @param imsTransportType The transport type that has failed to handover registration to.
diff --git a/telephony/java/android/telephony/ims/SipDelegateManager.java b/telephony/java/android/telephony/ims/SipDelegateManager.java
index 94e9afbe9e38..25ebdd0b8b40 100644
--- a/telephony/java/android/telephony/ims/SipDelegateManager.java
+++ b/telephony/java/android/telephony/ims/SipDelegateManager.java
@@ -513,4 +513,69 @@ public class SipDelegateManager {
// ignore it
}
}
+
+ /**
+ * Register a new callback, which is used to notify the registrant of changes
+ * to the state of the Sip Sessions managed remotely by the IMS stack.
+ *
+ * <p>Requires Permission:
+ * {@link android.Manifest.permission#READ_PRIVILEGED_PHONE_STATE}
+ *
+ * @param executor the Executor that will be used to call the {@link SipDialogStateCallback}.
+ * @param callback The callback instance being registered.
+ * @throws ImsException in the case that the callback can not be registered.
+ * See {@link ImsException#getCode} for more information on when this is called.
+ */
+ @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
+ public void registerSipDialogStateCallback(@NonNull Executor executor,
+ @NonNull SipDialogStateCallback callback) throws ImsException {
+ Objects.requireNonNull(callback, "Must include a non-null SipDialogStateCallback.");
+ Objects.requireNonNull(executor, "Must include a non-null Executor.");
+
+ callback.attachExecutor(executor);
+ try {
+ IImsRcsController controller = mBinderCache.listenOnBinder(
+ callback, callback::binderDied);
+ if (controller == null) {
+ throw new ImsException("Telephony server is down",
+ ImsException.CODE_ERROR_SERVICE_UNAVAILABLE);
+ }
+ controller.registerSipDialogStateCallback(mSubId, callback.getCallbackBinder());
+ } catch (ServiceSpecificException e) {
+ throw new ImsException(e.getMessage(), e.errorCode);
+ } catch (RemoteException e) {
+ throw new ImsException(e.getMessage(), ImsException.CODE_ERROR_SERVICE_UNAVAILABLE);
+ } catch (IllegalStateException e) {
+ throw new IllegalStateException(e.getMessage());
+ }
+ }
+
+ /**
+ * Unregisters a previously registered callback.
+ *
+ * <p>Requires Permission:
+ * {@link android.Manifest.permission#READ_PRIVILEGED_PHONE_STATE}
+ *
+ * @param callback The callback instance to be unregistered.
+ */
+ @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
+ public void unregisterSipDialogStateCallback(@NonNull SipDialogStateCallback callback)
+ throws ImsException {
+ Objects.requireNonNull(callback, "Must include a non-null SipDialogStateCallback.");
+
+ IImsRcsController controller = mBinderCache.removeRunnable(callback);
+ try {
+ if (controller == null) {
+ throw new ImsException("Telephony server is down",
+ ImsException.CODE_ERROR_SERVICE_UNAVAILABLE);
+ }
+ controller.unregisterSipDialogStateCallback(mSubId, callback.getCallbackBinder());
+ } catch (ServiceSpecificException e) {
+ throw new ImsException(e.getMessage(), e.errorCode);
+ } catch (RemoteException e) {
+ throw new ImsException(e.getMessage(), ImsException.CODE_ERROR_SERVICE_UNAVAILABLE);
+ } catch (IllegalStateException e) {
+ throw new IllegalStateException(e.getMessage());
+ }
+ }
}
diff --git a/telephony/java/android/telephony/ims/SipDetails.aidl b/telephony/java/android/telephony/ims/SipDetails.aidl
new file mode 100644
index 000000000000..476d806c881a
--- /dev/null
+++ b/telephony/java/android/telephony/ims/SipDetails.aidl
@@ -0,0 +1,19 @@
+/*
+ * Copyright (c) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.telephony.ims;
+
+parcelable SipDetails;
diff --git a/telephony/java/android/telephony/ims/SipDetails.java b/telephony/java/android/telephony/ims/SipDetails.java
new file mode 100644
index 000000000000..fe58eb31b115
--- /dev/null
+++ b/telephony/java/android/telephony/ims/SipDetails.java
@@ -0,0 +1,309 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.telephony.ims;
+
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.text.TextUtils;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.Objects;
+
+/**
+ * Contains the information for SIP.
+ */
+public final class SipDetails implements Parcelable {
+ /**
+ * Define a SIP method type related to this information.
+ * @hide
+ */
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef(prefix = "METHOD_", value = {
+ METHOD_UNKNOWN,
+ METHOD_REGISTER,
+ METHOD_PUBLISH,
+ METHOD_SUBSCRIBE
+ })
+ public @interface Method {}
+
+ public static final int METHOD_UNKNOWN = 0;
+
+ /**
+ * Indicates information related to the SIP registration method.
+ * See RFC 3261 for details.
+ */
+ public static final int METHOD_REGISTER = 1;
+ /**
+ * Indicates information related to the SIP publication method.
+ * See RFC 3903 for details.
+ */
+ public static final int METHOD_PUBLISH = 2;
+ /**
+ * Indicates information related to the SIP subscription method.
+ * See RFC 3856 for details.
+ */
+ public static final int METHOD_SUBSCRIBE = 3;
+
+ /**
+ * Builder for creating {@link SipDetails} instances.
+ * @hide
+ */
+ public static final class Builder {
+ private int mMethod;
+ // Command Sequence value defined in RFC3261 Section 8.1.1.5
+ private int mCseq = 0;
+ private int mResponseCode = 0;
+ private String mResponsePhrase = "";
+ private int mReasonHeaderCause = 0;
+ private String mReasonHeaderText = "";
+ private @Nullable String mCallId;
+
+ /**
+ * Build a new instance of {@link SipDetails}.
+ *
+ * @param method Indicates which SIP method this information is for.
+ */
+ public Builder(@Method int method) {
+ this.mMethod = method;
+ }
+
+ /**
+ * Sets the value of the CSeq header field for this SIP method.
+ * The CSeq header field serves as a way to identify and order transactions.
+ * It consists of a sequence number and a method.
+ * The method MUST match that of the request.
+ * Ref RFC3261 Section 8.1.1.5.
+ * @param cSeq The value of the CSeq header field.
+ * @return The same instance of the builder.
+ */
+ public @NonNull Builder setCSeq(int cSeq) {
+ this.mCseq = cSeq;
+ return this;
+ }
+
+ /**
+ * Sets the SIP response code and reason response for this SIP method.
+ * Ref RFC3261 Section 21.
+ * @param responseCode The SIP response code sent from the network for the
+ * operation token specified.
+ * @param responsePhrase The optional reason response from the network. If
+ * there is a reason header included in the response, that should take
+ * precedence over the reason provided in the status line. If the network
+ * provided no reason with the SIP code, the string should be empty.
+ * @return The same instance of the builder.
+ */
+ public Builder setSipResponseCode(int responseCode,
+ @NonNull String responsePhrase) {
+ this.mResponseCode = responseCode;
+ this.mResponsePhrase = responsePhrase;
+ return this;
+ }
+
+
+ /**
+ * Sets the detailed information of reason header for this SIP method.
+ * Ref RFC3326.
+ * @param reasonHeaderCause The “cause” parameter of the “reason”
+ * header included in the SIP message.
+ * @param reasonHeaderText The “text” parameter of the “reason”
+ * header included in the SIP message.
+ * @return The same instance of the builder.
+ */
+ public Builder setSipResponseReasonHeader(int reasonHeaderCause,
+ @NonNull String reasonHeaderText) {
+ this.mReasonHeaderCause = reasonHeaderCause;
+ this.mReasonHeaderText = reasonHeaderText;
+ return this;
+ }
+
+
+ /**
+ * Sets the value of the Call-ID header field for this SIP method.
+ * Ref RFC3261 Section 8.1.1.4.
+ * @param callId The value of the Call-ID header field.
+ * @return The same instance of the builder.
+ */
+ public @NonNull Builder setCallId(@NonNull String callId) {
+ this.mCallId = callId;
+ return this;
+ }
+
+ /**
+ * @return a new SipDetails from this Builder.
+ */
+ public @NonNull SipDetails build() {
+ return new SipDetails(this);
+ }
+ }
+
+ private final int mMethod;
+ private final int mCseq;
+ private final int mResponseCode;
+ private final @NonNull String mResponsePhrase;
+ private final int mReasonHeaderCause;
+ private final @NonNull String mReasonHeaderText;
+ private final @Nullable String mCallId;
+
+ private SipDetails(Builder builder) {
+ mMethod = builder.mMethod;
+ mCseq = builder.mCseq;
+ mResponseCode = builder.mResponseCode;
+ mResponsePhrase = builder.mResponsePhrase;
+ mReasonHeaderCause = builder.mReasonHeaderCause;
+ mReasonHeaderText = builder.mReasonHeaderText;
+ mCallId = builder.mCallId;
+ }
+
+ /**
+ * Get the method type of this instance.
+ * @return The method type associated with this SIP information.
+ */
+ public @Method int getMethod() {
+ return mMethod;
+ }
+
+ /**
+ * Get the value of CSeq header field.
+ * The CSeq header field serves as a way to identify and order transactions.
+ * @return The command sequence value associated with this SIP information.
+ */
+ public int getCSeq() {
+ return mCseq;
+ }
+
+ /**
+ * Get the value of response code from the SIP response.
+ * The SIP response code sent from the network for the operation token specified.
+ * @return The SIP response code associated with this SIP information.
+ */
+ public int getResponseCode() {
+ return mResponseCode;
+ }
+
+ /**
+ * Get the value of reason from the SIP response.
+ * The optional reason response from the network. If
+ * there is a reason header included in the response, that should take
+ * precedence over the reason provided in the status line.
+ * @return The optional reason response associated with this SIP information. If the network
+ * provided no reason with the SIP code, the string should be empty.
+ */
+ public @NonNull String getResponsePhrase() {
+ return mResponsePhrase;
+ }
+
+ /**
+ * Get the "cause" parameter of the "reason" header.
+ * @return The "cause" parameter of the reason header. If the SIP message from the network
+ * does not have a reason header, it should be 0.
+ */
+ public int getReasonHeaderCause() {
+ return mReasonHeaderCause;
+ }
+
+ /**
+ * Get the "text" parameter of the "reason" header in the SIP message.
+ * @return The "text" parameter of the reason header. If the SIP message from the network
+ * does not have a reason header, it can be empty.
+ */
+ public @NonNull String getReasonHeaderText() {
+ return mReasonHeaderText;
+ }
+
+ /**
+ * Get the value of the Call-ID header field for this SIP method.
+ * @return The Call-ID value associated with this SIP information. If the Call-ID value is
+ * not set when ImsService notifies the framework, this value will be null.
+ */
+ public @Nullable String getCallId() {
+ return mCallId;
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(@NonNull Parcel dest, int flags) {
+ dest.writeInt(mMethod);
+ dest.writeInt(mCseq);
+ dest.writeInt(mResponseCode);
+ dest.writeString(mResponsePhrase);
+ dest.writeInt(mReasonHeaderCause);
+ dest.writeString(mReasonHeaderText);
+ dest.writeString(mCallId);
+ }
+
+ public static final @NonNull Creator<SipDetails> CREATOR =
+ new Creator<SipDetails>() {
+ @Override
+ public SipDetails createFromParcel(Parcel source) {
+ return new SipDetails(source);
+ }
+
+ @Override
+ public SipDetails[] newArray(int size) {
+ return new SipDetails[size];
+ }
+ };
+
+ /**
+ * Construct a SipDetails object from the given parcel.
+ */
+ private SipDetails(Parcel in) {
+ mMethod = in.readInt();
+ mCseq = in.readInt();
+ mResponseCode = in.readInt();
+ mResponsePhrase = in.readString();
+ mReasonHeaderCause = in.readInt();
+ mReasonHeaderText = in.readString();
+ mCallId = in.readString();
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ SipDetails that = (SipDetails) o;
+ return mMethod == that.mMethod
+ && mCseq == that.mCseq
+ && mResponseCode == that.mResponseCode
+ && TextUtils.equals(mResponsePhrase, that.mResponsePhrase)
+ && mReasonHeaderCause == that.mReasonHeaderCause
+ && TextUtils.equals(mReasonHeaderText, that.mReasonHeaderText)
+ && TextUtils.equals(mCallId, that.mCallId);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(mMethod, mCseq, mResponseCode, mResponsePhrase, mReasonHeaderCause,
+ mReasonHeaderText, mCallId);
+ }
+
+ @Override
+ public String toString() {
+ return "SipDetails { methodType= " + mMethod + ", cSeq=" + mCseq
+ + ", ResponseCode=" + mResponseCode + ", ResponseCPhrase=" + mResponsePhrase
+ + ", ReasonHeaderCause=" + mReasonHeaderCause
+ + ", ReasonHeaderText=" + mReasonHeaderText + ", callId=" + mCallId + "}";
+ }
+}
diff --git a/telephony/java/android/telephony/ims/SipDialogState.aidl b/telephony/java/android/telephony/ims/SipDialogState.aidl
new file mode 100644
index 000000000000..0f084c744ce6
--- /dev/null
+++ b/telephony/java/android/telephony/ims/SipDialogState.aidl
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.telephony.ims;
+
+parcelable SipDialogState; \ No newline at end of file
diff --git a/telephony/java/android/telephony/ims/SipDialogState.java b/telephony/java/android/telephony/ims/SipDialogState.java
new file mode 100644
index 000000000000..815c59ae9b2c
--- /dev/null
+++ b/telephony/java/android/telephony/ims/SipDialogState.java
@@ -0,0 +1,135 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.telephony.ims;
+
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.Objects;
+
+/**
+ * The state of an ongoing SIP dialog.
+ * @hide
+ */
+@SystemApi
+public final class SipDialogState implements Parcelable {
+
+ /**@hide*/
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef(prefix = "STATE_", value = {STATE_EARLY, STATE_CONFIRMED, STATE_CLOSED})
+ public @interface SipDialogStateCode {}
+ /**
+ * The device has sent out a dialog starting event and is awaiting a confirmation.
+ */
+ public static final int STATE_EARLY = 0;
+
+ /**
+ * The device has received a 2XX response to the early dialog.
+ */
+ public static final int STATE_CONFIRMED = 1;
+
+ /**
+ * The device has received either a 3XX+ response to a pending dialog request or a BYE
+ * request has been sent on this dialog.
+ */
+ public static final int STATE_CLOSED = 2;
+
+ private final int mState;
+
+ /**
+ * Builder for {@link SipDialogState}.
+ * @hide
+ */
+ public static final class Builder {
+ private int mState = STATE_EARLY;
+
+ /**
+ * constructor
+ * @param state The state of SipDialog
+ */
+ public Builder(@SipDialogStateCode int state) {
+ mState = state;
+ }
+
+ /**
+ * Build the {@link SipDialogState}.
+ * @return The {@link SipDialogState} instance.
+ */
+ public @NonNull SipDialogState build() {
+ return new SipDialogState(this);
+ }
+ }
+
+ /**
+ * set Dialog state
+ */
+ private SipDialogState(@NonNull Builder builder) {
+ this.mState = builder.mState;
+ }
+
+ private SipDialogState(Parcel in) {
+ mState = in.readInt();
+ }
+
+ /**
+ * @return The state of the SIP dialog
+ */
+ public @SipDialogStateCode int getState() {
+ return mState;
+ }
+
+ public static final @NonNull Creator<SipDialogState> CREATOR = new Creator<SipDialogState>() {
+ @Override
+ public SipDialogState createFromParcel(@NonNull Parcel in) {
+ return new SipDialogState(in);
+ }
+
+ @Override
+ public SipDialogState[] newArray(int size) {
+ return new SipDialogState[size];
+ }
+ };
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(@NonNull Parcel dest, int flags) {
+ dest.writeInt(mState);
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ SipDialogState sipDialog = (SipDialogState) o;
+
+ return mState == sipDialog.mState;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(mState);
+ }
+}
diff --git a/telephony/java/android/telephony/ims/SipDialogStateCallback.java b/telephony/java/android/telephony/ims/SipDialogStateCallback.java
new file mode 100644
index 000000000000..5730bac09d57
--- /dev/null
+++ b/telephony/java/android/telephony/ims/SipDialogStateCallback.java
@@ -0,0 +1,103 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.telephony.ims;
+
+import android.annotation.CallbackExecutor;
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
+import android.os.Binder;
+
+import com.android.internal.telephony.ISipDialogStateCallback;
+
+import java.lang.ref.WeakReference;
+import java.util.List;
+import java.util.concurrent.Executor;
+
+/**
+ * This callback is used to notify listeners of SIP Dialog state changes.
+ * @hide
+ */
+@SystemApi
+public abstract class SipDialogStateCallback {
+
+ private CallbackBinder mCallback;
+ /**
+ * @hide
+ */
+ public void attachExecutor(@NonNull @CallbackExecutor Executor executor) {
+ if (executor == null) {
+ throw new IllegalArgumentException("SipDialogStateCallback Executor must be non-null");
+ }
+ mCallback = new CallbackBinder(this, executor);
+ }
+
+ private static class CallbackBinder extends ISipDialogStateCallback.Stub {
+ private WeakReference<SipDialogStateCallback> mSipDialogStateCallbackWeakRef;
+ private Executor mExecutor;
+
+ private CallbackBinder(SipDialogStateCallback callback, Executor executor) {
+ mSipDialogStateCallbackWeakRef = new WeakReference<SipDialogStateCallback>(callback);
+ mExecutor = executor;
+ }
+
+ Executor getExecutor() {
+ return mExecutor;
+ }
+
+ @Override
+ public void onActiveSipDialogsChanged(List<SipDialogState> dialogs) {
+ SipDialogStateCallback callback = mSipDialogStateCallbackWeakRef.get();
+ if (callback == null || dialogs == null) return;
+
+ Binder.withCleanCallingIdentity(
+ () -> mExecutor.execute(() -> callback.onActiveSipDialogsChanged(dialogs)));
+ }
+ }
+
+ /**
+ * The state of one or more SIP dialogs has changed.
+ *
+ * @param dialogs A List of SipDialogState objects representing the state of the active
+ * SIP Dialogs.
+ */
+ public abstract void onActiveSipDialogsChanged(@NonNull List<SipDialogState> dialogs);
+
+ /**
+ * An unexpected error has occurred and the Telephony process has crashed. This
+ * has caused this callback to be deregistered. The callback must be re-registered
+ * in order to continue listening to the IMS service state.
+ */
+ public abstract void onError();
+
+ /**
+ * The callback to notify the death of telephony process
+ * @hide
+ */
+ public final void binderDied() {
+ if (mCallback != null) {
+ mCallback.getExecutor().execute(() -> onError());
+ }
+ }
+
+ /**
+ * Return the callback binder
+ * @hide
+ */
+ public CallbackBinder getCallbackBinder() {
+ return mCallback;
+ }
+}
diff --git a/telephony/java/android/telephony/ims/SrvccCall.aidl b/telephony/java/android/telephony/ims/SrvccCall.aidl
new file mode 100644
index 000000000000..0f0a0795cb2e
--- /dev/null
+++ b/telephony/java/android/telephony/ims/SrvccCall.aidl
@@ -0,0 +1,19 @@
+/*
+ * Copyright (c) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.telephony.ims;
+
+parcelable SrvccCall;
diff --git a/telephony/java/android/telephony/ims/SrvccCall.java b/telephony/java/android/telephony/ims/SrvccCall.java
new file mode 100644
index 000000000000..cdc271ec8070
--- /dev/null
+++ b/telephony/java/android/telephony/ims/SrvccCall.java
@@ -0,0 +1,153 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.telephony.ims;
+
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.telephony.Annotation.PreciseCallStates;
+
+import java.util.Objects;
+
+/**
+ * A Parcelable object to represent the current state of an IMS call that is being tracked
+ * in the ImsService when an SRVCC begins. This information will be delivered to modem.
+ * @see SrvccStartedCallback
+ *
+ * @hide
+ */
+@SystemApi
+public final class SrvccCall implements Parcelable {
+ private static final String TAG = "SrvccCall";
+
+ /** The IMS call profile */
+ private ImsCallProfile mImsCallProfile;
+
+ /** The IMS call id */
+ private String mCallId;
+
+ /** The call state */
+ private @PreciseCallStates int mCallState;
+
+ private SrvccCall(Parcel in) {
+ readFromParcel(in);
+ }
+
+ /**
+ * Constructs an instance of SrvccCall.
+ *
+ * @param callId the call ID associated with the IMS call
+ * @param callState the state of this IMS call
+ * @param imsCallProfile the profile associated with this IMS call
+ * @throws IllegalArgumentException if the callId or the imsCallProfile is null
+ */
+ public SrvccCall(@NonNull String callId, @PreciseCallStates int callState,
+ @NonNull ImsCallProfile imsCallProfile) {
+ if (callId == null) throw new IllegalArgumentException("callId is null");
+ if (imsCallProfile == null) throw new IllegalArgumentException("imsCallProfile is null");
+
+ mCallId = callId;
+ mCallState = callState;
+ mImsCallProfile = imsCallProfile;
+ }
+
+ /**
+ * @return the {@link ImsCallProfile} associated with this IMS call,
+ * which will be used to get the address, the name, and the audio direction
+ * including the call in pre-alerting state.
+ */
+ @NonNull
+ public ImsCallProfile getImsCallProfile() {
+ return mImsCallProfile;
+ }
+
+ /**
+ * @return the call ID associated with this IMS call.
+ *
+ * @see android.telephony.ims.stub.ImsCallSessionImplBase#getCallId().
+ */
+ @NonNull
+ public String getCallId() {
+ return mCallId;
+ }
+
+ /**
+ * @return the call state of the associated IMS call.
+ */
+ public @PreciseCallStates int getPreciseCallState() {
+ return mCallState;
+ }
+
+ @NonNull
+ @Override
+ public String toString() {
+ return "{ callId=" + mCallId
+ + ", callState=" + mCallState
+ + ", imsCallProfile=" + mImsCallProfile
+ + " }";
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ SrvccCall that = (SrvccCall) o;
+ return mImsCallProfile.equals(that.mImsCallProfile)
+ && mCallId.equals(that.mCallId)
+ && mCallState == that.mCallState;
+ }
+
+ @Override
+ public int hashCode() {
+ int result = Objects.hash(mImsCallProfile, mCallId);
+ result = 31 * result + mCallState;
+ return result;
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(@NonNull Parcel out, int flags) {
+ out.writeString(mCallId);
+ out.writeInt(mCallState);
+ out.writeParcelable(mImsCallProfile, 0);
+ }
+
+ private void readFromParcel(Parcel in) {
+ mCallId = in.readString();
+ mCallState = in.readInt();
+ mImsCallProfile = in.readParcelable(ImsCallProfile.class.getClassLoader(),
+ android.telephony.ims.ImsCallProfile.class);
+ }
+
+ public static final @android.annotation.NonNull Creator<SrvccCall> CREATOR =
+ new Creator<SrvccCall>() {
+ @Override
+ public SrvccCall createFromParcel(Parcel in) {
+ return new SrvccCall(in);
+ }
+
+ @Override
+ public SrvccCall[] newArray(int size) {
+ return new SrvccCall[size];
+ }
+ };
+}
diff --git a/telephony/java/android/telephony/ims/aidl/CapabilityExchangeAidlWrapper.java b/telephony/java/android/telephony/ims/aidl/CapabilityExchangeAidlWrapper.java
index c27fa4fc882d..0514df2cea10 100644
--- a/telephony/java/android/telephony/ims/aidl/CapabilityExchangeAidlWrapper.java
+++ b/telephony/java/android/telephony/ims/aidl/CapabilityExchangeAidlWrapper.java
@@ -23,6 +23,7 @@ import android.os.Binder;
import android.os.RemoteException;
import android.telephony.ims.ImsException;
import android.telephony.ims.RcsContactUceCapability;
+import android.telephony.ims.SipDetails;
import android.telephony.ims.stub.CapabilityExchangeEventListener;
import android.util.Log;
@@ -83,7 +84,11 @@ public class CapabilityExchangeAidlWrapper implements CapabilityExchangeEventLis
/**
* Receives the status of changes in the publishing connection from ims service
* and deliver this callback to the framework.
+ *
+ * @deprecated Replaced by {@link #onPublishUpdated(SipDetails)}, deprecated for
+ * sip information.
*/
+ @Deprecated
public void onPublishUpdated(int reasonCode, @NonNull String reasonPhrase,
int reasonHeaderCause, @NonNull String reasonHeaderText) throws ImsException {
ICapabilityExchangeEventListener listener = mListenerBinder;
@@ -91,8 +96,29 @@ public class CapabilityExchangeAidlWrapper implements CapabilityExchangeEventLis
return;
}
try {
- listener.onPublishUpdated(reasonCode, reasonPhrase,
- reasonHeaderCause, reasonHeaderText);
+ SipDetails details = new SipDetails.Builder(SipDetails.METHOD_PUBLISH)
+ .setSipResponseCode(reasonCode, reasonPhrase)
+ .setSipResponseReasonHeader(reasonHeaderCause, reasonHeaderText)
+ .build();
+ listener.onPublishUpdated(details);
+ } catch (RemoteException e) {
+ Log.w(LOG_TAG, "onPublishUpdated exception: " + e);
+ throw new ImsException("Remote is not available",
+ ImsException.CODE_ERROR_SERVICE_UNAVAILABLE);
+ }
+ }
+
+ /**
+ * Receives the status of changes in the publishing connection from ims service
+ * and deliver this callback to the framework.
+ */
+ public void onPublishUpdated(@NonNull SipDetails details) throws ImsException {
+ ICapabilityExchangeEventListener listener = mListenerBinder;
+ if (listener == null) {
+ return;
+ }
+ try {
+ listener.onPublishUpdated(details);
} catch (RemoteException e) {
Log.w(LOG_TAG, "onPublishUpdated exception: " + e);
throw new ImsException("Remote is not available",
diff --git a/telephony/java/android/telephony/ims/aidl/ICapabilityExchangeEventListener.aidl b/telephony/java/android/telephony/ims/aidl/ICapabilityExchangeEventListener.aidl
index c675bc3204f6..21c838040dc7 100644
--- a/telephony/java/android/telephony/ims/aidl/ICapabilityExchangeEventListener.aidl
+++ b/telephony/java/android/telephony/ims/aidl/ICapabilityExchangeEventListener.aidl
@@ -18,7 +18,7 @@ package android.telephony.ims.aidl;
import android.net.Uri;
import android.telephony.ims.aidl.IOptionsRequestCallback;
-
+import android.telephony.ims.SipDetails;
import java.util.List;
/**
@@ -31,8 +31,7 @@ import java.util.List;
oneway interface ICapabilityExchangeEventListener {
void onRequestPublishCapabilities(int publishTriggerType);
void onUnpublish();
- void onPublishUpdated(int reasonCode, String reasonPhrase, int reasonHeaderCause,
- String reasonHeaderText);
+ void onPublishUpdated(in SipDetails details);
void onRemoteCapabilityRequest(in Uri contactUri,
in List<String> remoteCapabilities, IOptionsRequestCallback cb);
}
diff --git a/telephony/java/android/telephony/ims/aidl/IImsCallSessionListener.aidl b/telephony/java/android/telephony/ims/aidl/IImsCallSessionListener.aidl
index ed0375251ffb..b58a5c79b76c 100644
--- a/telephony/java/android/telephony/ims/aidl/IImsCallSessionListener.aidl
+++ b/telephony/java/android/telephony/ims/aidl/IImsCallSessionListener.aidl
@@ -171,4 +171,17 @@ oneway interface IImsCallSessionListener {
* @param extensions the RTP header extensions received.
*/
void callSessionRtpHeaderExtensionsReceived(in List<RtpHeaderExtension> extensions);
+
+ /**
+ * Access Network Bitrate Recommendation Query (ANBRQ), see 3GPP TS 26.114.
+ * This API triggers radio to send ANBRQ message to the access network to query the desired
+ * bitrate.
+ *
+ * @param mediaType MediaType is used to identify media stream such as audio or video.
+ * @param direction Direction of this packet stream (e.g. uplink or downlink).
+ * @param bitsPerSecond This value is the bitrate requested by the other party UE
+ * through RTP CMR, RTCPAPP or TMMBR, and ImsStack converts this value to the MAC bitrate
+ * (defined in TS36.321, range: 0 ~ 8000 kbit/s).
+ */
+ void callSessionSendAnbrQuery(int mediaType, int direction, int bitsPerSecond);
}
diff --git a/telephony/java/android/telephony/ims/aidl/IImsMmTelFeature.aidl b/telephony/java/android/telephony/ims/aidl/IImsMmTelFeature.aidl
index 37fec7a73634..2f0eb6cb211b 100644
--- a/telephony/java/android/telephony/ims/aidl/IImsMmTelFeature.aidl
+++ b/telephony/java/android/telephony/ims/aidl/IImsMmTelFeature.aidl
@@ -20,7 +20,10 @@ import android.os.Message;
import android.telephony.ims.aidl.IImsMmTelListener;
import android.telephony.ims.aidl.IImsSmsListener;
import android.telephony.ims.aidl.IImsCapabilityCallback;
+import android.telephony.ims.aidl.ISrvccStartedCallback;
import android.telephony.ims.feature.CapabilityChangeRequest;
+import android.telephony.ims.MediaQualityStatus;
+import android.telephony.ims.MediaThreshold;
import android.telephony.ims.RtpHeaderExtensionType;
import android.telephony.ims.ImsCallProfile;
@@ -48,17 +51,27 @@ interface IImsMmTelFeature {
void setUiTtyMode(int uiTtyMode, in Message onCompleteMessage);
IImsMultiEndpoint getMultiEndpointInterface();
int queryCapabilityStatus();
+ void setTerminalBasedCallWaitingStatus(boolean enabled);
oneway void addCapabilityCallback(IImsCapabilityCallback c);
oneway void removeCapabilityCallback(IImsCapabilityCallback c);
oneway void changeCapabilitiesConfiguration(in CapabilityChangeRequest request,
IImsCapabilityCallback c);
oneway void queryCapabilityConfiguration(int capability, int radioTech,
IImsCapabilityCallback c);
+ oneway void notifySrvccStarted(in ISrvccStartedCallback cb);
+ oneway void notifySrvccCompleted();
+ oneway void notifySrvccFailed();
+ oneway void notifySrvccCanceled();
+ oneway void setMediaQualityThreshold(int mediaSessionType, in MediaThreshold threshold);
+ MediaQualityStatus queryMediaQualityStatus(int mediaSessionType);
+
// SMS APIs
void setSmsListener(IImsSmsListener l);
oneway void sendSms(in int token, int messageRef, String format, String smsc, boolean retry,
in byte[] pdu);
+ oneway void onMemoryAvailable(int token);
oneway void acknowledgeSms(int token, int messageRef, int result);
+ oneway void acknowledgeSmsWithPdu(int token, int messageRef, int result, in byte[] pdu);
oneway void acknowledgeSmsReport(int token, int messageRef, int result);
String getSmsFormat();
oneway void onSmsReady();
diff --git a/telephony/java/android/telephony/ims/aidl/IImsMmTelListener.aidl b/telephony/java/android/telephony/ims/aidl/IImsMmTelListener.aidl
index 52464703c608..e016c6153247 100644
--- a/telephony/java/android/telephony/ims/aidl/IImsMmTelListener.aidl
+++ b/telephony/java/android/telephony/ims/aidl/IImsMmTelListener.aidl
@@ -20,6 +20,9 @@ import android.os.Bundle;
import android.telephony.ims.ImsCallProfile;
import android.telephony.ims.ImsReasonInfo;
+import android.telephony.ims.MediaQualityStatus;
+import android.telephony.ims.aidl.IImsCallSessionListener;
+import android.telephony.ims.aidl.IImsTrafficSessionCallback;
import com.android.ims.internal.IImsCallSession;
@@ -31,7 +34,14 @@ import com.android.ims.internal.IImsCallSession;
// processed by telephony before the control flow returns to the ImsService to perform
// operations on the IImsCallSession.
interface IImsMmTelListener {
- void onIncomingCall(IImsCallSession c, in Bundle extras);
+ IImsCallSessionListener onIncomingCall(in IImsCallSession c, in String callId, in Bundle extras);
void onRejectedCall(in ImsCallProfile callProfile, in ImsReasonInfo reason);
oneway void onVoiceMessageCountUpdate(int count);
+ oneway void onAudioModeIsVoipChanged(int imsAudioHandler);
+ oneway void onTriggerEpsFallback(int reason);
+ oneway void onStartImsTrafficSession(int token, int trafficType, int accessNetworkType,
+ int trafficDirection, in IImsTrafficSessionCallback callback);
+ oneway void onModifyImsTrafficSession(int token, int accessNetworkType);
+ oneway void onStopImsTrafficSession(int token);
+ oneway void onMediaQualityStatusChanged(in MediaQualityStatus status);
}
diff --git a/telephony/java/android/telephony/ims/aidl/IImsRcsController.aidl b/telephony/java/android/telephony/ims/aidl/IImsRcsController.aidl
index 8931a78709ed..8a4a79684b08 100644
--- a/telephony/java/android/telephony/ims/aidl/IImsRcsController.aidl
+++ b/telephony/java/android/telephony/ims/aidl/IImsRcsController.aidl
@@ -30,6 +30,7 @@ import android.telephony.ims.aidl.ISipDelegateConnectionStateCallback;
import com.android.ims.ImsFeatureContainer;
import com.android.ims.internal.IImsServiceFeatureCallback;
import com.android.internal.telephony.IIntegerConsumer;
+import com.android.internal.telephony.ISipDialogStateCallback;
/**
* Interface used to interact with the Telephony IMS.
@@ -69,6 +70,10 @@ interface IImsRcsController {
void destroySipDelegate(int subId, ISipDelegate connection, int reason);
void triggerNetworkRegistration(int subId, ISipDelegate connection, int sipCode,
String sipReason);
+ @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)")
+ void registerSipDialogStateCallback(int subId, in ISipDialogStateCallback cb);
+ @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)")
+ void unregisterSipDialogStateCallback(int subId, in ISipDialogStateCallback cb);
// Internal commands that should not be made public
void registerRcsFeatureCallback(int slotId, in IImsServiceFeatureCallback callback);
diff --git a/telephony/java/android/telephony/ims/aidl/IImsRegistration.aidl b/telephony/java/android/telephony/ims/aidl/IImsRegistration.aidl
index 4fd904041365..219c9c88d825 100644
--- a/telephony/java/android/telephony/ims/aidl/IImsRegistration.aidl
+++ b/telephony/java/android/telephony/ims/aidl/IImsRegistration.aidl
@@ -31,4 +31,5 @@ interface IImsRegistration {
oneway void triggerFullNetworkRegistration(int sipCode, String sipReason);
oneway void triggerUpdateSipDelegateRegistration();
oneway void triggerSipDelegateDeregistration();
+ oneway void triggerDeregistration(int reason);
}
diff --git a/telephony/java/android/telephony/ims/aidl/IImsRegistrationCallback.aidl b/telephony/java/android/telephony/ims/aidl/IImsRegistrationCallback.aidl
index 179407c983e5..0a5ea170320b 100644
--- a/telephony/java/android/telephony/ims/aidl/IImsRegistrationCallback.aidl
+++ b/telephony/java/android/telephony/ims/aidl/IImsRegistrationCallback.aidl
@@ -22,6 +22,7 @@ import android.telephony.ims.stub.ImsFeatureConfiguration;
import android.telephony.ims.ImsReasonInfo;
import android.telephony.ims.ImsRegistrationAttributes;
+import android.telephony.ims.SipDetails;
/**
* See {@link ImsManager#RegistrationCallback} for more information.
@@ -31,7 +32,8 @@ import android.telephony.ims.ImsRegistrationAttributes;
oneway interface IImsRegistrationCallback {
void onRegistered(in ImsRegistrationAttributes attr);
void onRegistering(in ImsRegistrationAttributes attr);
- void onDeregistered(in ImsReasonInfo info);
+ void onDeregistered(in ImsReasonInfo info, int suggestedAction, int imsRadioTech);
+ void onDeregisteredWithDetails(in ImsReasonInfo info, int suggestedAction, int imsRadioTech, in SipDetails detail);
void onTechnologyChangeFailed(int imsRadioTech, in ImsReasonInfo info);
void onSubscriberAssociatedUriChanged(in Uri[] uris);
-} \ No newline at end of file
+}
diff --git a/telephony/java/android/telephony/ims/aidl/IImsServiceController.aidl b/telephony/java/android/telephony/ims/aidl/IImsServiceController.aidl
index ae6166fea02a..fdf43a52685a 100644
--- a/telephony/java/android/telephony/ims/aidl/IImsServiceController.aidl
+++ b/telephony/java/android/telephony/ims/aidl/IImsServiceController.aidl
@@ -47,4 +47,5 @@ interface IImsServiceController {
ISipTransport getSipTransport(int slotId);
oneway void enableIms(int slotId, int subId);
oneway void disableIms(int slotId, int subId);
+ oneway void resetIms(int slotId, int subId);
}
diff --git a/telephony/java/android/telephony/ims/aidl/IImsSmsListener.aidl b/telephony/java/android/telephony/ims/aidl/IImsSmsListener.aidl
index 5aa58c1ee7ee..ae677cad33b8 100644
--- a/telephony/java/android/telephony/ims/aidl/IImsSmsListener.aidl
+++ b/telephony/java/android/telephony/ims/aidl/IImsSmsListener.aidl
@@ -24,4 +24,5 @@ oneway interface IImsSmsListener {
void onSendSmsResult(int token, int messageRef, int status, int reason, int networkErrorCode);
void onSmsStatusReportReceived(int token, in String format, in byte[] pdu);
void onSmsReceived(int token, in String format, in byte[] pdu);
+ void onMemoryAvailableResult(int token, int status, int networkErrorCode);
}
diff --git a/telephony/java/android/telephony/ims/aidl/IImsTrafficSessionCallback.aidl b/telephony/java/android/telephony/ims/aidl/IImsTrafficSessionCallback.aidl
new file mode 100644
index 000000000000..05b97e5c78cf
--- /dev/null
+++ b/telephony/java/android/telephony/ims/aidl/IImsTrafficSessionCallback.aidl
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.telephony.ims.aidl;
+
+import android.telephony.ims.feature.ConnectionFailureInfo;
+
+/**
+ * {@hide}
+ */
+oneway interface IImsTrafficSessionCallback {
+ void onReady();
+ void onError(in ConnectionFailureInfo info);
+}
diff --git a/telephony/java/android/telephony/ims/aidl/IPublishResponseCallback.aidl b/telephony/java/android/telephony/ims/aidl/IPublishResponseCallback.aidl
index b99d8a7d6d38..cd08fcfce6c6 100644
--- a/telephony/java/android/telephony/ims/aidl/IPublishResponseCallback.aidl
+++ b/telephony/java/android/telephony/ims/aidl/IPublishResponseCallback.aidl
@@ -17,6 +17,7 @@
package android.telephony.ims.aidl;
import java.util.List;
+import android.telephony.ims.SipDetails;
/**
* Interface used by the framework to receive the response of the publish
@@ -25,6 +26,5 @@ import java.util.List;
*/
oneway interface IPublishResponseCallback {
void onCommandError(int code);
- void onNetworkResponse(int code, String reason);
- void onNetworkRespHeader(int code, String reasonPhrase, int reasonHeaderCause, String reasonHeaderText);
+ void onNetworkResponse(in SipDetails details);
}
diff --git a/telephony/java/android/telephony/ims/aidl/IRcsUceControllerCallback.aidl b/telephony/java/android/telephony/ims/aidl/IRcsUceControllerCallback.aidl
index 0f627b92a24c..acce7484b283 100644
--- a/telephony/java/android/telephony/ims/aidl/IRcsUceControllerCallback.aidl
+++ b/telephony/java/android/telephony/ims/aidl/IRcsUceControllerCallback.aidl
@@ -17,7 +17,7 @@
package android.telephony.ims.aidl;
import android.telephony.ims.RcsContactUceCapability;
-
+import android.telephony.ims.SipDetails;
/**
* Provides interface for RCS UCE when receive a change.
*
@@ -25,6 +25,6 @@ import android.telephony.ims.RcsContactUceCapability;
*/
oneway interface IRcsUceControllerCallback {
void onCapabilitiesReceived(in List<RcsContactUceCapability> contactCapabilities);
- void onComplete();
- void onError(int errorCode, long retryAfterMilliseconds);
+ void onComplete(in SipDetails details);
+ void onError(int errorCode, long retryAfterMilliseconds, in SipDetails details);
}
diff --git a/telephony/java/android/telephony/ims/aidl/IRcsUcePublishStateCallback.aidl b/telephony/java/android/telephony/ims/aidl/IRcsUcePublishStateCallback.aidl
index b6e84154f80f..e870c26eea5e 100644
--- a/telephony/java/android/telephony/ims/aidl/IRcsUcePublishStateCallback.aidl
+++ b/telephony/java/android/telephony/ims/aidl/IRcsUcePublishStateCallback.aidl
@@ -16,11 +16,12 @@
package android.telephony.ims.aidl;
+import android.telephony.ims.PublishAttributes;
/**
* Interface for RCS UCE publish state change callbacks.
*
* {@hide}
*/
oneway interface IRcsUcePublishStateCallback {
- void onPublishStateChanged(int publishState);
+ void onPublishUpdated(in PublishAttributes attributes);
}
diff --git a/telephony/java/android/telephony/ims/aidl/ISrvccStartedCallback.aidl b/telephony/java/android/telephony/ims/aidl/ISrvccStartedCallback.aidl
new file mode 100644
index 000000000000..a173abffbb8f
--- /dev/null
+++ b/telephony/java/android/telephony/ims/aidl/ISrvccStartedCallback.aidl
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.telephony.ims.aidl;
+
+import android.telephony.ims.SrvccCall;
+
+import java.util.List;
+
+/**
+ * {@hide}
+ */
+oneway interface ISrvccStartedCallback {
+ void onSrvccCallNotified(in List<SrvccCall> profiles);
+}
diff --git a/telephony/java/android/telephony/ims/aidl/ISubscribeResponseCallback.aidl b/telephony/java/android/telephony/ims/aidl/ISubscribeResponseCallback.aidl
index 8cc8020df29a..375ecd959f08 100644
--- a/telephony/java/android/telephony/ims/aidl/ISubscribeResponseCallback.aidl
+++ b/telephony/java/android/telephony/ims/aidl/ISubscribeResponseCallback.aidl
@@ -18,6 +18,7 @@ package android.telephony.ims.aidl;
import android.net.Uri;
import android.telephony.ims.RcsContactTerminatedReason;
+import android.telephony.ims.SipDetails;
import java.util.List;
import java.util.Map;
@@ -29,8 +30,7 @@ import java.util.Map;
*/
oneway interface ISubscribeResponseCallback {
void onCommandError(int code);
- void onNetworkResponse(int code, in String reason);
- void onNetworkRespHeader(int code, String reasonPhrase, int reasonHeaderCause, String reasonHeaderText);
+ void onNetworkResponse(in SipDetails detail);
void onNotifyCapabilitiesUpdate(in List<String> pidfXmls);
void onResourceTerminated(in List<RcsContactTerminatedReason> uriTerminatedReason);
void onTerminated(in String reason, long retryAfterMilliseconds);
diff --git a/telephony/java/android/telephony/ims/aidl/RcsPublishResponseAidlWrapper.java b/telephony/java/android/telephony/ims/aidl/RcsPublishResponseAidlWrapper.java
index 65415ea441b5..40cb5ca54990 100644
--- a/telephony/java/android/telephony/ims/aidl/RcsPublishResponseAidlWrapper.java
+++ b/telephony/java/android/telephony/ims/aidl/RcsPublishResponseAidlWrapper.java
@@ -16,8 +16,10 @@
package android.telephony.ims.aidl;
+import android.annotation.NonNull;
import android.os.RemoteException;
import android.telephony.ims.ImsException;
+import android.telephony.ims.SipDetails;
import android.telephony.ims.stub.RcsCapabilityExchangeImplBase.PublishResponseCallback;
/**
@@ -43,20 +45,38 @@ public class RcsPublishResponseAidlWrapper implements PublishResponseCallback {
}
@Override
- public void onNetworkResponse(int code, String reason) throws ImsException {
+ @Deprecated
+ public void onNetworkResponse(int code, String reasonPhrase) throws ImsException {
+ SipDetails details = new SipDetails.Builder(SipDetails.METHOD_PUBLISH)
+ .setSipResponseCode(code, reasonPhrase)
+ .build();
try {
- mResponseBinder.onNetworkResponse(code, reason);
+ mResponseBinder.onNetworkResponse(details);
} catch (RemoteException e) {
throw new ImsException(e.getMessage(), ImsException.CODE_ERROR_SERVICE_UNAVAILABLE);
}
}
@Override
+ @Deprecated
public void onNetworkResponse(int code, String reasonPhrase, int reasonHeaderCause,
String reasonHeaderText) throws ImsException {
+ SipDetails details = new SipDetails.Builder(SipDetails.METHOD_PUBLISH)
+ .setSipResponseCode(code, reasonPhrase)
+ .setSipResponseReasonHeader(reasonHeaderCause, reasonHeaderText)
+ .build();
try {
- mResponseBinder.onNetworkRespHeader(code, reasonPhrase, reasonHeaderCause,
- reasonHeaderText);
+ mResponseBinder.onNetworkResponse(details);
+ } catch (RemoteException e) {
+ throw new ImsException(e.getMessage(), ImsException.CODE_ERROR_SERVICE_UNAVAILABLE);
+ }
+ }
+
+ @Override
+ public void onNetworkResponse(@NonNull SipDetails details)
+ throws ImsException {
+ try {
+ mResponseBinder.onNetworkResponse(details);
} catch (RemoteException e) {
throw new ImsException(e.getMessage(), ImsException.CODE_ERROR_SERVICE_UNAVAILABLE);
}
diff --git a/telephony/java/android/telephony/ims/aidl/RcsSubscribeResponseAidlWrapper.java b/telephony/java/android/telephony/ims/aidl/RcsSubscribeResponseAidlWrapper.java
index 11118c0617c2..2f54001b80ce 100644
--- a/telephony/java/android/telephony/ims/aidl/RcsSubscribeResponseAidlWrapper.java
+++ b/telephony/java/android/telephony/ims/aidl/RcsSubscribeResponseAidlWrapper.java
@@ -16,10 +16,12 @@
package android.telephony.ims.aidl;
+import android.annotation.NonNull;
import android.net.Uri;
import android.os.RemoteException;
import android.telephony.ims.ImsException;
import android.telephony.ims.RcsContactTerminatedReason;
+import android.telephony.ims.SipDetails;
import android.telephony.ims.stub.RcsCapabilityExchangeImplBase.SubscribeResponseCallback;
import android.util.Pair;
@@ -49,20 +51,37 @@ public class RcsSubscribeResponseAidlWrapper implements SubscribeResponseCallbac
}
@Override
- public void onNetworkResponse(int code, String reason) throws ImsException {
+ @Deprecated
+ public void onNetworkResponse(int code, String reasonPhrase) throws ImsException {
try {
- mResponseBinder.onNetworkResponse(code, reason);
+ mResponseBinder.onNetworkResponse(new SipDetails.Builder(
+ SipDetails.METHOD_SUBSCRIBE)
+ .setSipResponseCode(code, reasonPhrase)
+ .build());
} catch (RemoteException e) {
throw new ImsException(e.getMessage(), ImsException.CODE_ERROR_SERVICE_UNAVAILABLE);
}
}
@Override
+ @Deprecated
public void onNetworkResponse(int code, String reasonPhrase, int reasonHeaderCause,
String reasonHeaderText) throws ImsException {
try {
- mResponseBinder.onNetworkRespHeader(code, reasonPhrase, reasonHeaderCause,
- reasonHeaderText);
+ mResponseBinder.onNetworkResponse(new SipDetails.Builder(
+ SipDetails.METHOD_SUBSCRIBE)
+ .setSipResponseCode(code, reasonPhrase)
+ .setSipResponseReasonHeader(reasonHeaderCause, reasonHeaderText)
+ .build());
+ } catch (RemoteException e) {
+ throw new ImsException(e.getMessage(), ImsException.CODE_ERROR_SERVICE_UNAVAILABLE);
+ }
+ }
+
+ @Override
+ public void onNetworkResponse(@NonNull SipDetails details) throws ImsException {
+ try {
+ mResponseBinder.onNetworkResponse(details);
} catch (RemoteException e) {
throw new ImsException(e.getMessage(), ImsException.CODE_ERROR_SERVICE_UNAVAILABLE);
}
diff --git a/telephony/java/android/telephony/ims/compat/stub/ImsCallSessionImplBase.java b/telephony/java/android/telephony/ims/compat/stub/ImsCallSessionImplBase.java
index 8dcd711a96a9..798e8019502f 100755
--- a/telephony/java/android/telephony/ims/compat/stub/ImsCallSessionImplBase.java
+++ b/telephony/java/android/telephony/ims/compat/stub/ImsCallSessionImplBase.java
@@ -417,6 +417,21 @@ public class ImsCallSessionImplBase extends IImsCallSession.Stub {
}
/**
+ * Deliver the bitrate for the indicated media type, direction and bitrate to the upper layer.
+ *
+ * @param mediaType MediaType is used to identify media stream such as audio or video.
+ * @param direction Direction of this packet stream (e.g. uplink or downlink).
+ * @param bitsPerSecond This value is the bitrate received from the NW through the Recommended
+ * bitrate MAC Control Element message and ImsStack converts this value from MAC bitrate
+ * to audio/video codec bitrate (defined in TS26.114).
+ * @hide
+ */
+ @Override
+ public void callSessionNotifyAnbr(int mediaType, int direction, int bitsPerSecond) {
+ // no-op; not supported in compat layer.
+ }
+
+ /**
* There are two different ImsCallSessionListeners that need to reconciled here, we need to
* convert the "old" version of the com.android.ims.internal.IImsCallSessionListener to the
* "new" version of the Listener android.telephony.ims.ImsCallSessionListener when calling
@@ -662,5 +677,11 @@ public class ImsCallSessionImplBase extends IImsCallSession.Stub {
public void callQualityChanged(CallQuality callQuality) throws RemoteException {
mNewListener.callQualityChanged(callQuality);
}
+
+ @Override
+ public void callSessionSendAnbrQuery(int mediaType, int direction,
+ int bitsPerSecond) throws RemoteException {
+ mNewListener.callSessionSendAnbrQuery(mediaType, direction, bitsPerSecond);
+ }
}
}
diff --git a/telephony/java/android/telephony/ims/feature/ConnectionFailureInfo.aidl b/telephony/java/android/telephony/ims/feature/ConnectionFailureInfo.aidl
new file mode 100644
index 000000000000..d24e5807d51d
--- /dev/null
+++ b/telephony/java/android/telephony/ims/feature/ConnectionFailureInfo.aidl
@@ -0,0 +1,19 @@
+/*
+ * Copyright (c) 2022 The Android Open Source Project
+ 2
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.telephony.ims.feature;
+
+parcelable ConnectionFailureInfo;
diff --git a/telephony/java/android/telephony/ims/feature/ConnectionFailureInfo.java b/telephony/java/android/telephony/ims/feature/ConnectionFailureInfo.java
new file mode 100644
index 000000000000..88d9aae3e19d
--- /dev/null
+++ b/telephony/java/android/telephony/ims/feature/ConnectionFailureInfo.java
@@ -0,0 +1,185 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.telephony.ims.feature;
+
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.util.SparseArray;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * Provides details on why transmitting IMS traffic failed.
+ *
+ * @hide
+ */
+public final class ConnectionFailureInfo implements Parcelable {
+
+ /** @hide */
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef(
+ prefix = "REASON_",
+ value = {
+ REASON_NONE,
+ REASON_ACCESS_DENIED,
+ REASON_NAS_FAILURE,
+ REASON_RACH_FAILURE,
+ REASON_RLC_FAILURE,
+ REASON_RRC_REJECT,
+ REASON_RRC_TIMEOUT,
+ REASON_NO_SERVICE,
+ REASON_PDN_NOT_AVAILABLE,
+ REASON_RF_BUSY,
+ REASON_UNSPECIFIED
+ })
+ public @interface FailureReason {}
+
+ /** Default value */
+ public static final int REASON_NONE = 0;
+ /** Access class check failed */
+ public static final int REASON_ACCESS_DENIED = 1;
+ /** 3GPP Non-access stratum failure */
+ public static final int REASON_NAS_FAILURE = 2;
+ /** Random access failure */
+ public static final int REASON_RACH_FAILURE = 3;
+ /** Radio link failure */
+ public static final int REASON_RLC_FAILURE = 4;
+ /** Radio connection establishment rejected by network */
+ public static final int REASON_RRC_REJECT = 5;
+ /** Radio connection establishment timed out */
+ public static final int REASON_RRC_TIMEOUT = 6;
+ /** Device currently not in service */
+ public static final int REASON_NO_SERVICE = 7;
+ /** The PDN is no more active */
+ public static final int REASON_PDN_NOT_AVAILABLE = 8;
+ /** Radio resource is busy with another subscription */
+ public static final int REASON_RF_BUSY = 9;
+ /** Unspecified reason */
+ public static final int REASON_UNSPECIFIED = 0xFFFF;
+
+ private static final SparseArray<String> sReasonMap;
+ static {
+ sReasonMap = new SparseArray<>();
+ sReasonMap.set(REASON_NONE, "NONE");
+ sReasonMap.set(REASON_ACCESS_DENIED, "ACCESS_DENIED");
+ sReasonMap.set(REASON_NAS_FAILURE, "NAS_FAILURE");
+ sReasonMap.set(REASON_RACH_FAILURE, "RACH_FAILURE");
+ sReasonMap.set(REASON_RLC_FAILURE, "RLC_FAILURE");
+ sReasonMap.set(REASON_RRC_REJECT, "RRC_REJECT");
+ sReasonMap.set(REASON_RRC_TIMEOUT, "RRC_TIMEOUT");
+ sReasonMap.set(REASON_NO_SERVICE, "NO_SERVICE");
+ sReasonMap.set(REASON_PDN_NOT_AVAILABLE, "PDN_NOT_AVAILABLE");
+ sReasonMap.set(REASON_RF_BUSY, "RF_BUSY");
+ sReasonMap.set(REASON_UNSPECIFIED, "UNSPECIFIED");
+ }
+
+ /** The reason of failure */
+ private final @FailureReason int mReason;
+
+ /**
+ * Failure cause code from network or modem specific to the failure
+ *
+ * Reference: 3GPP TS 24.401 Annex A (Cause values for EPS mobility management)
+ * Reference: 3GPP TS 24.501 Annex A (Cause values for 5GS mobility management)
+ */
+ private final int mCauseCode;
+
+ /** Retry wait time provided by network in milliseconds */
+ private final int mWaitTimeMillis;
+
+ private ConnectionFailureInfo(Parcel in) {
+ mReason = in.readInt();
+ mCauseCode = in.readInt();
+ mWaitTimeMillis = in.readInt();
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param reason The reason of failure.
+ * @param causeCode Failure cause code from network or modem specific to the failure.
+ * See 3GPP TS 24.401 Annex A (Cause values for EPS mobility management) and
+ * 3GPP TS 24.501 Annex A (Cause values for 5GS mobility management).
+ * @param waitTimeMillis Retry wait time provided by network in milliseconds.
+ * @hide
+ */
+ public ConnectionFailureInfo(@FailureReason int reason, int causeCode, int waitTimeMillis) {
+ mReason = reason;
+ mCauseCode = causeCode;
+ mWaitTimeMillis = waitTimeMillis;
+ }
+
+ /**
+ * @return the reason for the failure.
+ */
+ public @FailureReason int getReason() {
+ return mReason;
+ }
+
+ /**
+ * @return the cause code from the network or modem specific to the failure.
+ */
+ public int getCauseCode() {
+ return mCauseCode;
+ }
+
+ /**
+ * @return the retry wait time provided by the network in milliseconds.
+ */
+ public int getWaitTimeMillis() {
+ return mWaitTimeMillis;
+ }
+
+ /**
+ * @return the string format of {@link ConnectionFailureInfo}
+ */
+ @NonNull
+ @Override
+ public String toString() {
+ String reason = sReasonMap.get(mReason, "UNKNOWN");
+ return "ConnectionFailureInfo :: {" + mReason + " : " + reason + ", "
+ + mCauseCode + ", " + mWaitTimeMillis + "}";
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(@NonNull Parcel out, int flags) {
+ out.writeInt(mReason);
+ out.writeInt(mCauseCode);
+ out.writeInt(mWaitTimeMillis);
+ }
+
+ public static final @NonNull Creator<ConnectionFailureInfo> CREATOR =
+ new Creator<ConnectionFailureInfo>() {
+ @Override
+ public ConnectionFailureInfo createFromParcel(Parcel in) {
+ return new ConnectionFailureInfo(in);
+ }
+
+ @Override
+ public ConnectionFailureInfo[] newArray(int size) {
+ return new ConnectionFailureInfo[size];
+ }
+ };
+}
diff --git a/telephony/java/android/telephony/ims/feature/ImsFeature.java b/telephony/java/android/telephony/ims/feature/ImsFeature.java
index 174675fcde4c..a8fb36b591fa 100644
--- a/telephony/java/android/telephony/ims/feature/ImsFeature.java
+++ b/telephony/java/android/telephony/ims/feature/ImsFeature.java
@@ -342,8 +342,8 @@ public abstract class ImsFeature {
/**
* @return The SIM slot index associated with this ImsFeature.
*
- * @see SubscriptionManager#getSubscriptionIds(int) for more information on getting the
- * subscription IDs associated with this slot.
+ * @see SubscriptionManager#getSubscriptionId(int) for more information on getting the
+ * subscription ID associated with this slot.
* @hide
*/
@SystemApi
diff --git a/telephony/java/android/telephony/ims/feature/ImsTrafficSessionCallback.java b/telephony/java/android/telephony/ims/feature/ImsTrafficSessionCallback.java
new file mode 100644
index 000000000000..245ee1511d98
--- /dev/null
+++ b/telephony/java/android/telephony/ims/feature/ImsTrafficSessionCallback.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.telephony.ims.feature;
+
+import android.annotation.NonNull;
+
+/**
+ * A callback class used to receive the result of {@link MmTelFeature#startImsTrafficSession}.
+ * @hide
+ */
+public interface ImsTrafficSessionCallback {
+
+ /** The modem is ready to process the IMS traffic. */
+ void onReady();
+
+ /**
+ * Notifies that any IMS traffic is not sent to network due to any failure
+ * on cellular networks. IMS service shall call {@link MmTelFeature#stopImsTrafficSession()}
+ * when receiving this callback.
+ *
+ * @param info The information of the failure.
+ */
+ void onError(@NonNull ConnectionFailureInfo info);
+}
diff --git a/telephony/java/android/telephony/ims/feature/MmTelFeature.java b/telephony/java/android/telephony/ims/feature/MmTelFeature.java
index ebe11e938c39..746246c64e8c 100644
--- a/telephony/java/android/telephony/ims/feature/MmTelFeature.java
+++ b/telephony/java/android/telephony/ims/feature/MmTelFeature.java
@@ -16,23 +16,35 @@
package android.telephony.ims.feature;
+import android.annotation.CallbackExecutor;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
+import android.os.Binder;
import android.os.Bundle;
import android.os.Message;
import android.os.RemoteException;
+import android.os.ServiceSpecificException;
import android.telecom.TelecomManager;
+import android.telephony.AccessNetworkConstants;
import android.telephony.ims.ImsCallProfile;
import android.telephony.ims.ImsCallSession;
+import android.telephony.ims.ImsCallSessionListener;
+import android.telephony.ims.ImsException;
import android.telephony.ims.ImsReasonInfo;
import android.telephony.ims.ImsService;
+import android.telephony.ims.MediaQualityStatus;
+import android.telephony.ims.MediaThreshold;
import android.telephony.ims.RtpHeaderExtensionType;
+import android.telephony.ims.SrvccCall;
+import android.telephony.ims.aidl.IImsCallSessionListener;
import android.telephony.ims.aidl.IImsCapabilityCallback;
import android.telephony.ims.aidl.IImsMmTelFeature;
import android.telephony.ims.aidl.IImsMmTelListener;
import android.telephony.ims.aidl.IImsSmsListener;
+import android.telephony.ims.aidl.IImsTrafficSessionCallback;
+import android.telephony.ims.aidl.ISrvccStartedCallback;
import android.telephony.ims.stub.ImsCallSessionImplBase;
import android.telephony.ims.stub.ImsEcbmImplBase;
import android.telephony.ims.stub.ImsMultiEndpointImplBase;
@@ -50,6 +62,8 @@ import com.android.internal.telephony.util.TelephonyUtils;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
+import java.lang.ref.WeakReference;
+import java.util.HashMap;
import java.util.List;
import java.util.Set;
import java.util.concurrent.CancellationException;
@@ -57,7 +71,9 @@ import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionException;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executor;
+import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReference;
+import java.util.function.Consumer;
import java.util.function.Supplier;
/**
@@ -70,8 +86,12 @@ public class MmTelFeature extends ImsFeature {
private static final String LOG_TAG = "MmTelFeature";
private Executor mExecutor;
+ private ImsSmsImplBase mSmsImpl;
+ private HashMap<ImsTrafficSessionCallback, ImsTrafficSessionCallbackWrapper> mTrafficCallbacks =
+ new HashMap<>();
/**
+ * Creates a new MmTelFeature using the Executor set in {@link ImsService#getExecutor}
* @hide
*/
@SystemApi
@@ -239,7 +259,7 @@ public class MmTelFeature extends ImsFeature {
public void changeCapabilitiesConfiguration(CapabilityChangeRequest request,
IImsCapabilityCallback c) {
executeMethodAsyncNoException(() -> MmTelFeature.this
- .requestChangeEnabledCapabilities(request, c),
+ .requestChangeEnabledCapabilities(request, c),
"changeCapabilitiesConfiguration");
}
@@ -251,40 +271,121 @@ public class MmTelFeature extends ImsFeature {
}
@Override
+ public void setMediaQualityThreshold(@MediaQualityStatus.MediaSessionType int sessionType,
+ MediaThreshold mediaThreshold) {
+ if (mediaThreshold != null) {
+ executeMethodAsyncNoException(() -> setMediaThreshold(sessionType, mediaThreshold),
+ "setMediaQualityThreshold");
+ } else {
+ executeMethodAsyncNoException(() -> clearMediaThreshold(sessionType),
+ "clearMediaQualityThreshold");
+ }
+ }
+
+ @Override
+ public MediaQualityStatus queryMediaQualityStatus(
+ @MediaQualityStatus.MediaSessionType int sessionType)
+ throws RemoteException {
+ return executeMethodAsyncForResult(() -> MmTelFeature.this.queryMediaQualityStatus(
+ sessionType), "queryMediaQualityStatus");
+ }
+
+ @Override
public void setSmsListener(IImsSmsListener l) {
executeMethodAsyncNoException(() -> MmTelFeature.this.setSmsListener(l),
- "setSmsListener");
+ "setSmsListener", getImsSmsImpl().getExecutor());
}
@Override
public void sendSms(int token, int messageRef, String format, String smsc, boolean retry,
byte[] pdu) {
executeMethodAsyncNoException(() -> MmTelFeature.this
- .sendSms(token, messageRef, format, smsc, retry, pdu), "sendSms");
+ .sendSms(token, messageRef, format, smsc, retry, pdu), "sendSms",
+ getImsSmsImpl().getExecutor());
+ }
+
+ @Override
+ public void onMemoryAvailable(int token) {
+ executeMethodAsyncNoException(() -> MmTelFeature.this
+ .onMemoryAvailable(token), "onMemoryAvailable", getImsSmsImpl().getExecutor());
}
@Override
public void acknowledgeSms(int token, int messageRef, int result) {
executeMethodAsyncNoException(() -> MmTelFeature.this
- .acknowledgeSms(token, messageRef, result), "acknowledgeSms");
+ .acknowledgeSms(token, messageRef, result), "acknowledgeSms",
+ getImsSmsImpl().getExecutor());
+ }
+
+ @Override
+ public void acknowledgeSmsWithPdu(int token, int messageRef, int result, byte[] pdu) {
+ executeMethodAsyncNoException(() -> MmTelFeature.this
+ .acknowledgeSms(token, messageRef, result, pdu), "acknowledgeSms",
+ getImsSmsImpl().getExecutor());
}
@Override
public void acknowledgeSmsReport(int token, int messageRef, int result) {
executeMethodAsyncNoException(() -> MmTelFeature.this
- .acknowledgeSmsReport(token, messageRef, result), "acknowledgeSmsReport");
+ .acknowledgeSmsReport(token, messageRef, result), "acknowledgeSmsReport",
+ getImsSmsImpl().getExecutor());
}
@Override
public String getSmsFormat() {
return executeMethodAsyncForResultNoException(() -> MmTelFeature.this
- .getSmsFormat(), "getSmsFormat");
+ .getSmsFormat(), "getSmsFormat", getImsSmsImpl().getExecutor());
}
@Override
public void onSmsReady() {
executeMethodAsyncNoException(() -> MmTelFeature.this.onSmsReady(),
- "onSmsReady");
+ "onSmsReady", getImsSmsImpl().getExecutor());
+ }
+
+ @Override
+ public void notifySrvccStarted(final ISrvccStartedCallback cb) {
+ executeMethodAsyncNoException(
+ () -> MmTelFeature.this.notifySrvccStarted(
+ (profiles) -> {
+ try {
+ cb.onSrvccCallNotified(profiles);
+ } catch (Exception e) {
+ Log.e(LOG_TAG, "onSrvccCallNotified e=" + e);
+ }
+ }),
+ "notifySrvccStarted");
+ }
+
+ @Override
+ public void notifySrvccCompleted() {
+ executeMethodAsyncNoException(
+ () -> MmTelFeature.this.notifySrvccCompleted(), "notifySrvccCompleted");
+ }
+
+ @Override
+ public void notifySrvccFailed() {
+ executeMethodAsyncNoException(
+ () -> MmTelFeature.this.notifySrvccFailed(), "notifySrvccFailed");
+ }
+
+ @Override
+ public void notifySrvccCanceled() {
+ executeMethodAsyncNoException(
+ () -> MmTelFeature.this.notifySrvccCanceled(), "notifySrvccCanceled");
+ }
+
+ @Override
+ public void setTerminalBasedCallWaitingStatus(boolean enabled) throws RemoteException {
+ synchronized (mLock) {
+ try {
+ MmTelFeature.this.setTerminalBasedCallWaitingStatus(enabled);
+ } catch (ServiceSpecificException se) {
+ throw new ServiceSpecificException(se.errorCode, se.getMessage());
+ } catch (Exception e) {
+ throw new RemoteException(e.getMessage());
+ }
+ }
}
// Call the methods with a clean calling identity on the executor and wait indefinitely for
@@ -310,6 +411,17 @@ public class MmTelFeature extends ImsFeature {
}
}
+ private void executeMethodAsyncNoException(Runnable r, String errorLogName,
+ Executor executor) {
+ try {
+ CompletableFuture.runAsync(
+ () -> TelephonyUtils.runWithCleanCallingIdentity(r), executor).join();
+ } catch (CancellationException | CompletionException e) {
+ Log.w(LOG_TAG, "MmTelFeature Binder - " + errorLogName + " exception: "
+ + e.getMessage());
+ }
+ }
+
private <T> T executeMethodAsyncForResult(Supplier<T> r,
String errorLogName) throws RemoteException {
CompletableFuture<T> future = CompletableFuture.supplyAsync(
@@ -335,6 +447,19 @@ public class MmTelFeature extends ImsFeature {
return null;
}
}
+
+ private <T> T executeMethodAsyncForResultNoException(Supplier<T> r,
+ String errorLogName, Executor executor) {
+ CompletableFuture<T> future = CompletableFuture.supplyAsync(
+ () -> TelephonyUtils.runWithCleanCallingIdentity(r), executor);
+ try {
+ return future.get();
+ } catch (ExecutionException | InterruptedException e) {
+ Log.w(LOG_TAG, "MmTelFeature Binder - " + errorLogName + " exception: "
+ + e.getMessage());
+ return null;
+ }
+ }
};
/**
@@ -490,11 +615,19 @@ public class MmTelFeature extends ImsFeature {
/**
* Called when the IMS provider receives an incoming call.
* @param c The {@link ImsCallSession} associated with the new call.
+ * @param callId The call ID of the session of the new incoming call.
+ * @param extras A bundle containing extra parameters related to the call. See
+ * {@link #EXTRA_IS_UNKNOWN_CALL} and {@link #EXTRA_IS_USSD} above.
+ * @return the listener to listen to the session events. An {@link ImsCallSession} can only
+ * hold one listener at a time. see {@link ImsCallSessionListener}.
+ * If this method returns {@code null}, then the call could not be placed.
* @hide
*/
@Override
- public void onIncomingCall(IImsCallSession c, Bundle extras) {
-
+ @Nullable
+ public IImsCallSessionListener onIncomingCall(IImsCallSession c,
+ String callId, Bundle extras) {
+ return null;
}
/**
@@ -517,6 +650,200 @@ public class MmTelFeature extends ImsFeature {
public void onVoiceMessageCountUpdate(int count) {
}
+
+ /**
+ * Called to set the audio handler for this connection.
+ * @param imsAudioHandler an {@link ImsAudioHandler} used to handle the audio
+ * for this IMS call.
+ * @hide
+ */
+ @Override
+ public void onAudioModeIsVoipChanged(int imsAudioHandler) {
+
+ }
+
+ /**
+ * Called when the IMS triggers EPS fallback procedure.
+ *
+ * @param reason specifies the reason that causes EPS fallback.
+ * @hide
+ */
+ @Override
+ public void onTriggerEpsFallback(@EpsFallbackReason int reason) {
+
+ }
+
+ /**
+ * Called when the IMS notifies the upcoming traffic type to the radio.
+ *
+ * @param token A nonce to identify the request
+ * @param trafficType The {@link ImsTrafficType} type for IMS traffic.
+ * @param accessNetworkType The {@link AccessNetworkConstants#RadioAccessNetworkType}
+ * type of the radio access network.
+ * @param trafficDirection Indicates whether traffic is originated by mobile originated or
+ * mobile terminated use case eg. MO/MT call/SMS etc.
+ * @param callback The callback to receive the result.
+ * @hide
+ */
+ @Override
+ public void onStartImsTrafficSession(int token,
+ @ImsTrafficType int trafficType,
+ @AccessNetworkConstants.RadioAccessNetworkType int accessNetworkType,
+ @ImsTrafficDirection int trafficDirection,
+ IImsTrafficSessionCallback callback) {
+
+ }
+
+ /**
+ * Called when the IMS notifies the traffic type has been stopped.
+ *
+ * @param token A nonce registered with {@link #onStartImsTrafficSession}.
+ * @param accessNetworkType The {@link AccessNetworkConstants#RadioAccessNetworkType}
+ * type of the radio access network.
+ * @hide
+ */
+ @Override
+ public void onModifyImsTrafficSession(int token,
+ @AccessNetworkConstants.RadioAccessNetworkType int accessNetworkType) {
+
+ }
+
+ /**
+ * Called when the IMS notifies the traffic type has been stopped.
+ *
+ * @param token A nonce registered with {@link #onStartImsTrafficSession}.
+ * @hide
+ */
+ @Override
+ public void onStopImsTrafficSession(int token) {
+
+ }
+
+ /**
+ * Called when the IMS provider notifies {@link MediaQualityStatus}.
+ *
+ * @param status media quality status currently measured.
+ * @hide
+ */
+ @Override
+ public void onMediaQualityStatusChanged(MediaQualityStatus status) {
+
+ }
+ }
+
+ /**
+ * A wrapper class of {@link ImsTrafficSessionCallback}.
+ * @hide
+ */
+ public static class ImsTrafficSessionCallbackWrapper {
+ public static final int INVALID_TOKEN = -1;
+
+ private static final int MAX_TOKEN = 0x10000;
+
+ private static final AtomicInteger sTokenGenerator = new AtomicInteger();
+
+ /** Callback to receive the response */
+ private IImsTrafficSessionCallbackStub mCallback = null;
+ /** Identifier to distinguish each IMS traffic request */
+ private int mToken = INVALID_TOKEN;
+
+ private ImsTrafficSessionCallback mImsTrafficSessionCallback;
+
+ private ImsTrafficSessionCallbackWrapper(ImsTrafficSessionCallback callback) {
+ mImsTrafficSessionCallback = callback;
+ }
+
+ /**
+ * Updates the callback.
+ *
+ * The mToken should be kept since it is used to identify the traffic notified to the modem
+ * until calling {@link MmtelFEature#stopImsTrafficSession}.
+ */
+ final void update(@NonNull @CallbackExecutor Executor executor) {
+ if (executor == null) {
+ throw new IllegalArgumentException(
+ "ImsTrafficSessionCallback Executor must be non-null");
+ }
+
+ if (mCallback == null) {
+ // initial start of Ims traffic.
+ mCallback = new IImsTrafficSessionCallbackStub(
+ mImsTrafficSessionCallback, executor);
+ mToken = generateToken();
+ } else {
+ // handover between cellular and Wi-Fi
+ mCallback.update(executor);
+ }
+ }
+
+ /**
+ * Using a static class and weak reference here to avoid memory leak caused by the
+ * {@link IImsTrafficSessionCallback.Stub} callback retaining references to the outside
+ * {@link ImsTrafficSessionCallback}.
+ */
+ private static class IImsTrafficSessionCallbackStub
+ extends IImsTrafficSessionCallback.Stub {
+ private WeakReference<ImsTrafficSessionCallback> mImsTrafficSessionCallbackWeakRef;
+ private Executor mExecutor;
+
+ IImsTrafficSessionCallbackStub(ImsTrafficSessionCallback imsTrafficCallback,
+ Executor executor) {
+ mImsTrafficSessionCallbackWeakRef =
+ new WeakReference<ImsTrafficSessionCallback>(imsTrafficCallback);
+ mExecutor = executor;
+ }
+
+ void update(Executor executor) {
+ mExecutor = executor;
+ }
+
+ @Override
+ public void onReady() {
+ ImsTrafficSessionCallback callback = mImsTrafficSessionCallbackWeakRef.get();
+ if (callback == null) return;
+
+ Binder.withCleanCallingIdentity(
+ () -> mExecutor.execute(() -> callback.onReady()));
+ }
+
+ @Override
+ public void onError(ConnectionFailureInfo info) {
+ ImsTrafficSessionCallback callback = mImsTrafficSessionCallbackWeakRef.get();
+ if (callback == null) return;
+
+ Binder.withCleanCallingIdentity(
+ () -> mExecutor.execute(() -> callback.onError(info)));
+ }
+ }
+
+ /**
+ * Returns the callback binder.
+ */
+ final IImsTrafficSessionCallbackStub getCallbackBinder() {
+ return mCallback;
+ }
+
+ /**
+ * Returns the token.
+ */
+ final int getToken() {
+ return mToken;
+ }
+
+ /**
+ * Resets the members.
+ * It's called by {@link MmTelFeature#stopImsTrafficSession}.
+ */
+ final void reset() {
+ mCallback = null;
+ mToken = INVALID_TOKEN;
+ }
+
+ private static int generateToken() {
+ int token = sTokenGenerator.incrementAndGet();
+ if (token == MAX_TOKEN) sTokenGenerator.set(0);
+ return token;
+ }
}
/**
@@ -566,6 +893,147 @@ public class MmTelFeature extends ImsFeature {
public static final String EXTRA_IS_UNKNOWN_CALL =
"android.telephony.ims.feature.extra.IS_UNKNOWN_CALL";
+ /** @hide */
+ @IntDef(
+ prefix = "AUDIO_HANDLER_",
+ value = {
+ AUDIO_HANDLER_ANDROID,
+ AUDIO_HANDLER_BASEBAND
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface ImsAudioHandler {}
+
+ /**
+ * Audio Handler - Android
+ * @hide
+ */
+ @SystemApi
+ public static final int AUDIO_HANDLER_ANDROID = 0;
+
+ /**
+ * Audio Handler - Baseband
+ * @hide
+ */
+ @SystemApi
+ public static final int AUDIO_HANDLER_BASEBAND = 1;
+
+ /** @hide */
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef(
+ prefix = "EPS_FALLBACK_REASON_",
+ value = {
+ EPS_FALLBACK_REASON_INVALID,
+ EPS_FALLBACK_REASON_NO_NETWORK_TRIGGER,
+ EPS_FALLBACK_REASON_NO_NETWORK_RESPONSE,
+ })
+ public @interface EpsFallbackReason {}
+
+ /**
+ * Default value. Internal use only.
+ * This value should not be used to trigger EPS fallback.
+ * @hide
+ */
+ public static final int EPS_FALLBACK_REASON_INVALID = -1;
+
+ /**
+ * If the network only supports the EPS fallback in 5G NR SA for voice calling and the EPS
+ * Fallback procedure by the network during the call setup is not triggered, UE initiated
+ * fallback will be triggered with this reason. The modem shall locally release the 5G NR
+ * SA RRC connection and acquire the LTE network and perform a tracking area update
+ * procedure. After the EPS fallback procedure is completed, the call setup for voice will
+ * be established if there is no problem.
+ *
+ * @hide
+ */
+ public static final int EPS_FALLBACK_REASON_NO_NETWORK_TRIGGER = 1;
+
+ /**
+ * If the UE doesn't receive any response for SIP INVITE within a certain timeout in 5G NR
+ * SA for MO voice calling, the device determines that voice call is not available in 5G and
+ * terminates all active SIP dialogs and SIP requests and enters IMS non-registered state.
+ * In that case, UE initiated fallback will be triggered with this reason. The modem shall
+ * reset modem's data buffer of IMS PDU to prevent the ghost call. After the EPS fallback
+ * procedure is completed, VoLTE call could be tried if there is no problem.
+ *
+ * @hide
+ */
+ public static final int EPS_FALLBACK_REASON_NO_NETWORK_RESPONSE = 2;
+
+ /** @hide */
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef(
+ prefix = "IMS_TRAFFIC_TYPE_",
+ value = {
+ IMS_TRAFFIC_TYPE_NONE,
+ IMS_TRAFFIC_TYPE_EMERGENCY,
+ IMS_TRAFFIC_TYPE_EMERGENCY_SMS,
+ IMS_TRAFFIC_TYPE_VOICE,
+ IMS_TRAFFIC_TYPE_VIDEO,
+ IMS_TRAFFIC_TYPE_SMS,
+ IMS_TRAFFIC_TYPE_REGISTRATION,
+ IMS_TRAFFIC_TYPE_UT_XCAP
+ })
+ public @interface ImsTrafficType {}
+
+ /**
+ * Default value for initialization. Internal use only.
+ * @hide
+ */
+ public static final int IMS_TRAFFIC_TYPE_NONE = -1;
+ /**
+ * Emergency call
+ * @hide
+ */
+ public static final int IMS_TRAFFIC_TYPE_EMERGENCY = 0;
+ /**
+ * Emergency SMS
+ * @hide
+ */
+ public static final int IMS_TRAFFIC_TYPE_EMERGENCY_SMS = 1;
+ /**
+ * Voice call
+ * @hide
+ */
+ public static final int IMS_TRAFFIC_TYPE_VOICE = 2;
+ /**
+ * Video call
+ * @hide
+ */
+ public static final int IMS_TRAFFIC_TYPE_VIDEO = 3;
+ /**
+ * SMS over IMS
+ * @hide
+ */
+ public static final int IMS_TRAFFIC_TYPE_SMS = 4;
+ /**
+ * IMS registration and subscription for reg event package (signaling)
+ * @hide
+ */
+ public static final int IMS_TRAFFIC_TYPE_REGISTRATION = 5;
+ /**
+ * Ut/XCAP (XML Configuration Access Protocol)
+ * @hide
+ */
+ public static final int IMS_TRAFFIC_TYPE_UT_XCAP = 6;
+
+ /** @hide */
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef(
+ prefix = { "IMS_TRAFFIC_DIRECTION_" },
+ value = {IMS_TRAFFIC_DIRECTION_INCOMING, IMS_TRAFFIC_DIRECTION_OUTGOING})
+ public @interface ImsTrafficDirection {}
+
+ /**
+ * Indicates that the traffic is an incoming traffic.
+ * @hide
+ */
+ public static final int IMS_TRAFFIC_DIRECTION_INCOMING = 0;
+ /**
+ * Indicates that the traffic is an outgoing traffic.
+ * @hide
+ */
+ public static final int IMS_TRAFFIC_DIRECTION_OUTGOING = 1;
+
private IImsMmTelListener mListener;
/**
@@ -626,12 +1094,41 @@ public class MmTelFeature extends ImsFeature {
}
/**
+ * Notify the framework that the measured media quality has crossed a threshold set by {@link
+ * MmTelFeature#setMediaThreshold}
+ *
+ * @param status current media quality status measured.
+ * @hide
+ */
+ @SystemApi
+ public final void notifyMediaQualityStatusChanged(
+ @NonNull MediaQualityStatus status) {
+ if (status == null) {
+ throw new IllegalArgumentException(
+ "MediaQualityStatus must be non-null!");
+ }
+ Log.i(LOG_TAG, "notifyMediaQualityStatusChanged " + status);
+ IImsMmTelListener listener = getListener();
+ if (listener == null) {
+ throw new IllegalStateException("Session is not available.");
+ }
+ try {
+ listener.onMediaQualityStatusChanged(status);
+ } catch (RemoteException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ /**
* Notify the framework of an incoming call.
* @param c The {@link ImsCallSessionImplBase} of the new incoming call.
* @param extras A bundle containing extra parameters related to the call. See
* {@link #EXTRA_IS_UNKNOWN_CALL} and {@link #EXTRA_IS_USSD} above.
- * @hide
+ * @hide
+ *
+ * @deprecated use {@link #notifyIncomingCall(ImsCallSessionImplBase, String, Bundle)} instead
*/
+ @Deprecated
@SystemApi
public final void notifyIncomingCall(@NonNull ImsCallSessionImplBase c,
@NonNull Bundle extras) {
@@ -645,7 +1142,46 @@ public class MmTelFeature extends ImsFeature {
}
try {
c.setDefaultExecutor(MmTelFeature.this.mExecutor);
- listener.onIncomingCall(c.getServiceImpl(), extras);
+ listener.onIncomingCall(c.getServiceImpl(), null, extras);
+ } catch (RemoteException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ /**
+ * Notify the framework of an incoming call.
+ * @param c The {@link ImsCallSessionImplBase} of the new incoming call.
+ * @param callId The call ID of the session of the new incoming call.
+ * @param extras A bundle containing extra parameters related to the call. See
+ * {@link #EXTRA_IS_UNKNOWN_CALL} and {@link #EXTRA_IS_USSD} above.
+ * @return The listener used by the framework to listen to call session events created
+ * from the ImsService.
+ * If this method returns {@code null}, then the call could not be placed.
+ * @hide
+ */
+ @SystemApi
+ @Nullable
+ public final ImsCallSessionListener notifyIncomingCall(
+ @NonNull ImsCallSessionImplBase c, @NonNull String callId, @NonNull Bundle extras) {
+ if (c == null || callId == null || extras == null) {
+ throw new IllegalArgumentException("ImsCallSessionImplBase, callId, and Bundle can "
+ + "not be null.");
+ }
+ IImsMmTelListener listener = getListener();
+ if (listener == null) {
+ throw new IllegalStateException("Session is not available.");
+ }
+ try {
+ c.setDefaultExecutor(MmTelFeature.this.mExecutor);
+ IImsCallSessionListener isl =
+ listener.onIncomingCall(c.getServiceImpl(), callId, extras);
+ if (isl != null) {
+ ImsCallSessionListener iCSL = new ImsCallSessionListener(isl);
+ iCSL.setDefaultExecutor(MmTelFeature.this.mExecutor);
+ return iCSL;
+ } else {
+ return null;
+ }
} catch (RemoteException e) {
throw new RuntimeException(e);
}
@@ -687,7 +1223,7 @@ public class MmTelFeature extends ImsFeature {
throw new IllegalStateException("Session is not available.");
}
try {
- listener.onIncomingCall(c, extras);
+ listener.onIncomingCall(c, null, extras);
} catch (RemoteException e) {
throw new RuntimeException(e);
}
@@ -712,6 +1248,176 @@ public class MmTelFeature extends ImsFeature {
}
/**
+ * Sets the audio handler for this connection. The vendor IMS stack will invoke this API
+ * to inform Telephony/Telecom layers about which audio handlers i.e. either Android or Modem
+ * shall be used for handling the IMS call audio.
+ *
+ * @param imsAudioHandler {@link MmTelFeature#ImsAudioHandler} used to handle the audio
+ * for this IMS call.
+ * @hide
+ */
+ @SystemApi
+ public final void setCallAudioHandler(@ImsAudioHandler int imsAudioHandler) {
+ IImsMmTelListener listener = getListener();
+ if (listener == null) {
+ throw new IllegalStateException("Session is not available.");
+ }
+ try {
+ listener.onAudioModeIsVoipChanged(imsAudioHandler);
+ } catch (RemoteException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ /**
+ * Triggers the EPS fallback procedure.
+ *
+ * @param reason specifies the reason that causes EPS fallback.
+ * @hide
+ */
+ public final void triggerEpsFallback(@EpsFallbackReason int reason) {
+ IImsMmTelListener listener = getListener();
+ if (listener == null) {
+ throw new IllegalStateException("Session is not available.");
+ }
+ try {
+ listener.onTriggerEpsFallback(reason);
+ } catch (RemoteException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ /**
+ * Starts a new IMS traffic session with the framework.
+ *
+ * This API notifies the NAS and RRC layers of the modem that IMS traffic of type
+ * {@link ImsTrafficType} is starting for the IMS session represented by a
+ * {@link ImsTrafficSessionCallback}. The {@link ImsTrafficSessionCallback}
+ * will notify the caller when IMS traffic is ready to start via the
+ * {@link ImsTrafficSessionCallback#onReady()} callback. If there was an error starting
+ * IMS traffic for the specified traffic type, {@link ImsTrafficSessionCallback#onError()} will
+ * be called, which will also notify the caller of the reason of the failure.
+ *
+ * If there is a handover that changes the {@link AccessNetworkConstants#RadioAccessNetworkType}
+ * of this IMS traffic session, then {@link #modifyImsTrafficSession} should be called. This is
+ * used, for example, when a WiFi <-> cellular handover occurs.
+ *
+ * Once the IMS traffic session is finished, {@link #stopImsTrafficSession} must be called.
+ *
+ * Note: This API will be used to prioritize RF resources in case of DSDS. The service priority
+ * is EMERGENCY > EMERGENCY SMS > VOICE > VIDEO > SMS > REGISTRATION > Ut/XCAP. RF
+ * shall be prioritized to the subscription which handles the higher priority service.
+ * When both subscriptions are handling the same type of service, then RF shall be
+ * prioritized to the voice preferred sub.
+ *
+ * @param trafficType The {@link ImsTrafficType} type for IMS traffic.
+ * @param accessNetworkType The {@link AccessNetworkConstants#RadioAccessNetworkType} type of
+ * the radio access network.
+ * @param trafficDirection Indicates whether traffic is originated by mobile originated or
+ * mobile terminated use case eg. MO/MT call/SMS etc.
+ * @param executor The Executor that will be used to call the {@link ImsTrafficSessionCallback}.
+ * @param callback The session representing the IMS Session associated with a specific
+ * trafficType. This callback instance should only be used for the specified traffic type
+ * until {@link #stopImsTrafficSession} is called.
+ *
+ * @see modifyImsTrafficSession
+ * @see stopImsTrafficSession
+ *
+ * @hide
+ */
+ public final void startImsTrafficSession(@ImsTrafficType int trafficType,
+ @AccessNetworkConstants.RadioAccessNetworkType int accessNetworkType,
+ @ImsTrafficDirection int trafficDirection,
+ @NonNull Executor executor, @NonNull ImsTrafficSessionCallback callback) {
+ IImsMmTelListener listener = getListener();
+ if (listener == null) {
+ throw new IllegalStateException("Session is not available.");
+ }
+ // TODO: retrieve from the callback list
+ ImsTrafficSessionCallbackWrapper callbackWrapper = mTrafficCallbacks.get(callback);
+ if (callbackWrapper == null) {
+ callbackWrapper = new ImsTrafficSessionCallbackWrapper(callback);
+ mTrafficCallbacks.put(callback, callbackWrapper);
+ }
+ try {
+ callbackWrapper.update(executor);
+ listener.onStartImsTrafficSession(callbackWrapper.getToken(),
+ trafficType, accessNetworkType, trafficDirection,
+ callbackWrapper.getCallbackBinder());
+ } catch (RemoteException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ /**
+ * Modifies an existing IMS traffic session represented by the associated
+ * {@link ImsTrafficSessionCallback}.
+ *
+ * The {@link ImsTrafficSessionCallback} will notify the caller when IMS traffic is ready to
+ * start after modification using the {@link ImsTrafficSessionCallback#onReady()} callback.
+ * If there was an error modifying IMS traffic for the new radio access network type type,
+ * {@link ImsTrafficSessionCallback#onError()} will be called, which will also notify the
+ * caller of the reason of the failure.
+ *
+ * @param accessNetworkType The {@link AccessNetworkConstants#RadioAccessNetworkType} type of
+ * the radio access network.
+ * @param callback The callback registered with {@link #startImsTrafficSession}.
+ *
+ * @see startImsTrafficSession
+ * @see stopImsTrafficSession
+ *
+ * @hide
+ */
+ public final void modifyImsTrafficSession(
+ @AccessNetworkConstants.RadioAccessNetworkType int accessNetworkType,
+ @NonNull ImsTrafficSessionCallback callback) {
+ IImsMmTelListener listener = getListener();
+ if (listener == null) {
+ throw new IllegalStateException("Session is not available.");
+ }
+ ImsTrafficSessionCallbackWrapper callbackWrapper = mTrafficCallbacks.get(callback);
+ if (callbackWrapper == null) {
+ // should not reach here.
+ throw new IllegalStateException("Unknown ImsTrafficSessionCallback instance.");
+ }
+ try {
+ listener.onModifyImsTrafficSession(callbackWrapper.getToken(), accessNetworkType);
+ } catch (RemoteException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ /**
+ * Notifies the framework that the IMS traffic session represented by the associated
+ * {@link ImsTrafficSessionCallback} has ended.
+ *
+ * @param callback The callback registered with {@link #startImsTrafficSession}.
+ *
+ * @see startImsTrafficSession
+ * @see modifyImsTrafficSession
+ *
+ * @hide
+ */
+ public final void stopImsTrafficSession(@NonNull ImsTrafficSessionCallback callback) {
+ IImsMmTelListener listener = getListener();
+ if (listener == null) {
+ throw new IllegalStateException("Session is not available.");
+ }
+ ImsTrafficSessionCallbackWrapper callbackWrapper = mTrafficCallbacks.get(callback);
+ if (callbackWrapper == null) {
+ // should not reach here.
+ throw new IllegalStateException("Unknown ImsTrafficSessionCallback instance.");
+ }
+ try {
+ listener.onStopImsTrafficSession(callbackWrapper.getToken());
+ callbackWrapper.reset();
+ mTrafficCallbacks.remove(callback);
+ } catch (RemoteException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ /**
* Provides the MmTelFeature with the ability to return the framework Capability Configuration
* for a provided Capability. If the framework calls {@link #changeEnabledCapabilities} and
* includes a capability A to enable or disable, this method should return the correct enabled
@@ -749,6 +1455,62 @@ public class MmTelFeature extends ImsFeature {
}
/**
+ * Called by the framework to pass {@link MediaThreshold}. The MmTelFeature should override this
+ * method to get Media quality threshold. This will pass the consolidated threshold values from
+ * Telephony framework. IMS provider needs to monitor media quality of active call and notify
+ * media quality {@link #notifyMediaQualityStatusChanged(MediaQualityStatus)} when the measured
+ * media quality crosses at least one of {@link MediaThreshold} set by this.
+ *
+ * @param mediaSessionType media session type for this Threshold info.
+ * @param mediaThreshold media threshold information
+ * @hide
+ */
+ @SystemApi
+ public void setMediaThreshold(
+ @MediaQualityStatus.MediaSessionType int mediaSessionType,
+ @NonNull MediaThreshold mediaThreshold) {
+ // Base Implementation - Should be overridden.
+ Log.d(LOG_TAG, "setMediaThreshold is not supported." + mediaThreshold);
+ }
+
+ /**
+ * The MmTelFeature should override this method to clear Media quality thresholds that were
+ * registered and stop media quality status updates.
+ *
+ * @param mediaSessionType media session type
+ * @hide
+ */
+ @SystemApi
+ public void clearMediaThreshold(@MediaQualityStatus.MediaSessionType int mediaSessionType) {
+ // Base Implementation - Should be overridden.
+ Log.d(LOG_TAG, "clearMediaThreshold is not supported." + mediaSessionType);
+ }
+
+ /**
+ * IMS provider should override this method to return currently measured media quality status.
+ *
+ * <p/>
+ * If media quality status is not yet measured after call is active, it needs to notify media
+ * quality status {@link #notifyMediaQualityStatusChanged(MediaQualityStatus)} when the first
+ * measurement is done.
+ *
+ * @param mediaSessionType media session type
+ * @return Current media quality status. It could be null if media quality status is not
+ * measured yet or {@link MediaThreshold} was not set corresponding to the media session
+ * type.
+ *
+ * @hide
+ */
+ @SystemApi
+ @Nullable
+ public MediaQualityStatus queryMediaQualityStatus(
+ @MediaQualityStatus.MediaSessionType int mediaSessionType) {
+ // Base Implementation - Should be overridden.
+ Log.d(LOG_TAG, "queryMediaQualityStatus is not supported." + mediaSessionType);
+ return null;
+ }
+
+ /**
* Creates a {@link ImsCallProfile} from the service capabilities & IMS registration state.
*
* @param callSessionType a service type that is specified in {@link ImsCallProfile}
@@ -878,6 +1640,19 @@ public class MmTelFeature extends ImsFeature {
}
/**
+ * @hide
+ */
+ public @NonNull ImsSmsImplBase getImsSmsImpl() {
+ synchronized (mLock) {
+ if (mSmsImpl == null) {
+ mSmsImpl = getSmsImplementation();
+ mSmsImpl.setDefaultExecutor(mExecutor);
+ }
+ return mSmsImpl;
+ }
+ }
+
+ /**
* @return The {@link ImsUtImplBase} Ut interface implementation for the supplementary service
* configuration.
* @hide
@@ -937,27 +1712,123 @@ public class MmTelFeature extends ImsFeature {
// Base Implementation - Should be overridden
}
+ /**
+ * Notifies the MmTelFeature of the enablement status of terminal based call waiting
+ *
+ * If the terminal based call waiting is provisioned,
+ * IMS controls the enablement of terminal based call waiting which is defined
+ * in 3GPP TS 24.615.
+ *
+ * @param enabled user setting controlling whether or not call waiting is enabled.
+ *
+ * @hide
+ */
+ @SystemApi
+ public void setTerminalBasedCallWaitingStatus(boolean enabled) {
+ // Base Implementation - Should be overridden by IMS service
+ throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION,
+ "Not implemented on device.");
+ }
+
+ /**
+ * Notifies the MmTelFeature that the network has initiated an SRVCC (Single radio voice
+ * call continuity) for all IMS calls. When the network initiates an SRVCC, calls from
+ * the LTE domain are handed over to the legacy circuit switched domain. The modem requires
+ * knowledge of ongoing calls in the IMS domain in order to complete the SRVCC operation.
+ * <p>
+ * @param consumer The callback used to notify the framework of the list of IMS calls and their
+ * state at the time of the SRVCC.
+ *
+ * @hide
+ */
+ @SystemApi
+ public void notifySrvccStarted(@NonNull Consumer<List<SrvccCall>> consumer) {
+ // Base Implementation - Should be overridden by IMS service
+ }
+
+ /**
+ * Notifies the MmTelFeature that the SRVCC is completed and the calls have been moved
+ * over to the circuit-switched domain.
+ * {@link android.telephony.CarrierConfigManager.ImsVoice#KEY_SRVCC_TYPE_INT_ARRAY}
+ * specifies the calls can be moved. Other calls will be disconnected.
+ * <p>
+ * The MmTelFeature may now release all resources related to the IMS calls.
+ *
+ * @hide
+ */
+ @SystemApi
+ public void notifySrvccCompleted() {
+ // Base Implementation - Should be overridden by IMS service
+ }
+
+ /**
+ * Notifies the MmTelFeature that the SRVCC has failed.
+ *
+ * The handover can fail by encountering a failure at the radio level
+ * or temporary MSC server internal errors in handover procedure.
+ * Refer to 3GPP TS 23.216 section 8 Handover Failure.
+ * <p>
+ * IMS service will recover and continue calls over IMS.
+ * Per TS 24.237 12.2.4.2, UE shall send SIP UPDATE request containing the reason-text
+ * set to "failure to transition to CS domain".
+ *
+ * @hide
+ */
+ @SystemApi
+ public void notifySrvccFailed() {
+ // Base Implementation - Should be overridden by IMS service
+ }
+
+ /**
+ * Notifies the MmTelFeature that the SRVCC has been canceled.
+ *
+ * Since the state of network can be changed, the network can decide to terminate
+ * the handover procedure before its completion and to return to its state before the handover
+ * procedure was triggered.
+ * Refer to 3GPP TS 23.216 section 8.1.3 Handover Cancellation.
+ *
+ * <p>
+ * IMS service will recover and continue calls over IMS.
+ * Per TS 24.237 12.2.4.2, UE shall send SIP UPDATE request containing the reason-text
+ * set to "handover canceled".
+ *
+ * @hide
+ */
+ @SystemApi
+ public void notifySrvccCanceled() {
+ // Base Implementation - Should be overridden by IMS service
+ }
+
private void setSmsListener(IImsSmsListener listener) {
- getSmsImplementation().registerSmsListener(listener);
+ getImsSmsImpl().registerSmsListener(listener);
}
private void sendSms(int token, int messageRef, String format, String smsc, boolean isRetry,
byte[] pdu) {
- getSmsImplementation().sendSms(token, messageRef, format, smsc, isRetry, pdu);
+ getImsSmsImpl().sendSms(token, messageRef, format, smsc, isRetry, pdu);
+ }
+
+ private void onMemoryAvailable(int token) {
+ getImsSmsImpl().onMemoryAvailable(token);
}
private void acknowledgeSms(int token, int messageRef,
@ImsSmsImplBase.DeliverStatusResult int result) {
- getSmsImplementation().acknowledgeSms(token, messageRef, result);
+ getImsSmsImpl().acknowledgeSms(token, messageRef, result);
+ }
+
+ private void acknowledgeSms(int token, int messageRef,
+ @ImsSmsImplBase.DeliverStatusResult int result, byte[] pdu) {
+ getImsSmsImpl().acknowledgeSms(token, messageRef, result, pdu);
}
private void acknowledgeSmsReport(int token, int messageRef,
@ImsSmsImplBase.StatusReportResult int result) {
- getSmsImplementation().acknowledgeSmsReport(token, messageRef, result);
+ getImsSmsImpl().acknowledgeSmsReport(token, messageRef, result);
}
private void onSmsReady() {
- getSmsImplementation().onReady();
+ getImsSmsImpl().onReady();
}
/**
@@ -974,7 +1845,7 @@ public class MmTelFeature extends ImsFeature {
}
private String getSmsFormat() {
- return getSmsImplementation().getSmsFormat();
+ return getImsSmsImpl().getSmsFormat();
}
/**
diff --git a/telephony/java/android/telephony/ims/stub/CapabilityExchangeEventListener.java b/telephony/java/android/telephony/ims/stub/CapabilityExchangeEventListener.java
index 7a1a2af060d2..28c2d59e2d68 100644
--- a/telephony/java/android/telephony/ims/stub/CapabilityExchangeEventListener.java
+++ b/telephony/java/android/telephony/ims/stub/CapabilityExchangeEventListener.java
@@ -23,6 +23,7 @@ import android.net.Uri;
import android.telephony.ims.ImsException;
import android.telephony.ims.RcsContactUceCapability;
import android.telephony.ims.RcsUceAdapter;
+import android.telephony.ims.SipDetails;
import android.telephony.ims.feature.ImsFeature;
import android.telephony.ims.feature.RcsFeature;
@@ -108,12 +109,35 @@ public interface CapabilityExchangeEventListener {
* the {@link ImsFeature#onFeatureReady()} callback. This may also happen in rare
* cases when the Telephony stack has crashed.
*
+ * @deprecated Replaced sip information with the newly added
+ * {@link #onPublishUpdated(SipDetails)}.
*/
+ @Deprecated
default void onPublishUpdated(int reasonCode, @NonNull String reasonPhrase,
int reasonHeaderCause, @NonNull String reasonHeaderText) throws ImsException {
+ onPublishUpdated(new SipDetails.Builder(SipDetails.METHOD_PUBLISH)
+ .setSipResponseCode(reasonCode, reasonPhrase)
+ .setSipResponseReasonHeader(reasonHeaderCause, reasonHeaderText)
+ .build());
}
/**
+ * Notify the framework that the ImsService has refreshed the PUBLISH
+ * internally, which has resulted in a new PUBLISH result.
+ * <p>
+ * This method must be called to notify the framework of SUCCESS (200 OK) and FAILURE (300+)
+ * codes in order to keep the AOSP stack up to date.
+ * @param details The SIP information received in response to a publish operation.
+ * @throws ImsException If this {@link RcsCapabilityExchangeImplBase} instance is not
+ * currently connected to the framework. This can happen if the {@link RcsFeature} is not
+ * {@link ImsFeature#STATE_READY} and the {@link RcsFeature} has not received
+ * the {@link ImsFeature#onFeatureReady()} callback. This may also happen in rare
+ * cases when the Telephony stack has crashed.
+ */
+ default void onPublishUpdated(@NonNull SipDetails details)
+ throws ImsException {
+ }
+ /**
* Inform the framework of an OPTIONS query from a remote device for this device's UCE
* capabilities.
* <p>
diff --git a/telephony/java/android/telephony/ims/stub/ImsCallSessionImplBase.java b/telephony/java/android/telephony/ims/stub/ImsCallSessionImplBase.java
index 25bf7d6af9ca..30a0684af101 100644
--- a/telephony/java/android/telephony/ims/stub/ImsCallSessionImplBase.java
+++ b/telephony/java/android/telephony/ims/stub/ImsCallSessionImplBase.java
@@ -16,8 +16,11 @@
package android.telephony.ims.stub;
+import android.annotation.IntDef;
+import android.annotation.IntRange;
import android.annotation.NonNull;
import android.annotation.SystemApi;
+import android.os.Bundle;
import android.os.Message;
import android.os.RemoteException;
import android.telephony.ims.ImsCallProfile;
@@ -36,6 +39,8 @@ import com.android.ims.internal.IImsCallSession;
import com.android.ims.internal.IImsVideoCallProvider;
import com.android.internal.telephony.util.TelephonyUtils;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
import java.util.List;
import java.util.Set;
import java.util.concurrent.CancellationException;
@@ -67,6 +72,48 @@ public class ImsCallSessionImplBase implements AutoCloseable {
*/
public static final int USSD_MODE_REQUEST = 1;
+ /** @hide */
+ @IntDef(
+ prefix = "MEDIA_STREAM_TYPE_",
+ value = {
+ MEDIA_STREAM_TYPE_AUDIO,
+ MEDIA_STREAM_TYPE_VIDEO
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface MediaStreamType {}
+
+ /**
+ * Media Stream Type - Audio
+ * @hide
+ */
+ public static final int MEDIA_STREAM_TYPE_AUDIO = 1;
+ /**
+ * Media Stream Type - Video
+ * @hide
+ */
+ public static final int MEDIA_STREAM_TYPE_VIDEO = 2;
+
+ /** @hide */
+ @IntDef(
+ prefix = "MEDIA_STREAM_DIRECTION_",
+ value = {
+ MEDIA_STREAM_DIRECTION_UPLINK,
+ MEDIA_STREAM_DIRECTION_DOWNLINK
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface MediaStreamDirection {}
+
+ /**
+ * Media Stream Direction - Uplink
+ * @hide
+ */
+ public static final int MEDIA_STREAM_DIRECTION_UPLINK = 1;
+ /**
+ * Media Stream Direction - Downlink
+ * @hide
+ */
+ public static final int MEDIA_STREAM_DIRECTION_DOWNLINK = 2;
+
/**
* Defines IMS call session state.
*/
@@ -327,6 +374,12 @@ public class ImsCallSessionImplBase implements AutoCloseable {
new ArraySet<RtpHeaderExtension>(extensions)), "sendRtpHeaderExtensions");
}
+ @Override
+ public void callSessionNotifyAnbr(int mediaType, int direction, int bitsPerSecond) {
+ executeMethodAsync(() -> ImsCallSessionImplBase.this.callSessionNotifyAnbr(
+ mediaType, direction, bitsPerSecond), "callSessionNotifyAnbr");
+ }
+
// Call the methods with a clean calling identity on the executor and wait indefinitely for
// the future to return.
private void executeMethodAsync(Runnable r, String errorLogName) {
@@ -367,7 +420,11 @@ public class ImsCallSessionImplBase implements AutoCloseable {
*
* @param listener {@link ImsCallSessionListener} used to notify the framework of updates
* to the ImsCallSession
+
+ * @deprecated use {@link android.telephony.ims.feature.MmTelFeature#notifyIncomingCall(
+ * ImsCallSessionImplBase, String, Bundle)} to get the listener instead
*/
+ @Deprecated
public void setListener(ImsCallSessionListener listener) {
}
@@ -726,6 +783,22 @@ public class ImsCallSessionImplBase implements AutoCloseable {
public void sendRtpHeaderExtensions(@NonNull Set<RtpHeaderExtension> rtpHeaderExtensions) {
}
+ /**
+ * Deliver the bitrate for the indicated media type, direction and bitrate to the upper layer.
+ *
+ * @param mediaType MediaType is used to identify media stream such as audio or video.
+ * @param direction Direction of this packet stream (e.g. uplink or downlink).
+ * @param bitsPerSecond This value is the bitrate received from the NW through the Recommended
+ * bitrate MAC Control Element message and ImsStack converts this value from MAC bitrate
+ * to audio/video codec bitrate (defined in TS26.114).
+ * @hide
+ */
+ public void callSessionNotifyAnbr(@MediaStreamType int mediaType,
+ @MediaStreamDirection int direction, @IntRange(from = 0) int bitsPerSecond) {
+ // Base Implementation - Should be overridden by IMS service
+ Log.i(LOG_TAG, "ImsCallSessionImplBase callSessionNotifyAnbr - mediaType: " + mediaType);
+ }
+
/** @hide */
public IImsCallSession getServiceImpl() {
return mServiceImpl;
diff --git a/telephony/java/android/telephony/ims/stub/ImsConfigImplBase.java b/telephony/java/android/telephony/ims/stub/ImsConfigImplBase.java
index f371ec3a28a7..ad8a936c3c27 100644
--- a/telephony/java/android/telephony/ims/stub/ImsConfigImplBase.java
+++ b/telephony/java/android/telephony/ims/stub/ImsConfigImplBase.java
@@ -22,6 +22,7 @@ import android.annotation.SystemApi;
import android.content.Context;
import android.os.PersistableBundle;
import android.os.RemoteException;
+import android.telephony.ims.ImsService;
import android.telephony.ims.ProvisioningManager;
import android.telephony.ims.RcsClientConfiguration;
import android.telephony.ims.RcsConfig;
@@ -481,6 +482,17 @@ public class ImsConfigImplBase {
}
}
+ /**
+ * Clear cached configuration value.
+ */
+ public void clearCachedValue() {
+ Log.i(TAG, "clearCachedValue");
+ synchronized (mLock) {
+ mProvisionedIntValue.clear();
+ mProvisionedStringValue.clear();
+ }
+ }
+
// Call the methods with a clean calling identity on the executor and wait indefinitely for
// the future to return.
private void executeMethodAsync(Runnable r, String errorLogName) throws RemoteException {
@@ -538,10 +550,11 @@ public class ImsConfigImplBase {
private final RemoteCallbackListExt<IRcsConfigCallback> mRcsCallbacks =
new RemoteCallbackListExt<>();
private byte[] mRcsConfigData;
+ private final Object mRcsConfigDataLock = new Object();
ImsConfigStub mImsConfigStub;
/**
- * Create a ImsConfig using the Executor specified for methods being called by the
+ * Create an ImsConfig using the Executor specified for methods being called by the
* framework.
* @param executor The executor for the framework to use when executing the methods overridden
* by the implementation of ImsConfig.
@@ -557,6 +570,9 @@ public class ImsConfigImplBase {
mImsConfigStub = new ImsConfigStub(this, null);
}
+ /**
+ * Create an ImsConfig using the Executor defined in {@link ImsService#getExecutor}
+ */
public ImsConfigImplBase() {
mImsConfigStub = new ImsConfigStub(this, null);
}
@@ -616,12 +632,20 @@ public class ImsConfigImplBase {
private void addRcsConfigCallback(IRcsConfigCallback c) {
mRcsCallbacks.register(c);
- if (mRcsConfigData != null) {
- try {
- c.onConfigurationChanged(mRcsConfigData);
- } catch (RemoteException e) {
- Log.w(TAG, "dead binder to call onConfigurationChanged, skipping.");
+
+ // This is used to avoid calling the binder out of the synchronized scope.
+ byte[] cloneRcsConfigData;
+ synchronized (mRcsConfigDataLock) {
+ if (mRcsConfigData == null) {
+ return;
}
+ cloneRcsConfigData = mRcsConfigData.clone();
+ }
+
+ try {
+ c.onConfigurationChanged(cloneRcsConfigData);
+ } catch (RemoteException e) {
+ Log.w(TAG, "dead binder to call onConfigurationChanged, skipping.");
}
}
@@ -631,18 +655,23 @@ public class ImsConfigImplBase {
private void onNotifyRcsAutoConfigurationReceived(byte[] config, boolean isCompressed) {
// cache uncompressed config
- config = isCompressed ? RcsConfig.decompressGzip(config) : config;
- if (Arrays.equals(mRcsConfigData, config)) {
- return;
+ final byte[] rcsConfigData = isCompressed ? RcsConfig.decompressGzip(config) : config;
+
+ synchronized (mRcsConfigDataLock) {
+ if (Arrays.equals(mRcsConfigData, config)) {
+ return;
+ }
+ mRcsConfigData = rcsConfigData;
}
- mRcsConfigData = config;
// can be null in testing
if (mRcsCallbacks != null) {
synchronized (mRcsCallbacks) {
mRcsCallbacks.broadcastAction(c -> {
try {
- c.onConfigurationChanged(mRcsConfigData);
+ // config is cloned here so modifications to the config passed to the
+ // vendor do not accidentally modify the cache.
+ c.onConfigurationChanged(rcsConfigData.clone());
} catch (RemoteException e) {
Log.w(TAG, "dead binder in notifyRcsAutoConfigurationReceived, skipping.");
}
@@ -653,7 +682,9 @@ public class ImsConfigImplBase {
}
private void onNotifyRcsAutoConfigurationRemoved() {
- mRcsConfigData = null;
+ synchronized (mRcsConfigDataLock) {
+ mRcsConfigData = null;
+ }
if (mRcsCallbacks != null) {
synchronized (mRcsCallbacks) {
mRcsCallbacks.broadcastAction(c -> {
@@ -857,4 +888,17 @@ public class ImsConfigImplBase {
mImsConfigStub.mExecutor = executor;
}
}
+
+ /**
+ * Clear all cached config data. This will be called when the config data is no longer valid
+ * such as when the SIM was removed.
+ * @hide
+ */
+ public final void clearConfigurationCache() {
+ mImsConfigStub.clearCachedValue();
+
+ synchronized (mRcsConfigDataLock) {
+ mRcsConfigData = null;
+ }
+ }
}
diff --git a/telephony/java/android/telephony/ims/stub/ImsRegistrationImplBase.java b/telephony/java/android/telephony/ims/stub/ImsRegistrationImplBase.java
index 593f0807ef27..ff378ba02856 100644
--- a/telephony/java/android/telephony/ims/stub/ImsRegistrationImplBase.java
+++ b/telephony/java/android/telephony/ims/stub/ImsRegistrationImplBase.java
@@ -26,6 +26,7 @@ import android.os.RemoteException;
import android.telephony.ims.ImsReasonInfo;
import android.telephony.ims.ImsRegistrationAttributes;
import android.telephony.ims.RegistrationManager;
+import android.telephony.ims.SipDetails;
import android.telephony.ims.aidl.IImsRegistration;
import android.telephony.ims.aidl.IImsRegistrationCallback;
import android.util.Log;
@@ -42,6 +43,7 @@ import java.util.concurrent.CompletionException;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executor;
import java.util.concurrent.atomic.AtomicReference;
+import java.util.function.Consumer;
import java.util.function.Supplier;
/**
@@ -64,7 +66,8 @@ public class ImsRegistrationImplBase {
REGISTRATION_TECH_LTE,
REGISTRATION_TECH_IWLAN,
REGISTRATION_TECH_CROSS_SIM,
- REGISTRATION_TECH_NR
+ REGISTRATION_TECH_NR,
+ REGISTRATION_TECH_3G
})
@Retention(RetentionPolicy.SOURCE)
public @interface ImsRegistrationTech {}
@@ -92,10 +95,15 @@ public class ImsRegistrationImplBase {
public static final int REGISTRATION_TECH_NR = 3;
/**
+ * This ImsService is registered to IMS via 3G.
+ */
+ public static final int REGISTRATION_TECH_3G = 4;
+
+ /**
* This is used to check the upper range of registration tech
* @hide
*/
- public static final int REGISTRATION_TECH_MAX = REGISTRATION_TECH_NR + 1;
+ public static final int REGISTRATION_TECH_MAX = REGISTRATION_TECH_3G + 1;
// Registration states, used to notify new ImsRegistrationImplBase#Callbacks of the current
// state.
@@ -104,6 +112,73 @@ public class ImsRegistrationImplBase {
// yet.
private static final int REGISTRATION_STATE_UNKNOWN = -1;
+ /** @hide */
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef(
+ prefix = {"REASON_"},
+ value = {
+ REASON_UNKNOWN,
+ REASON_SIM_REMOVED,
+ REASON_SIM_REFRESH,
+ REASON_ALLOWED_NETWORK_TYPES_CHANGED,
+ REASON_NON_IMS_CAPABLE_NETWORK,
+ REASON_RADIO_POWER_OFF,
+ REASON_HANDOVER_FAILED,
+ REASON_VOPS_NOT_SUPPORTED,
+ })
+ public @interface ImsDeregistrationReason{}
+
+ /**
+ * Unspecified reason.
+ * @hide
+ */
+ public static final int REASON_UNKNOWN = 0;
+
+ /**
+ * Since SIM is removed, the credentials for IMS service is also removed.
+ * @hide
+ */
+ public static final int REASON_SIM_REMOVED = 1;
+
+ /**
+ * Detach from the network shall be performed due to the SIM refresh. IMS service should be
+ * deregistered before that procedure.
+ * @hide
+ */
+ public static final int REASON_SIM_REFRESH = 2;
+
+ /**
+ * The allowed network types have changed, resulting in a network type
+ * that does not support IMS.
+ * @hide
+ */
+ public static final int REASON_ALLOWED_NETWORK_TYPES_CHANGED = 3;
+
+ /**
+ * The device camped on a network that does not support IMS.
+ * @hide
+ */
+ public static final int REASON_NON_IMS_CAPABLE_NETWORK = 4;
+
+ /**
+ * IMS service should be deregistered from the network before turning off the radio.
+ * @hide
+ */
+ public static final int REASON_RADIO_POWER_OFF = 5;
+
+ /**
+ * Since the handover is failed or not allowed, the data service for IMS shall be
+ * disconnected.
+ * @hide
+ */
+ public static final int REASON_HANDOVER_FAILED = 6;
+
+ /**
+ * The network is changed to a network that does not support voice over IMS.
+ * @hide
+ */
+ public static final int REASON_VOPS_NOT_SUPPORTED = 7;
+
private Executor mExecutor;
/**
@@ -182,6 +257,12 @@ public class ImsRegistrationImplBase {
.triggerSipDelegateDeregistration(), "triggerSipDelegateDeregistration");
}
+ @Override
+ public void triggerDeregistration(@ImsDeregistrationReason int reason) {
+ executeMethodAsyncNoException(() -> ImsRegistrationImplBase.this
+ .triggerDeregistration(reason), "triggerDeregistration");
+ }
+
// Call the methods with a clean calling identity on the executor and wait indefinitely for
// the future to return.
private void executeMethodAsync(Runnable r, String errorLogName) throws RemoteException {
@@ -228,6 +309,9 @@ public class ImsRegistrationImplBase {
private int mRegistrationState = REGISTRATION_STATE_UNKNOWN;
// Locked on mLock, create unspecified disconnect cause.
private ImsReasonInfo mLastDisconnectCause = new ImsReasonInfo();
+ // Locked on mLock
+ private int mLastDisconnectSuggestedAction = RegistrationManager.SUGGESTED_ACTION_NONE;
+ private int mLastDisconnectRadioTech = REGISTRATION_TECH_NONE;
// We hold onto the uris each time they change so that we can send it to a callback when its
// first added.
@@ -242,11 +326,19 @@ public class ImsRegistrationImplBase {
}
private void addRegistrationCallback(IImsRegistrationCallback c) throws RemoteException {
+ // This is purposefully not synchronized with broadcastToCallbacksLocked because the
+ // list of callbacks to notify is copied over from the original list modified here. I also
+ // do not want to risk introducing a deadlock by using the same mCallbacks Object to
+ // synchronize on outgoing and incoming operations.
mCallbacks.register(c);
updateNewCallbackWithState(c);
}
private void removeRegistrationCallback(IImsRegistrationCallback c) {
+ // This is purposefully not synchronized with broadcastToCallbacksLocked because the
+ // list of callbacks to notify is copied over from the original list modified here. I also
+ // do not want to risk introducing a deadlock by using the same mCallbacks Object to
+ // synchronize on outgoing and incoming operations.
mCallbacks.unregister(c);
}
@@ -303,6 +395,19 @@ public class ImsRegistrationImplBase {
// Stub implementation, ImsService should implement this
}
+ /**
+ * Requests IMS stack to perform graceful IMS deregistration before radio performing
+ * network detach in the events of SIM remove, refresh or and so on. The radio waits for
+ * the IMS deregistration, which will be notified by telephony via
+ * {@link android.hardware.radio.ims.IRadioIms#updateImsRegistrationInfo()},
+ * or a certain timeout interval to start the network detach procedure.
+ *
+ * @param reason the reason why the deregistration is triggered.
+ * @hide
+ */
+ public void triggerDeregistration(@ImsDeregistrationReason int reason) {
+ // Stub Implementation, can be overridden by ImsService
+ }
/**
* Notify the framework that the device is connected to the IMS network.
@@ -324,7 +429,7 @@ public class ImsRegistrationImplBase {
@SystemApi
public final void onRegistered(@NonNull ImsRegistrationAttributes attributes) {
updateToState(attributes, RegistrationManager.REGISTRATION_STATE_REGISTERED);
- mCallbacks.broadcastAction((c) -> {
+ broadcastToCallbacksLocked((c) -> {
try {
c.onRegistered(attributes);
} catch (RemoteException e) {
@@ -353,7 +458,7 @@ public class ImsRegistrationImplBase {
@SystemApi
public final void onRegistering(@NonNull ImsRegistrationAttributes attributes) {
updateToState(attributes, RegistrationManager.REGISTRATION_STATE_REGISTERING);
- mCallbacks.broadcastAction((c) -> {
+ broadcastToCallbacksLocked((c) -> {
try {
c.onRegistering(attributes);
} catch (RemoteException e) {
@@ -381,12 +486,101 @@ public class ImsRegistrationImplBase {
*/
@SystemApi
public final void onDeregistered(ImsReasonInfo info) {
- updateToDisconnectedState(info);
+ // Default impl to keep backwards compatibility with old implementations
+ onDeregistered(info, RegistrationManager.SUGGESTED_ACTION_NONE, REGISTRATION_TECH_NONE);
+ }
+
+ /**
+ * Notify the framework that the device is disconnected from the IMS network.
+ * <p>
+ * Note: Prior to calling {@link #onDeregistered(ImsReasonInfo,int)}, you should ensure that any
+ * changes to {@link android.telephony.ims.feature.ImsFeature} capability availability is sent
+ * to the framework. For example,
+ * {@link android.telephony.ims.feature.MmTelFeature.MmTelCapabilities#CAPABILITY_TYPE_VIDEO}
+ * and
+ * {@link android.telephony.ims.feature.MmTelFeature.MmTelCapabilities#CAPABILITY_TYPE_VOICE}
+ * may be set to unavailable to ensure the framework knows these services are no longer
+ * available due to de-registration. If you do not report capability changes impacted by
+ * de-registration, the framework will not know which features are no longer available as a
+ * result.
+ *
+ * @param info the {@link ImsReasonInfo} associated with why registration was disconnected.
+ * @param suggestedAction the expected behavior of radio protocol stack.
+ * @param imsRadioTech the network type on which IMS registration has failed.
+ * @hide This API is not part of the Android public SDK API
+ */
+ @SystemApi
+ public final void onDeregistered(@Nullable ImsReasonInfo info,
+ @RegistrationManager.SuggestedAction int suggestedAction,
+ @ImsRegistrationTech int imsRadioTech) {
+ updateToDisconnectedState(info, suggestedAction, imsRadioTech);
+ // ImsReasonInfo should never be null.
+ final ImsReasonInfo reasonInfo = (info != null) ? info : new ImsReasonInfo();
+ broadcastToCallbacksLocked((c) -> {
+ try {
+ c.onDeregistered(reasonInfo, suggestedAction, imsRadioTech);
+ } catch (RemoteException e) {
+ Log.w(LOG_TAG, e + "onDeregistered() - Skipping callback.");
+ }
+ });
+ }
+
+ /**
+ * Notify the framework that the device is disconnected from the IMS network.
+ * <p>
+ * Note: Before calling {@link #onDeregistered(ImsReasonInfo, SipDetails)}, ImsService should
+ * ensure that any changes to {@link android.telephony.ims.feature.ImsFeature} capability
+ * availability is sent to the framework.
+ * For example,
+ * {@link android.telephony.ims.feature.MmTelFeature.MmTelCapabilities#CAPABILITY_TYPE_VIDEO}
+ * and
+ * {@link android.telephony.ims.feature.MmTelFeature.MmTelCapabilities#CAPABILITY_TYPE_VOICE}
+ * may be set to unavailable to ensure the framework knows these services are no longer
+ * available due to de-registration. If ImsService do not report capability changes impacted
+ * by de-registration, the framework will not know which features are no longer available as a
+ * result.
+ *
+ * @param info the {@link ImsReasonInfo} associated with why registration was disconnected.
+ * @param details the {@link SipDetails} related to disconnected Ims registration
+ * @hide This API is not part of the Android public SDK API
+ */
+ @SystemApi
+ public final void onDeregistered(@Nullable ImsReasonInfo info,
+ @NonNull SipDetails details) {
+ onDeregistered(info, RegistrationManager.SUGGESTED_ACTION_NONE, REGISTRATION_TECH_NONE,
+ details);
+ }
+
+ /**
+ * Notify the framework that the device is disconnected from the IMS network.
+ * <p>
+ * Note: Before calling {@link #onDeregistered(ImsReasonInfo, SipDetails)}, ImsService should
+ * ensure that any changes to {@link android.telephony.ims.feature.ImsFeature} capability
+ * availability is sent to the framework.
+ * For example,
+ * {@link android.telephony.ims.feature.MmTelFeature.MmTelCapabilities#CAPABILITY_TYPE_VIDEO}
+ * and
+ * {@link android.telephony.ims.feature.MmTelFeature.MmTelCapabilities#CAPABILITY_TYPE_VOICE}
+ * may be set to unavailable to ensure the framework knows these services are no longer
+ * available due to de-registration. If ImsService do not report capability changes impacted
+ * by de-registration, the framework will not know which features are no longer available as a
+ * result.
+ *
+ * @param info the {@link ImsReasonInfo} associated with why registration was disconnected.
+ * @param suggestedAction the expected behavior of radio protocol stack.
+ * @param details the {@link SipDetails} related to disconnected Ims registration
+ * @hide This API is not part of the Android public SDK API
+ */
+ @SystemApi
+ public final void onDeregistered(@Nullable ImsReasonInfo info,
+ @RegistrationManager.SuggestedAction int suggestedAction,
+ @ImsRegistrationTech int imsRadioTech, @NonNull SipDetails details) {
+ updateToDisconnectedState(info, suggestedAction, imsRadioTech);
// ImsReasonInfo should never be null.
final ImsReasonInfo reasonInfo = (info != null) ? info : new ImsReasonInfo();
- mCallbacks.broadcastAction((c) -> {
+ broadcastToCallbacksLocked((c) -> {
try {
- c.onDeregistered(reasonInfo);
+ c.onDeregisteredWithDetails(reasonInfo, suggestedAction, imsRadioTech, details);
} catch (RemoteException e) {
Log.w(LOG_TAG, e + "onDeregistered() - Skipping callback.");
}
@@ -406,7 +600,7 @@ public class ImsRegistrationImplBase {
public final void onTechnologyChangeFailed(@ImsRegistrationTech int imsRadioTech,
ImsReasonInfo info) {
final ImsReasonInfo reasonInfo = (info != null) ? info : new ImsReasonInfo();
- mCallbacks.broadcastAction((c) -> {
+ broadcastToCallbacksLocked((c) -> {
try {
c.onTechnologyChangeFailed(imsRadioTech, reasonInfo);
} catch (RemoteException e) {
@@ -429,7 +623,20 @@ public class ImsRegistrationImplBase {
mUris = ArrayUtils.cloneOrNull(uris);
mUrisSet = true;
}
- mCallbacks.broadcastAction((c) -> onSubscriberAssociatedUriChanged(c, uris));
+ broadcastToCallbacksLocked((c) -> onSubscriberAssociatedUriChanged(c, uris));
+ }
+
+ /**
+ * Broadcast the specified operation in a synchronized manner so that multiple threads do not
+ * try to call broadcast at the same time, which will generate an error.
+ * @param c The Consumer lambda method containing the callback to call.
+ */
+ private void broadcastToCallbacksLocked(Consumer<IImsRegistrationCallback> c) {
+ // One broadcast can happen at a time, so synchronize threads so only one
+ // beginBroadcast/endBroadcast happens at a time.
+ synchronized (mCallbacks) {
+ mCallbacks.broadcastAction(c);
+ }
}
private void onSubscriberAssociatedUriChanged(IImsRegistrationCallback callback, Uri[] uris) {
@@ -445,10 +652,14 @@ public class ImsRegistrationImplBase {
mRegistrationAttributes = attributes;
mRegistrationState = newState;
mLastDisconnectCause = null;
+ mLastDisconnectSuggestedAction = RegistrationManager.SUGGESTED_ACTION_NONE;
+ mLastDisconnectRadioTech = REGISTRATION_TECH_NONE;
}
}
- private void updateToDisconnectedState(ImsReasonInfo info) {
+ private void updateToDisconnectedState(ImsReasonInfo info,
+ @RegistrationManager.SuggestedAction int suggestedAction,
+ @ImsRegistrationTech int imsRadioTech) {
synchronized (mLock) {
//We don't want to send this info over if we are disconnected
mUrisSet = false;
@@ -458,6 +669,8 @@ public class ImsRegistrationImplBase {
RegistrationManager.REGISTRATION_STATE_NOT_REGISTERED);
if (info != null) {
mLastDisconnectCause = info;
+ mLastDisconnectSuggestedAction = suggestedAction;
+ mLastDisconnectRadioTech = imsRadioTech;
} else {
Log.w(LOG_TAG, "updateToDisconnectedState: no ImsReasonInfo provided.");
mLastDisconnectCause = new ImsReasonInfo();
@@ -474,18 +687,22 @@ public class ImsRegistrationImplBase {
int state;
ImsRegistrationAttributes attributes;
ImsReasonInfo disconnectInfo;
+ int suggestedAction;
+ int imsDisconnectRadioTech;
boolean urisSet;
Uri[] uris;
synchronized (mLock) {
state = mRegistrationState;
attributes = mRegistrationAttributes;
disconnectInfo = mLastDisconnectCause;
+ suggestedAction = mLastDisconnectSuggestedAction;
+ imsDisconnectRadioTech = mLastDisconnectRadioTech;
urisSet = mUrisSet;
uris = mUris;
}
switch (state) {
case RegistrationManager.REGISTRATION_STATE_NOT_REGISTERED: {
- c.onDeregistered(disconnectInfo);
+ c.onDeregistered(disconnectInfo, suggestedAction, imsDisconnectRadioTech);
break;
}
case RegistrationManager.REGISTRATION_STATE_REGISTERING: {
@@ -517,4 +734,16 @@ public class ImsRegistrationImplBase {
mExecutor = executor;
}
}
+
+ /**
+ * Clear the cached data when the subscription is no longer valid
+ * such as when a sim is removed.
+ * @hide
+ */
+ public final void clearRegistrationCache() {
+ synchronized (mLock) {
+ mUris = null;
+ mUrisSet = false;
+ }
+ }
}
diff --git a/telephony/java/android/telephony/ims/stub/ImsSmsImplBase.java b/telephony/java/android/telephony/ims/stub/ImsSmsImplBase.java
index fb997d118419..e7e0ec212839 100644
--- a/telephony/java/android/telephony/ims/stub/ImsSmsImplBase.java
+++ b/telephony/java/android/telephony/ims/stub/ImsSmsImplBase.java
@@ -18,6 +18,7 @@ package android.telephony.ims.stub;
import android.annotation.IntDef;
import android.annotation.IntRange;
+import android.annotation.NonNull;
import android.annotation.SystemApi;
import android.os.RemoteException;
import android.telephony.SmsManager;
@@ -27,6 +28,7 @@ import android.util.Log;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
+import java.util.concurrent.Executor;
/**
* Base implementation for SMS over IMS.
@@ -128,6 +130,22 @@ public class ImsSmsImplBase {
// Lock for feature synchronization
private final Object mLock = new Object();
private IImsSmsListener mListener;
+ private Executor mExecutor;
+
+ /**
+ * Create a new ImsSmsImplBase using the Executor set in MmTelFeature
+ */
+ public ImsSmsImplBase() {
+ }
+
+ /**
+ * Create a new ImsSmsImplBase with specified executor.
+ * <p>
+ * @param executor Default executor for ImsSmsImplBase
+ */
+ public ImsSmsImplBase(@NonNull Executor executor) {
+ mExecutor = executor;
+ }
/**
* Registers a listener responsible for handling tasks like delivering messages.
@@ -170,10 +188,29 @@ public class ImsSmsImplBase {
}
/**
+ * This method will be triggered by the platform when memory becomes available to receive SMS
+ * after a memory full event. This method should be implemented by IMS providers to
+ * send RP-SMMA notification from SMS Relay Layer to server over IMS as per section 7.3.2 of
+ * TS 124.11. Once the RP-SMMA Notification is sent to the network. The network will deliver all
+ * the pending messages which failed due to Unavailability of Memory.
+ *
+ * @param token unique token generated in {@link ImsSmsDispatcher#onMemoryAvailable(void)} that
+ * should be used when triggering callbacks for this specific message.
+ *
+ * @hide
+ */
+ public void onMemoryAvailable(int token) {
+ // Base Implementation - Should be overridden
+ }
+
+ /**
* This method will be triggered by the platform after
* {@link #onSmsReceived(int, String, byte[])} has been called to deliver the result to the IMS
* provider.
*
+ * If the framework needs to provide the PDU used to acknowledge the SMS,
+ * {@link #acknowledgeSms(int, int, int, byte[])} will be called.
+ *
* @param token token provided in {@link #onSmsReceived(int, String, byte[])}
* @param messageRef the message reference, which may be 1 byte if it is in
* {@link SmsMessage#FORMAT_3GPP} format (see TS.123.040) or 2 bytes if it is in
@@ -186,6 +223,27 @@ public class ImsSmsImplBase {
}
/**
+ * This method will be called by the platform after
+ * {@link #onSmsReceived(int, String, byte[])} has been called to acknowledge an incoming SMS.
+ *
+ * This method is only called in cases where the framework needs to provide the PDU such as the
+ * case where we provide the Short Message Transfer Layer PDU (see 3GPP TS 23.040). Otherwise,
+ * {@link #acknowledgeSms(int, int, int)} will be used.
+ *
+ * @param token token provided in {@link #onSmsReceived(int, String, byte[])}
+ * @param messageRef the message reference, which may be 1 byte if it is in
+ * {@link SmsMessage#FORMAT_3GPP} format (see TS.123.040) or 2 bytes if it is in
+ * {@link SmsMessage#FORMAT_3GPP2} format (see 3GPP2 C.S0015-B).
+ * @param result result of delivering the message.
+ * @param pdu PDU representing the contents of the message.
+ */
+ public void acknowledgeSms(int token, @IntRange(from = 0, to = 65535) int messageRef,
+ @DeliverStatusResult int result, @NonNull byte[] pdu) {
+ Log.e(LOG_TAG, "acknowledgeSms() not implemented. acknowledgeSms(int, int, int) called.");
+ acknowledgeSms(token, messageRef, result);
+ }
+
+ /**
* This method will be triggered by the platform after
* {@link #onSmsStatusReportReceived(int, int, String, byte[])} or
* {@link #onSmsStatusReportReceived(int, String, byte[])} has been called to provide the
@@ -347,6 +405,38 @@ public class ImsSmsImplBase {
}
/**
+ * This API is used to report the result of sending
+ * RP-SMMA to framework based on received network responses(RP-ACK,
+ * RP-ERROR or SIP error).
+ *
+ * @param token provided in {@link #onMemoryAvailable()}.
+ * @param result based on RP-ACK or RP_ERROR
+ * @param networkErrorCode the error code reported by the carrier
+ * network if sending this SMS has resulted in an error or
+ * {@link #RESULT_NO_NETWORK_ERROR} if no network error was generated. See
+ * 3GPP TS 24.011 Section 7.3.4 for valid error codes and more
+ * information.
+ *
+ * @hide
+ */
+ public final void onMemoryAvailableResult(int token, @SendStatusResult int result,
+ int networkErrorCode) throws RuntimeException {
+ IImsSmsListener listener = null;
+ synchronized (mLock) {
+ listener = mListener;
+ }
+
+ if (listener == null) {
+ throw new RuntimeException("Feature not ready.");
+ }
+ try {
+ listener.onMemoryAvailableResult(token, result, networkErrorCode);
+ } catch (RemoteException e) {
+ e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
* This method should be triggered by the IMS providers when the status report of the sent
* message is received. The platform will handle the report and notify the IMS provider of the
* result by calling {@link #acknowledgeSmsReport(int, int, int)}.
@@ -443,4 +533,29 @@ public class ImsSmsImplBase {
public void onReady() {
// Base Implementation - Should be overridden
}
+
+ /**
+ * Set default Executor for ImsSmsImplBase.
+ *
+ * @param executor The default executor for the framework to use when executing the methods
+ * overridden by the implementation of ImsSms.
+ * @hide
+ */
+ public final void setDefaultExecutor(@NonNull Executor executor) {
+ if (mExecutor == null) {
+ mExecutor = executor;
+ }
+ }
+
+ /**
+ * Get Executor from ImsSmsImplBase.
+ * If there is no settings for the executor, all ImsSmsImplBase method calls will use
+ * Runnable::run as default
+ *
+ * @return an Executor used to execute methods in ImsSms called remotely by the framework.
+ * @hide
+ */
+ public @NonNull Executor getExecutor() {
+ return mExecutor != null ? mExecutor : Runnable::run;
+ }
}
diff --git a/telephony/java/android/telephony/ims/stub/RcsCapabilityExchangeImplBase.java b/telephony/java/android/telephony/ims/stub/RcsCapabilityExchangeImplBase.java
index 474eb05ca19c..66442a6adb54 100644
--- a/telephony/java/android/telephony/ims/stub/RcsCapabilityExchangeImplBase.java
+++ b/telephony/java/android/telephony/ims/stub/RcsCapabilityExchangeImplBase.java
@@ -24,8 +24,10 @@ import android.annotation.SystemApi;
import android.net.Uri;
import android.telephony.ims.ImsException;
import android.telephony.ims.RcsUceAdapter;
+import android.telephony.ims.SipDetails;
import android.telephony.ims.feature.ImsFeature;
import android.telephony.ims.feature.RcsFeature;
+import android.text.TextUtils;
import android.util.Log;
import android.util.Pair;
@@ -155,7 +157,11 @@ public class RcsCapabilityExchangeImplBase {
* is not {@link ImsFeature#STATE_READY} and the {@link RcsFeature} has not received
* the {@link ImsFeature#onFeatureReady()} callback. This may also happen in rare cases
* when the Telephony stack has crashed.
+ *
+ * @deprecated Replaced sip information with the newly added
+ * {@link #onNetworkResponse(SipDetails)}.
*/
+ @Deprecated
void onNetworkResponse(@IntRange(from = 100, to = 699) int sipCode,
@NonNull String reason) throws ImsException;
@@ -178,11 +184,35 @@ public class RcsCapabilityExchangeImplBase {
* {@link ImsFeature#STATE_READY} and the {@link RcsFeature} has not received
* the {@link ImsFeature#onFeatureReady()} callback. This may also happen in
* rare cases when the Telephony stack has crashed.
+ *
+ * @deprecated Replaced sip information with the newly added
+ * {@link #onNetworkResponse(SipDetails)}.
*/
+ @Deprecated
void onNetworkResponse(@IntRange(from = 100, to = 699) int sipCode,
@NonNull String reasonPhrase,
@IntRange(from = 100, to = 699) int reasonHeaderCause,
@NonNull String reasonHeaderText) throws ImsException;
+
+ /**
+ * Provide the framework with a subsequent network response update to
+ * {@link #publishCapabilities(String, PublishResponseCallback)}.
+ *
+ * @param details The SIP information received in response to a publish operation.
+ * @throws ImsException If this {@link RcsCapabilityExchangeImplBase} instance is
+ * not currently connected to the framework. This can happen if the {@link RcsFeature}
+ * is not {@link ImsFeature#STATE_READY} and the {@link RcsFeature} has not received
+ * the {@link ImsFeature#onFeatureReady()} callback. This may also happen in rare cases
+ * when the Telephony stack has crashed.
+ */
+ default void onNetworkResponse(@NonNull SipDetails details) throws ImsException {
+ if (TextUtils.isEmpty(details.getReasonHeaderText())) {
+ onNetworkResponse(details.getResponseCode(), details.getResponsePhrase());
+ } else {
+ onNetworkResponse(details.getResponseCode(), details.getResponsePhrase(),
+ details.getReasonHeaderCause(), details.getReasonHeaderText());
+ }
+ }
}
/**
@@ -262,7 +292,11 @@ public class RcsCapabilityExchangeImplBase {
* {@link RcsFeature} is not {@link ImsFeature#STATE_READY} and the
* {@link RcsFeature} has not received the {@link ImsFeature#onFeatureReady()} callback.
* This may also happen in rare cases when the Telephony stack has crashed.
+ *
+ * @deprecated Replaced sip information with the newly added
+ * {@link #onNetworkResponse(SipDetails)}.
*/
+ @Deprecated
void onNetworkResponse(@IntRange(from = 100, to = 699) int sipCode,
@NonNull String reason) throws ImsException;
@@ -285,13 +319,42 @@ public class RcsCapabilityExchangeImplBase {
* {@link ImsFeature#STATE_READY} and the {@link RcsFeature} has not received
* the {@link ImsFeature#onFeatureReady()} callback. This may also happen in
* rare cases when the Telephony stack has crashed.
+ *
+ * @deprecated Replaced sip information with the newly added
+ * {@link #onNetworkResponse(SipDetails)}.
*/
+ @Deprecated
void onNetworkResponse(@IntRange(from = 100, to = 699) int sipCode,
@NonNull String reasonPhrase,
@IntRange(from = 100, to = 699) int reasonHeaderCause,
@NonNull String reasonHeaderText) throws ImsException;
/**
+ * Notify the framework of the response to the SUBSCRIBE request from
+ * {@link #subscribeForCapabilities(Collection, SubscribeResponseCallback)}.
+ * <p>
+ * If the carrier network responds to the SUBSCRIBE request with a 2XX response, then the
+ * framework will expect the IMS stack to call {@link #onNotifyCapabilitiesUpdate},
+ * {@link #onResourceTerminated}, and {@link #onTerminated} as required for the
+ * subsequent NOTIFY responses to the subscription.
+ *
+ * @param details The SIP information related to this request.
+ * @throws ImsException If this {@link RcsCapabilityExchangeImplBase} instance is
+ * not currently connected to the framework. This can happen if the
+ * {@link RcsFeature} is not {@link ImsFeature#STATE_READY} and the
+ * {@link RcsFeature} has not received the {@link ImsFeature#onFeatureReady()} callback.
+ * This may also happen in rare cases when the Telephony stack has crashed.
+ */
+ default void onNetworkResponse(@NonNull SipDetails details) throws ImsException {
+ if (TextUtils.isEmpty(details.getReasonHeaderText())) {
+ onNetworkResponse(details.getResponseCode(), details.getResponsePhrase());
+ } else {
+ onNetworkResponse(details.getResponseCode(), details.getResponsePhrase(),
+ details.getReasonHeaderCause(), details.getReasonHeaderText());
+ }
+ };
+
+ /**
* Notify the framework of the latest XML PIDF documents included in the network response
* for the requested contacts' capabilities requested by the Framework using
* {@link RcsUceAdapter#requestCapabilities(List, Executor,
diff --git a/telephony/java/android/telephony/mbms/MbmsDownloadReceiver.java b/telephony/java/android/telephony/mbms/MbmsDownloadReceiver.java
index dd1061f3bd46..556d6f4565d4 100644
--- a/telephony/java/android/telephony/mbms/MbmsDownloadReceiver.java
+++ b/telephony/java/android/telephony/mbms/MbmsDownloadReceiver.java
@@ -195,7 +195,7 @@ public class MbmsDownloadReceiver extends BroadcastReceiver {
return false;
}
DownloadRequest request = intent.getParcelableExtra(
- MbmsDownloadSession.EXTRA_MBMS_DOWNLOAD_REQUEST);
+ MbmsDownloadSession.EXTRA_MBMS_DOWNLOAD_REQUEST, android.telephony.mbms.DownloadRequest.class);
String expectedTokenFileName = request.getHash() + DOWNLOAD_TOKEN_SUFFIX;
File expectedTokenFile = new File(
MbmsUtils.getEmbmsTempFileDirForService(context, request.getFileServiceId()),
@@ -236,7 +236,7 @@ public class MbmsDownloadReceiver extends BroadcastReceiver {
private void moveDownloadedFile(Context context, Intent intent) {
DownloadRequest request = intent.getParcelableExtra(
- MbmsDownloadSession.EXTRA_MBMS_DOWNLOAD_REQUEST);
+ MbmsDownloadSession.EXTRA_MBMS_DOWNLOAD_REQUEST, android.telephony.mbms.DownloadRequest.class);
Intent intentForApp = request.getIntentForApp();
if (intentForApp == null) {
Log.i(LOG_TAG, "Malformed app notification intent");
@@ -256,7 +256,7 @@ public class MbmsDownloadReceiver extends BroadcastReceiver {
return;
}
- Uri finalTempFile = intent.getParcelableExtra(VendorUtils.EXTRA_FINAL_URI);
+ Uri finalTempFile = intent.getParcelableExtra(VendorUtils.EXTRA_FINAL_URI, android.net.Uri.class);
if (!verifyTempFilePath(context, request.getFileServiceId(), finalTempFile)) {
Log.w(LOG_TAG, "Download result specified an invalid temp file " + finalTempFile);
setResultCode(RESULT_DOWNLOAD_FINALIZATION_ERROR);
@@ -264,7 +264,7 @@ public class MbmsDownloadReceiver extends BroadcastReceiver {
}
FileInfo completedFileInfo =
- (FileInfo) intent.getParcelableExtra(MbmsDownloadSession.EXTRA_MBMS_FILE_INFO);
+ (FileInfo) intent.getParcelableExtra(MbmsDownloadSession.EXTRA_MBMS_FILE_INFO, android.telephony.mbms.FileInfo.class);
Path appSpecifiedDestination = FileSystems.getDefault().getPath(
request.getDestinationUri().getPath());
@@ -288,13 +288,13 @@ public class MbmsDownloadReceiver extends BroadcastReceiver {
private void cleanupPostMove(Context context, Intent intent) {
DownloadRequest request = intent.getParcelableExtra(
- MbmsDownloadSession.EXTRA_MBMS_DOWNLOAD_REQUEST);
+ MbmsDownloadSession.EXTRA_MBMS_DOWNLOAD_REQUEST, android.telephony.mbms.DownloadRequest.class);
if (request == null) {
Log.w(LOG_TAG, "Intent does not include a DownloadRequest. Ignoring.");
return;
}
- List<Uri> tempFiles = intent.getParcelableArrayListExtra(VendorUtils.EXTRA_TEMP_LIST);
+ List<Uri> tempFiles = intent.getParcelableArrayListExtra(VendorUtils.EXTRA_TEMP_LIST, android.net.Uri.class);
if (tempFiles == null) {
return;
}
@@ -318,7 +318,7 @@ public class MbmsDownloadReceiver extends BroadcastReceiver {
return;
}
int fdCount = intent.getIntExtra(VendorUtils.EXTRA_FD_COUNT, 0);
- List<Uri> pausedList = intent.getParcelableArrayListExtra(VendorUtils.EXTRA_PAUSED_LIST);
+ List<Uri> pausedList = intent.getParcelableArrayListExtra(VendorUtils.EXTRA_PAUSED_LIST, android.net.Uri.class);
if (fdCount == 0 && (pausedList == null || pausedList.size() == 0)) {
Log.i(LOG_TAG, "No temp files actually requested. Ending.");
@@ -417,7 +417,7 @@ public class MbmsDownloadReceiver extends BroadcastReceiver {
String serviceId = intent.getStringExtra(VendorUtils.EXTRA_SERVICE_ID);
File tempFileDir = MbmsUtils.getEmbmsTempFileDirForService(context, serviceId);
final List<Uri> filesInUse =
- intent.getParcelableArrayListExtra(VendorUtils.EXTRA_TEMP_FILES_IN_USE);
+ intent.getParcelableArrayListExtra(VendorUtils.EXTRA_TEMP_FILES_IN_USE, android.net.Uri.class);
File[] filesToDelete = tempFileDir.listFiles(new FileFilter() {
@Override
public boolean accept(File file) {
diff --git a/telephony/java/android/telephony/satellite/AntennaDirection.aidl b/telephony/java/android/telephony/satellite/AntennaDirection.aidl
new file mode 100644
index 000000000000..c838f6fbb8ac
--- /dev/null
+++ b/telephony/java/android/telephony/satellite/AntennaDirection.aidl
@@ -0,0 +1,19 @@
+/*
+ * Copyright 2023, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.telephony.satellite;
+
+parcelable AntennaDirection;
diff --git a/telephony/java/android/telephony/satellite/AntennaDirection.java b/telephony/java/android/telephony/satellite/AntennaDirection.java
new file mode 100644
index 000000000000..02b0bc7364a2
--- /dev/null
+++ b/telephony/java/android/telephony/satellite/AntennaDirection.java
@@ -0,0 +1,138 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.telephony.satellite;
+
+import android.annotation.NonNull;
+import android.compat.annotation.UnsupportedAppUsage;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.util.Objects;
+
+/**
+ * Antenna direction is provided as X/Y/Z values corresponding to the direction of the antenna
+ * main lobe as a unit vector in CTIA coordinate system (as specified in Appendix A of Wireless
+ * device CTIA OTAn test plan). CTIA coordinate system is defined relative to device’s screen
+ * when the device is held in default portrait mode with screen facing the user:
+ *
+ * Z axis is vertical along the plane of the device with positive Z pointing up and negative z
+ * pointing towards bottom of the device
+ * Y axis is horizontal along the plane of the device with positive Y pointing towards right of
+ * the phone screen and negative Y pointing towards left
+ * X axis is orthogonal to the Y-Z plane (phone screen), pointing away from the phone screen for
+ * positive X and pointing away from back of the phone for negative X.
+ * @hide
+ */
+public final class AntennaDirection implements Parcelable {
+ /** Antenna x axis direction. */
+ private float mX;
+
+ /** Antenna y axis direction. */
+ private float mY;
+
+ /** Antenna z axis direction. */
+ private float mZ;
+
+ /**
+ * @hide
+ */
+ @UnsupportedAppUsage
+ public AntennaDirection(float x, float y, float z) {
+ mX = x;
+ mY = y;
+ mZ = z;
+ }
+
+ private AntennaDirection(Parcel in) {
+ readFromParcel(in);
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(@NonNull Parcel out, int flags) {
+ out.writeFloat(mX);
+ out.writeFloat(mY);
+ out.writeFloat(mZ);
+ }
+
+ @NonNull
+ public static final Creator<AntennaDirection> CREATOR =
+ new Creator<>() {
+ @Override
+ public AntennaDirection createFromParcel(Parcel in) {
+ return new AntennaDirection(in);
+ }
+
+ @Override
+ public AntennaDirection[] newArray(int size) {
+ return new AntennaDirection[size];
+ }
+ };
+
+ @Override
+ @NonNull public String toString() {
+ StringBuilder sb = new StringBuilder();
+ sb.append("X:");
+ sb.append(mX);
+ sb.append(",");
+
+ sb.append("Y:");
+ sb.append(mY);
+ sb.append(",");
+
+ sb.append("Z:");
+ sb.append(mZ);
+ return sb.toString();
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ AntennaDirection that = (AntennaDirection) o;
+ return mX == that.mX
+ && mY == that.mY
+ && mZ == that.mZ;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(mX, mY, mZ);
+ }
+
+ public float getX() {
+ return mX;
+ }
+
+ public float getY() {
+ return mY;
+ }
+
+ public float getZ() {
+ return mZ;
+ }
+
+ private void readFromParcel(Parcel in) {
+ mX = in.readFloat();
+ mY = in.readFloat();
+ mZ = in.readFloat();
+ }
+}
diff --git a/telephony/java/android/telephony/satellite/AntennaPosition.aidl b/telephony/java/android/telephony/satellite/AntennaPosition.aidl
new file mode 100644
index 000000000000..00525624329c
--- /dev/null
+++ b/telephony/java/android/telephony/satellite/AntennaPosition.aidl
@@ -0,0 +1,19 @@
+/*
+ * Copyright 2023, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.telephony.satellite;
+
+parcelable AntennaPosition;
diff --git a/telephony/java/android/telephony/satellite/AntennaPosition.java b/telephony/java/android/telephony/satellite/AntennaPosition.java
new file mode 100644
index 000000000000..eefc8b00f8e8
--- /dev/null
+++ b/telephony/java/android/telephony/satellite/AntennaPosition.java
@@ -0,0 +1,117 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.telephony.satellite;
+
+import android.annotation.NonNull;
+import android.compat.annotation.UnsupportedAppUsage;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.util.Objects;
+
+/**
+ * Antenna Position received from satellite modem which gives information about antenna
+ * direction to be used with satellite communication and suggested device hold positions.
+ * @hide
+ */
+public final class AntennaPosition implements Parcelable {
+ /** Antenna direction used for satellite communication. */
+ @NonNull AntennaDirection mAntennaDirection;
+
+ /** Enum corresponding to device hold position to be used by the end user. */
+ @SatelliteManager.DeviceHoldPosition int mSuggestedHoldPosition;
+
+ /**
+ * @hide
+ */
+ @UnsupportedAppUsage
+ public AntennaPosition(@NonNull AntennaDirection antennaDirection, int suggestedHoldPosition) {
+ mAntennaDirection = antennaDirection;
+ mSuggestedHoldPosition = suggestedHoldPosition;
+ }
+
+ private AntennaPosition(Parcel in) {
+ readFromParcel(in);
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(@NonNull Parcel out, int flags) {
+ out.writeParcelable(mAntennaDirection, flags);
+ out.writeInt(mSuggestedHoldPosition);
+ }
+
+ @NonNull
+ public static final Creator<AntennaPosition> CREATOR =
+ new Creator<>() {
+ @Override
+ public AntennaPosition createFromParcel(Parcel in) {
+ return new AntennaPosition(in);
+ }
+
+ @Override
+ public AntennaPosition[] newArray(int size) {
+ return new AntennaPosition[size];
+ }
+ };
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ AntennaPosition that = (AntennaPosition) o;
+ return Objects.equals(mAntennaDirection, that.mAntennaDirection)
+ && mSuggestedHoldPosition == that.mSuggestedHoldPosition;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(mAntennaDirection, mSuggestedHoldPosition);
+ }
+
+ @Override
+ @NonNull public String toString() {
+ StringBuilder sb = new StringBuilder();
+ sb.append("antennaDirection:");
+ sb.append(mAntennaDirection);
+ sb.append(",");
+
+ sb.append("suggestedHoldPosition:");
+ sb.append(mSuggestedHoldPosition);
+ return sb.toString();
+ }
+
+ @NonNull
+ public AntennaDirection getAntennaDirection() {
+ return mAntennaDirection;
+ }
+
+ @SatelliteManager.DeviceHoldPosition
+ public int getSuggestedHoldPosition() {
+ return mSuggestedHoldPosition;
+ }
+
+ private void readFromParcel(Parcel in) {
+ mAntennaDirection = in.readParcelable(AntennaDirection.class.getClassLoader(),
+ AntennaDirection.class);
+ mSuggestedHoldPosition = in.readInt();
+ }
+}
diff --git a/telephony/java/android/telephony/satellite/ISatelliteDatagramCallback.aidl b/telephony/java/android/telephony/satellite/ISatelliteDatagramCallback.aidl
new file mode 100644
index 000000000000..e229f05b1ad3
--- /dev/null
+++ b/telephony/java/android/telephony/satellite/ISatelliteDatagramCallback.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.telephony.satellite;
+
+import android.telephony.satellite.SatelliteDatagram;
+
+import com.android.internal.telephony.IVoidConsumer;
+
+/**
+ * Interface for satellite datagrams callback.
+ * @hide
+ */
+oneway interface ISatelliteDatagramCallback {
+ /**
+ * Called when there is an incoming datagram to be received from satellite.
+ *
+ * @param datagramId An id that uniquely identifies incoming datagram.
+ * @param datagram Datagram received from satellite.
+ * @param pendingCount Number of datagrams yet to be received from satellite.
+ * @param callback This callback will be used by datagram receiver app to to inform
+ * Telephony that datagram is received. If the callback is not received
+ * within five minutes, Telephony will resend the datagram.
+ */
+ void onSatelliteDatagramReceived(long datagramId, in SatelliteDatagram datagram,
+ int pendingCount, IVoidConsumer callback);
+}
diff --git a/telephony/java/android/telephony/satellite/ISatelliteProvisionStateCallback.aidl b/telephony/java/android/telephony/satellite/ISatelliteProvisionStateCallback.aidl
new file mode 100644
index 000000000000..f981fb1d67c7
--- /dev/null
+++ b/telephony/java/android/telephony/satellite/ISatelliteProvisionStateCallback.aidl
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.telephony.satellite;
+
+/**
+ * Interface for satellite provision state callback.
+ * @hide
+ */
+oneway interface ISatelliteProvisionStateCallback {
+ /**
+ * Indicates that the satellite provision state has changed.
+ *
+ * @param provisioned True means the service is provisioned and false means it is not.
+ */
+ void onSatelliteProvisionStateChanged(in boolean provisioned);
+}
diff --git a/telephony/java/android/telephony/satellite/ISatelliteStateCallback.aidl b/telephony/java/android/telephony/satellite/ISatelliteStateCallback.aidl
new file mode 100644
index 000000000000..cd9d81e1ee9b
--- /dev/null
+++ b/telephony/java/android/telephony/satellite/ISatelliteStateCallback.aidl
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.telephony.satellite;
+
+/**
+ * Interface for satellite state change callback.
+ * @hide
+ */
+oneway interface ISatelliteStateCallback {
+ /**
+ * Indicates that the satellite modem state has changed.
+ *
+ * @param state The current satellite modem state.
+ */
+ void onSatelliteModemStateChanged(in int state);
+}
diff --git a/telephony/java/android/telephony/satellite/ISatelliteTransmissionUpdateCallback.aidl b/telephony/java/android/telephony/satellite/ISatelliteTransmissionUpdateCallback.aidl
new file mode 100644
index 000000000000..a81444d51374
--- /dev/null
+++ b/telephony/java/android/telephony/satellite/ISatelliteTransmissionUpdateCallback.aidl
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.telephony.satellite;
+
+import android.telephony.satellite.PointingInfo;
+
+/**
+ * Interface for position update and datagram transfer state change callback.
+ * @hide
+ */
+oneway interface ISatelliteTransmissionUpdateCallback {
+ /**
+ * Called when satellite datagram send state changed.
+ *
+ * @param state The new send datagram transfer state.
+ * @param sendPendingCount The number of datagrams that are currently being sent.
+ * @param errorCode If datagram transfer failed, the reason for failure.
+ */
+ void onSendDatagramStateChanged(in int state, in int sendPendingCount, in int errorCode);
+
+ /**
+ * Called when satellite datagram receive state changed.
+ *
+ * @param state The new receive datagram transfer state.
+ * @param receivePendingCount The number of datagrams that are currently pending to be received.
+ * @param errorCode If datagram transfer failed, the reason for failure.
+ */
+ void onReceiveDatagramStateChanged(in int state, in int receivePendingCount, in int errorCode);
+
+ /**
+ * Called when the satellite position changed.
+ *
+ * @param pointingInfo The pointing info containing the satellite location.
+ */
+ void onSatellitePositionChanged(in PointingInfo pointingInfo);
+}
diff --git a/telephony/java/android/telephony/satellite/PointingInfo.aidl b/telephony/java/android/telephony/satellite/PointingInfo.aidl
new file mode 100644
index 000000000000..7ff95cdeee85
--- /dev/null
+++ b/telephony/java/android/telephony/satellite/PointingInfo.aidl
@@ -0,0 +1,19 @@
+/*
+ * Copyright 2023, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.telephony.satellite;
+
+parcelable PointingInfo;
diff --git a/telephony/java/android/telephony/satellite/PointingInfo.java b/telephony/java/android/telephony/satellite/PointingInfo.java
new file mode 100644
index 000000000000..a559b32f0021
--- /dev/null
+++ b/telephony/java/android/telephony/satellite/PointingInfo.java
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.telephony.satellite;
+
+import android.annotation.NonNull;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * @hide
+ */
+public final class PointingInfo implements Parcelable {
+ /** Satellite azimuth in degrees */
+ private float mSatelliteAzimuthDegrees;
+
+ /** Satellite elevation in degrees */
+ private float mSatelliteElevationDegrees;
+
+ /**
+ * @hide
+ */
+
+ public PointingInfo(float satelliteAzimuthDegrees, float satelliteElevationDegrees) {
+ mSatelliteAzimuthDegrees = satelliteAzimuthDegrees;
+ mSatelliteElevationDegrees = satelliteElevationDegrees;
+ }
+
+ private PointingInfo(Parcel in) {
+ readFromParcel(in);
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(@NonNull Parcel out, int flags) {
+ out.writeFloat(mSatelliteAzimuthDegrees);
+ out.writeFloat(mSatelliteElevationDegrees);
+ }
+
+ public static final @android.annotation.NonNull Creator<PointingInfo> CREATOR =
+ new Creator<PointingInfo>() {
+ @Override
+ public PointingInfo createFromParcel(Parcel in) {
+ return new PointingInfo(in);
+ }
+
+ @Override
+ public PointingInfo[] newArray(int size) {
+ return new PointingInfo[size];
+ }
+ };
+
+ @NonNull
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder();
+
+ sb.append("SatelliteAzimuthDegrees:");
+ sb.append(mSatelliteAzimuthDegrees);
+ sb.append(",");
+
+ sb.append("SatelliteElevationDegrees:");
+ sb.append(mSatelliteElevationDegrees);
+ return sb.toString();
+ }
+
+ public float getSatelliteAzimuthDegrees() {
+ return mSatelliteAzimuthDegrees;
+ }
+
+ public float getSatelliteElevationDegrees() {
+ return mSatelliteElevationDegrees;
+ }
+
+ private void readFromParcel(Parcel in) {
+ mSatelliteAzimuthDegrees = in.readFloat();
+ mSatelliteElevationDegrees = in.readFloat();
+ }
+}
diff --git a/telephony/java/android/telephony/satellite/SatelliteCapabilities.aidl b/telephony/java/android/telephony/satellite/SatelliteCapabilities.aidl
new file mode 100644
index 000000000000..a09306b07208
--- /dev/null
+++ b/telephony/java/android/telephony/satellite/SatelliteCapabilities.aidl
@@ -0,0 +1,19 @@
+/*
+ * Copyright 2023, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.telephony.satellite;
+
+parcelable SatelliteCapabilities;
diff --git a/telephony/java/android/telephony/satellite/SatelliteCapabilities.java b/telephony/java/android/telephony/satellite/SatelliteCapabilities.java
new file mode 100644
index 000000000000..6856cc0c5df2
--- /dev/null
+++ b/telephony/java/android/telephony/satellite/SatelliteCapabilities.java
@@ -0,0 +1,218 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.telephony.satellite;
+
+import android.annotation.NonNull;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Set;
+
+/**
+ * @hide
+ */
+public final class SatelliteCapabilities implements Parcelable {
+ /**
+ * List of technologies supported by the satellite modem.
+ */
+ @NonNull @SatelliteManager.NTRadioTechnology private Set<Integer> mSupportedRadioTechnologies;
+
+ /**
+ * Whether UE needs to point to a satellite to send and receive data.
+ */
+ private boolean mIsPointingRequired;
+
+ /**
+ * The maximum number of bytes per datagram that can be sent over satellite.
+ */
+ private int mMaxBytesPerOutgoingDatagram;
+
+ /**
+ * Antenna Position received from satellite modem which gives information about antenna
+ * direction to be used with satellite communication and suggested device hold positions.
+ * Map key: {@link SatelliteManager.DeviceHoldPosition} value: AntennaPosition
+ */
+ @NonNull
+ private Map<Integer, AntennaPosition> mAntennaPositionMap;
+
+ /**
+ * @hide
+ */
+ public SatelliteCapabilities(Set<Integer> supportedRadioTechnologies,
+ boolean isPointingRequired, int maxBytesPerOutgoingDatagram,
+ @NonNull Map<Integer, AntennaPosition> antennaPositionMap) {
+ mSupportedRadioTechnologies = supportedRadioTechnologies == null
+ ? new HashSet<>() : supportedRadioTechnologies;
+ mIsPointingRequired = isPointingRequired;
+ mMaxBytesPerOutgoingDatagram = maxBytesPerOutgoingDatagram;
+ mAntennaPositionMap = antennaPositionMap;
+ }
+
+ private SatelliteCapabilities(Parcel in) {
+ readFromParcel(in);
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(@NonNull Parcel out, int flags) {
+ if (mSupportedRadioTechnologies != null && !mSupportedRadioTechnologies.isEmpty()) {
+ out.writeInt(mSupportedRadioTechnologies.size());
+ for (int technology : mSupportedRadioTechnologies) {
+ out.writeInt(technology);
+ }
+ } else {
+ out.writeInt(0);
+ }
+
+ out.writeBoolean(mIsPointingRequired);
+ out.writeInt(mMaxBytesPerOutgoingDatagram);
+
+ if (mAntennaPositionMap != null && !mAntennaPositionMap.isEmpty()) {
+ int size = mAntennaPositionMap.size();
+ out.writeInt(size);
+ for (Map.Entry<Integer, AntennaPosition> entry : mAntennaPositionMap.entrySet()) {
+ out.writeInt(entry.getKey());
+ out.writeParcelable(entry.getValue(), flags);
+ }
+ } else {
+ out.writeInt(0);
+ }
+ }
+
+ @NonNull public static final Creator<SatelliteCapabilities> CREATOR = new Creator<>() {
+ @Override
+ public SatelliteCapabilities createFromParcel(Parcel in) {
+ return new SatelliteCapabilities(in);
+ }
+
+ @Override
+ public SatelliteCapabilities[] newArray(int size) {
+ return new SatelliteCapabilities[size];
+ }
+ };
+
+ @Override
+ @NonNull public String toString() {
+ StringBuilder sb = new StringBuilder();
+
+ sb.append("SupportedRadioTechnology:");
+ if (mSupportedRadioTechnologies != null && !mSupportedRadioTechnologies.isEmpty()) {
+ for (int technology : mSupportedRadioTechnologies) {
+ sb.append(technology);
+ sb.append(",");
+ }
+ } else {
+ sb.append("none,");
+ }
+
+ sb.append("isPointingRequired:");
+ sb.append(mIsPointingRequired);
+ sb.append(",");
+
+ sb.append("maxBytesPerOutgoingDatagram:");
+ sb.append(mMaxBytesPerOutgoingDatagram);
+ sb.append(",");
+
+ sb.append("antennaPositionMap:");
+ sb.append(mAntennaPositionMap);
+ return sb.toString();
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ SatelliteCapabilities that = (SatelliteCapabilities) o;
+ return Objects.equals(mSupportedRadioTechnologies, that.mSupportedRadioTechnologies)
+ && mIsPointingRequired == that.mIsPointingRequired
+ && mMaxBytesPerOutgoingDatagram == that.mMaxBytesPerOutgoingDatagram
+ && Objects.equals(mAntennaPositionMap, that.mAntennaPositionMap);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(mSupportedRadioTechnologies, mIsPointingRequired,
+ mMaxBytesPerOutgoingDatagram, mAntennaPositionMap);
+ }
+
+ /**
+ * @return The list of technologies supported by the satellite modem.
+ */
+ @NonNull @SatelliteManager.NTRadioTechnology public Set<Integer>
+ getSupportedRadioTechnologies() {
+ return mSupportedRadioTechnologies;
+ }
+
+ /**
+ * Get whether UE needs to point to a satellite to send and receive data.
+ *
+ * @return {@code true} if UE needs to point to a satellite to send and receive data and
+ * {@code false} otherwise.
+ */
+ public boolean isPointingRequired() {
+ return mIsPointingRequired;
+ }
+
+ /**
+ * The maximum number of bytes per datagram that can be sent over satellite.
+ *
+ * @return The maximum number of bytes per datagram that can be sent over satellite.
+ */
+ public int getMaxBytesPerOutgoingDatagram() {
+ return mMaxBytesPerOutgoingDatagram;
+ }
+
+ /**
+ * Antenna Position received from satellite modem which gives information about antenna
+ * direction to be used with satellite communication and suggested device hold positions.
+ * @return Map key: {@link SatelliteManager.DeviceHoldPosition} value: AntennaPosition
+ */
+ @NonNull
+ public Map<Integer, AntennaPosition> getAntennaPositionMap() {
+ return mAntennaPositionMap;
+ }
+
+ private void readFromParcel(Parcel in) {
+ mSupportedRadioTechnologies = new HashSet<>();
+ int numSupportedRadioTechnologies = in.readInt();
+ if (numSupportedRadioTechnologies > 0) {
+ for (int i = 0; i < numSupportedRadioTechnologies; i++) {
+ mSupportedRadioTechnologies.add(in.readInt());
+ }
+ }
+
+ mIsPointingRequired = in.readBoolean();
+ mMaxBytesPerOutgoingDatagram = in.readInt();
+
+ mAntennaPositionMap = new HashMap<>();
+ int antennaPositionMapSize = in.readInt();
+ for (int i = 0; i < antennaPositionMapSize; i++) {
+ int key = in.readInt();
+ AntennaPosition antennaPosition = in.readParcelable(
+ AntennaPosition.class.getClassLoader(), AntennaPosition.class);
+ mAntennaPositionMap.put(key, antennaPosition);
+ }
+ }
+}
diff --git a/telephony/java/android/telephony/satellite/SatelliteDatagram.aidl b/telephony/java/android/telephony/satellite/SatelliteDatagram.aidl
new file mode 100644
index 000000000000..993aacf80bd1
--- /dev/null
+++ b/telephony/java/android/telephony/satellite/SatelliteDatagram.aidl
@@ -0,0 +1,19 @@
+/*
+ * Copyright 2023, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.telephony.satellite;
+
+parcelable SatelliteDatagram;
diff --git a/telephony/java/android/telephony/satellite/SatelliteDatagram.java b/telephony/java/android/telephony/satellite/SatelliteDatagram.java
new file mode 100644
index 000000000000..d3cb8a07e4ba
--- /dev/null
+++ b/telephony/java/android/telephony/satellite/SatelliteDatagram.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.telephony.satellite;
+
+import android.annotation.NonNull;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * @hide
+ */
+public final class SatelliteDatagram implements Parcelable {
+ /**
+ * Datagram to be sent or received over satellite.
+ */
+ @NonNull private byte[] mData;
+
+ /**
+ * @hide
+ */
+ public SatelliteDatagram(@NonNull byte[] data) {
+ mData = data;
+ }
+
+ private SatelliteDatagram(Parcel in) {
+ readFromParcel(in);
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(@NonNull Parcel out, int flags) {
+ out.writeByteArray(mData);
+ }
+
+ @NonNull public static final Creator<SatelliteDatagram> CREATOR =
+ new Creator<>() {
+ @Override
+ public SatelliteDatagram createFromParcel(Parcel in) {
+ return new SatelliteDatagram(in);
+ }
+
+ @Override
+ public SatelliteDatagram[] newArray(int size) {
+ return new SatelliteDatagram[size];
+ }
+ };
+
+ @NonNull public byte[] getSatelliteDatagram() {
+ return mData;
+ }
+
+ private void readFromParcel(Parcel in) {
+ mData = in.createByteArray();
+ }
+}
diff --git a/telephony/java/android/telephony/satellite/SatelliteDatagramCallback.java b/telephony/java/android/telephony/satellite/SatelliteDatagramCallback.java
new file mode 100644
index 000000000000..b2dec71ecb32
--- /dev/null
+++ b/telephony/java/android/telephony/satellite/SatelliteDatagramCallback.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.telephony.satellite;
+
+import android.annotation.NonNull;
+
+import java.util.function.Consumer;
+
+/**
+ * A callback class for listening to satellite datagrams.
+ *
+ * @hide
+ */
+public interface SatelliteDatagramCallback {
+ /**
+ * Called when there is an incoming datagram to be received.
+ *
+ * @param datagramId An id that uniquely identifies incoming datagram.
+ * @param datagram Datagram to be received over satellite.
+ * @param pendingCount Number of datagrams yet to be received by the app.
+ * @param callback This callback will be used by datagram receiver app to inform Telephony
+ * that they received the datagram. If the callback is not received within
+ * five minutes, Telephony will resend the datagram.
+ */
+ void onSatelliteDatagramReceived(long datagramId, @NonNull SatelliteDatagram datagram,
+ int pendingCount, @NonNull Consumer<Void> callback);
+}
diff --git a/telephony/java/android/telephony/satellite/SatelliteManager.java b/telephony/java/android/telephony/satellite/SatelliteManager.java
new file mode 100644
index 000000000000..2021ac7c4cd5
--- /dev/null
+++ b/telephony/java/android/telephony/satellite/SatelliteManager.java
@@ -0,0 +1,1561 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.telephony.satellite;
+
+import android.Manifest;
+import android.annotation.CallbackExecutor;
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.RequiresFeature;
+import android.annotation.RequiresPermission;
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.os.Binder;
+import android.os.Bundle;
+import android.os.CancellationSignal;
+import android.os.ICancellationSignal;
+import android.os.OutcomeReceiver;
+import android.os.RemoteException;
+import android.os.ResultReceiver;
+import android.telephony.SubscriptionManager;
+import android.telephony.TelephonyFrameworkInitializer;
+
+import com.android.internal.telephony.IIntegerConsumer;
+import com.android.internal.telephony.ITelephony;
+import com.android.internal.telephony.IVoidConsumer;
+import com.android.telephony.Rlog;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.time.Duration;
+import java.util.Objects;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.Executor;
+import java.util.function.Consumer;
+
+/**
+ * Manages satellite operations such as provisioning, pointing, messaging, location sharing, etc.
+ * To get the object, call {@link Context#getSystemService(String)}.
+ *
+ * @hide
+ */
+@RequiresFeature(PackageManager.FEATURE_TELEPHONY_SATELLITE)
+public class SatelliteManager {
+ private static final String TAG = "SatelliteManager";
+
+ private static final ConcurrentHashMap<SatelliteDatagramCallback, ISatelliteDatagramCallback>
+ sSatelliteDatagramCallbackMap = new ConcurrentHashMap<>();
+ private static final ConcurrentHashMap<SatelliteProvisionStateCallback,
+ ISatelliteProvisionStateCallback> sSatelliteProvisionStateCallbackMap =
+ new ConcurrentHashMap<>();
+ private static final ConcurrentHashMap<SatelliteStateCallback, ISatelliteStateCallback>
+ sSatelliteStateCallbackMap = new ConcurrentHashMap<>();
+ private static final ConcurrentHashMap<SatelliteTransmissionUpdateCallback,
+ ISatelliteTransmissionUpdateCallback> sSatelliteTransmissionUpdateCallbackMap =
+ new ConcurrentHashMap<>();
+
+ private final int mSubId;
+
+ /**
+ * Context this SatelliteManager is for.
+ */
+ @Nullable private final Context mContext;
+
+ /**
+ * Create an instance of the SatelliteManager.
+ *
+ * @param context The context the SatelliteManager belongs to.
+ * @hide
+ */
+
+ public SatelliteManager(@Nullable Context context) {
+ this(context, SubscriptionManager.DEFAULT_SUBSCRIPTION_ID);
+ }
+
+ /**
+ * Create an instance of the SatelliteManager associated with a particular subscription.
+ *
+ * @param context The context the SatelliteManager belongs to.
+ * @param subId The subscription ID associated with the SatelliteManager.
+ */
+ private SatelliteManager(@Nullable Context context, int subId) {
+ mContext = context;
+ mSubId = subId;
+ }
+
+ /**
+ * Exception from the satellite service containing the {@link SatelliteError} error code.
+ */
+ public static class SatelliteException extends Exception {
+ @SatelliteError private final int mErrorCode;
+
+ /**
+ * Create a SatelliteException with a given error code.
+ *
+ * @param errorCode The {@link SatelliteError}.
+ */
+ public SatelliteException(@SatelliteError int errorCode) {
+ mErrorCode = errorCode;
+ }
+
+ /**
+ * Get the error code returned from the satellite service.
+ *
+ * @return The {@link SatelliteError}.
+ */
+ @SatelliteError public int getErrorCode() {
+ return mErrorCode;
+ }
+ }
+
+ /**
+ * Bundle key to get the response from
+ * {@link #requestIsSatelliteEnabled(Executor, OutcomeReceiver)}.
+ * @hide
+ */
+
+ public static final String KEY_SATELLITE_ENABLED = "satellite_enabled";
+
+ /**
+ * Bundle key to get the response from
+ * {@link #requestIsDemoModeEnabled(Executor, OutcomeReceiver)}.
+ * @hide
+ */
+
+ public static final String KEY_DEMO_MODE_ENABLED = "demo_mode_enabled";
+
+ /**
+ * Bundle key to get the response from
+ * {@link #requestIsSatelliteSupported(Executor, OutcomeReceiver)}.
+ * @hide
+ */
+
+ public static final String KEY_SATELLITE_SUPPORTED = "satellite_supported";
+
+ /**
+ * Bundle key to get the response from
+ * {@link #requestSatelliteCapabilities(Executor, OutcomeReceiver)}.
+ * @hide
+ */
+
+ public static final String KEY_SATELLITE_CAPABILITIES = "satellite_capabilities";
+
+ /**
+ * Bundle key to get the response from
+ * {@link #requestIsSatelliteProvisioned(Executor, OutcomeReceiver)}.
+ * @hide
+ */
+
+ public static final String KEY_SATELLITE_PROVISIONED = "satellite_provisioned";
+
+ /**
+ * Bundle key to get the response from
+ * {@link #requestIsSatelliteCommunicationAllowedForCurrentLocation(Executor, OutcomeReceiver)}.
+ * @hide
+ */
+
+ public static final String KEY_SATELLITE_COMMUNICATION_ALLOWED =
+ "satellite_communication_allowed";
+
+ /**
+ * Bundle key to get the response from
+ * {@link #requestTimeForNextSatelliteVisibility(Executor, OutcomeReceiver)}.
+ * @hide
+ */
+
+ public static final String KEY_SATELLITE_NEXT_VISIBILITY = "satellite_next_visibility";
+
+ /**
+ * The request was successfully processed.
+ */
+ public static final int SATELLITE_ERROR_NONE = 0;
+ /**
+ * A generic error which should be used only when other specific errors cannot be used.
+ */
+ public static final int SATELLITE_ERROR = 1;
+ /**
+ * Error received from the satellite server.
+ */
+ public static final int SATELLITE_SERVER_ERROR = 2;
+ /**
+ * Error received from the vendor service. This generic error code should be used
+ * only when the error cannot be mapped to other specific service error codes.
+ */
+ public static final int SATELLITE_SERVICE_ERROR = 3;
+ /**
+ * Error received from satellite modem. This generic error code should be used only when
+ * the error cannot be mapped to other specific modem error codes.
+ */
+ public static final int SATELLITE_MODEM_ERROR = 4;
+ /**
+ * Error received from the satellite network. This generic error code should be used only when
+ * the error cannot be mapped to other specific network error codes.
+ */
+ public static final int SATELLITE_NETWORK_ERROR = 5;
+ /**
+ * Telephony is not in a valid state to receive requests from clients.
+ */
+ public static final int SATELLITE_INVALID_TELEPHONY_STATE = 6;
+ /**
+ * Satellite modem is not in a valid state to receive requests from clients.
+ */
+ public static final int SATELLITE_INVALID_MODEM_STATE = 7;
+ /**
+ * Either vendor service, or modem, or Telephony framework has received a request with
+ * invalid arguments from its clients.
+ */
+ public static final int SATELLITE_INVALID_ARGUMENTS = 8;
+ /**
+ * Telephony framework failed to send a request or receive a response from the vendor service
+ * or satellite modem due to internal error.
+ */
+ public static final int SATELLITE_REQUEST_FAILED = 9;
+ /**
+ * Radio did not start or is resetting.
+ */
+ public static final int SATELLITE_RADIO_NOT_AVAILABLE = 10;
+ /**
+ * The request is not supported by either the satellite modem or the network.
+ */
+ public static final int SATELLITE_REQUEST_NOT_SUPPORTED = 11;
+ /**
+ * Satellite modem or network has no resources available to handle requests from clients.
+ */
+ public static final int SATELLITE_NO_RESOURCES = 12;
+ /**
+ * Satellite service is not provisioned yet.
+ */
+ public static final int SATELLITE_SERVICE_NOT_PROVISIONED = 13;
+ /**
+ * Satellite service provision is already in progress.
+ */
+ public static final int SATELLITE_SERVICE_PROVISION_IN_PROGRESS = 14;
+ /**
+ * The ongoing request was aborted by either the satellite modem or the network.
+ * This error is also returned when framework decides to abort current send request as one
+ * of the previous send request failed.
+ */
+ public static final int SATELLITE_REQUEST_ABORTED = 15;
+ /**
+ * The device/subscriber is barred from accessing the satellite service.
+ */
+ public static final int SATELLITE_ACCESS_BARRED = 16;
+ /**
+ * Satellite modem timeout to receive ACK or response from the satellite network after
+ * sending a request to the network.
+ */
+ public static final int SATELLITE_NETWORK_TIMEOUT = 17;
+ /**
+ * Satellite network is not reachable from the modem.
+ */
+ public static final int SATELLITE_NOT_REACHABLE = 18;
+ /**
+ * The device/subscriber is not authorized to register with the satellite service provider.
+ */
+ public static final int SATELLITE_NOT_AUTHORIZED = 19;
+ /**
+ * The device does not support satellite.
+ */
+ public static final int SATELLITE_NOT_SUPPORTED = 20;
+
+ /**
+ * The current request is already in-progress.
+ */
+ public static final int SATELLITE_REQUEST_IN_PROGRESS = 21;
+
+ /**
+ * Satellite modem is currently busy due to which current request cannot be processed.
+ */
+ public static final int SATELLITE_MODEM_BUSY = 22;
+
+ /** @hide */
+ @IntDef(prefix = {"SATELLITE_"}, value = {
+ SATELLITE_ERROR_NONE,
+ SATELLITE_ERROR,
+ SATELLITE_SERVER_ERROR,
+ SATELLITE_SERVICE_ERROR,
+ SATELLITE_MODEM_ERROR,
+ SATELLITE_NETWORK_ERROR,
+ SATELLITE_INVALID_TELEPHONY_STATE,
+ SATELLITE_INVALID_MODEM_STATE,
+ SATELLITE_INVALID_ARGUMENTS,
+ SATELLITE_REQUEST_FAILED,
+ SATELLITE_RADIO_NOT_AVAILABLE,
+ SATELLITE_REQUEST_NOT_SUPPORTED,
+ SATELLITE_NO_RESOURCES,
+ SATELLITE_SERVICE_NOT_PROVISIONED,
+ SATELLITE_SERVICE_PROVISION_IN_PROGRESS,
+ SATELLITE_REQUEST_ABORTED,
+ SATELLITE_ACCESS_BARRED,
+ SATELLITE_NETWORK_TIMEOUT,
+ SATELLITE_NOT_REACHABLE,
+ SATELLITE_NOT_AUTHORIZED,
+ SATELLITE_NOT_SUPPORTED,
+ SATELLITE_REQUEST_IN_PROGRESS,
+ SATELLITE_MODEM_BUSY
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface SatelliteError {}
+
+ /**
+ * Unknown Non-Terrestrial radio technology. This generic radio technology should be used
+ * only when the radio technology cannot be mapped to other specific radio technologies.
+ */
+ public static final int NT_RADIO_TECHNOLOGY_UNKNOWN = 0;
+ /**
+ * 3GPP NB-IoT (Narrowband Internet of Things) over Non-Terrestrial-Networks technology.
+ */
+ public static final int NT_RADIO_TECHNOLOGY_NB_IOT_NTN = 1;
+ /**
+ * 3GPP 5G NR over Non-Terrestrial-Networks technology.
+ */
+ public static final int NT_RADIO_TECHNOLOGY_NR_NTN = 2;
+ /**
+ * 3GPP eMTC (enhanced Machine-Type Communication) over Non-Terrestrial-Networks technology.
+ */
+ public static final int NT_RADIO_TECHNOLOGY_EMTC_NTN = 3;
+ /**
+ * Proprietary technology.
+ */
+ public static final int NT_RADIO_TECHNOLOGY_PROPRIETARY = 4;
+
+ /** @hide */
+ @IntDef(prefix = "NT_RADIO_TECHNOLOGY_", value = {
+ NT_RADIO_TECHNOLOGY_UNKNOWN,
+ NT_RADIO_TECHNOLOGY_NB_IOT_NTN,
+ NT_RADIO_TECHNOLOGY_NR_NTN,
+ NT_RADIO_TECHNOLOGY_EMTC_NTN,
+ NT_RADIO_TECHNOLOGY_PROPRIETARY
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface NTRadioTechnology {}
+
+ /** Suggested device hold position is unknown. */
+ public static final int DEVICE_HOLD_POSITION_UNKNOWN = 0;
+ /** User is suggested to hold the device in portrait mode. */
+ public static final int DEVICE_HOLD_POSITION_PORTRAIT = 1;
+ /** User is suggested to hold the device in landscape mode with left hand. */
+ public static final int DEVICE_HOLD_POSITION_LANDSCAPE_LEFT = 2;
+ /** User is suggested to hold the device in landscape mode with right hand. */
+ public static final int DEVICE_HOLD_POSITION_LANDSCAPE_RIGHT = 3;
+
+ /** @hide */
+ @IntDef(prefix = {"DEVICE_HOLD_POSITION_"}, value = {
+ DEVICE_HOLD_POSITION_UNKNOWN,
+ DEVICE_HOLD_POSITION_PORTRAIT,
+ DEVICE_HOLD_POSITION_LANDSCAPE_LEFT,
+ DEVICE_HOLD_POSITION_LANDSCAPE_RIGHT
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface DeviceHoldPosition {}
+
+ /** Display mode is unknown. */
+ public static final int DISPLAY_MODE_UNKNOWN = 0;
+ /** Display mode of the device used for satellite communication for non-foldable phones. */
+ public static final int DISPLAY_MODE_FIXED = 1;
+ /** Display mode of the device used for satellite communication for foldabale phones when the
+ * device is opened. */
+ public static final int DISPLAY_MODE_OPENED = 2;
+ /** Display mode of the device used for satellite communication for foldabable phones when the
+ * device is closed. */
+ public static final int DISPLAY_MODE_CLOSED = 3;
+
+ /** @hide */
+ @IntDef(prefix = {"ANTENNA_POSITION_"}, value = {
+ DISPLAY_MODE_UNKNOWN,
+ DISPLAY_MODE_FIXED,
+ DISPLAY_MODE_OPENED,
+ DISPLAY_MODE_CLOSED
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface DisplayMode {}
+
+ /**
+ * Request to enable or disable the satellite modem and demo mode. If the satellite modem is
+ * enabled, this may also disable the cellular modem, and if the satellite modem is disabled,
+ * this may also re-enable the cellular modem.
+ *
+ * @param enableSatellite {@code true} to enable the satellite modem and
+ * {@code false} to disable.
+ * @param enableDemoMode {@code true} to enable demo mode and {@code false} to disable.
+ * @param executor The executor on which the error code listener will be called.
+ * @param resultListener Listener for the {@link SatelliteError} result of the operation.
+ *
+ * @throws SecurityException if the caller doesn't have required permission.
+ * @throws IllegalStateException if the Telephony process is not currently available.
+ */
+ @RequiresPermission(Manifest.permission.SATELLITE_COMMUNICATION)
+
+ public void requestSatelliteEnabled(boolean enableSatellite, boolean enableDemoMode,
+ @NonNull @CallbackExecutor Executor executor,
+ @SatelliteError @NonNull Consumer<Integer> resultListener) {
+ Objects.requireNonNull(executor);
+ Objects.requireNonNull(resultListener);
+
+ try {
+ ITelephony telephony = getITelephony();
+ if (telephony != null) {
+ IIntegerConsumer errorCallback = new IIntegerConsumer.Stub() {
+ @Override
+ public void accept(int result) {
+ executor.execute(() -> Binder.withCleanCallingIdentity(
+ () -> resultListener.accept(result)));
+ }
+ };
+ telephony.requestSatelliteEnabled(mSubId, enableSatellite, enableDemoMode,
+ errorCallback);
+ } else {
+ throw new IllegalStateException("telephony service is null.");
+ }
+ } catch (RemoteException ex) {
+ Rlog.e(TAG, "requestSatelliteEnabled() RemoteException: ", ex);
+ ex.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * Request to get whether the satellite modem is enabled.
+ *
+ * @param executor The executor on which the callback will be called.
+ * @param callback The callback object to which the result will be delivered.
+ * If the request is successful, {@link OutcomeReceiver#onResult(Object)}
+ * will return a {@code boolean} with value {@code true} if the satellite modem
+ * is enabled and {@code false} otherwise.
+ * If the request is not successful, {@link OutcomeReceiver#onError(Throwable)}
+ * will return a {@link SatelliteException} with the {@link SatelliteError}.
+ *
+ * @throws SecurityException if the caller doesn't have required permission.
+ * @throws IllegalStateException if the Telephony process is not currently available.
+ */
+ @RequiresPermission(Manifest.permission.SATELLITE_COMMUNICATION)
+
+ public void requestIsSatelliteEnabled(@NonNull @CallbackExecutor Executor executor,
+ @NonNull OutcomeReceiver<Boolean, SatelliteException> callback) {
+ Objects.requireNonNull(executor);
+ Objects.requireNonNull(callback);
+
+ try {
+ ITelephony telephony = getITelephony();
+ if (telephony != null) {
+ ResultReceiver receiver = new ResultReceiver(null) {
+ @Override
+ protected void onReceiveResult(int resultCode, Bundle resultData) {
+ if (resultCode == SATELLITE_ERROR_NONE) {
+ if (resultData.containsKey(KEY_SATELLITE_ENABLED)) {
+ boolean isSatelliteEnabled =
+ resultData.getBoolean(KEY_SATELLITE_ENABLED);
+ executor.execute(() -> Binder.withCleanCallingIdentity(() ->
+ callback.onResult(isSatelliteEnabled)));
+ } else {
+ loge("KEY_SATELLITE_ENABLED does not exist.");
+ executor.execute(() -> Binder.withCleanCallingIdentity(() ->
+ callback.onError(
+ new SatelliteException(SATELLITE_REQUEST_FAILED))));
+ }
+ } else {
+ executor.execute(() -> Binder.withCleanCallingIdentity(() ->
+ callback.onError(new SatelliteException(resultCode))));
+ }
+ }
+ };
+ telephony.requestIsSatelliteEnabled(mSubId, receiver);
+ } else {
+ throw new IllegalStateException("telephony service is null.");
+ }
+ } catch (RemoteException ex) {
+ loge("requestIsSatelliteEnabled() RemoteException: " + ex);
+ ex.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * Request to get whether the satellite service demo mode is enabled.
+ *
+ * @param executor The executor on which the callback will be called.
+ * @param callback The callback object to which the result will be delivered.
+ * If the request is successful, {@link OutcomeReceiver#onResult(Object)}
+ * will return a {@code boolean} with value {@code true} if demo mode is enabled
+ * and {@code false} otherwise.
+ * If the request is not successful, {@link OutcomeReceiver#onError(Throwable)}
+ * will return a {@link SatelliteException} with the {@link SatelliteError}.
+ *
+ * @throws SecurityException if the caller doesn't have required permission.
+ * @throws IllegalStateException if the Telephony process is not currently available.
+ */
+ @RequiresPermission(Manifest.permission.SATELLITE_COMMUNICATION)
+
+ public void requestIsDemoModeEnabled(@NonNull @CallbackExecutor Executor executor,
+ @NonNull OutcomeReceiver<Boolean, SatelliteException> callback) {
+ Objects.requireNonNull(executor);
+ Objects.requireNonNull(callback);
+
+ try {
+ ITelephony telephony = getITelephony();
+ if (telephony != null) {
+ ResultReceiver receiver = new ResultReceiver(null) {
+ @Override
+ protected void onReceiveResult(int resultCode, Bundle resultData) {
+ if (resultCode == SATELLITE_ERROR_NONE) {
+ if (resultData.containsKey(KEY_DEMO_MODE_ENABLED)) {
+ boolean isDemoModeEnabled =
+ resultData.getBoolean(KEY_DEMO_MODE_ENABLED);
+ executor.execute(() -> Binder.withCleanCallingIdentity(() ->
+ callback.onResult(isDemoModeEnabled)));
+ } else {
+ loge("KEY_DEMO_MODE_ENABLED does not exist.");
+ executor.execute(() -> Binder.withCleanCallingIdentity(() ->
+ callback.onError(
+ new SatelliteException(SATELLITE_REQUEST_FAILED))));
+ }
+ } else {
+ executor.execute(() -> Binder.withCleanCallingIdentity(() ->
+ callback.onError(new SatelliteException(resultCode))));
+ }
+ }
+ };
+ telephony.requestIsDemoModeEnabled(mSubId, receiver);
+ } else {
+ throw new IllegalStateException("telephony service is null.");
+ }
+ } catch (RemoteException ex) {
+ loge("requestIsDemoModeEnabled() RemoteException: " + ex);
+ ex.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * Request to get whether the satellite service is supported on the device.
+ *
+ * @param executor The executor on which the callback will be called.
+ * @param callback The callback object to which the result will be delivered.
+ * If the request is successful, {@link OutcomeReceiver#onResult(Object)}
+ * will return a {@code boolean} with value {@code true} if the satellite
+ * service is supported on the device and {@code false} otherwise.
+ * If the request is not successful, {@link OutcomeReceiver#onError(Throwable)}
+ * will return a {@link SatelliteException} with the {@link SatelliteError}.
+ *
+ * @throws IllegalStateException if the Telephony process is not currently available.
+ */
+
+ public void requestIsSatelliteSupported(@NonNull @CallbackExecutor Executor executor,
+ @NonNull OutcomeReceiver<Boolean, SatelliteException> callback) {
+ Objects.requireNonNull(executor);
+ Objects.requireNonNull(callback);
+
+ try {
+ ITelephony telephony = getITelephony();
+ if (telephony != null) {
+ ResultReceiver receiver = new ResultReceiver(null) {
+ @Override
+ protected void onReceiveResult(int resultCode, Bundle resultData) {
+ if (resultCode == SATELLITE_ERROR_NONE) {
+ if (resultData.containsKey(KEY_SATELLITE_SUPPORTED)) {
+ boolean isSatelliteSupported =
+ resultData.getBoolean(KEY_SATELLITE_SUPPORTED);
+ executor.execute(() -> Binder.withCleanCallingIdentity(() ->
+ callback.onResult(isSatelliteSupported)));
+ } else {
+ loge("KEY_SATELLITE_SUPPORTED does not exist.");
+ executor.execute(() -> Binder.withCleanCallingIdentity(() ->
+ callback.onError(
+ new SatelliteException(SATELLITE_REQUEST_FAILED))));
+ }
+ } else {
+ executor.execute(() -> Binder.withCleanCallingIdentity(() ->
+ callback.onError(new SatelliteException(resultCode))));
+ }
+ }
+ };
+ telephony.requestIsSatelliteSupported(mSubId, receiver);
+ } else {
+ throw new IllegalStateException("telephony service is null.");
+ }
+ } catch (RemoteException ex) {
+ loge("requestIsSatelliteSupported() RemoteException: " + ex);
+ ex.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * Request to get the {@link SatelliteCapabilities} of the satellite service.
+ *
+ * @param executor The executor on which the callback will be called.
+ * @param callback The callback object to which the result will be delivered.
+ * If the request is successful, {@link OutcomeReceiver#onResult(Object)}
+ * will return the {@link SatelliteCapabilities} of the satellite service.
+ * If the request is not successful, {@link OutcomeReceiver#onError(Throwable)}
+ * will return a {@link SatelliteException} with the {@link SatelliteError}.
+ *
+ * @throws SecurityException if the caller doesn't have required permission.
+ * @throws IllegalStateException if the Telephony process is not currently available.
+ */
+ @RequiresPermission(Manifest.permission.SATELLITE_COMMUNICATION)
+
+ public void requestSatelliteCapabilities(@NonNull @CallbackExecutor Executor executor,
+ @NonNull OutcomeReceiver<SatelliteCapabilities, SatelliteException> callback) {
+ Objects.requireNonNull(executor);
+ Objects.requireNonNull(callback);
+
+ try {
+ ITelephony telephony = getITelephony();
+ if (telephony != null) {
+ ResultReceiver receiver = new ResultReceiver(null) {
+ @Override
+ protected void onReceiveResult(int resultCode, Bundle resultData) {
+ if (resultCode == SATELLITE_ERROR_NONE) {
+ if (resultData.containsKey(KEY_SATELLITE_CAPABILITIES)) {
+ SatelliteCapabilities capabilities =
+ resultData.getParcelable(KEY_SATELLITE_CAPABILITIES,
+ SatelliteCapabilities.class);
+ executor.execute(() -> Binder.withCleanCallingIdentity(() ->
+ callback.onResult(capabilities)));
+ } else {
+ loge("KEY_SATELLITE_CAPABILITIES does not exist.");
+ executor.execute(() -> Binder.withCleanCallingIdentity(() ->
+ callback.onError(
+ new SatelliteException(SATELLITE_REQUEST_FAILED))));
+ }
+ } else {
+ executor.execute(() -> Binder.withCleanCallingIdentity(() ->
+ callback.onError(new SatelliteException(resultCode))));
+ }
+ }
+ };
+ telephony.requestSatelliteCapabilities(mSubId, receiver);
+ } else {
+ throw new IllegalStateException("telephony service is null.");
+ }
+ } catch (RemoteException ex) {
+ loge("requestSatelliteCapabilities() RemoteException: " + ex);
+ ex.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * The default state indicating that datagram transfer is idle.
+ * This should be sent if there are no message transfer activity happening.
+ */
+ public static final int SATELLITE_DATAGRAM_TRANSFER_STATE_IDLE = 0;
+ /**
+ * A transition state indicating that a datagram is being sent.
+ */
+ public static final int SATELLITE_DATAGRAM_TRANSFER_STATE_SENDING = 1;
+ /**
+ * An end state indicating that datagram sending completed successfully.
+ * After datagram transfer completes, {@link #SATELLITE_DATAGRAM_TRANSFER_STATE_IDLE}
+ * will be sent if no more messages are pending.
+ */
+ public static final int SATELLITE_DATAGRAM_TRANSFER_STATE_SEND_SUCCESS = 2;
+ /**
+ * An end state indicating that datagram sending completed with a failure.
+ * After datagram transfer completes, {@link #SATELLITE_DATAGRAM_TRANSFER_STATE_IDLE}
+ * must be sent before reporting any additional datagram transfer state changes. All pending
+ * messages will be reported as failed, to the corresponding applications.
+ */
+ public static final int SATELLITE_DATAGRAM_TRANSFER_STATE_SEND_FAILED = 3;
+ /**
+ * A transition state indicating that a datagram is being received.
+ */
+ public static final int SATELLITE_DATAGRAM_TRANSFER_STATE_RECEIVING = 4;
+ /**
+ * An end state indicating that datagram receiving completed successfully.
+ * After datagram transfer completes, {@link #SATELLITE_DATAGRAM_TRANSFER_STATE_IDLE}
+ * will be sent if no more messages are pending.
+ */
+ public static final int SATELLITE_DATAGRAM_TRANSFER_STATE_RECEIVE_SUCCESS = 5;
+ /**
+ * An end state indicating that datagram receive operation found that there are no
+ * messages to be retrieved from the satellite.
+ * After datagram transfer completes, {@link #SATELLITE_DATAGRAM_TRANSFER_STATE_IDLE}
+ * will be sent if no more messages are pending.
+ */
+ public static final int SATELLITE_DATAGRAM_TRANSFER_STATE_RECEIVE_NONE = 6;
+ /**
+ * An end state indicating that datagram receive completed with a failure.
+ * After datagram transfer completes, {@link #SATELLITE_DATAGRAM_TRANSFER_STATE_IDLE}
+ * will be sent if no more messages are pending.
+ */
+ public static final int SATELLITE_DATAGRAM_TRANSFER_STATE_RECEIVE_FAILED = 7;
+ /**
+ * The datagram transfer state is unknown. This generic datagram transfer state should be used
+ * only when the datagram transfer state cannot be mapped to other specific datagram transfer
+ * states.
+ */
+ public static final int SATELLITE_DATAGRAM_TRANSFER_STATE_UNKNOWN = -1;
+
+ /** @hide */
+ @IntDef(prefix = {"SATELLITE_DATAGRAM_TRANSFER_STATE_"}, value = {
+ SATELLITE_DATAGRAM_TRANSFER_STATE_IDLE,
+ SATELLITE_DATAGRAM_TRANSFER_STATE_SENDING,
+ SATELLITE_DATAGRAM_TRANSFER_STATE_SEND_SUCCESS,
+ SATELLITE_DATAGRAM_TRANSFER_STATE_SEND_FAILED,
+ SATELLITE_DATAGRAM_TRANSFER_STATE_RECEIVING,
+ SATELLITE_DATAGRAM_TRANSFER_STATE_RECEIVE_SUCCESS,
+ SATELLITE_DATAGRAM_TRANSFER_STATE_RECEIVE_NONE,
+ SATELLITE_DATAGRAM_TRANSFER_STATE_RECEIVE_FAILED,
+ SATELLITE_DATAGRAM_TRANSFER_STATE_UNKNOWN
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface SatelliteDatagramTransferState {}
+ // TODO: Split into two enums for sending and receiving states
+
+ /**
+ * Satellite modem is in idle state.
+ */
+ public static final int SATELLITE_MODEM_STATE_IDLE = 0;
+ /**
+ * Satellite modem is listening for incoming datagrams.
+ */
+ public static final int SATELLITE_MODEM_STATE_LISTENING = 1;
+ /**
+ * Satellite modem is sending and/or receiving datagrams.
+ */
+ public static final int SATELLITE_MODEM_STATE_DATAGRAM_TRANSFERRING = 2;
+ /**
+ * Satellite modem is retrying to send and/or receive datagrams.
+ */
+ public static final int SATELLITE_MODEM_STATE_DATAGRAM_RETRYING = 3;
+ /**
+ * Satellite modem is powered off.
+ */
+ public static final int SATELLITE_MODEM_STATE_OFF = 4;
+ /**
+ * Satellite modem is unavailable.
+ */
+ public static final int SATELLITE_MODEM_STATE_UNAVAILABLE = 5;
+ /**
+ * Satellite modem state is unknown. This generic modem state should be used only when the
+ * modem state cannot be mapped to other specific modem states.
+ */
+ public static final int SATELLITE_MODEM_STATE_UNKNOWN = -1;
+
+ /** @hide */
+ @IntDef(prefix = {"SATELLITE_MODEM_STATE_"}, value = {
+ SATELLITE_MODEM_STATE_IDLE,
+ SATELLITE_MODEM_STATE_LISTENING,
+ SATELLITE_MODEM_STATE_DATAGRAM_TRANSFERRING,
+ SATELLITE_MODEM_STATE_DATAGRAM_RETRYING,
+ SATELLITE_MODEM_STATE_OFF,
+ SATELLITE_MODEM_STATE_UNAVAILABLE,
+ SATELLITE_MODEM_STATE_UNKNOWN
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface SatelliteModemState {}
+
+ /**
+ * Datagram type is unknown. This generic datagram type should be used only when the
+ * datagram type cannot be mapped to other specific datagram types.
+ */
+ public static final int DATAGRAM_TYPE_UNKNOWN = 0;
+ /**
+ * Datagram type indicating that the datagram to be sent or received is of type SOS message.
+ */
+ public static final int DATAGRAM_TYPE_SOS_MESSAGE = 1;
+ /**
+ * Datagram type indicating that the datagram to be sent or received is of type
+ * location sharing.
+ */
+ public static final int DATAGRAM_TYPE_LOCATION_SHARING = 2;
+
+ /** @hide */
+ @IntDef(prefix = "DATAGRAM_TYPE_", value = {
+ DATAGRAM_TYPE_UNKNOWN,
+ DATAGRAM_TYPE_SOS_MESSAGE,
+ DATAGRAM_TYPE_LOCATION_SHARING
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface DatagramType {}
+
+ /**
+ * Start receiving satellite transmission updates.
+ * This can be called by the pointing UI when the user starts pointing to the satellite.
+ * Modem should continue to report the pointing input as the device or satellite moves.
+ * Satellite transmission updates are started only on {@link #SATELLITE_ERROR_NONE}.
+ * All other results indicate that this operation failed.
+ * Once satellite transmission updates begin, position and datagram transfer state updates
+ * will be sent through {@link SatelliteTransmissionUpdateCallback}.
+ *
+ * @param executor The executor on which the callback and error code listener will be called.
+ * @param resultListener Listener for the {@link SatelliteError} result of the operation.
+ * @param callback The callback to notify of satellite transmission updates.
+ *
+ * @throws SecurityException if the caller doesn't have required permission.
+ * @throws IllegalStateException if the Telephony process is not currently available.
+ */
+ @RequiresPermission(Manifest.permission.SATELLITE_COMMUNICATION)
+
+ public void startSatelliteTransmissionUpdates(@NonNull @CallbackExecutor Executor executor,
+ @SatelliteError @NonNull Consumer<Integer> resultListener,
+ @NonNull SatelliteTransmissionUpdateCallback callback) {
+ Objects.requireNonNull(executor);
+ Objects.requireNonNull(resultListener);
+ Objects.requireNonNull(callback);
+
+ try {
+ ITelephony telephony = getITelephony();
+ if (telephony != null) {
+ IIntegerConsumer errorCallback = new IIntegerConsumer.Stub() {
+ @Override
+ public void accept(int result) {
+ executor.execute(() -> Binder.withCleanCallingIdentity(
+ () -> resultListener.accept(result)));
+ }
+ };
+ ISatelliteTransmissionUpdateCallback internalCallback =
+ new ISatelliteTransmissionUpdateCallback.Stub() {
+
+ @Override
+ public void onSatellitePositionChanged(PointingInfo pointingInfo) {
+ executor.execute(() -> Binder.withCleanCallingIdentity(
+ () -> callback.onSatellitePositionChanged(pointingInfo)));
+ }
+
+ @Override
+ public void onSendDatagramStateChanged(int state, int sendPendingCount,
+ int errorCode) {
+ executor.execute(() -> Binder.withCleanCallingIdentity(
+ () -> callback.onSendDatagramStateChanged(
+ state, sendPendingCount, errorCode)));
+ }
+
+ @Override
+ public void onReceiveDatagramStateChanged(int state,
+ int receivePendingCount, int errorCode) {
+ executor.execute(() -> Binder.withCleanCallingIdentity(
+ () -> callback.onReceiveDatagramStateChanged(
+ state, receivePendingCount, errorCode)));
+ }
+ };
+ sSatelliteTransmissionUpdateCallbackMap.put(callback, internalCallback);
+ telephony.startSatelliteTransmissionUpdates(mSubId, errorCallback,
+ internalCallback);
+ } else {
+ throw new IllegalStateException("telephony service is null.");
+ }
+ } catch (RemoteException ex) {
+ loge("startSatelliteTransmissionUpdates() RemoteException: " + ex);
+ ex.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * Stop receiving satellite transmission updates.
+ * This can be called by the pointing UI when the user stops pointing to the satellite.
+ * Satellite transmission updates are stopped and the callback is unregistered only on
+ * {@link #SATELLITE_ERROR_NONE}. All other results that this operation failed.
+ *
+ * @param callback The callback that was passed to {@link
+ * #startSatelliteTransmissionUpdates(Executor, Consumer, SatelliteTransmissionUpdateCallback)}.
+ * @param executor The executor on which the error code listener will be called.
+ * @param resultListener Listener for the {@link SatelliteError} result of the operation.
+ *
+ * @throws SecurityException if the caller doesn't have required permission.
+ * @throws IllegalStateException if the Telephony process is not currently available.
+ */
+ @RequiresPermission(Manifest.permission.SATELLITE_COMMUNICATION)
+
+ public void stopSatelliteTransmissionUpdates(
+ @NonNull SatelliteTransmissionUpdateCallback callback,
+ @NonNull @CallbackExecutor Executor executor,
+ @SatelliteError @NonNull Consumer<Integer> resultListener) {
+ Objects.requireNonNull(callback);
+ Objects.requireNonNull(executor);
+ Objects.requireNonNull(resultListener);
+ ISatelliteTransmissionUpdateCallback internalCallback =
+ sSatelliteTransmissionUpdateCallbackMap.remove(callback);
+
+ try {
+ ITelephony telephony = getITelephony();
+ if (telephony != null) {
+ if (internalCallback != null) {
+ IIntegerConsumer errorCallback = new IIntegerConsumer.Stub() {
+ @Override
+ public void accept(int result) {
+ executor.execute(() -> Binder.withCleanCallingIdentity(
+ () -> resultListener.accept(result)));
+ }
+ };
+ telephony.stopSatelliteTransmissionUpdates(mSubId, errorCallback,
+ internalCallback);
+ // TODO: Notify SmsHandler that pointing UI stopped
+ } else {
+ loge("stopSatelliteTransmissionUpdates: No internal callback.");
+ executor.execute(() -> Binder.withCleanCallingIdentity(
+ () -> resultListener.accept(SATELLITE_INVALID_ARGUMENTS)));
+ }
+ } else {
+ throw new IllegalStateException("telephony service is null.");
+ }
+ } catch (RemoteException ex) {
+ loge("stopSatelliteTransmissionUpdates() RemoteException: " + ex);
+ ex.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * Provision the device with a satellite provider.
+ * This is needed if the provider allows dynamic registration.
+ *
+ * @param token The token to be used as a unique identifier for provisioning with satellite
+ * gateway.
+ * @param provisionData Data from the provisioning app that can be used by provisioning server
+ * @param cancellationSignal The optional signal used by the caller to cancel the provision
+ * request. Even when the cancellation is signaled, Telephony will
+ * still trigger the callback to return the result of this request.
+ * @param executor The executor on which the error code listener will be called.
+ * @param resultListener Listener for the {@link SatelliteError} result of the operation.
+ *
+ * @throws SecurityException if the caller doesn't have required permission.
+ * @throws IllegalStateException if the Telephony process is not currently available.
+ */
+ @RequiresPermission(Manifest.permission.SATELLITE_COMMUNICATION)
+
+ public void provisionSatelliteService(@NonNull String token, @NonNull byte[] provisionData,
+ @Nullable CancellationSignal cancellationSignal,
+ @NonNull @CallbackExecutor Executor executor,
+ @SatelliteError @NonNull Consumer<Integer> resultListener) {
+ Objects.requireNonNull(token);
+ Objects.requireNonNull(executor);
+ Objects.requireNonNull(resultListener);
+ Objects.requireNonNull(provisionData);
+
+ ICancellationSignal cancelRemote = null;
+ try {
+ ITelephony telephony = getITelephony();
+ if (telephony != null) {
+ IIntegerConsumer errorCallback = new IIntegerConsumer.Stub() {
+ @Override
+ public void accept(int result) {
+ executor.execute(() -> Binder.withCleanCallingIdentity(
+ () -> resultListener.accept(result)));
+ }
+ };
+ cancelRemote = telephony.provisionSatelliteService(mSubId, token, provisionData,
+ errorCallback);
+ } else {
+ throw new IllegalStateException("telephony service is null.");
+ }
+ } catch (RemoteException ex) {
+ loge("provisionSatelliteService() RemoteException=" + ex);
+ ex.rethrowFromSystemServer();
+ }
+ if (cancellationSignal != null) {
+ cancellationSignal.setRemote(cancelRemote);
+ }
+ }
+
+ /**
+ * Deprovision the device with the satellite provider.
+ * This is needed if the provider allows dynamic registration. Once deprovisioned,
+ * {@link SatelliteProvisionStateCallback#onSatelliteProvisionStateChanged(boolean)}
+ * should report as deprovisioned.
+ * For provisioning satellite service, refer to
+ * {@link #provisionSatelliteService(String, String, CancellationSignal, Executor, Consumer)}
+ *
+ * @param token The token of the device/subscription to be deprovisioned.
+ * @param resultListener Listener for the {@link SatelliteError} result of the operation.
+ *
+ * @throws SecurityException if the caller doesn't have required permission.
+ * @throws IllegalStateException if the Telephony process is not currently available.
+ */
+ @RequiresPermission(Manifest.permission.SATELLITE_COMMUNICATION)
+
+ public void deprovisionSatelliteService(@NonNull String token,
+ @NonNull @CallbackExecutor Executor executor,
+ @SatelliteError @NonNull Consumer<Integer> resultListener) {
+ Objects.requireNonNull(token);
+ Objects.requireNonNull(executor);
+ Objects.requireNonNull(resultListener);
+
+ try {
+ ITelephony telephony = getITelephony();
+ if (telephony != null) {
+ IIntegerConsumer errorCallback = new IIntegerConsumer.Stub() {
+ @Override
+ public void accept(int result) {
+ executor.execute(() -> Binder.withCleanCallingIdentity(
+ () -> resultListener.accept(result)));
+ }
+ };
+ telephony.deprovisionSatelliteService(mSubId, token, errorCallback);
+ } else {
+ throw new IllegalStateException("telephony service is null.");
+ }
+ } catch (RemoteException ex) {
+ loge("deprovisionSatelliteService() RemoteException=" + ex);
+ ex.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * Registers for the satellite provision state changed.
+ *
+ * @param executor The executor on which the callback will be called.
+ * @param callback The callback to handle the satellite provision state changed event.
+ *
+ * @return The {@link SatelliteError} result of the operation.
+ *
+ * @throws SecurityException if the caller doesn't have required permission.
+ * @throws IllegalStateException if the Telephony process is not currently available.
+ */
+ @RequiresPermission(Manifest.permission.SATELLITE_COMMUNICATION)
+
+ @SatelliteError public int registerForSatelliteProvisionStateChanged(
+ @NonNull @CallbackExecutor Executor executor,
+ @NonNull SatelliteProvisionStateCallback callback) {
+ Objects.requireNonNull(executor);
+ Objects.requireNonNull(callback);
+
+ try {
+ ITelephony telephony = getITelephony();
+ if (telephony != null) {
+ ISatelliteProvisionStateCallback internalCallback =
+ new ISatelliteProvisionStateCallback.Stub() {
+ @Override
+ public void onSatelliteProvisionStateChanged(boolean provisioned) {
+ executor.execute(() -> Binder.withCleanCallingIdentity(
+ () -> callback.onSatelliteProvisionStateChanged(
+ provisioned)));
+ }
+ };
+ sSatelliteProvisionStateCallbackMap.put(callback, internalCallback);
+ return telephony.registerForSatelliteProvisionStateChanged(
+ mSubId, internalCallback);
+ } else {
+ throw new IllegalStateException("telephony service is null.");
+ }
+ } catch (RemoteException ex) {
+ loge("registerForSatelliteProvisionStateChanged() RemoteException: " + ex);
+ ex.rethrowFromSystemServer();
+ }
+ return SATELLITE_REQUEST_FAILED;
+ }
+
+ /**
+ * Unregisters for the satellite provision state changed.
+ * If callback was not registered before, the request will be ignored.
+ *
+ * @param callback The callback that was passed to
+ * {@link #registerForSatelliteProvisionStateChanged(Executor, SatelliteProvisionStateCallback)}
+ *
+ * @throws SecurityException if the caller doesn't have required permission.
+ * @throws IllegalStateException if the Telephony process is not currently available.
+ */
+ @RequiresPermission(Manifest.permission.SATELLITE_COMMUNICATION)
+
+ public void unregisterForSatelliteProvisionStateChanged(
+ @NonNull SatelliteProvisionStateCallback callback) {
+ Objects.requireNonNull(callback);
+ ISatelliteProvisionStateCallback internalCallback =
+ sSatelliteProvisionStateCallbackMap.remove(callback);
+
+ try {
+ ITelephony telephony = getITelephony();
+ if (telephony != null) {
+ if (internalCallback != null) {
+ telephony.unregisterForSatelliteProvisionStateChanged(mSubId, internalCallback);
+ } else {
+ loge("unregisterForSatelliteProvisionStateChanged: No internal callback.");
+ }
+ } else {
+ throw new IllegalStateException("telephony service is null.");
+ }
+ } catch (RemoteException ex) {
+ loge("unregisterForSatelliteProvisionStateChanged() RemoteException: " + ex);
+ ex.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * Request to get whether this device is provisioned with a satellite provider.
+ *
+ * @param executor The executor on which the callback will be called.
+ * @param callback The callback object to which the result will be delivered.
+ * If the request is successful, {@link OutcomeReceiver#onResult(Object)}
+ * will return a {@code boolean} with value {@code true} if the device is
+ * provisioned with a satellite provider and {@code false} otherwise.
+ * If the request is not successful, {@link OutcomeReceiver#onError(Throwable)}
+ * will return a {@link SatelliteException} with the {@link SatelliteError}.
+ *
+ * @throws SecurityException if the caller doesn't have required permission.
+ * @throws IllegalStateException if the Telephony process is not currently available.
+ */
+ @RequiresPermission(Manifest.permission.SATELLITE_COMMUNICATION)
+
+ public void requestIsSatelliteProvisioned(@NonNull @CallbackExecutor Executor executor,
+ @NonNull OutcomeReceiver<Boolean, SatelliteException> callback) {
+ Objects.requireNonNull(executor);
+ Objects.requireNonNull(callback);
+
+ try {
+ ITelephony telephony = getITelephony();
+ if (telephony != null) {
+ ResultReceiver receiver = new ResultReceiver(null) {
+ @Override
+ protected void onReceiveResult(int resultCode, Bundle resultData) {
+ if (resultCode == SATELLITE_ERROR_NONE) {
+ if (resultData.containsKey(KEY_SATELLITE_PROVISIONED)) {
+ boolean isSatelliteProvisioned =
+ resultData.getBoolean(KEY_SATELLITE_PROVISIONED);
+ executor.execute(() -> Binder.withCleanCallingIdentity(() ->
+ callback.onResult(isSatelliteProvisioned)));
+ } else {
+ loge("KEY_SATELLITE_PROVISIONED does not exist.");
+ executor.execute(() -> Binder.withCleanCallingIdentity(() ->
+ callback.onError(
+ new SatelliteException(SATELLITE_REQUEST_FAILED))));
+ }
+ } else {
+ executor.execute(() -> Binder.withCleanCallingIdentity(() ->
+ callback.onError(new SatelliteException(resultCode))));
+ }
+ }
+ };
+ telephony.requestIsSatelliteProvisioned(mSubId, receiver);
+ } else {
+ throw new IllegalStateException("telephony service is null.");
+ }
+ } catch (RemoteException ex) {
+ loge("requestIsSatelliteProvisioned() RemoteException: " + ex);
+ ex.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * Registers for modem state changed from satellite modem.
+ *
+ * @param executor The executor on which the callback will be called.
+ * @param callback The callback to handle the satellite modem state changed event.
+ *
+ * @return The {@link SatelliteError} result of the operation.
+ *
+ * @throws SecurityException if the caller doesn't have required permission.
+ * @throws IllegalStateException if the Telephony process is not currently available.
+ */
+ @RequiresPermission(Manifest.permission.SATELLITE_COMMUNICATION)
+
+ @SatelliteError public int registerForSatelliteModemStateChanged(
+ @NonNull @CallbackExecutor Executor executor,
+ @NonNull SatelliteStateCallback callback) {
+ Objects.requireNonNull(executor);
+ Objects.requireNonNull(callback);
+
+ try {
+ ITelephony telephony = getITelephony();
+ if (telephony != null) {
+ ISatelliteStateCallback internalCallback = new ISatelliteStateCallback.Stub() {
+ @Override
+ public void onSatelliteModemStateChanged(int state) {
+ executor.execute(() -> Binder.withCleanCallingIdentity(() ->
+ callback.onSatelliteModemStateChanged(state)));
+ }
+ };
+ sSatelliteStateCallbackMap.put(callback, internalCallback);
+ return telephony.registerForSatelliteModemStateChanged(mSubId, internalCallback);
+ } else {
+ throw new IllegalStateException("telephony service is null.");
+ }
+ } catch (RemoteException ex) {
+ loge("registerForSatelliteModemStateChanged() RemoteException:" + ex);
+ ex.rethrowFromSystemServer();
+ }
+ return SATELLITE_REQUEST_FAILED;
+ }
+
+ /**
+ * Unregisters for modem state changed from satellite modem.
+ * If callback was not registered before, the request will be ignored.
+ *
+ * @param callback The callback that was passed to
+ * {@link #registerForSatelliteModemStateChanged(Executor, SatelliteStateCallback)}.
+ *
+ * @throws SecurityException if the caller doesn't have required permission.
+ * @throws IllegalStateException if the Telephony process is not currently available.
+ */
+ @RequiresPermission(Manifest.permission.SATELLITE_COMMUNICATION)
+
+ public void unregisterForSatelliteModemStateChanged(@NonNull SatelliteStateCallback callback) {
+ Objects.requireNonNull(callback);
+ ISatelliteStateCallback internalCallback = sSatelliteStateCallbackMap.remove(callback);
+
+ try {
+ ITelephony telephony = getITelephony();
+ if (telephony != null) {
+ if (internalCallback != null) {
+ telephony.unregisterForSatelliteModemStateChanged(mSubId, internalCallback);
+ } else {
+ loge("unregisterForSatelliteModemStateChanged: No internal callback.");
+ }
+ } else {
+ throw new IllegalStateException("telephony service is null.");
+ }
+ } catch (RemoteException ex) {
+ loge("unregisterForSatelliteModemStateChanged() RemoteException:" + ex);
+ ex.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * Register to receive incoming datagrams over satellite.
+ *
+ * @param executor The executor on which the callback will be called.
+ * @param callback The callback to handle incoming datagrams over satellite.
+ * This callback with be invoked when a new datagram is received from satellite.
+ *
+ * @return The {@link SatelliteError} result of the operation.
+ *
+ * @throws SecurityException if the caller doesn't have required permission.
+ * @throws IllegalStateException if the Telephony process is not currently available.
+ */
+ @RequiresPermission(Manifest.permission.SATELLITE_COMMUNICATION)
+
+ @SatelliteError public int registerForSatelliteDatagram(
+ @NonNull @CallbackExecutor Executor executor,
+ @NonNull SatelliteDatagramCallback callback) {
+ Objects.requireNonNull(executor);
+ Objects.requireNonNull(callback);
+
+ try {
+ ITelephony telephony = getITelephony();
+ if (telephony != null) {
+ ISatelliteDatagramCallback internalCallback =
+ new ISatelliteDatagramCallback.Stub() {
+ @Override
+ public void onSatelliteDatagramReceived(long datagramId,
+ @NonNull SatelliteDatagram datagram, int pendingCount,
+ @NonNull IVoidConsumer internalAck) {
+ Consumer<Void> externalAck = new Consumer<Void>() {
+ @Override
+ public void accept(Void result) {
+ try {
+ internalAck.accept();
+ } catch (RemoteException e) {
+ logd("onSatelliteDatagramReceived "
+ + "RemoteException: " + e);
+ }
+ }
+ };
+
+ executor.execute(() -> Binder.withCleanCallingIdentity(
+ () -> callback.onSatelliteDatagramReceived(
+ datagramId, datagram, pendingCount, externalAck)));
+ }
+ };
+ sSatelliteDatagramCallbackMap.put(callback, internalCallback);
+ return telephony.registerForSatelliteDatagram(mSubId, internalCallback);
+ } else {
+ throw new IllegalStateException("telephony service is null.");
+ }
+ } catch (RemoteException ex) {
+ loge("registerForSatelliteDatagram() RemoteException:" + ex);
+ ex.rethrowFromSystemServer();
+ }
+ return SATELLITE_REQUEST_FAILED;
+ }
+
+ /**
+ * Unregister to stop receiving incoming datagrams over satellite.
+ * If callback was not registered before, the request will be ignored.
+ *
+ * @param callback The callback that was passed to
+ * {@link #registerForSatelliteDatagram(Executor, SatelliteDatagramCallback)}.
+ *
+ * @throws SecurityException if the caller doesn't have required permission.
+ * @throws IllegalStateException if the Telephony process is not currently available.
+ */
+ @RequiresPermission(Manifest.permission.SATELLITE_COMMUNICATION)
+
+ public void unregisterForSatelliteDatagram(@NonNull SatelliteDatagramCallback callback) {
+ Objects.requireNonNull(callback);
+ ISatelliteDatagramCallback internalCallback =
+ sSatelliteDatagramCallbackMap.remove(callback);
+
+ try {
+ ITelephony telephony = getITelephony();
+ if (telephony != null) {
+ if (internalCallback != null) {
+ telephony.unregisterForSatelliteDatagram(mSubId, internalCallback);
+ } else {
+ loge("unregisterForSatelliteDatagram: No internal callback.");
+ }
+ } else {
+ throw new IllegalStateException("telephony service is null.");
+ }
+ } catch (RemoteException ex) {
+ loge("unregisterForSatelliteDatagram() RemoteException:" + ex);
+ ex.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * Poll pending satellite datagrams over satellite.
+ *
+ * This method requests modem to check if there are any pending datagrams to be received over
+ * satellite. If there are any incoming datagrams, they will be received via
+ * {@link SatelliteDatagramCallback#onSatelliteDatagramReceived(long, SatelliteDatagram, int,
+ * Consumer)} )}
+ *
+ * @param executor The executor on which the result listener will be called.
+ * @param resultListener Listener for the {@link SatelliteError} result of the operation.
+ *
+ * @throws SecurityException if the caller doesn't have required permission.
+ * @throws IllegalStateException if the Telephony process is not currently available.
+ */
+ @RequiresPermission(Manifest.permission.SATELLITE_COMMUNICATION)
+
+ public void pollPendingSatelliteDatagrams(@NonNull @CallbackExecutor Executor executor,
+ @SatelliteError @NonNull Consumer<Integer> resultListener) {
+ Objects.requireNonNull(executor);
+ Objects.requireNonNull(resultListener);
+
+ try {
+ ITelephony telephony = getITelephony();
+ if (telephony != null) {
+ IIntegerConsumer internalCallback = new IIntegerConsumer.Stub() {
+ @Override
+ public void accept(int result) {
+ executor.execute(() -> Binder.withCleanCallingIdentity(
+ () -> resultListener.accept(result)));
+ }
+ };
+ telephony.pollPendingSatelliteDatagrams(mSubId, internalCallback);
+ } else {
+ throw new IllegalStateException("telephony service is null.");
+ }
+ } catch (RemoteException ex) {
+ loge("pollPendingSatelliteDatagrams() RemoteException:" + ex);
+ ex.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * Send datagram over satellite.
+ *
+ * Gateway encodes SOS message or location sharing message into a datagram and passes it as
+ * input to this method. Datagram received here will be passed down to modem without any
+ * encoding or encryption.
+ *
+ * @param datagramType datagram type indicating whether the datagram is of type
+ * SOS_SMS or LOCATION_SHARING.
+ * @param datagram encoded gateway datagram which is encrypted by the caller.
+ * Datagram will be passed down to modem without any encoding or encryption.
+ * @param needFullScreenPointingUI If set to true, this indicates pointingUI app to open in full
+ * screen mode if satellite communication needs pointingUI.
+ * If this is set to false, pointingUI may be presented to the
+ * user in collapsed view. Application may decide to mark this
+ * flag as true when the user is sending data for the first time
+ * or whenever there is a considerable idle time between
+ * satellite activity. This decision should be done based upon
+ * user activity and the application's ability to determine the
+ * best possible UX experience for the user.
+ * @param executor The executor on which the result listener will be called.
+ * @param resultListener Listener for the {@link SatelliteError} result of the operation.
+ *
+ * @throws SecurityException if the caller doesn't have required permission.
+ * @throws IllegalStateException if the Telephony process is not currently available.
+ */
+ @RequiresPermission(Manifest.permission.SATELLITE_COMMUNICATION)
+
+ public void sendSatelliteDatagram(@DatagramType int datagramType,
+ @NonNull SatelliteDatagram datagram, boolean needFullScreenPointingUI,
+ @NonNull @CallbackExecutor Executor executor,
+ @SatelliteError @NonNull Consumer<Integer> resultListener) {
+ Objects.requireNonNull(datagram);
+ Objects.requireNonNull(executor);
+ Objects.requireNonNull(resultListener);
+
+ try {
+ ITelephony telephony = getITelephony();
+ if (telephony != null) {
+ IIntegerConsumer internalCallback = new IIntegerConsumer.Stub() {
+ @Override
+ public void accept(int result) {
+ executor.execute(() -> Binder.withCleanCallingIdentity(
+ () -> resultListener.accept(result)));
+ }
+ };
+ telephony.sendSatelliteDatagram(mSubId, datagramType, datagram,
+ needFullScreenPointingUI, internalCallback);
+ } else {
+ throw new IllegalStateException("telephony service is null.");
+ }
+ } catch (RemoteException ex) {
+ loge("sendSatelliteDatagram() RemoteException:" + ex);
+ ex.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * Request to get whether satellite communication is allowed for the current location.
+ *
+ * @param executor The executor on which the callback will be called.
+ * @param callback The callback object to which the result will be delivered.
+ * If the request is successful, {@link OutcomeReceiver#onResult(Object)}
+ * will return a {@code boolean} with value {@code true} if satellite
+ * communication is allowed for the current location and
+ * {@code false} otherwise.
+ * If the request is not successful, {@link OutcomeReceiver#onError(Throwable)}
+ * will return a {@link SatelliteException} with the {@link SatelliteError}.
+ *
+ * @throws SecurityException if the caller doesn't have required permission.
+ * @throws IllegalStateException if the Telephony process is not currently available.
+ */
+ @RequiresPermission(Manifest.permission.SATELLITE_COMMUNICATION)
+
+ public void requestIsSatelliteCommunicationAllowedForCurrentLocation(
+ @NonNull @CallbackExecutor Executor executor,
+ @NonNull OutcomeReceiver<Boolean, SatelliteException> callback) {
+ Objects.requireNonNull(executor);
+ Objects.requireNonNull(callback);
+
+ try {
+ ITelephony telephony = getITelephony();
+ if (telephony != null) {
+ ResultReceiver receiver = new ResultReceiver(null) {
+ @Override
+ protected void onReceiveResult(int resultCode, Bundle resultData) {
+ if (resultCode == SATELLITE_ERROR_NONE) {
+ if (resultData.containsKey(KEY_SATELLITE_COMMUNICATION_ALLOWED)) {
+ boolean isSatelliteCommunicationAllowed =
+ resultData.getBoolean(KEY_SATELLITE_COMMUNICATION_ALLOWED);
+ executor.execute(() -> Binder.withCleanCallingIdentity(() ->
+ callback.onResult(isSatelliteCommunicationAllowed)));
+ } else {
+ loge("KEY_SATELLITE_COMMUNICATION_ALLOWED does not exist.");
+ executor.execute(() -> Binder.withCleanCallingIdentity(() ->
+ callback.onError(
+ new SatelliteException(SATELLITE_REQUEST_FAILED))));
+ }
+ } else {
+ executor.execute(() -> Binder.withCleanCallingIdentity(() ->
+ callback.onError(new SatelliteException(resultCode))));
+ }
+ }
+ };
+ telephony.requestIsSatelliteCommunicationAllowedForCurrentLocation(mSubId,
+ receiver);
+ } else {
+ throw new IllegalStateException("telephony service is null.");
+ }
+ } catch (RemoteException ex) {
+ loge("requestIsSatelliteCommunicationAllowedForCurrentLocation() RemoteException: "
+ + ex);
+ ex.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * Request to get the duration in seconds after which the satellite will be visible.
+ * This will be {@link Duration#ZERO} if the satellite is currently visible.
+ *
+ * @param executor The executor on which the callback will be called.
+ * @param callback The callback object to which the result will be delivered.
+ * If the request is successful, {@link OutcomeReceiver#onResult(Object)}
+ * will return the time after which the satellite will be visible.
+ * If the request is not successful, {@link OutcomeReceiver#onError(Throwable)}
+ * will return a {@link SatelliteException} with the {@link SatelliteError}.
+ *
+ * @throws SecurityException if the caller doesn't have required permission.
+ * @throws IllegalStateException if the Telephony process is not currently available.
+ */
+ @RequiresPermission(Manifest.permission.SATELLITE_COMMUNICATION)
+
+ public void requestTimeForNextSatelliteVisibility(@NonNull @CallbackExecutor Executor executor,
+ @NonNull OutcomeReceiver<Duration, SatelliteException> callback) {
+ Objects.requireNonNull(executor);
+ Objects.requireNonNull(callback);
+
+ try {
+ ITelephony telephony = getITelephony();
+ if (telephony != null) {
+ ResultReceiver receiver = new ResultReceiver(null) {
+ @Override
+ protected void onReceiveResult(int resultCode, Bundle resultData) {
+ if (resultCode == SATELLITE_ERROR_NONE) {
+ if (resultData.containsKey(KEY_SATELLITE_NEXT_VISIBILITY)) {
+ int nextVisibilityDuration =
+ resultData.getInt(KEY_SATELLITE_NEXT_VISIBILITY);
+ executor.execute(() -> Binder.withCleanCallingIdentity(() ->
+ callback.onResult(
+ Duration.ofSeconds(nextVisibilityDuration))));
+ } else {
+ loge("KEY_SATELLITE_NEXT_VISIBILITY does not exist.");
+ executor.execute(() -> Binder.withCleanCallingIdentity(() ->
+ callback.onError(
+ new SatelliteException(SATELLITE_REQUEST_FAILED))));
+ }
+ } else {
+ executor.execute(() -> Binder.withCleanCallingIdentity(() ->
+ callback.onError(new SatelliteException(resultCode))));
+ }
+ }
+ };
+ telephony.requestTimeForNextSatelliteVisibility(mSubId, receiver);
+ } else {
+ throw new IllegalStateException("telephony service is null.");
+ }
+ } catch (RemoteException ex) {
+ loge("requestTimeForNextSatelliteVisibility() RemoteException: " + ex);
+ ex.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * Inform whether the device is aligned with the satellite for demo mode.
+ *
+ * @param isAligned {@true} Device is aligned with the satellite for demo mode
+ * {@false} Device is not aligned with the satellite for demo mode
+ *
+ * @throws SecurityException if the caller doesn't have required permission.
+ * @throws IllegalStateException if the Telephony process is not currently available.
+ */
+ @RequiresPermission(Manifest.permission.SATELLITE_COMMUNICATION)
+
+ public void onDeviceAlignedWithSatellite(boolean isAligned) {
+ try {
+ ITelephony telephony = getITelephony();
+ if (telephony != null) {
+ telephony.onDeviceAlignedWithSatellite(mSubId, isAligned);
+ } else {
+ throw new IllegalStateException("telephony service is null.");
+ }
+ } catch (RemoteException ex) {
+ loge("informDeviceAlignedToSatellite() RemoteException:" + ex);
+ ex.rethrowFromSystemServer();
+ }
+ }
+
+ private static ITelephony getITelephony() {
+ ITelephony binder = ITelephony.Stub.asInterface(TelephonyFrameworkInitializer
+ .getTelephonyServiceManager()
+ .getTelephonyServiceRegisterer()
+ .get());
+ if (binder == null) {
+ throw new RuntimeException("Could not find Telephony Service.");
+ }
+ return binder;
+ }
+
+ private static void logd(@NonNull String log) {
+ Rlog.d(TAG, log);
+ }
+
+ private static void loge(@NonNull String log) {
+ Rlog.e(TAG, log);
+ }
+}
diff --git a/telephony/java/android/telephony/satellite/SatelliteProvisionStateCallback.java b/telephony/java/android/telephony/satellite/SatelliteProvisionStateCallback.java
new file mode 100644
index 000000000000..a62eb8b8a5fb
--- /dev/null
+++ b/telephony/java/android/telephony/satellite/SatelliteProvisionStateCallback.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.telephony.satellite;
+
+/**
+ * A callback class for monitoring satellite provision state change events.
+ *
+ * @hide
+ */
+public interface SatelliteProvisionStateCallback {
+ /**
+ * Called when satellite provision state changes.
+ *
+ * @param provisioned The new provision state. {@code true} means satellite is provisioned
+ * {@code false} means satellite is not provisioned.
+ */
+ void onSatelliteProvisionStateChanged(boolean provisioned);
+}
diff --git a/telephony/java/android/telephony/satellite/SatelliteStateCallback.java b/telephony/java/android/telephony/satellite/SatelliteStateCallback.java
new file mode 100644
index 000000000000..d9ecaa3467e3
--- /dev/null
+++ b/telephony/java/android/telephony/satellite/SatelliteStateCallback.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.telephony.satellite;
+
+/**
+ * A callback class for monitoring satellite modem state change events.
+ *
+ * @hide
+ */
+public interface SatelliteStateCallback {
+ /**
+ * Called when satellite modem state changes.
+ * @param state The new satellite modem state.
+ */
+ void onSatelliteModemStateChanged(@SatelliteManager.SatelliteModemState int state);
+}
diff --git a/telephony/java/android/telephony/satellite/SatelliteTransmissionUpdateCallback.java b/telephony/java/android/telephony/satellite/SatelliteTransmissionUpdateCallback.java
new file mode 100644
index 000000000000..d4fe57a0be2e
--- /dev/null
+++ b/telephony/java/android/telephony/satellite/SatelliteTransmissionUpdateCallback.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.telephony.satellite;
+
+import android.annotation.NonNull;
+
+/**
+ * A callback class for monitoring satellite position update and datagram transfer state change
+ * events.
+ *
+ * @hide
+ */
+public interface SatelliteTransmissionUpdateCallback {
+ /**
+ * Called when the satellite position changed.
+ *
+ * @param pointingInfo The pointing info containing the satellite location.
+ */
+ void onSatellitePositionChanged(@NonNull PointingInfo pointingInfo);
+
+ /**
+ * Called when satellite datagram send state changed.
+ *
+ * @param state The new send datagram transfer state.
+ * @param sendPendingCount The number of datagrams that are currently being sent.
+ * @param errorCode If datagram transfer failed, the reason for failure.
+ */
+ void onSendDatagramStateChanged(
+ @SatelliteManager.SatelliteDatagramTransferState int state, int sendPendingCount,
+ @SatelliteManager.SatelliteError int errorCode);
+
+ /**
+ * Called when satellite datagram receive state changed.
+ *
+ * @param state The new receive datagram transfer state.
+ * @param receivePendingCount The number of datagrams that are currently pending to be received.
+ * @param errorCode If datagram transfer failed, the reason for failure.
+ */
+ void onReceiveDatagramStateChanged(
+ @SatelliteManager.SatelliteDatagramTransferState int state, int receivePendingCount,
+ @SatelliteManager.SatelliteError int errorCode);
+}
diff --git a/telephony/java/android/telephony/satellite/stub/ISatellite.aidl b/telephony/java/android/telephony/satellite/stub/ISatellite.aidl
new file mode 100644
index 000000000000..ea4e2e2ef1b9
--- /dev/null
+++ b/telephony/java/android/telephony/satellite/stub/ISatellite.aidl
@@ -0,0 +1,385 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.telephony.satellite.stub;
+
+import android.telephony.satellite.stub.ISatelliteCapabilitiesConsumer;
+import android.telephony.satellite.stub.ISatelliteListener;
+import android.telephony.satellite.stub.SatelliteDatagram;
+
+import com.android.internal.telephony.IBooleanConsumer;
+import com.android.internal.telephony.IIntegerConsumer;
+
+/**
+ * {@hide}
+ */
+oneway interface ISatellite {
+ /**
+ * Register the callback interface with satellite service.
+ *
+ * @param listener The callback interface to handle satellite service indications.
+ *
+ * Valid error codes returned:
+ * SatelliteError:ERROR_NONE
+ * SatelliteError:SERVICE_ERROR
+ * SatelliteError:MODEM_ERROR
+ * SatelliteError:INVALID_MODEM_STATE
+ * SatelliteError:INVALID_ARGUMENTS
+ * SatelliteError:RADIO_NOT_AVAILABLE
+ * SatelliteError:REQUEST_NOT_SUPPORTED
+ * SatelliteError:NO_RESOURCES
+ */
+ void setSatelliteListener(in ISatelliteListener listener);
+
+ /**
+ * Request to enable or disable the satellite service listening mode.
+ * Listening mode allows the satellite service to listen for incoming pages.
+ *
+ * @param enable True to enable satellite listening mode and false to disable.
+ * @param timeout How long the satellite modem should wait for the next incoming page before
+ * disabling listening mode.
+ * @param resultCallback The callback to receive the error code result of the operation.
+ *
+ * Valid error codes returned:
+ * SatelliteError:ERROR_NONE
+ * SatelliteError:SERVICE_ERROR
+ * SatelliteError:MODEM_ERROR
+ * SatelliteError:INVALID_MODEM_STATE
+ * SatelliteError:INVALID_ARGUMENTS
+ * SatelliteError:RADIO_NOT_AVAILABLE
+ * SatelliteError:REQUEST_NOT_SUPPORTED
+ * SatelliteError:NO_RESOURCES
+ */
+ void requestSatelliteListeningEnabled(in boolean enable, in int timeout,
+ in IIntegerConsumer resultCallback);
+
+ /**
+ * Allow cellular modem scanning while satellite mode is on.
+ * @param enabled {@code true} to enable cellular modem while satellite mode is on
+ * and {@code false} to disable
+ * @param errorCallback The callback to receive the error code result of the operation.
+ */
+ void enableCellularModemWhileSatelliteModeIsOn(in boolean enabled,
+ in IIntegerConsumer errorCallback);
+
+ /**
+ * Request to enable or disable the satellite modem and demo mode. If the satellite modem
+ * is enabled, this may also disable the cellular modem, and if the satellite modem is disabled,
+ * this may also re-enable the cellular modem.
+ *
+ * @param enableSatellite True to enable the satellite modem and false to disable.
+ * @param enableDemoMode True to enable demo mode and false to disable.
+ * @param resultCallback The callback to receive the error code result of the operation.
+ *
+ * Valid error codes returned:
+ * SatelliteError:ERROR_NONE
+ * SatelliteError:SERVICE_ERROR
+ * SatelliteError:MODEM_ERROR
+ * SatelliteError:INVALID_MODEM_STATE
+ * SatelliteError:INVALID_ARGUMENTS
+ * SatelliteError:RADIO_NOT_AVAILABLE
+ * SatelliteError:REQUEST_NOT_SUPPORTED
+ * SatelliteError:NO_RESOURCES
+ */
+ void requestSatelliteEnabled(in boolean enableSatellite, in boolean enableDemoMode,
+ in IIntegerConsumer resultCallback);
+
+ /**
+ * Request to get whether the satellite modem is enabled.
+ *
+ * @param resultCallback The callback to receive the error code result of the operation.
+ * This must only be sent when the error is not SatelliteError#ERROR_NONE.
+ * @param callback If the result is SatelliteError#ERROR_NONE, the callback to receive
+ * whether the satellite modem is enabled.
+ *
+ * Valid error codes returned:
+ * SatelliteError:ERROR_NONE
+ * SatelliteError:SERVICE_ERROR
+ * SatelliteError:MODEM_ERROR
+ * SatelliteError:INVALID_MODEM_STATE
+ * SatelliteError:INVALID_ARGUMENTS
+ * SatelliteError:RADIO_NOT_AVAILABLE
+ * SatelliteError:REQUEST_NOT_SUPPORTED
+ * SatelliteError:NO_RESOURCES
+ */
+ void requestIsSatelliteEnabled(in IIntegerConsumer resultCallback, in IBooleanConsumer callback);
+
+ /**
+ * Request to get whether the satellite service is supported on the device.
+ *
+ * @param resultCallback The callback to receive the error code result of the operation.
+ * This must only be sent when the error is not SatelliteError#ERROR_NONE.
+ * @param callback If the result is SatelliteError#ERROR_NONE, the callback to receive
+ * whether the satellite service is supported on the device.
+ *
+ * Valid error codes returned:
+ * SatelliteError:ERROR_NONE
+ * SatelliteError:SERVICE_ERROR
+ * SatelliteError:MODEM_ERROR
+ * SatelliteError:INVALID_MODEM_STATE
+ * SatelliteError:INVALID_ARGUMENTS
+ * SatelliteError:RADIO_NOT_AVAILABLE
+ * SatelliteError:REQUEST_NOT_SUPPORTED
+ * SatelliteError:NO_RESOURCES
+ */
+ void requestIsSatelliteSupported(in IIntegerConsumer resultCallback,
+ in IBooleanConsumer callback);
+
+ /**
+ * Request to get the SatelliteCapabilities of the satellite service.
+ *
+ * @param resultCallback The callback to receive the error code result of the operation.
+ * This must only be sent when the error is not SatelliteError#ERROR_NONE.
+ * @param callback If the result is SatelliteError#ERROR_NONE, the callback to receive
+ * the SatelliteCapabilities of the satellite service.
+ *
+ * Valid error codes returned:
+ * SatelliteError:ERROR_NONE
+ * SatelliteError:SERVICE_ERROR
+ * SatelliteError:MODEM_ERROR
+ * SatelliteError:INVALID_MODEM_STATE
+ * SatelliteError:INVALID_ARGUMENTS
+ * SatelliteError:RADIO_NOT_AVAILABLE
+ * SatelliteError:REQUEST_NOT_SUPPORTED
+ * SatelliteError:NO_RESOURCES
+ */
+ void requestSatelliteCapabilities(in IIntegerConsumer resultCallback,
+ in ISatelliteCapabilitiesConsumer callback);
+
+ /**
+ * User started pointing to the satellite.
+ * The satellite service should report the satellite pointing info via
+ * ISatelliteListener#onSatellitePositionChanged as the user device/satellite moves.
+ *
+ * @param resultCallback The callback to receive the error code result of the operation.
+ *
+ * Valid error codes returned:
+ * SatelliteError:ERROR_NONE
+ * SatelliteError:SERVICE_ERROR
+ * SatelliteError:MODEM_ERROR
+ * SatelliteError:INVALID_MODEM_STATE
+ * SatelliteError:INVALID_ARGUMENTS
+ * SatelliteError:RADIO_NOT_AVAILABLE
+ * SatelliteError:REQUEST_NOT_SUPPORTED
+ * SatelliteError:NO_RESOURCES
+ */
+ void startSendingSatellitePointingInfo(in IIntegerConsumer resultCallback);
+
+ /**
+ * User stopped pointing to the satellite.
+ * The satellite service should stop reporting satellite pointing info to the framework.
+ *
+ * @param resultCallback The callback to receive the error code result of the operation.
+ *
+ * Valid error codes returned:
+ * SatelliteError:ERROR_NONE
+ * SatelliteError:SERVICE_ERROR
+ * SatelliteError:MODEM_ERROR
+ * SatelliteError:INVALID_MODEM_STATE
+ * SatelliteError:INVALID_ARGUMENTS
+ * SatelliteError:RADIO_NOT_AVAILABLE
+ * SatelliteError:REQUEST_NOT_SUPPORTED
+ * SatelliteError:NO_RESOURCES
+ */
+ void stopSendingSatellitePointingInfo(in IIntegerConsumer resultCallback);
+
+ /**
+ * Provision the device with a satellite provider.
+ * This is needed if the provider allows dynamic registration.
+ * Once provisioned, ISatelliteListener#onSatelliteProvisionStateChanged should report true.
+ *
+ * @param token The token to be used as a unique identifier for provisioning with satellite
+ * gateway.
+ * @param provisionData Data from the provisioning app that can be used by provisioning server
+ * @param resultCallback The callback to receive the error code result of the operation.
+ *
+ * Valid error codes returned:
+ * SatelliteError:ERROR_NONE
+ * SatelliteError:SERVICE_ERROR
+ * SatelliteError:MODEM_ERROR
+ * SatelliteError:NETWORK_ERROR
+ * SatelliteError:INVALID_MODEM_STATE
+ * SatelliteError:INVALID_ARGUMENTS
+ * SatelliteError:RADIO_NOT_AVAILABLE
+ * SatelliteError:REQUEST_NOT_SUPPORTED
+ * SatelliteError:NO_RESOURCES
+ * SatelliteError:REQUEST_ABORTED
+ * SatelliteError:NETWORK_TIMEOUT
+ */
+ void provisionSatelliteService(in String token, in byte[] provisionData,
+ in IIntegerConsumer resultCallback);
+
+ /**
+ * Deprovision the device with the satellite provider.
+ * This is needed if the provider allows dynamic registration.
+ * Once deprovisioned, ISatelliteListener#onSatelliteProvisionStateChanged should report false.
+ *
+ * @param token The token of the device/subscription to be deprovisioned.
+ * @param resultCallback The callback to receive the error code result of the operation.
+ *
+ * Valid error codes returned:
+ * SatelliteError:ERROR_NONE
+ * SatelliteError:SERVICE_ERROR
+ * SatelliteError:MODEM_ERROR
+ * SatelliteError:NETWORK_ERROR
+ * SatelliteError:INVALID_MODEM_STATE
+ * SatelliteError:INVALID_ARGUMENTS
+ * SatelliteError:RADIO_NOT_AVAILABLE
+ * SatelliteError:REQUEST_NOT_SUPPORTED
+ * SatelliteError:NO_RESOURCES
+ * SatelliteError:REQUEST_ABORTED
+ * SatelliteError:NETWORK_TIMEOUT
+ */
+ void deprovisionSatelliteService(in String token, in IIntegerConsumer resultCallback);
+
+ /**
+ * Request to get whether this device is provisioned with a satellite provider.
+ *
+ * @param resultCallback The callback to receive the error code result of the operation.
+ * This must only be sent when the error is not SatelliteError#ERROR_NONE.
+ * @param callback If the result is SatelliteError#ERROR_NONE, the callback to receive
+ * whether this device is provisioned with a satellite provider.
+ *
+ * Valid error codes returned:
+ * SatelliteError:ERROR_NONE
+ * SatelliteError:SERVICE_ERROR
+ * SatelliteError:MODEM_ERROR
+ * SatelliteError:INVALID_MODEM_STATE
+ * SatelliteError:INVALID_ARGUMENTS
+ * SatelliteError:RADIO_NOT_AVAILABLE
+ * SatelliteError:REQUEST_NOT_SUPPORTED
+ * SatelliteError:NO_RESOURCES
+ */
+ void requestIsSatelliteProvisioned(in IIntegerConsumer resultCallback,
+ in IBooleanConsumer callback);
+
+ /**
+ * Poll the pending datagrams to be received over satellite.
+ * The satellite service should check if there are any pending datagrams to be received over
+ * satellite and report them via ISatelliteListener#onSatelliteDatagramsReceived.
+ *
+ * @param resultCallback The callback to receive the error code result of the operation.
+ *
+ * Valid error codes returned:
+ * SatelliteError:ERROR_NONE
+ * SatelliteError:SERVICE_ERROR
+ * SatelliteError:MODEM_ERROR
+ * SatelliteError:NETWORK_ERROR
+ * SatelliteError:INVALID_MODEM_STATE
+ * SatelliteError:INVALID_ARGUMENTS
+ * SatelliteError:RADIO_NOT_AVAILABLE
+ * SatelliteError:REQUEST_NOT_SUPPORTED
+ * SatelliteError:NO_RESOURCES
+ * SatelliteError:SATELLITE_ACCESS_BARRED
+ * SatelliteError:NETWORK_TIMEOUT
+ * SatelliteError:SATELLITE_NOT_REACHABLE
+ * SatelliteError:NOT_AUTHORIZED
+ */
+ void pollPendingSatelliteDatagrams(in IIntegerConsumer resultCallback);
+
+ /**
+ * Send datagram over satellite.
+ *
+ * @param datagram Datagram to send in byte format.
+ * @param isEmergency Whether this is an emergency datagram.
+ * @param resultCallback The callback to receive the error code result of the operation.
+ *
+ * Valid error codes returned:
+ * SatelliteError:ERROR_NONE
+ * SatelliteError:SERVICE_ERROR
+ * SatelliteError:MODEM_ERROR
+ * SatelliteError:NETWORK_ERROR
+ * SatelliteError:INVALID_MODEM_STATE
+ * SatelliteError:INVALID_ARGUMENTS
+ * SatelliteError:RADIO_NOT_AVAILABLE
+ * SatelliteError:REQUEST_NOT_SUPPORTED
+ * SatelliteError:NO_RESOURCES
+ * SatelliteError:REQUEST_ABORTED
+ * SatelliteError:SATELLITE_ACCESS_BARRED
+ * SatelliteError:NETWORK_TIMEOUT
+ * SatelliteError:SATELLITE_NOT_REACHABLE
+ * SatelliteError:NOT_AUTHORIZED
+ */
+ void sendSatelliteDatagram(in SatelliteDatagram datagram, in boolean isEmergency,
+ in IIntegerConsumer resultCallback);
+
+ /**
+ * Request the current satellite modem state.
+ * The satellite service should report the current satellite modem state via
+ * ISatelliteListener#onSatelliteModemStateChanged.
+ *
+ * @param resultCallback The callback to receive the error code result of the operation.
+ * This must only be sent when the error is not SatelliteError#ERROR_NONE.
+ * @param callback If the result is SatelliteError#ERROR_NONE, the callback to receive
+ * the current satellite modem state.
+ *
+ * Valid error codes returned:
+ * SatelliteError:ERROR_NONE
+ * SatelliteError:SERVICE_ERROR
+ * SatelliteError:MODEM_ERROR
+ * SatelliteError:INVALID_MODEM_STATE
+ * SatelliteError:INVALID_ARGUMENTS
+ * SatelliteError:RADIO_NOT_AVAILABLE
+ * SatelliteError:REQUEST_NOT_SUPPORTED
+ * SatelliteError:NO_RESOURCES
+ */
+ void requestSatelliteModemState(in IIntegerConsumer resultCallback,
+ in IIntegerConsumer callback);
+
+ /**
+ * Request to get whether satellite communication is allowed for the current location.
+ *
+ * @param resultCallback The callback to receive the error code result of the operation.
+ * This must only be sent when the error is not SatelliteError#ERROR_NONE.
+ * @param callback If the result is SatelliteError#ERROR_NONE, the callback to receive
+ * whether satellite communication is allowed for the current location.
+ *
+ * Valid error codes returned:
+ * SatelliteError:ERROR_NONE
+ * SatelliteError:SERVICE_ERROR
+ * SatelliteError:MODEM_ERROR
+ * SatelliteError:INVALID_MODEM_STATE
+ * SatelliteError:INVALID_ARGUMENTS
+ * SatelliteError:RADIO_NOT_AVAILABLE
+ * SatelliteError:REQUEST_NOT_SUPPORTED
+ * SatelliteError:NO_RESOURCES
+ */
+ void requestIsSatelliteCommunicationAllowedForCurrentLocation(
+ in IIntegerConsumer resultCallback, in IBooleanConsumer callback);
+
+ /**
+ * Request to get the time after which the satellite will be visible. This is an int
+ * representing the duration in seconds after which the satellite will be visible.
+ * This will return 0 if the satellite is currently visible.
+ *
+ * @param resultCallback The callback to receive the error code result of the operation.
+ * This must only be sent when the error is not SatelliteError#ERROR_NONE.
+ * @param callback If the result is SatelliteError#ERROR_NONE, the callback to receive
+ * the time after which the satellite will be visible.
+ *
+ * Valid error codes returned:
+ * SatelliteError:ERROR_NONE
+ * SatelliteError:SERVICE_ERROR
+ * SatelliteError:MODEM_ERROR
+ * SatelliteError:INVALID_MODEM_STATE
+ * SatelliteError:INVALID_ARGUMENTS
+ * SatelliteError:RADIO_NOT_AVAILABLE
+ * SatelliteError:REQUEST_NOT_SUPPORTED
+ * SatelliteError:NO_RESOURCES
+ */
+ void requestTimeForNextSatelliteVisibility(in IIntegerConsumer resultCallback,
+ in IIntegerConsumer callback);
+}
diff --git a/telephony/java/android/telephony/satellite/stub/ISatelliteCapabilitiesConsumer.aidl b/telephony/java/android/telephony/satellite/stub/ISatelliteCapabilitiesConsumer.aidl
new file mode 100644
index 000000000000..e87c6da80518
--- /dev/null
+++ b/telephony/java/android/telephony/satellite/stub/ISatelliteCapabilitiesConsumer.aidl
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.telephony.satellite.stub;
+
+import android.telephony.satellite.stub.SatelliteCapabilities;
+
+/**
+ * Consumer pattern for a request that receives a SatelliteCapabilities from the SatelliteService.
+ * @hide
+ */
+oneway interface ISatelliteCapabilitiesConsumer {
+ void accept(in SatelliteCapabilities result);
+}
diff --git a/telephony/java/android/telephony/satellite/stub/ISatelliteGateway.aidl b/telephony/java/android/telephony/satellite/stub/ISatelliteGateway.aidl
new file mode 100644
index 000000000000..4f1a13623c3b
--- /dev/null
+++ b/telephony/java/android/telephony/satellite/stub/ISatelliteGateway.aidl
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.telephony.satellite.stub;
+
+/**
+ * {@hide}
+ */
+oneway interface ISatelliteGateway {
+ // An empty service because Telephony does not need to use any APIs from this service.
+ // Once satellite modem is enabled, Telephony will bind to the ISatelliteGateway service; and
+ // when satellite modem is disabled, Telephony will unbind to the service.
+}
diff --git a/telephony/java/android/telephony/satellite/stub/ISatelliteListener.aidl b/telephony/java/android/telephony/satellite/stub/ISatelliteListener.aidl
new file mode 100644
index 000000000000..5e692151c604
--- /dev/null
+++ b/telephony/java/android/telephony/satellite/stub/ISatelliteListener.aidl
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.telephony.satellite.stub;
+
+import android.telephony.satellite.stub.NTRadioTechnology;
+import android.telephony.satellite.stub.PointingInfo;
+import android.telephony.satellite.stub.SatelliteDatagram;
+import android.telephony.satellite.stub.SatelliteError;
+import android.telephony.satellite.stub.SatelliteModemState;
+
+/**
+ * {@hide}
+ */
+oneway interface ISatelliteListener {
+ /**
+ * Indicates that the satellite provision state has changed.
+ *
+ * @param provisioned True means the service is provisioned and false means it is not.
+ */
+ void onSatelliteProvisionStateChanged(in boolean provisioned);
+
+ /**
+ * Indicates that new datagrams have been received on the device.
+ *
+ * @param datagram New datagram that was received.
+ * @param pendingCount Number of additional datagrams yet to be received.
+ */
+ void onSatelliteDatagramReceived(in SatelliteDatagram datagram, in int pendingCount);
+
+ /**
+ * Indicates that the satellite has pending datagrams for the device to be pulled.
+ */
+ void onPendingDatagrams();
+
+ /**
+ * Indicates that the satellite pointing input has changed.
+ *
+ * @param pointingInfo The current pointing info.
+ */
+ void onSatellitePositionChanged(in PointingInfo pointingInfo);
+
+ /**
+ * Indicates that the satellite modem state has changed.
+ *
+ * @param state The current satellite modem state.
+ */
+ void onSatelliteModemStateChanged(in SatelliteModemState state);
+}
diff --git a/telephony/java/android/telephony/satellite/stub/NTRadioTechnology.aidl b/telephony/java/android/telephony/satellite/stub/NTRadioTechnology.aidl
new file mode 100644
index 000000000000..33164084ea40
--- /dev/null
+++ b/telephony/java/android/telephony/satellite/stub/NTRadioTechnology.aidl
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.telephony.satellite.stub;
+
+/**
+ * {@hide}
+ */
+@Backing(type="int")
+enum NTRadioTechnology {
+ /**
+ * 3GPP NB-IoT (Narrowband Internet of Things) over Non-Terrestrial-Networks technology.
+ */
+ NB_IOT_NTN = 0,
+ /*
+ * 3GPP 5G NR over Non-Terrestrial-Networks technology.
+ */
+ NR_NTN = 1,
+ /**
+ * 3GPP eMTC (enhanced Machine-Type Communication) over Non-Terrestrial-Networks technology.
+ */
+ EMTC_NTN = 2,
+ /**
+ * Proprietary technology.
+ */
+ PROPRIETARY = 3,
+ /**
+ * Unknown Non-Terrestrial radio technology. This generic radio technology should be used
+ * only when the radio technology cannot be mapped to other specific radio technologies.
+ */
+ UNKNOWN = -1,
+}
diff --git a/telephony/java/android/telephony/satellite/stub/PointingInfo.aidl b/telephony/java/android/telephony/satellite/stub/PointingInfo.aidl
new file mode 100644
index 000000000000..52a36d8b29a3
--- /dev/null
+++ b/telephony/java/android/telephony/satellite/stub/PointingInfo.aidl
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.telephony.satellite.stub;
+
+/**
+ * @hide
+ */
+parcelable PointingInfo {
+ /**
+ * Satellite azimuth in degrees.
+ */
+ float satelliteAzimuth;
+
+ /**
+ * Satellite elevation in degrees.
+ */
+ float satelliteElevation;
+}
diff --git a/telephony/java/android/telephony/satellite/stub/SatelliteCapabilities.aidl b/telephony/java/android/telephony/satellite/stub/SatelliteCapabilities.aidl
new file mode 100644
index 000000000000..eaf96abeb80a
--- /dev/null
+++ b/telephony/java/android/telephony/satellite/stub/SatelliteCapabilities.aidl
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.telephony.satellite.stub;
+
+import android.telephony.satellite.stub.NTRadioTechnology;
+import android.telephony.satellite.AntennaPosition;
+/**
+ * {@hide}
+ */
+parcelable SatelliteCapabilities {
+ /**
+ * List of technologies supported by the satellite modem.
+ */
+ NTRadioTechnology[] supportedRadioTechnologies;
+
+ /**
+ * Whether UE needs to point to a satellite to send and receive data.
+ */
+ boolean isPointingRequired;
+
+ /**
+ * The maximum number of bytes per datagram that can be sent over satellite.
+ */
+ int maxBytesPerOutgoingDatagram;
+
+ /**
+ * Keys which are used to fill mAntennaPositionMap.
+ */
+ int[] antennaPositionKeys;
+
+ /**
+ * Antenna Position for different display modes received from satellite modem.
+ */
+ AntennaPosition[] antennaPositionValues;
+}
diff --git a/telephony/java/android/telephony/satellite/stub/SatelliteDatagram.aidl b/telephony/java/android/telephony/satellite/stub/SatelliteDatagram.aidl
new file mode 100644
index 000000000000..f92cf0e1f06a
--- /dev/null
+++ b/telephony/java/android/telephony/satellite/stub/SatelliteDatagram.aidl
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.telephony.satellite.stub;
+
+/**
+ * @hide
+ */
+parcelable SatelliteDatagram {
+ /**
+ * The contents of this datagram as a byte array.
+ */
+ byte[] data;
+}
diff --git a/telephony/java/android/telephony/satellite/stub/SatelliteError.aidl b/telephony/java/android/telephony/satellite/stub/SatelliteError.aidl
new file mode 100644
index 000000000000..6a110a90276f
--- /dev/null
+++ b/telephony/java/android/telephony/satellite/stub/SatelliteError.aidl
@@ -0,0 +1,110 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.telephony.satellite.stub;
+
+/**
+ * {@hide}
+ */
+@Backing(type="int")
+enum SatelliteError {
+ /**
+ * The request was successfully processed.
+ */
+ ERROR_NONE = 0,
+ /**
+ * A generic error which should be used only when other specific errors cannot be used.
+ */
+ SATELLITE_ERROR = 1,
+ /**
+ * Error received from the satellite server.
+ */
+ SERVER_ERROR = 2,
+ /**
+ * Error received from the vendor service. This generic error code should be used
+ * only when the error cannot be mapped to other specific service error codes.
+ */
+ SERVICE_ERROR = 3,
+ /**
+ * Error received from satellite modem. This generic error code should be used only when
+ * the error cannot be mapped to other specific modem error codes.
+ */
+ MODEM_ERROR = 4,
+ /**
+ * Error received from the satellite network. This generic error code should be used only when
+ * the error cannot be mapped to other specific network error codes.
+ */
+ NETWORK_ERROR = 5,
+ /**
+ * Telephony is not in a valid state to receive requests from clients.
+ */
+ INVALID_TELEPHONY_STATE = 6,
+ /**
+ * Satellite modem is not in a valid state to receive requests from clients.
+ */
+ INVALID_MODEM_STATE = 7,
+ /**
+ * Either vendor service, or modem, or Telephony framework has received a request with
+ * invalid arguments from its clients.
+ */
+ INVALID_ARGUMENTS = 8,
+ /**
+ * Telephony framework failed to send a request or receive a response from the vendor service
+ * or satellite modem due to internal error.
+ */
+ REQUEST_FAILED = 9,
+ /**
+ * Radio did not start or is resetting.
+ */
+ RADIO_NOT_AVAILABLE = 10,
+ /**
+ * The request is not supported by either the satellite modem or the network.
+ */
+ REQUEST_NOT_SUPPORTED = 11,
+ /**
+ * Satellite modem or network has no resources available to handle requests from clients.
+ */
+ NO_RESOURCES = 12,
+ /**
+ * Satellite service is not provisioned yet.
+ */
+ SERVICE_NOT_PROVISIONED = 13,
+ /**
+ * Satellite service provision is already in progress.
+ */
+ SERVICE_PROVISION_IN_PROGRESS = 14,
+ /**
+ * The ongoing request was aborted by either the satellite modem or the network.
+ */
+ REQUEST_ABORTED = 15,
+ /**
+ * The device/subscriber is barred from accessing the satellite service.
+ */
+ SATELLITE_ACCESS_BARRED = 16,
+ /**
+ * Satellite modem timeout to receive ACK or response from the satellite network after
+ * sending a request to the network.
+ */
+ NETWORK_TIMEOUT = 17,
+ /**
+ * Satellite network is not reachable from the modem.
+ */
+ SATELLITE_NOT_REACHABLE = 18,
+ /**
+ * The device/subscriber is not authorized to register with the satellite service provider.
+ */
+ NOT_AUTHORIZED = 19
+}
diff --git a/telephony/java/android/telephony/satellite/stub/SatelliteGatewayService.java b/telephony/java/android/telephony/satellite/stub/SatelliteGatewayService.java
new file mode 100644
index 000000000000..f4514a6de413
--- /dev/null
+++ b/telephony/java/android/telephony/satellite/stub/SatelliteGatewayService.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.telephony.satellite.stub;
+
+import android.annotation.SdkConstant;
+import android.app.Service;
+import android.content.Intent;
+import android.os.IBinder;
+
+import com.android.telephony.Rlog;
+
+/**
+ * Main SatelliteGatewayService implementation, which binds via the Telephony SatelliteController.
+ * Services that extend SatelliteGatewayService must register the service in their AndroidManifest
+ * to be detected by the framework. The application must declare that they require the
+ * "android.permission.BIND_SATELLITE_GATEWAY_SERVICE" permission to ensure that nothing else can
+ * bind to their service except the Telephony framework. The SatelliteGatewayService definition in
+ * the manifest must follow the following format:
+ *
+ * ...
+ * <service android:name=".EgSatelliteGatewayService"
+ * android:permission="android.permission.BIND_SATELLITE_GATEWAY_SERVICE" >
+ * ...
+ * <intent-filter>
+ * <action android:name="android.telephony.satellite.SatelliteGatewayService" />
+ * </intent-filter>
+ * </service>
+ * ...
+ *
+ * The telephony framework will then bind to the SatelliteGatewayService defined in the manifest if
+ * it is the default SatelliteGatewayService defined in the device overlay
+ * "config_satellite_gateway_service_package".
+ * @hide
+ */
+public abstract class SatelliteGatewayService extends Service {
+ private static final String TAG = "SatelliteGatewayService";
+
+ @SdkConstant(SdkConstant.SdkConstantType.SERVICE_ACTION)
+ public static final String SERVICE_INTERFACE =
+ "android.telephony.satellite.SatelliteGatewayService";
+
+ private final IBinder mBinder = new ISatelliteGateway.Stub() {};
+
+ /**
+ * @hide
+ */
+ @Override
+ public final IBinder onBind(Intent intent) {
+ if (SERVICE_INTERFACE.equals(intent.getAction())) {
+ Rlog.d(TAG, "SatelliteGatewayService bound");
+ return mBinder;
+ }
+ return null;
+ }
+
+ /**
+ * @return The binder for the ISatelliteGateway.
+ * @hide
+ */
+ public final IBinder getBinder() {
+ return mBinder;
+ }
+}
diff --git a/telephony/java/android/telephony/satellite/stub/SatelliteImplBase.java b/telephony/java/android/telephony/satellite/stub/SatelliteImplBase.java
new file mode 100644
index 000000000000..d606f874e422
--- /dev/null
+++ b/telephony/java/android/telephony/satellite/stub/SatelliteImplBase.java
@@ -0,0 +1,621 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.telephony.satellite.stub;
+
+import android.annotation.NonNull;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.util.Log;
+
+import com.android.internal.telephony.IBooleanConsumer;
+import com.android.internal.telephony.IIntegerConsumer;
+import com.android.internal.telephony.util.TelephonyUtils;
+
+import java.util.concurrent.CancellationException;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.CompletionException;
+import java.util.concurrent.Executor;
+
+/**
+ * Base implementation of satellite service.
+ * Any service wishing to provide satellite services should extend this class and implement all
+ * methods that the service supports.
+ * @hide
+ */
+public class SatelliteImplBase extends SatelliteService {
+ private static final String TAG = "SatelliteImplBase";
+
+ protected final Executor mExecutor;
+
+ /**
+ * Create SatelliteImplBase using the Executor specified for methods being called from the
+ * framework.
+ * @param executor The executor for the framework to use when executing the methods overridden
+ * by the implementation of Satellite.
+ * @hide
+ */
+ public SatelliteImplBase(@NonNull Executor executor) {
+ super();
+ mExecutor = executor;
+ }
+
+ /**
+ * @return The binder for the Satellite implementation.
+ * @hide
+ */
+ public final IBinder getBinder() {
+ return mBinder;
+ }
+
+ private final IBinder mBinder = new ISatellite.Stub() {
+ @Override
+ public void setSatelliteListener(ISatelliteListener listener) throws RemoteException {
+ executeMethodAsync(
+ () -> SatelliteImplBase.this.setSatelliteListener(listener),
+ "setSatelliteListener");
+ }
+
+ @Override
+ public void requestSatelliteListeningEnabled(boolean enable, int timeout,
+ IIntegerConsumer errorCallback) throws RemoteException {
+ executeMethodAsync(
+ () -> SatelliteImplBase.this
+ .requestSatelliteListeningEnabled(enable, timeout, errorCallback),
+ "requestSatelliteListeningEnabled");
+ }
+
+ @Override
+ public void enableCellularModemWhileSatelliteModeIsOn(boolean enabled,
+ IIntegerConsumer errorCallback) throws RemoteException {
+ executeMethodAsync(
+ () -> SatelliteImplBase.this
+ .enableCellularModemWhileSatelliteModeIsOn(enabled, errorCallback),
+ "enableCellularModemWhileSatelliteModeIsOn");
+ }
+
+ @Override
+ public void requestSatelliteEnabled(boolean enableSatellite, boolean enableDemoMode,
+ IIntegerConsumer errorCallback) throws RemoteException {
+ executeMethodAsync(
+ () -> SatelliteImplBase.this
+ .requestSatelliteEnabled(
+ enableSatellite, enableDemoMode, errorCallback),
+ "requestSatelliteEnabled");
+ }
+
+ @Override
+ public void requestIsSatelliteEnabled(IIntegerConsumer errorCallback,
+ IBooleanConsumer callback) throws RemoteException {
+ executeMethodAsync(
+ () -> SatelliteImplBase.this
+ .requestIsSatelliteEnabled(errorCallback, callback),
+ "requestIsSatelliteEnabled");
+ }
+
+ @Override
+ public void requestIsSatelliteSupported(IIntegerConsumer errorCallback,
+ IBooleanConsumer callback) throws RemoteException {
+ executeMethodAsync(
+ () -> SatelliteImplBase.this
+ .requestIsSatelliteSupported(errorCallback, callback),
+ "requestIsSatelliteSupported");
+ }
+
+ @Override
+ public void requestSatelliteCapabilities(IIntegerConsumer errorCallback,
+ ISatelliteCapabilitiesConsumer callback) throws RemoteException {
+ executeMethodAsync(
+ () -> SatelliteImplBase.this
+ .requestSatelliteCapabilities(errorCallback, callback),
+ "requestSatelliteCapabilities");
+ }
+
+ @Override
+ public void startSendingSatellitePointingInfo(IIntegerConsumer errorCallback)
+ throws RemoteException {
+ executeMethodAsync(
+ () -> SatelliteImplBase.this.startSendingSatellitePointingInfo(errorCallback),
+ "startSendingSatellitePointingInfo");
+ }
+
+ @Override
+ public void stopSendingSatellitePointingInfo(IIntegerConsumer errorCallback)
+ throws RemoteException {
+ executeMethodAsync(
+ () -> SatelliteImplBase.this.stopSendingSatellitePointingInfo(errorCallback),
+ "stopSendingSatellitePointingInfo");
+ }
+
+ @Override
+ public void provisionSatelliteService(String token, byte[] provisionData,
+ IIntegerConsumer errorCallback) throws RemoteException {
+ executeMethodAsync(
+ () -> SatelliteImplBase.this
+ .provisionSatelliteService(token, provisionData, errorCallback),
+ "provisionSatelliteService");
+ }
+
+ @Override
+ public void deprovisionSatelliteService(String token, IIntegerConsumer errorCallback)
+ throws RemoteException {
+ executeMethodAsync(
+ () -> SatelliteImplBase.this.deprovisionSatelliteService(token, errorCallback),
+ "deprovisionSatelliteService");
+ }
+
+ @Override
+ public void requestIsSatelliteProvisioned(IIntegerConsumer errorCallback,
+ IBooleanConsumer callback) throws RemoteException {
+ executeMethodAsync(
+ () -> SatelliteImplBase.this
+ .requestIsSatelliteProvisioned(errorCallback, callback),
+ "requestIsSatelliteProvisioned");
+ }
+
+ @Override
+ public void pollPendingSatelliteDatagrams(IIntegerConsumer errorCallback)
+ throws RemoteException {
+ executeMethodAsync(
+ () -> SatelliteImplBase.this.pollPendingSatelliteDatagrams(errorCallback),
+ "pollPendingSatelliteDatagrams");
+ }
+
+ @Override
+ public void sendSatelliteDatagram(SatelliteDatagram datagram, boolean isEmergency,
+ IIntegerConsumer errorCallback) throws RemoteException {
+ executeMethodAsync(
+ () -> SatelliteImplBase.this
+ .sendSatelliteDatagram(datagram, isEmergency, errorCallback),
+ "sendSatelliteDatagram");
+ }
+
+ @Override
+ public void requestSatelliteModemState(IIntegerConsumer errorCallback,
+ IIntegerConsumer callback) throws RemoteException {
+ executeMethodAsync(
+ () -> SatelliteImplBase.this
+ .requestSatelliteModemState(errorCallback, callback),
+ "requestSatelliteModemState");
+ }
+
+ @Override
+ public void requestIsSatelliteCommunicationAllowedForCurrentLocation(
+ IIntegerConsumer errorCallback, IBooleanConsumer callback)
+ throws RemoteException {
+ executeMethodAsync(
+ () -> SatelliteImplBase.this
+ .requestIsSatelliteCommunicationAllowedForCurrentLocation(
+ errorCallback, callback),
+ "requestIsSatelliteCommunicationAllowedForCurrentLocation");
+ }
+
+ @Override
+ public void requestTimeForNextSatelliteVisibility(IIntegerConsumer errorCallback,
+ IIntegerConsumer callback) throws RemoteException {
+ executeMethodAsync(
+ () -> SatelliteImplBase.this
+ .requestTimeForNextSatelliteVisibility(errorCallback, callback),
+ "requestTimeForNextSatelliteVisibility");
+ }
+
+ // Call the methods with a clean calling identity on the executor and wait indefinitely for
+ // the future to return.
+ private void executeMethodAsync(Runnable r, String errorLogName) throws RemoteException {
+ try {
+ CompletableFuture.runAsync(
+ () -> TelephonyUtils.runWithCleanCallingIdentity(r), mExecutor).join();
+ } catch (CancellationException | CompletionException e) {
+ Log.w(TAG, "SatelliteImplBase Binder - " + errorLogName + " exception: "
+ + e.getMessage());
+ throw new RemoteException(e.getMessage());
+ }
+ }
+ };
+
+ /**
+ * Register the callback interface with satellite service.
+ *
+ * @param listener The callback interface to handle satellite service indications.
+ *
+ * Valid error codes returned:
+ * SatelliteError:ERROR_NONE
+ * SatelliteError:SERVICE_ERROR
+ * SatelliteError:MODEM_ERROR
+ * SatelliteError:INVALID_MODEM_STATE
+ * SatelliteError:INVALID_ARGUMENTS
+ * SatelliteError:RADIO_NOT_AVAILABLE
+ * SatelliteError:REQUEST_NOT_SUPPORTED
+ * SatelliteError:NO_RESOURCES
+ */
+ public void setSatelliteListener(@NonNull ISatelliteListener listener) {
+ // stub implementation
+ }
+
+ /**
+ * Request to enable or disable the satellite service listening mode.
+ * Listening mode allows the satellite service to listen for incoming pages.
+ *
+ * @param enable True to enable satellite listening mode and false to disable.
+ * @param timeout How long the satellite modem should wait for the next incoming page before
+ * disabling listening mode.
+ * @param errorCallback The callback to receive the error code result of the operation.
+ *
+ * Valid error codes returned:
+ * SatelliteError:ERROR_NONE
+ * SatelliteError:SERVICE_ERROR
+ * SatelliteError:MODEM_ERROR
+ * SatelliteError:INVALID_MODEM_STATE
+ * SatelliteError:INVALID_ARGUMENTS
+ * SatelliteError:RADIO_NOT_AVAILABLE
+ * SatelliteError:REQUEST_NOT_SUPPORTED
+ * SatelliteError:NO_RESOURCES
+ */
+ public void requestSatelliteListeningEnabled(boolean enable, int timeout,
+ @NonNull IIntegerConsumer errorCallback) {
+ // stub implementation
+ }
+
+ /**
+ * Allow cellular modem scanning while satellite mode is on.
+ * @param enabled {@code true} to enable cellular modem while satellite mode is on
+ * and {@code false} to disable
+ * @param errorCallback The callback to receive the error code result of the operation.
+ */
+ public void enableCellularModemWhileSatelliteModeIsOn(boolean enabled,
+ @NonNull IIntegerConsumer errorCallback) {
+ // stub implementation
+ }
+
+ /**
+ * Request to enable or disable the satellite modem and demo mode. If the satellite modem is
+ * enabled, this may also disable the cellular modem, and if the satellite modem is disabled,
+ * this may also re-enable the cellular modem.
+ *
+ * @param enableSatellite True to enable the satellite modem and false to disable.
+ * @param enableDemoMode True to enable demo mode and false to disable.
+ * @param errorCallback The callback to receive the error code result of the operation.
+ *
+ * Valid error codes returned:
+ * SatelliteError:ERROR_NONE
+ * SatelliteError:SERVICE_ERROR
+ * SatelliteError:MODEM_ERROR
+ * SatelliteError:INVALID_MODEM_STATE
+ * SatelliteError:INVALID_ARGUMENTS
+ * SatelliteError:RADIO_NOT_AVAILABLE
+ * SatelliteError:REQUEST_NOT_SUPPORTED
+ * SatelliteError:NO_RESOURCES
+ */
+ public void requestSatelliteEnabled(boolean enableSatellite, boolean enableDemoMode,
+ @NonNull IIntegerConsumer errorCallback) {
+ // stub implementation
+ }
+
+ /**
+ * Request to get whether the satellite modem is enabled.
+ *
+ * @param errorCallback The callback to receive the error code result of the operation.
+ * This must only be sent when the result is not SatelliteError#ERROR_NONE.
+ * @param callback If the result is SatelliteError#ERROR_NONE, the callback to receive
+ * whether the satellite modem is enabled.
+ *
+ * Valid error codes returned:
+ * SatelliteError:ERROR_NONE
+ * SatelliteError:SERVICE_ERROR
+ * SatelliteError:MODEM_ERROR
+ * SatelliteError:INVALID_MODEM_STATE
+ * SatelliteError:INVALID_ARGUMENTS
+ * SatelliteError:RADIO_NOT_AVAILABLE
+ * SatelliteError:REQUEST_NOT_SUPPORTED
+ * SatelliteError:NO_RESOURCES
+ */
+ public void requestIsSatelliteEnabled(@NonNull IIntegerConsumer errorCallback,
+ @NonNull IBooleanConsumer callback) {
+ // stub implementation
+ }
+
+ /**
+ * Request to get whether the satellite service is supported on the device.
+ *
+ * @param errorCallback The callback to receive the error code result of the operation.
+ * This must only be sent when the result is not SatelliteError#ERROR_NONE.
+ * @param callback If the result is SatelliteError#ERROR_NONE, the callback to receive
+ * whether the satellite service is supported on the device.
+ *
+ * Valid error codes returned:
+ * SatelliteError:ERROR_NONE
+ * SatelliteError:SERVICE_ERROR
+ * SatelliteError:MODEM_ERROR
+ * SatelliteError:INVALID_MODEM_STATE
+ * SatelliteError:INVALID_ARGUMENTS
+ * SatelliteError:RADIO_NOT_AVAILABLE
+ * SatelliteError:REQUEST_NOT_SUPPORTED
+ * SatelliteError:NO_RESOURCES
+ */
+ public void requestIsSatelliteSupported(@NonNull IIntegerConsumer errorCallback,
+ @NonNull IBooleanConsumer callback) {
+ // stub implementation
+ }
+
+ /**
+ * Request to get the SatelliteCapabilities of the satellite service.
+ *
+ * @param errorCallback The callback to receive the error code result of the operation.
+ * This must only be sent when the result is not SatelliteError#ERROR_NONE.
+ * @param callback If the result is SatelliteError#ERROR_NONE, the callback to receive
+ * the SatelliteCapabilities of the satellite service.
+ *
+ * Valid error codes returned:
+ * SatelliteError:ERROR_NONE
+ * SatelliteError:SERVICE_ERROR
+ * SatelliteError:MODEM_ERROR
+ * SatelliteError:INVALID_MODEM_STATE
+ * SatelliteError:INVALID_ARGUMENTS
+ * SatelliteError:RADIO_NOT_AVAILABLE
+ * SatelliteError:REQUEST_NOT_SUPPORTED
+ * SatelliteError:NO_RESOURCES
+ */
+ public void requestSatelliteCapabilities(@NonNull IIntegerConsumer errorCallback,
+ @NonNull ISatelliteCapabilitiesConsumer callback) {
+ // stub implementation
+ }
+
+ /**
+ * User started pointing to the satellite.
+ * The satellite service should report the satellite pointing info via
+ * ISatelliteListener#onSatellitePositionChanged as the user device/satellite moves.
+ *
+ * @param errorCallback The callback to receive the error code result of the operation.
+ *
+ * Valid error codes returned:
+ * SatelliteError:ERROR_NONE
+ * SatelliteError:SERVICE_ERROR
+ * SatelliteError:MODEM_ERROR
+ * SatelliteError:INVALID_MODEM_STATE
+ * SatelliteError:INVALID_ARGUMENTS
+ * SatelliteError:RADIO_NOT_AVAILABLE
+ * SatelliteError:REQUEST_NOT_SUPPORTED
+ * SatelliteError:NO_RESOURCES
+ */
+ public void startSendingSatellitePointingInfo(@NonNull IIntegerConsumer errorCallback) {
+ // stub implementation
+ }
+
+ /**
+ * User stopped pointing to the satellite.
+ * The satellite service should stop reporting satellite pointing info to the framework.
+ *
+ * @param errorCallback The callback to receive the error code result of the operation.
+ *
+ * Valid error codes returned:
+ * SatelliteError:ERROR_NONE
+ * SatelliteError:SERVICE_ERROR
+ * SatelliteError:MODEM_ERROR
+ * SatelliteError:INVALID_MODEM_STATE
+ * SatelliteError:INVALID_ARGUMENTS
+ * SatelliteError:RADIO_NOT_AVAILABLE
+ * SatelliteError:REQUEST_NOT_SUPPORTED
+ * SatelliteError:NO_RESOURCES
+ */
+ public void stopSendingSatellitePointingInfo(@NonNull IIntegerConsumer errorCallback) {
+ // stub implementation
+ }
+
+ /**
+ * Provision the device with a satellite provider.
+ * This is needed if the provider allows dynamic registration.
+ * Once provisioned, ISatelliteListener#onSatelliteProvisionStateChanged should report true.
+ *
+ * @param token The token to be used as a unique identifier for provisioning with satellite
+ * gateway.
+ * @param provisionData Data from the provisioning app that can be used by provisioning
+ * server
+ * @param errorCallback The callback to receive the error code result of the operation.
+ *
+ * Valid error codes returned:
+ * SatelliteError:ERROR_NONE
+ * SatelliteError:SERVICE_ERROR
+ * SatelliteError:MODEM_ERROR
+ * SatelliteError:NETWORK_ERROR
+ * SatelliteError:INVALID_MODEM_STATE
+ * SatelliteError:INVALID_ARGUMENTS
+ * SatelliteError:RADIO_NOT_AVAILABLE
+ * SatelliteError:REQUEST_NOT_SUPPORTED
+ * SatelliteError:NO_RESOURCES
+ * SatelliteError:REQUEST_ABORTED
+ * SatelliteError:NETWORK_TIMEOUT
+ */
+ public void provisionSatelliteService(@NonNull String token, @NonNull byte[] provisionData,
+ @NonNull IIntegerConsumer errorCallback) {
+ // stub implementation
+ }
+
+ /**
+ * Deprovision the device with the satellite provider.
+ * This is needed if the provider allows dynamic registration.
+ * Once deprovisioned, ISatelliteListener#onSatelliteProvisionStateChanged should report false.
+ *
+ * @param token The token of the device/subscription to be deprovisioned.
+ * @param errorCallback The callback to receive the error code result of the operation.
+ *
+ * Valid error codes returned:
+ * SatelliteError:ERROR_NONE
+ * SatelliteError:SERVICE_ERROR
+ * SatelliteError:MODEM_ERROR
+ * SatelliteError:NETWORK_ERROR
+ * SatelliteError:INVALID_MODEM_STATE
+ * SatelliteError:INVALID_ARGUMENTS
+ * SatelliteError:RADIO_NOT_AVAILABLE
+ * SatelliteError:REQUEST_NOT_SUPPORTED
+ * SatelliteError:NO_RESOURCES
+ * SatelliteError:REQUEST_ABORTED
+ * SatelliteError:NETWORK_TIMEOUT
+ */
+ public void deprovisionSatelliteService(@NonNull String token,
+ @NonNull IIntegerConsumer errorCallback) {
+ // stub implementation
+ }
+
+ /**
+ * Request to get whether this device is provisioned with a satellite provider.
+ *
+ * @param errorCallback The callback to receive the error code result of the operation.
+ * This must only be sent when the result is not SatelliteError#ERROR_NONE.
+ * @param callback If the result is SatelliteError#ERROR_NONE, the callback to receive
+ * whether this device is provisioned with a satellite provider.
+ *
+ * Valid error codes returned:
+ * SatelliteError:ERROR_NONE
+ * SatelliteError:SERVICE_ERROR
+ * SatelliteError:MODEM_ERROR
+ * SatelliteError:INVALID_MODEM_STATE
+ * SatelliteError:INVALID_ARGUMENTS
+ * SatelliteError:RADIO_NOT_AVAILABLE
+ * SatelliteError:REQUEST_NOT_SUPPORTED
+ * SatelliteError:NO_RESOURCES
+ */
+ public void requestIsSatelliteProvisioned(@NonNull IIntegerConsumer errorCallback,
+ @NonNull IBooleanConsumer callback) {
+ // stub implementation
+ }
+
+ /**
+ * Poll the pending datagrams to be received over satellite.
+ * The satellite service should check if there are any pending datagrams to be received over
+ * satellite and report them via ISatelliteListener#onSatelliteDatagramsReceived.
+ *
+ * @param errorCallback The callback to receive the error code result of the operation.
+ *
+ * Valid error codes returned:
+ * SatelliteError:ERROR_NONE
+ * SatelliteError:SERVICE_ERROR
+ * SatelliteError:MODEM_ERROR
+ * SatelliteError:NETWORK_ERROR
+ * SatelliteError:INVALID_MODEM_STATE
+ * SatelliteError:INVALID_ARGUMENTS
+ * SatelliteError:RADIO_NOT_AVAILABLE
+ * SatelliteError:REQUEST_NOT_SUPPORTED
+ * SatelliteError:NO_RESOURCES
+ * SatelliteError:SATELLITE_ACCESS_BARRED
+ * SatelliteError:NETWORK_TIMEOUT
+ * SatelliteError:SATELLITE_NOT_REACHABLE
+ * SatelliteError:NOT_AUTHORIZED
+ */
+ public void pollPendingSatelliteDatagrams(@NonNull IIntegerConsumer errorCallback) {
+ // stub implementation
+ }
+
+ /**
+ * Send datagram over satellite.
+ *
+ * @param datagram Datagram to send in byte format.
+ * @param isEmergency Whether this is an emergency datagram.
+ * @param errorCallback The callback to receive the error code result of the operation.
+ *
+ * Valid error codes returned:
+ * SatelliteError:ERROR_NONE
+ * SatelliteError:SERVICE_ERROR
+ * SatelliteError:MODEM_ERROR
+ * SatelliteError:NETWORK_ERROR
+ * SatelliteError:INVALID_MODEM_STATE
+ * SatelliteError:INVALID_ARGUMENTS
+ * SatelliteError:RADIO_NOT_AVAILABLE
+ * SatelliteError:REQUEST_NOT_SUPPORTED
+ * SatelliteError:NO_RESOURCES
+ * SatelliteError:REQUEST_ABORTED
+ * SatelliteError:SATELLITE_ACCESS_BARRED
+ * SatelliteError:NETWORK_TIMEOUT
+ * SatelliteError:SATELLITE_NOT_REACHABLE
+ * SatelliteError:NOT_AUTHORIZED
+ */
+ public void sendSatelliteDatagram(@NonNull SatelliteDatagram datagram, boolean isEmergency,
+ @NonNull IIntegerConsumer errorCallback) {
+ // stub implementation
+ }
+
+ /**
+ * Request the current satellite modem state.
+ * The satellite service should report the current satellite modem state via
+ * ISatelliteListener#onSatelliteModemStateChanged.
+ *
+ * @param errorCallback The callback to receive the error code result of the operation.
+ * This must only be sent when the result is not SatelliteError#ERROR_NONE.
+ * @param callback If the result is SatelliteError#ERROR_NONE, the callback to receive
+ * the current satellite modem state.
+ *
+ * Valid error codes returned:
+ * SatelliteError:ERROR_NONE
+ * SatelliteError:SERVICE_ERROR
+ * SatelliteError:MODEM_ERROR
+ * SatelliteError:INVALID_MODEM_STATE
+ * SatelliteError:INVALID_ARGUMENTS
+ * SatelliteError:RADIO_NOT_AVAILABLE
+ * SatelliteError:REQUEST_NOT_SUPPORTED
+ * SatelliteError:NO_RESOURCES
+ */
+ public void requestSatelliteModemState(@NonNull IIntegerConsumer errorCallback,
+ @NonNull IIntegerConsumer callback) {
+ // stub implementation
+ }
+
+ /**
+ * Request to get whether satellite communication is allowed for the current location.
+ *
+ * @param errorCallback The callback to receive the error code result of the operation.
+ * This must only be sent when the result is not SatelliteError#ERROR_NONE.
+ * @param callback If the result is SatelliteError#ERROR_NONE, the callback to receive
+ * whether satellite communication is allowed for the current location.
+ *
+ * Valid error codes returned:
+ * SatelliteError:ERROR_NONE
+ * SatelliteError:SERVICE_ERROR
+ * SatelliteError:MODEM_ERROR
+ * SatelliteError:INVALID_MODEM_STATE
+ * SatelliteError:INVALID_ARGUMENTS
+ * SatelliteError:RADIO_NOT_AVAILABLE
+ * SatelliteError:REQUEST_NOT_SUPPORTED
+ * SatelliteError:NO_RESOURCES
+ */
+ public void requestIsSatelliteCommunicationAllowedForCurrentLocation(
+ @NonNull IIntegerConsumer errorCallback, @NonNull IBooleanConsumer callback) {
+ // stub implementation
+ }
+
+ /**
+ * Request to get the time after which the satellite will be visible. This is an int
+ * representing the duration in seconds after which the satellite will be visible.
+ * This will return 0 if the satellite is currently visible.
+ *
+ * @param errorCallback The callback to receive the error code result of the operation.
+ * This must only be sent when the result is not SatelliteError#ERROR_NONE.
+ * @param callback If the result is SatelliteError#ERROR_NONE, the callback to receive
+ * the time after which the satellite will be visible.
+ *
+ * Valid error codes returned:
+ * SatelliteError:ERROR_NONE
+ * SatelliteError:SERVICE_ERROR
+ * SatelliteError:MODEM_ERROR
+ * SatelliteError:INVALID_MODEM_STATE
+ * SatelliteError:INVALID_ARGUMENTS
+ * SatelliteError:RADIO_NOT_AVAILABLE
+ * SatelliteError:REQUEST_NOT_SUPPORTED
+ * SatelliteError:NO_RESOURCES
+ */
+ public void requestTimeForNextSatelliteVisibility(@NonNull IIntegerConsumer errorCallback,
+ @NonNull IIntegerConsumer callback) {
+ // stub implementation
+ }
+}
diff --git a/telephony/java/android/telephony/satellite/stub/SatelliteModemState.aidl b/telephony/java/android/telephony/satellite/stub/SatelliteModemState.aidl
new file mode 100644
index 000000000000..e4f94134caa1
--- /dev/null
+++ b/telephony/java/android/telephony/satellite/stub/SatelliteModemState.aidl
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.telephony.satellite.stub;
+
+/**
+ * {@hide}
+ */
+@Backing(type="int")
+enum SatelliteModemState {
+ /**
+ * Satellite modem is in idle state.
+ */
+ SATELLITE_MODEM_STATE_IDLE = 0,
+ /**
+ * Satellite modem is listening for incoming datagrams.
+ */
+ SATELLITE_MODEM_STATE_LISTENING = 1,
+ /**
+ * Satellite modem is sending and/or receiving datagrams.
+ */
+ SATELLITE_MODEM_STATE_DATAGRAM_TRANSFERRING = 2,
+ /**
+ * Satellite modem is retrying to send and/or receive datagrams.
+ */
+ SATELLITE_MODEM_STATE_DATAGRAM_RETRYING = 3,
+ /**
+ * Satellite modem is powered off.
+ */
+ SATELLITE_MODEM_STATE_OFF = 4,
+ /**
+ * Satellite modem is unavailable.
+ */
+ SATELLITE_MODEM_STATE_UNAVAILABLE = 5,
+ /**
+ * Satellite modem state is unknown. This generic modem state should be used only when the
+ * modem state cannot be mapped to other specific modem states.
+ */
+ SATELLITE_MODEM_STATE_UNKNOWN = -1,
+}
diff --git a/telephony/java/android/telephony/satellite/stub/SatelliteService.java b/telephony/java/android/telephony/satellite/stub/SatelliteService.java
new file mode 100644
index 000000000000..5b96e34186e9
--- /dev/null
+++ b/telephony/java/android/telephony/satellite/stub/SatelliteService.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.telephony.satellite.stub;
+
+import android.annotation.SdkConstant;
+import android.app.Service;
+import android.content.Intent;
+import android.os.IBinder;
+
+import com.android.telephony.Rlog;
+
+/**
+ * Main SatelliteService implementation, which binds via the Telephony SatelliteServiceController.
+ * Services that extend SatelliteService must register the service in their AndroidManifest to be
+ * detected by the framework. First, the application must declare that they use the
+ * "android.permission.BIND_SATELLITE_SERVICE" permission. Then, the SatelliteService definition in
+ * the manifest must follow the following format:
+ *
+ * ...
+ * <service android:name=".EgSatelliteService"
+ * android:permission="android.permission.BIND_SATELLITE_SERVICE" >
+ * ...
+ * <intent-filter>
+ * <action android:name="android.telephony.satellite.SatelliteService" />
+ * </intent-filter>
+ * </service>
+ * ...
+ *
+ * The telephony framework will then bind to the SatelliteService defined in the manifest if it is
+ * the default SatelliteService defined in the device overlay "config_satellite_service_package".
+ * @hide
+ */
+public class SatelliteService extends Service {
+ private static final String TAG = "SatelliteService";
+
+ @SdkConstant(SdkConstant.SdkConstantType.SERVICE_ACTION)
+ public static final String SERVICE_INTERFACE = "android.telephony.satellite.SatelliteService";
+
+ /**
+ * @hide
+ */
+ @Override
+ public IBinder onBind(Intent intent) {
+ if (SERVICE_INTERFACE.equals(intent.getAction())) {
+ Rlog.d(TAG, "SatelliteService bound");
+ return new SatelliteImplBase(Runnable::run).getBinder();
+ }
+ return null;
+ }
+}
diff --git a/telephony/java/com/android/ims/internal/IImsCallSession.aidl b/telephony/java/com/android/ims/internal/IImsCallSession.aidl
index e3a8aeed7ad5..60a74788b709 100644
--- a/telephony/java/com/android/ims/internal/IImsCallSession.aidl
+++ b/telephony/java/com/android/ims/internal/IImsCallSession.aidl
@@ -91,6 +91,8 @@ interface IImsCallSession {
* override the previous listener.
*
* @param listener to listen to the session events of this object
+ *
+ * @deprecated This is depreacated.
*/
void setListener(in IImsCallSessionListener listener);
@@ -305,4 +307,15 @@ interface IImsCallSession {
* @param extensions the header extensions to be sent
*/
void sendRtpHeaderExtensions(in List<RtpHeaderExtension> extensions);
+
+ /*
+ * Deliver the bitrate for the indicated media type, direction and bitrate to the upper layer.
+ *
+ * @param mediaType MediaType is used to identify media stream such as audio or video.
+ * @param direction Direction of this packet stream (e.g. uplink or downlink).
+ * @param bitsPerSecond This value is the bitrate received from the NW through the Recommended
+ * bitrate MAC Control Element message and ImsStack converts this value from MAC bitrate
+ * to audio/video codec bitrate (defined in TS26.114).
+ */
+ void callSessionNotifyAnbr(int mediaType, int direction, int bitsPerSecond);
}
diff --git a/telephony/java/com/android/ims/internal/IImsCallSessionListener.aidl b/telephony/java/com/android/ims/internal/IImsCallSessionListener.aidl
index 8afd85633322..9395fbd6a85e 100644
--- a/telephony/java/com/android/ims/internal/IImsCallSessionListener.aidl
+++ b/telephony/java/com/android/ims/internal/IImsCallSessionListener.aidl
@@ -194,4 +194,17 @@ oneway interface IImsCallSessionListener {
* @param callQuality then updated call quality
*/
void callQualityChanged(in CallQuality callQuality);
+
+ /**
+ * Access Network Bitrate Recommendation Query (ANBRQ), see 3GPP TS 26.114.
+ * This API triggers radio to send ANBRQ message to the access network to query the desired
+ * bitrate.
+ *
+ * @param mediaType MediaType is used to identify media stream such as audio or video.
+ * @param direction Direction of this packet stream (e.g. uplink or downlink).
+ * @param bitsPerSecond This value is the bitrate requested by the other party UE through
+ * RTP CMR, RTCPAPP or TMMBR, and ImsStack converts this value to the MAC bitrate
+ * (defined in TS36.321, range: 0 ~ 8000 kbit/s).
+ */
+ void callSessionSendAnbrQuery(int mediaType, int direction, int bitsPerSecond);
}
diff --git a/telephony/java/com/android/internal/telephony/IDomainSelectionServiceController.aidl b/telephony/java/com/android/internal/telephony/IDomainSelectionServiceController.aidl
new file mode 100644
index 000000000000..8ad79ed3430e
--- /dev/null
+++ b/telephony/java/com/android/internal/telephony/IDomainSelectionServiceController.aidl
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.telephony;
+
+import android.telephony.BarringInfo;
+import android.telephony.DomainSelectionService.SelectionAttributes;
+import android.telephony.ServiceState;
+
+import com.android.internal.telephony.ITransportSelectorCallback;
+
+oneway interface IDomainSelectionServiceController {
+ void selectDomain(in SelectionAttributes attr, in ITransportSelectorCallback callback);
+ void updateServiceState(int slotId, int subId, in ServiceState serviceState);
+ void updateBarringInfo(int slotId, int subId, in BarringInfo info);
+}
diff --git a/telephony/java/com/android/internal/telephony/IDomainSelector.aidl b/telephony/java/com/android/internal/telephony/IDomainSelector.aidl
new file mode 100644
index 000000000000..d94840b112ee
--- /dev/null
+++ b/telephony/java/com/android/internal/telephony/IDomainSelector.aidl
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.telephony;
+
+import android.telephony.DomainSelectionService.SelectionAttributes;
+
+oneway interface IDomainSelector {
+ void cancelSelection();
+ void reselectDomain(in SelectionAttributes attr);
+ void finishSelection();
+}
diff --git a/telephony/java/com/android/internal/telephony/ILongConsumer.aidl b/telephony/java/com/android/internal/telephony/ILongConsumer.aidl
new file mode 100644
index 000000000000..2f0d4a00e405
--- /dev/null
+++ b/telephony/java/com/android/internal/telephony/ILongConsumer.aidl
@@ -0,0 +1,25 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+ package com.android.internal.telephony;
+
+ /**
+ * Copies consumer pattern for an operation that requires long result from another process to
+ * finish.
+ */
+ oneway interface ILongConsumer {
+ void accept(long result);
+ }
diff --git a/telephony/java/com/android/internal/telephony/IPhoneSubInfo.aidl b/telephony/java/com/android/internal/telephony/IPhoneSubInfo.aidl
index ce2017bb9a35..b4d93fddd7aa 100644
--- a/telephony/java/com/android/internal/telephony/IPhoneSubInfo.aidl
+++ b/telephony/java/com/android/internal/telephony/IPhoneSubInfo.aidl
@@ -17,6 +17,7 @@
package com.android.internal.telephony;
import android.telephony.ImsiEncryptionInfo;
+import android.net.Uri;
/**
* Interface used to retrieve various phone-related subscriber information.
@@ -179,6 +180,19 @@ interface IPhoneSubInfo {
String getIsimImpi(int subId);
/**
+ * Fetches the ISIM PrivateUserIdentity (EF_IMPI) based on subId
+ *
+ * @param subId subscriptionId
+ * @return IMPI (IMS private user identity) of type string or null if EF_IMPI is not available.
+ * @throws IllegalArgumentException if the subscriptionId is not valid
+ * @throws IllegalStateException in case the ISIM hasn’t been loaded.
+ * @throws SecurityException if the caller does not have the required permission
+ */
+ @JavaPassthrough(annotation="@android.annotation.RequiresPermission("
+ + "android.Manifest.permission.USE_ICC_AUTH_WITH_DEVICE_IDENTIFIER)")
+ String getImsPrivateUserIdentity(int subId, String callingPackage, String callingFeatureId);
+
+ /**
* Returns the IMS home network domain name that was loaded from the ISIM.
* @return the IMS domain name, or null if not present or not loaded
*/
@@ -192,6 +206,14 @@ interface IPhoneSubInfo {
String[] getIsimImpu(int subId);
/**
+ * Fetches the ISIM public user identities (EF_IMPU) from UICC based on subId
+ */
+ @JavaPassthrough(annotation="@android.annotation.RequiresPermission(" +
+ "anyOf={android.Manifest.permission.READ_PHONE_NUMBERS, android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE})")
+ List<Uri> getImsPublicUserIdentities(int subId, String callingPackage,
+ String callingFeatureId);
+
+ /**
* Returns the IMS Service Table (IST) that was loaded from the ISIM.
* @return IMS Service Table or null if not present or not loaded
*/
@@ -218,4 +240,39 @@ interface IPhoneSubInfo {
*/
String getIccSimChallengeResponse(int subId, int appType, int authType, String data,
String callingPackage, String callingFeatureId);
+
+ /**
+ * Fetches the EF_PSISMSC value from the UICC that contains the Public Service Identity of
+ * the SM-SC (either a SIP URI or tel URI). The EF_PSISMSC of ISIM and USIM can be found in
+ * DF_TELECOM.
+ * The EF_PSISMSC value is used by the ME to submit SMS over IP as defined in 24.341 [55].
+ *
+ * @return Uri : Public Service Identity of SM-SC
+ * @throws SecurityException if the caller does not have the required permission/privileges
+ * @hide
+ */
+ @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)")
+ Uri getSmscIdentity(int subId, int appType);
+
+ /**
+ * Fetches the sim service table from the EFUST/EFIST based on the application type
+ * {@link #APPTYPE_USIM} or {@link #APPTYPE_ISIM}. The return value is hexaString format
+ * representing X bytes (x >= 1). Each bit of every byte indicates which optional services
+ * are available for the given application type.
+ * The USIM service table EF is described in as per Section 4.2.8 of 3GPP TS 31.102.
+ * The ISIM service table EF is described in as per Section 4.2.7 of 3GPP TS 31.103.
+ * The list of services mapped to the exact nth byte of response as mentioned in Section 4.2
+ * .7 of 3GPP TS 31.103. Eg. Service n°1: Local Phone Book, Service n°2: Fixed Dialling
+ * Numbers (FDN) - Bit 1 and 2 of the 1st Byte represent service Local Phone Book and Fixed
+ * Dialling Numbers (FDN)respectively. The coding format for each service type should be
+ * interpreted as bit = 1: service available;bit = 0:service not available.
+ *
+ * @param appType of type int of either {@link #APPTYPE_USIM} or {@link #APPTYPE_ISIM}.
+ * @return HexString represents sim service table else null.
+ * @throws SecurityException if the caller does not have the required permission/privileges
+ * @throws IllegalStateException in case if phone or UiccApplication is not available.
+ * @hide
+ */
+ @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)")
+ String getSimServiceTable(int subId, int appType);
}
diff --git a/telephony/java/com/android/internal/telephony/ISipDialogStateCallback.aidl b/telephony/java/com/android/internal/telephony/ISipDialogStateCallback.aidl
new file mode 100644
index 000000000000..6847eb4d92a3
--- /dev/null
+++ b/telephony/java/com/android/internal/telephony/ISipDialogStateCallback.aidl
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.telephony;
+
+import android.telephony.ims.SipDialogState;
+
+/**
+ * Provides callback interface for SipDialogState when a state is changed.
+ *
+ */
+oneway interface ISipDialogStateCallback {
+ void onActiveSipDialogsChanged(in List<SipDialogState> dialogs);
+}
diff --git a/telephony/java/com/android/internal/telephony/ISms.aidl b/telephony/java/com/android/internal/telephony/ISms.aidl
index 9ec3c6716a29..0e23f364134c 100644
--- a/telephony/java/com/android/internal/telephony/ISms.aidl
+++ b/telephony/java/com/android/internal/telephony/ISms.aidl
@@ -530,6 +530,25 @@ interface ISms {
int subId, String callingPkg, String prefixes, in PendingIntent intent);
/**
+ * set Memory Status in SmsStorageMonitor
+ *
+ * @param subId the subscription Id.
+ * @param callingPackage the package name of the calling app.
+ * @param isStorageAvailable sets StorageAvailable to false or true
+ * for testing behaviour of SmsStorageMonitor
+ */
+ void setStorageMonitorMemoryStatusOverride(int subId, boolean isStorageAvailable);
+
+ /**
+ * reset Memory Status change made by TestApi setStorageMonitorMemoryStatusOverride
+ * in SmsStorageMonitor
+ *
+ * @param subId the subscription Id.
+ * @param callingPackage the package name of the calling app.
+ */
+ void clearStorageMonitorMemoryStatusOverride(int subId);
+
+ /**
* Check if the destination is a possible premium short code.
*
* @param destAddress the destination address to test for possible short code
diff --git a/telephony/java/com/android/internal/telephony/ISmsImplBase.java b/telephony/java/com/android/internal/telephony/ISmsImplBase.java
index c361d5bec097..686455688203 100644
--- a/telephony/java/com/android/internal/telephony/ISmsImplBase.java
+++ b/telephony/java/com/android/internal/telephony/ISmsImplBase.java
@@ -192,6 +192,16 @@ public class ISmsImplBase extends ISms.Stub {
}
@Override
+ public void setStorageMonitorMemoryStatusOverride(int subId, boolean storageAvailable) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void clearStorageMonitorMemoryStatusOverride(int subId) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
public int checkSmsShortCodeDestination(int subid, String callingPackage,
String callingFeatureId, String destAddress, String countryIso) {
throw new UnsupportedOperationException();
diff --git a/telephony/java/com/android/internal/telephony/ISub.aidl b/telephony/java/com/android/internal/telephony/ISub.aidl
index 6a5380ddb36e..21a6b447d6a4 100644
--- a/telephony/java/com/android/internal/telephony/ISub.aidl
+++ b/telephony/java/com/android/internal/telephony/ISub.aidl
@@ -129,9 +129,9 @@ interface ISub {
* @param uniqueId This is the unique identifier for the subscription within the specific
* subscription type.
* @param subscriptionType the type of subscription to be removed
- * @return 0 if success, < 0 on error.
+ * @return true if success, false on error.
*/
- int removeSubInfo(String uniqueId, int subscriptionType);
+ boolean removeSubInfo(String uniqueId, int subscriptionType);
/**
* Set SIM icon tint color by simInfo index
@@ -260,7 +260,7 @@ interface ISub {
int[] getActiveSubIdList(boolean visibleOnly);
- int setSubscriptionProperty(int subId, String propKey, String propValue);
+ void setSubscriptionProperty(int subId, String propKey, String propValue);
String getSubscriptionProperty(int subId, String propKey, String callingPackage,
String callingFeatureId);
@@ -353,13 +353,6 @@ interface ISub {
*/
List<SubscriptionInfo> getSubscriptionInfoListAssociatedWithUser(in UserHandle userHandle);
- /**
- * @return {@code true} if using SubscriptionManagerService instead of
- * SubscriptionController.
- */
- //TODO: Removed before U AOSP public release.
- boolean isSubscriptionManagerServiceEnabled();
-
/**
* Called during setup wizard restore flow to attempt to restore the backed up sim-specific
* configs to device for all existing SIMs in the subscription database
diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl
index 9d05517050e2..23f4217caf9d 100644
--- a/telephony/java/com/android/internal/telephony/ITelephony.aidl
+++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl
@@ -17,9 +17,11 @@
package com.android.internal.telephony;
import android.app.PendingIntent;
+import android.content.ComponentName;
import android.content.Intent;
import android.content.IntentSender;
import android.os.Bundle;
+import android.os.ICancellationSignal;
import android.os.IBinder;
import android.os.Messenger;
import android.os.ParcelFileDescriptor;
@@ -34,6 +36,7 @@ import android.telephony.CallForwardingInfo;
import android.telephony.CarrierRestrictionRules;
import android.telephony.CellIdentity;
import android.telephony.CellInfo;
+import android.telephony.CellBroadcastIdRange;
import android.telephony.ClientRequestStats;
import android.telephony.ThermalMitigationRequest;
import android.telephony.gba.UaSecurityProtocolIdentifier;
@@ -64,6 +67,12 @@ import android.telephony.ims.aidl.IImsRcsFeature;
import android.telephony.ims.aidl.IImsRegistration;
import android.telephony.ims.aidl.IImsRegistrationCallback;
import android.telephony.ims.aidl.IRcsConfigCallback;
+import android.telephony.satellite.ISatelliteDatagramCallback;
+import android.telephony.satellite.ISatelliteTransmissionUpdateCallback;
+import android.telephony.satellite.ISatelliteProvisionStateCallback;
+import android.telephony.satellite.ISatelliteStateCallback;
+import android.telephony.satellite.SatelliteCapabilities;
+import android.telephony.satellite.SatelliteDatagram;
import com.android.ims.internal.IImsServiceFeatureCallback;
import com.android.internal.telephony.CellNetworkScanResult;
import com.android.internal.telephony.IBooleanConsumer;
@@ -244,6 +253,44 @@ interface ITelephony {
boolean setRadioPower(boolean turnOn);
/**
+ * Vote on powering off the radio for a reason. The radio will be turned on only when there is
+ * no reason to power it off. When any of the voters want to power it off, it will be turned
+ * off. In case of emergency, the radio will be turned on even if there are some reasons for
+ * powering it off, and these radio off votes will be cleared.
+ * Multiple apps can vote for the same reason and the last vote will take effect. Each app is
+ * responsible for its vote. A powering-off vote of a reason will be maintained until it is
+ * cleared by calling {@link clearRadioPowerOffForReason} for that reason, or an emergency call
+ * is made, or the device is rebooted. When an app comes backup from a crash, it needs to make
+ * sure if its vote is as expected. An app can use the API {@link getRadioPowerOffReasons} to
+ * check its vote.
+ *
+ * @param subId The subscription ID.
+ * @param reason The reason for powering off radio.
+ * @return true on success and false on failure.
+ */
+ boolean requestRadioPowerOffForReason(int subId, int reason);
+
+ /**
+ * Remove the vote on powering off the radio for a reasonas, requested by
+ * {@link requestRadioPowerOffForReason}.
+ *
+ * @param subId The subscription ID.
+ * @param reason The reason for powering off radio.
+ * @return true on success and false on failure.
+ */
+ boolean clearRadioPowerOffForReason(int subId, int reason);
+
+ /**
+ * Get reasons for powering off radio, as requested by {@link requestRadioPowerOffForReason}.
+ *
+ * @param subId The subscription ID.
+ * @param callingPackage The package making the call.
+ * @param callingFeatureId The feature in the package.
+ * @return List of reasons for powering off radio.
+ */
+ List getRadioPowerOffReasons(int subId, String callingPackage, String callingFeatureId);
+
+ /**
* This method has been removed due to security and stability issues.
*/
@UnsupportedAppUsage
@@ -583,7 +630,7 @@ interface ITelephony {
/**
* Sets minimum time in milli-seconds between onCellInfoChanged
*/
- void setCellInfoListRate(int rateInMillis);
+ void setCellInfoListRate(int rateInMillis, int subId);
/**
* Opens a logical channel to the ICC card.
@@ -1281,6 +1328,16 @@ interface ITelephony {
String getImeiForSlot(int slotIndex, String callingPackage, String callingFeatureId);
/**
+ * Returns the primary IMEI of the device
+ *
+ * @param callingPackage The package name of the caller
+ * @param callingFeatureId The feature Id of the calling package
+ * @throws UnsupportedOperationException if the radio doesn't support this feature.
+ * @throws SecurityException if the caller does not have the required permission/privileges
+ */
+ String getPrimaryImei(String callingPackage, String callingFeatureId);
+
+ /**
* Returns the Type Allocation Code from the IMEI for the given slot.
*
* @param slotIndex - Which slot to retrieve the Type Allocation Code from.
@@ -1483,7 +1540,7 @@ interface ITelephony {
*/
CarrierRestrictionRules getAllowedCarriers();
- /**
+ /**
* Returns carrier id of the given subscription.
* <p>To recognize carrier as a first class identity, assign each carrier with a canonical
* integer a.k.a carrier id.
@@ -2137,6 +2194,12 @@ interface ITelephony {
int getRadioHalVersion();
/**
+ * Get the HAL Version of a specific service
+ * encoded as 100 * MAJOR_VERSION + MINOR_VERSION or -1 if unknown
+ */
+ int getHalVersion(int service);
+
+ /**
* Get the current calling package name.
*/
String getCurrentPackageName();
@@ -2169,6 +2232,11 @@ interface ITelephony {
IIntegerConsumer subIdResult);
/**
+ * Show error dialog to switch to managed profile.
+ */
+ oneway void showSwitchToManagedProfileDialog();
+
+ /**
* Returns the MMS user agent.
*/
String getMmsUserAgent(int subId);
@@ -2507,6 +2575,16 @@ interface ITelephony {
void getSlicingConfig(in ResultReceiver callback);
/**
+ * Check whether the given premium capability is available for purchase from the carrier.
+ */
+ boolean isPremiumCapabilityAvailableForPurchase(int capability, int subId);
+
+ /**
+ * Purchase the given premium capability from the carrier.
+ */
+ void purchasePremiumCapability(int capability, IIntegerConsumer callback, int subId);
+
+ /**
* Register an IMS connection state callback
*/
void registerImsStateCallback(int subId, int feature, in IImsStateCallback cb,
@@ -2582,9 +2660,388 @@ interface ITelephony {
boolean isRemovableEsimDefaultEuicc(String callingPackage);
/**
+ * Get the component name of the default app to direct respond-via-message intent for the
+ * user associated with this subscription, update the cache if there is no respond-via-message
+ * application currently configured for this user.
+ * @return component name of the app and class to direct Respond Via Message intent to, or
+ * {@code null} if the functionality is not supported.
+ * @hide
+ */
+ ComponentName getDefaultRespondViaMessageApplication(int subId, boolean updateIfNeeded);
+
+ /**
* Get the SIM state for the logical SIM slot index.
*
* @param slotIndex Logical SIM slot index.
*/
int getSimStateForSlotIndex(int slotIndex);
+
+ /**
+ * Request telephony to persist state for debugging emergency call failures.
+ *
+ * @param dropBoxTag Tag to use when persisting data to dropbox service.
+ * @param enableLogcat whether to collect logcat output
+ * @param logcatStartTimestampMillis timestamp from when logcat buffers would be persisted
+ * @param enableTelecomDump whether to collect telecom dumpsys
+ * @param enableTelephonyDump whether to collect telephony dumpsys
+ *
+ * @hide
+ */
+ @JavaPassthrough(annotation="@android.annotation.RequiresPermission("
+ + "android.Manifest.permission.DUMP)")
+ void persistEmergencyCallDiagnosticData(String dropboxTag, boolean enableLogcat,
+ long logcatStartTimestampMillis, boolean enableTelecomDump, boolean enableTelephonyDump);
+ /**
+ * Set whether the radio is able to connect with null ciphering or integrity
+ * algorithms. This is a global setting and will apply to all active subscriptions
+ * and all new subscriptions after this.
+ *
+ * <p>Requires Permission:
+ * {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE}
+ *
+ * @param enabled when true, null cipher and integrity algorithms are allowed.
+ * @hide
+ */
+ void setNullCipherAndIntegrityEnabled(boolean enabled);
+
+ /**
+ * Get whether the radio is able to connect with null ciphering or integrity
+ * algorithms. Note that this retrieves the phone-global preference and not
+ * the state of the radio.
+ *
+ * @hide
+ */
+ boolean isNullCipherAndIntegrityPreferenceEnabled();
+
+ /**
+ * Get current broadcast ranges.
+ */
+ List<CellBroadcastIdRange> getCellBroadcastIdRanges(int subId);
+
+ /**
+ * Set reception of cell broadcast messages with the list of the given ranges
+ */
+ void setCellBroadcastIdRanges(int subId, in List<CellBroadcastIdRange> ranges,
+ IIntegerConsumer callback);
+
+ /**
+ * Returns whether the domain selection service is supported.
+ *
+ * @return {@code true} if the domain selection service is supported.
+ */
+ boolean isDomainSelectionSupported();
+
+ /**
+ * Get the carrier restriction status of the device.
+ */
+ void getCarrierRestrictionStatus(IIntegerConsumer internalCallback, String packageName);
+
+ /**
+ * Request to enable or disable the satellite modem.
+ *
+ * @param subId The subId of the subscription to enable or disable the satellite modem for.
+ * @param enable True to enable the satellite modem and false to disable.
+ * @param isDemoModeEnabled True if demo mode is enabled and false otherwise.
+ * @param callback The callback to get the result of the request.
+ */
+ @JavaPassthrough(annotation="@android.annotation.RequiresPermission("
+ + "android.Manifest.permission.SATELLITE_COMMUNICATION)")
+ void requestSatelliteEnabled(int subId, boolean enable, boolean isDemoModeEnabled,
+ in IIntegerConsumer callback);
+
+ /**
+ * Request to get whether the satellite modem is enabled.
+ *
+ * @param subId The subId of the subscription to request whether satellite is enabled for.
+ * @param receiver Result receiver to get the error code of the request and whether the
+ * satellite modem is enabled.
+ */
+ @JavaPassthrough(annotation="@android.annotation.RequiresPermission("
+ + "android.Manifest.permission.SATELLITE_COMMUNICATION)")
+ void requestIsSatelliteEnabled(int subId, in ResultReceiver receiver);
+
+ /**
+ * Request to get whether the satellite service demo mode is enabled.
+ *
+ * @param subId The subId of the subscription to request whether the satellite demo mode is
+ * enabled for.
+ * @param receiver Result receiver to get the error code of the request and whether the
+ * satellite demo mode is enabled.
+ */
+ @JavaPassthrough(annotation="@android.annotation.RequiresPermission("
+ + "android.Manifest.permission.SATELLITE_COMMUNICATION)")
+ void requestIsDemoModeEnabled(int subId, in ResultReceiver receiver);
+
+ /**
+ * Request to get whether the satellite service is supported on the device.
+ *
+ * @param subId The subId of the subscription to check whether satellite is supported for.
+ * @param receiver Result receiver to get the error code of the request and whether the
+ * satellite service is supported on the device.
+ */
+ void requestIsSatelliteSupported(int subId, in ResultReceiver receiver);
+
+ /**
+ * Request to get the capabilities of the satellite service.
+ *
+ * @param subId The subId of the subscription to get the capabilities for.
+ * @param receiver Result receiver to get the error code of the request and the requested
+ * capabilities of the satellite service.
+ */
+ @JavaPassthrough(annotation="@android.annotation.RequiresPermission("
+ + "android.Manifest.permission.SATELLITE_COMMUNICATION)")
+ void requestSatelliteCapabilities(int subId, in ResultReceiver receiver);
+
+ /**
+ * Start receiving satellite transmission updates.
+ *
+ * @param subId The subId of the subscription to stop satellite transmission updates for.
+ * @param resultCallback The callback to get the result of the request.
+ * @param callback The callback to handle transmission updates.
+ */
+ @JavaPassthrough(annotation="@android.annotation.RequiresPermission("
+ + "android.Manifest.permission.SATELLITE_COMMUNICATION)")
+ void startSatelliteTransmissionUpdates(int subId, in IIntegerConsumer resultCallback,
+ in ISatelliteTransmissionUpdateCallback callback);
+
+ /**
+ * Stop receiving satellite transmission updates.
+ *
+ * @param subId The subId of the subscritpion to stop satellite transmission updates for.
+ * @param resultCallback The callback to get the result of the request.
+ * @param callback The callback that was passed to startSatelliteTransmissionUpdates.
+ */
+ @JavaPassthrough(annotation="@android.annotation.RequiresPermission("
+ + "android.Manifest.permission.SATELLITE_COMMUNICATION)")
+ void stopSatelliteTransmissionUpdates(int subId, in IIntegerConsumer resultCallback,
+ in ISatelliteTransmissionUpdateCallback callback);
+
+ /**
+ * Register the subscription with a satellite provider.
+ * This is needed to register the subscription if the provider allows dynamic registration.
+ *
+ * @param subId The subId of the subscription to be provisioned.
+ * @param token The token to be used as a unique identifier for provisioning with satellite
+ * gateway.
+ * @provisionData Data from the provisioning app that can be used by provisioning server
+ * @param callback The callback to get the result of the request.
+ *
+ * @return The signal transport used by callers to cancel the provision request.
+ */
+ @JavaPassthrough(annotation="@android.annotation.RequiresPermission("
+ + "android.Manifest.permission.SATELLITE_COMMUNICATION)")
+ ICancellationSignal provisionSatelliteService(int subId, in String token,
+ in byte[] provisionData, in IIntegerConsumer callback);
+
+ /**
+ * Unregister the subscription with the satellite provider.
+ * This is needed to unregister the subscription if the provider allows dynamic registration.
+ * Once deprovisioned,
+ * {@link SatelliteCallback.SatelliteProvisionStateListener#onSatelliteProvisionStateChanged}
+ * should report as deprovisioned.
+ *
+ * @param subId The subId of the subscription to be deprovisioned.
+ * @param token The token of the device/subscription to be deprovisioned.
+ * @param callback The callback to get the result of the request.
+ */
+ @JavaPassthrough(annotation="@android.annotation.RequiresPermission("
+ + "android.Manifest.permission.SATELLITE_COMMUNICATION)")
+ void deprovisionSatelliteService(int subId, in String token, in IIntegerConsumer callback);
+
+
+ /**
+ * Registers for provision state changed from satellite modem.
+ *
+ * @param subId The subId of the subscription to register for provision state changed.
+ * @param callback The callback to handle the satellite provision state changed event.
+ *
+ * @return The {@link SatelliteError} result of the operation.
+ */
+ @JavaPassthrough(annotation="@android.annotation.RequiresPermission("
+ + "android.Manifest.permission.SATELLITE_COMMUNICATION)")
+ int registerForSatelliteProvisionStateChanged(int subId,
+ in ISatelliteProvisionStateCallback callback);
+
+ /**
+ * Unregisters for provision state changed from satellite modem.
+ * If callback was not registered before, the request will be ignored.
+ *
+ * @param subId The subId of the subscription to unregister for provision state changed.
+ * @param callback The callback that was passed to registerForSatelliteProvisionStateChanged.
+ */
+ @JavaPassthrough(annotation="@android.annotation.RequiresPermission("
+ + "android.Manifest.permission.SATELLITE_COMMUNICATION)")
+ void unregisterForSatelliteProvisionStateChanged(int subId,
+ in ISatelliteProvisionStateCallback callback);
+
+ /**
+ * Request to get whether the device is provisioned with a satellite provider.
+ *
+ * @param subId The subId of the subscription to get whether the device is provisioned for.
+ * @param receiver Result receiver to get the error code of the request and whether the
+ * device is provisioned with a satellite provider.
+ */
+ @JavaPassthrough(annotation="@android.annotation.RequiresPermission("
+ + "android.Manifest.permission.SATELLITE_COMMUNICATION)")
+ void requestIsSatelliteProvisioned(int subId, in ResultReceiver receiver);
+
+ /**
+ * Registers for modem state changed from satellite modem.
+ *
+ * @param subId The subId of the subscription to register for satellite modem state changed.
+ * @param callback The callback to handle the satellite modem state changed event.
+ *
+ * @return The {@link SatelliteError} result of the operation.
+ */
+ @JavaPassthrough(annotation="@android.annotation.RequiresPermission("
+ + "android.Manifest.permission.SATELLITE_COMMUNICATION)")
+ int registerForSatelliteModemStateChanged(int subId, ISatelliteStateCallback callback);
+
+ /**
+ * Unregisters for modem state changed from satellite modem.
+ * If callback was not registered before, the request will be ignored.
+ *
+ * @param subId The subId of the subscription to unregister for satellite modem state changed.
+ * @param callback The callback that was passed to registerForSatelliteStateChanged.
+ */
+ @JavaPassthrough(annotation="@android.annotation.RequiresPermission("
+ + "android.Manifest.permission.SATELLITE_COMMUNICATION)")
+ void unregisterForSatelliteModemStateChanged(int subId, ISatelliteStateCallback callback);
+
+ /**
+ * Register to receive incoming datagrams over satellite.
+ *
+ * @param subId The subId of the subscription to register for incoming satellite datagrams.
+ * @param callback The callback to handle the incoming datagrams.
+ *
+ * @return The {@link SatelliteError} result of the operation.
+ */
+ @JavaPassthrough(annotation="@android.annotation.RequiresPermission("
+ + "android.Manifest.permission.SATELLITE_COMMUNICATION)")
+ int registerForSatelliteDatagram(int subId, ISatelliteDatagramCallback callback);
+
+ /**
+ * Unregister to stop receiving incoming datagrams over satellite.
+ * If callback was not registered before, the request will be ignored.
+ *
+ * @param subId The subId of the subscription to unregister for incoming satellite datagrams.
+ * @param callback The callback that was passed to registerForSatelliteDatagram.
+ */
+ @JavaPassthrough(annotation="@android.annotation.RequiresPermission("
+ + "android.Manifest.permission.SATELLITE_COMMUNICATION)")
+ void unregisterForSatelliteDatagram(int subId, ISatelliteDatagramCallback callback);
+
+ /**
+ * Poll pending satellite datagrams over satellite.
+ *
+ * @param subId The subId of the subscription used for receiving datagrams.
+ * @param callback The callback to get the result of the request.
+ */
+ @JavaPassthrough(annotation="@android.annotation.RequiresPermission("
+ + "android.Manifest.permission.SATELLITE_COMMUNICATION)")
+ void pollPendingSatelliteDatagrams(int subId, IIntegerConsumer callback);
+
+ /**
+ * Send datagram over satellite.
+ *
+ * @param subId The subId of the subscription to send satellite datagrams for.
+ * @param datagramType Type of datagram.
+ * @param datagram Datagram to send over satellite.
+ * @param needFullScreenPointingUI this is used to indicate pointingUI app to open in
+ * full screen mode.
+ * @param callback The callback to get the result of the request.
+ */
+ @JavaPassthrough(annotation="@android.annotation.RequiresPermission("
+ + "android.Manifest.permission.SATELLITE_COMMUNICATION)")
+ void sendSatelliteDatagram(int subId, int datagramType,
+ in SatelliteDatagram datagram, in boolean needFullScreenPointingUI,
+ IIntegerConsumer callback);
+
+ /**
+ * Request to get whether satellite communication is allowed for the current location.
+ *
+ * @param subId The subId of the subscription to get whether satellite communication is allowed
+ * for the current location for.
+ * @param receiver Result receiver to get the error code of the request and whether satellite
+ * communication is allowed for the current location.
+ */
+ @JavaPassthrough(annotation="@android.annotation.RequiresPermission("
+ + "android.Manifest.permission.SATELLITE_COMMUNICATION)")
+ void requestIsSatelliteCommunicationAllowedForCurrentLocation(int subId,
+ in ResultReceiver receiver);
+
+ /**
+ * Request to get the time after which the satellite will be visible.
+ *
+ * @param subId The subId to get the time after which the satellite will be visible for.
+ * @param receiver Result receiver to get the error code of the request and the requested
+ * time after which the satellite will be visible.
+ */
+ @JavaPassthrough(annotation="@android.annotation.RequiresPermission("
+ + "android.Manifest.permission.SATELLITE_COMMUNICATION)")
+ void requestTimeForNextSatelliteVisibility(int subId, in ResultReceiver receiver);
+
+ /**
+ * Inform whether the device is aligned with the satellite within in margin for demo mode.
+ *
+ * @param isAligned {@true} Device is aligned with the satellite for demo mode
+ * {@false} Device is not aligned with the satellite for demo mode
+ */
+ @JavaPassthrough(annotation="@android.annotation.RequiresPermission("
+ + "android.Manifest.permission.SATELLITE_COMMUNICATION)")
+ void onDeviceAlignedWithSatellite(int subId, in boolean isAligned);
+
+ /**
+ * This API can be used by only CTS to update satellite vendor service package name.
+ *
+ * @param servicePackageName The package name of the satellite vendor service.
+ * @return {@code true} if the satellite vendor service is set successfully,
+ * {@code false} otherwise.
+ */
+ boolean setSatelliteServicePackageName(in String servicePackageName);
+
+ /**
+ * This API can be used by only CTS to update satellite gateway service package name.
+ *
+ * @param servicePackageName The package name of the satellite gateway service.
+ * @return {@code true} if the satellite gateway service is set successfully,
+ * {@code false} otherwise.
+ */
+ boolean setSatelliteGatewayServicePackageName(in String servicePackageName);
+
+ /**
+ * This API can be used by only CTS to update the timeout duration in milliseconds that
+ * satellite should stay at listening mode to wait for the next incoming page before disabling
+ * listening mode.
+ *
+ * @param timeoutMillis The timeout duration in millisecond.
+ * @return {@code true} if the timeout duration is set successfully, {@code false} otherwise.
+ */
+ boolean setSatelliteListeningTimeoutDuration(in long timeoutMillis);
+
+ /**
+ * This API can be used by only CTS to update satellite pointing UI app package and class names.
+ *
+ * @param packageName The package name of the satellite pointing UI app.
+ * @param className The class name of the satellite pointing UI app.
+ * @return {@code true} if the satellite pointing UI app package and class is set successfully,
+ * {@code false} otherwise.
+ */
+ boolean setSatellitePointingUiClassName(in String packageName, in String className);
+
+ /**
+ * This API can be used by only CTS to update the timeout duration in milliseconds whether
+ * the device is aligned with the satellite for demo mode
+ *
+ * @param timeoutMillis The timeout duration in millisecond.
+ * @return {@code true} if the timeout duration is set successfully, {@code false} otherwise.
+ */
+ boolean setSatelliteDeviceAlignedTimeoutDuration(long timeoutMillis);
+
+ /**
+ * Test method to confirm the file contents are not altered.
+ */
+ @JavaPassthrough(annotation="@android.annotation.RequiresPermission("
+ + "android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)")
+ List<String> getShaIdFromAllowList(String pkgName, int carrierId);
}
diff --git a/telephony/java/com/android/internal/telephony/ITransportSelectorCallback.aidl b/telephony/java/com/android/internal/telephony/ITransportSelectorCallback.aidl
new file mode 100644
index 000000000000..6777256d171e
--- /dev/null
+++ b/telephony/java/com/android/internal/telephony/ITransportSelectorCallback.aidl
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.telephony;
+
+import com.android.internal.telephony.IDomainSelector;
+import com.android.internal.telephony.ITransportSelectorResultCallback;
+import com.android.internal.telephony.IWwanSelectorCallback;
+
+interface ITransportSelectorCallback {
+ oneway void onCreated(in IDomainSelector selector);
+ oneway void onWlanSelected(boolean useEmergencyPdn);
+ IWwanSelectorCallback onWwanSelected();
+ oneway void onWwanSelectedAsync(in ITransportSelectorResultCallback cb);
+ oneway void onSelectionTerminated(int cause);
+}
diff --git a/telephony/java/com/android/internal/telephony/ITransportSelectorResultCallback.aidl b/telephony/java/com/android/internal/telephony/ITransportSelectorResultCallback.aidl
new file mode 100644
index 000000000000..1460b45acac5
--- /dev/null
+++ b/telephony/java/com/android/internal/telephony/ITransportSelectorResultCallback.aidl
@@ -0,0 +1,23 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.telephony;
+
+import com.android.internal.telephony.IWwanSelectorCallback;
+
+oneway interface ITransportSelectorResultCallback {
+ void onCompleted(in IWwanSelectorCallback cb);
+}
diff --git a/telephony/java/com/android/internal/telephony/IVoidConsumer.aidl b/telephony/java/com/android/internal/telephony/IVoidConsumer.aidl
new file mode 100644
index 000000000000..b5557fde2a02
--- /dev/null
+++ b/telephony/java/com/android/internal/telephony/IVoidConsumer.aidl
@@ -0,0 +1,25 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+ package com.android.internal.telephony;
+
+ /**
+ * Copies consumer pattern for an operation that requires void result from another process to
+ * finish.
+ */
+ oneway interface IVoidConsumer {
+ void accept();
+ } \ No newline at end of file
diff --git a/telephony/java/com/android/internal/telephony/IWwanSelectorCallback.aidl b/telephony/java/com/android/internal/telephony/IWwanSelectorCallback.aidl
new file mode 100644
index 000000000000..94e7c871066e
--- /dev/null
+++ b/telephony/java/com/android/internal/telephony/IWwanSelectorCallback.aidl
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.telephony;
+
+import com.android.internal.telephony.IWwanSelectorResultCallback;
+
+oneway interface IWwanSelectorCallback {
+ void onRequestEmergencyNetworkScan(in int[] preferredNetworks,
+ int scanType, in IWwanSelectorResultCallback cb);
+ void onDomainSelected(int domain, boolean useEmergencyPdn);
+ void onCancel();
+}
diff --git a/telephony/java/com/android/internal/telephony/IWwanSelectorResultCallback.aidl b/telephony/java/com/android/internal/telephony/IWwanSelectorResultCallback.aidl
new file mode 100644
index 000000000000..0d61fcbb266e
--- /dev/null
+++ b/telephony/java/com/android/internal/telephony/IWwanSelectorResultCallback.aidl
@@ -0,0 +1,23 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.telephony;
+
+import android.telephony.EmergencyRegResult;
+
+oneway interface IWwanSelectorResultCallback {
+ void onComplete(in EmergencyRegResult result);
+}
diff --git a/telephony/java/com/android/internal/telephony/PhoneConstants.java b/telephony/java/com/android/internal/telephony/PhoneConstants.java
index 813e80e6f355..07f2916838e8 100644
--- a/telephony/java/com/android/internal/telephony/PhoneConstants.java
+++ b/telephony/java/com/android/internal/telephony/PhoneConstants.java
@@ -226,6 +226,8 @@ public class PhoneConstants {
// per 3GPP TS 31.102 (Section 7.1.2)
public static final int AUTH_CONTEXT_EAP_SIM = 128;
public static final int AUTH_CONTEXT_EAP_AKA = 129;
+ public static final int AUTH_CONTEXT_GBA_BOOTSTRAP = 132;
+ public static final int AUTHTYPE_GBA_NAF_KEY_EXTERNAL = 133;
public static final int AUTH_CONTEXT_UNDEFINED = -1;
/**
@@ -237,4 +239,20 @@ public class PhoneConstants {
public static final int CELL_OFF_FLAG = 0;
public static final int CELL_ON_FLAG = 1;
public static final int CELL_OFF_DUE_TO_AIRPLANE_MODE_FLAG = 2;
+
+ /** The key to specify the selected domain for dialing calls. */
+ public static final String EXTRA_DIAL_DOMAIN = "dial_domain";
+
+ /**
+ * Indicates that this call should be routed over Wi-Fi.
+ * An internal extension of NetworkRegistrationInfo's DOMAIN_* constants
+ * to also include NON_3GPP_PS routing for the domain selection service.
+ */
+ public static final int DOMAIN_NON_3GPP_PS = 4;
+
+ /** Key to enable comparison of domain selection results from legacy and new code. */
+ public static final String EXTRA_COMPARE_DOMAIN = "compare_domain";
+
+ /** The key to specify the emergency service category */
+ public static final String EXTRA_EMERGENCY_SERVICE_CATEGORY = "emergency_service_category";
}
diff --git a/telephony/java/com/android/internal/telephony/RILConstants.java b/telephony/java/com/android/internal/telephony/RILConstants.java
index 39ab7eb0973c..b273ba2e9f11 100644
--- a/telephony/java/com/android/internal/telephony/RILConstants.java
+++ b/telephony/java/com/android/internal/telephony/RILConstants.java
@@ -120,6 +120,31 @@ public interface RILConstants {
int BLOCKED_DUE_TO_CALL = 69; /* SMS is blocked due to call control */
int RF_HARDWARE_ISSUE = 70; /* RF HW issue is detected */
int NO_RF_CALIBRATION_INFO = 71; /* No RF calibration in device */
+ int ENCODING_NOT_SUPPORTED = 72; /* The encoding scheme is not supported by
+ either the network or the MS. */
+ int FEATURE_NOT_SUPPORTED = 73; /* The requesting feature is not supported by
+ the service provider. */
+ int INVALID_CONTACT = 74; /* The contact to be added is either not
+ existing or not valid. */
+ int MODEM_INCOMPATIBLE = 75; /* The modem of the MS is not compatible with
+ the service provider. */
+ int NETWORK_TIMEOUT = 76; /* Modem timeout to receive ACK or response from
+ network after sending a request to it. */
+ int NO_SATELLITE_SIGNAL = 77; /* Modem fails to communicate with the satellite
+ network since there is no satellite signal.*/
+ int NOT_SUFFICIENT_ACCOUNT_BALANCE = 78; /* The request cannot be performed since the
+ subscriber's account balance is not
+ sufficient. */
+ int RADIO_TECHNOLOGY_NOT_SUPPORTED = 79; /* The radio technology is not supported by the
+ service provider. */
+ int SUBSCRIBER_NOT_AUTHORIZED = 80; /* The subscription is not authorized to
+ register with the service provider. */
+ int SWITCHED_FROM_SATELLITE_TO_TERRESTRIAL = 81; /* While processing a request from the
+ Framework the satellite modem detects
+ terrestrial signal, aborts the request, and
+ switches to the terrestrial network. */
+ int UNIDENTIFIED_SUBSCRIBER = 82; /* The subscriber is not registered with the
+ service provider */
// Below is list of OEM specific error codes which can by used by OEMs in case they don't want to
// reveal particular replacement for Generic failure
@@ -500,7 +525,7 @@ public interface RILConstants {
int RIL_REQUEST_GET_SIM_PHONEBOOK_CAPACITY = 149;
int RIL_REQUEST_GET_SIM_PHONEBOOK_RECORDS = 150;
int RIL_REQUEST_UPDATE_SIM_PHONEBOOK_RECORD = 151;
-
+ int RIL_REQUEST_DEVICE_IMEI = 152;
/* The following requests are not defined in RIL.h */
int RIL_REQUEST_HAL_NON_RIL_BASE = 200;
int RIL_REQUEST_GET_SLOT_STATUS = 200;
@@ -532,6 +557,21 @@ public interface RILConstants {
int RIL_REQUEST_IS_VONR_ENABLED = 226;
int RIL_REQUEST_SET_USAGE_SETTING = 227;
int RIL_REQUEST_GET_USAGE_SETTING = 228;
+ int RIL_REQUEST_SET_EMERGENCY_MODE = 229;
+ int RIL_REQUEST_TRIGGER_EMERGENCY_NETWORK_SCAN = 230;
+ int RIL_REQUEST_CANCEL_EMERGENCY_NETWORK_SCAN = 231;
+ int RIL_REQUEST_EXIT_EMERGENCY_MODE = 232;
+ int RIL_REQUEST_SET_SRVCC_CALL_INFO = 233;
+ int RIL_REQUEST_UPDATE_IMS_REGISTRATION_INFO = 234;
+ int RIL_REQUEST_START_IMS_TRAFFIC = 235;
+ int RIL_REQUEST_STOP_IMS_TRAFFIC = 236;
+ int RIL_REQUEST_SEND_ANBR_QUERY = 237;
+ int RIL_REQUEST_TRIGGER_EPS_FALLBACK = 238;
+ int RIL_REQUEST_SET_NULL_CIPHER_AND_INTEGRITY_ENABLED = 239;
+ int RIL_REQUEST_UPDATE_IMS_CALL_STATUS = 240;
+ int RIL_REQUEST_SET_N1_MODE_ENABLED = 241;
+ int RIL_REQUEST_IS_N1_MODE_ENABLED = 242;
+ int RIL_REQUEST_IS_NULL_CIPHER_AND_INTEGRITY_ENABLED = 259;
/* Responses begin */
int RIL_RESPONSE_ACKNOWLEDGEMENT = 800;
@@ -602,4 +642,8 @@ public interface RILConstants {
int RIL_UNSOL_UICC_APPLICATIONS_ENABLEMENT_CHANGED = 1103;
int RIL_UNSOL_REGISTRATION_FAILED = 1104;
int RIL_UNSOL_BARRING_INFO_CHANGED = 1105;
+ int RIL_UNSOL_EMERGENCY_NETWORK_SCAN_RESULT = 1106;
+ int RIL_UNSOL_TRIGGER_IMS_DEREGISTRATION = 1107;
+ int RIL_UNSOL_CONNECTION_SETUP_FAILURE = 1108;
+ int RIL_UNSOL_NOTIFY_ANBR = 1109;
}
diff --git a/telephony/java/com/android/internal/telephony/TelephonyIntents.java b/telephony/java/com/android/internal/telephony/TelephonyIntents.java
index b905212a9100..09101d88130c 100644
--- a/telephony/java/com/android/internal/telephony/TelephonyIntents.java
+++ b/telephony/java/com/android/internal/telephony/TelephonyIntents.java
@@ -212,23 +212,6 @@ public class TelephonyIntents {
public static final String SECRET_CODE_ACTION = "android.provider.Telephony.SECRET_CODE";
/**
- * <p>Broadcast Action: It indicates one column of a subinfo record has been changed
- * <p class="note">This is a protected intent that can only be sent
- * by the system.
- */
- public static final String ACTION_SUBINFO_CONTENT_CHANGE
- = "android.intent.action.ACTION_SUBINFO_CONTENT_CHANGE";
-
- /**
- * <p>Broadcast Action: It indicates subinfo record update is completed
- * when SIM inserted state change
- * <p class="note">This is a protected intent that can only be sent
- * by the system.
- */
- public static final String ACTION_SUBINFO_RECORD_UPDATED
- = "android.intent.action.ACTION_SUBINFO_RECORD_UPDATED";
-
- /**
* Broadcast Action: The default subscription has changed. This has the following
* extra values:</p>
* <ul>
diff --git a/telephony/java/com/android/internal/telephony/gsm/SmsBroadcastConfigInfo.java b/telephony/java/com/android/internal/telephony/gsm/SmsBroadcastConfigInfo.java
index f4f40361fb69..b70d548df969 100644
--- a/telephony/java/com/android/internal/telephony/gsm/SmsBroadcastConfigInfo.java
+++ b/telephony/java/com/android/internal/telephony/gsm/SmsBroadcastConfigInfo.java
@@ -16,6 +16,8 @@
package com.android.internal.telephony.gsm;
+import java.util.Objects;
+
/**
* SmsBroadcastConfigInfo defines one configuration of Cell Broadcast
* Message (CBM) to be received by the ME
@@ -130,4 +132,24 @@ public final class SmsBroadcastConfigInfo {
mFromCodeScheme + ',' + mToCodeScheme + "] " +
(mSelected ? "ENABLED" : "DISABLED");
}
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(mFromServiceId, mToServiceId,
+ mFromCodeScheme, mToCodeScheme, mSelected);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (!(obj instanceof SmsBroadcastConfigInfo)) {
+ return false;
+ }
+
+ SmsBroadcastConfigInfo other = (SmsBroadcastConfigInfo) obj;
+
+ return mFromServiceId == other.mFromServiceId
+ && mToServiceId == other.mToServiceId
+ && mFromCodeScheme == other.mFromCodeScheme
+ && mToCodeScheme == other.mToCodeScheme && mSelected == other.mSelected;
+ }
}