diff options
author | Scott Lobdell <slobdell@google.com> | 2021-01-21 14:57:51 -0800 |
---|---|---|
committer | Scott Lobdell <slobdell@google.com> | 2021-01-22 13:24:00 -0800 |
commit | 7fd6edc3a3ff37a750641d5e192835fe217f6050 (patch) | |
tree | 4369f3a76ed7ba782801984a51f7badb159a43c9 /telephony/java | |
parent | d1a606fc7dfdbd4a3ded9d384a2b14f36f348c51 (diff) | |
parent | d462c4768522d0a62f3bc6cf08158ac813bc09e6 (diff) |
Merge SP1A.210105.001
Change-Id: Iebfaf27bb339a99d9303a53e6c2c397b0001c814
Diffstat (limited to 'telephony/java')
69 files changed, 4081 insertions, 855 deletions
diff --git a/telephony/java/android/service/euicc/OWNERS b/telephony/java/android/service/euicc/OWNERS new file mode 100644 index 000000000000..6aa399d9ebfb --- /dev/null +++ b/telephony/java/android/service/euicc/OWNERS @@ -0,0 +1,5 @@ +# Bug component: 20868 + +rgreenwalt@google.com +tgunn@google.com +amitmahajan@google.com diff --git a/telephony/java/android/service/sms/OWNERS b/telephony/java/android/service/sms/OWNERS new file mode 100644 index 000000000000..6aa399d9ebfb --- /dev/null +++ b/telephony/java/android/service/sms/OWNERS @@ -0,0 +1,5 @@ +# Bug component: 20868 + +rgreenwalt@google.com +tgunn@google.com +amitmahajan@google.com diff --git a/telephony/java/android/telephony/Annotation.java b/telephony/java/android/telephony/Annotation.java index f900c387f060..99f2e5ee0755 100644 --- a/telephony/java/android/telephony/Annotation.java +++ b/telephony/java/android/telephony/Annotation.java @@ -624,6 +624,20 @@ public class Annotation { public @interface UiccAppType{} /** + * UICC SIM Application Types including UNKNOWN + */ + @IntDef(prefix = { "APPTYPE_" }, value = { + TelephonyManager.APPTYPE_UNKNOWN, + TelephonyManager.APPTYPE_SIM, + TelephonyManager.APPTYPE_USIM, + TelephonyManager.APPTYPE_RUIM, + TelephonyManager.APPTYPE_CSIM, + TelephonyManager.APPTYPE_ISIM + }) + @Retention(RetentionPolicy.SOURCE) + public @interface UiccAppTypeExt{} + + /** * Override network type */ @Retention(RetentionPolicy.SOURCE) diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java index 4c9eea8f01b4..a15cf30ed2a6 100644 --- a/telephony/java/android/telephony/CarrierConfigManager.java +++ b/telephony/java/android/telephony/CarrierConfigManager.java @@ -17,6 +17,7 @@ package android.telephony; import android.Manifest; +import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.RequiresPermission; @@ -2091,7 +2092,13 @@ public class CarrierConfigManager { * 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. + * + * @deprecated No longer used in framework code, however it may still be used by applications + * that have not updated their code. This config should still be set to {@code true} if + * {@link Ims#KEY_RCS_BULK_CAPABILITY_EXCHANGE_BOOL} is set to {@code true} and + * {@link Ims#KEY_ENABLE_PRESENCE_CAPABILITY_EXCHANGE_BOOL} is set to {@code true}. */ + @Deprecated public static final String KEY_USE_RCS_PRESENCE_BOOL = "use_rcs_presence_bool"; /** @@ -3907,13 +3914,51 @@ public class CarrierConfigManager { * <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 #KEY_USE_RCS_PRESENCE_BOOL} must also be set to false to ensure apps do not - * improperly think that capability exchange via SIP PUBLISH is enabled. + * {@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. * <p> The default value for this key is {@code false}. */ public static final String KEY_ENABLE_PRESENCE_PUBLISH_BOOL = KEY_PREFIX + "enable_presence_publish_bool"; + /** + * Flag indicating whether or not this carrier supports the exchange of phone numbers with + * the carrier's RCS presence server in order to retrieve the RCS capabilities of requested + * contacts used in the RCS User Capability Exchange (UCE) procedure. See RCC.71, section 3 + * for more information. + * <p> + * When presence is supported, the device uses the SIP SUBSCRIBE/NOTIFY procedure internally + * to retrieve the requested RCS capabilities. See + * {@link android.telephony.ims.RcsUceAdapter} for more information on how RCS capabilities + * can be retrieved from the carrier's network. + */ + 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 + * capabilities of call contacts when the SIM card is first inserted or when a new contact + * is added, removed, or modified. This corresponds to the RCC.07 A.19 + * "DISABLE INITIAL ADDRESS BOOK SCAN" parameter. + * <p> + * If this flag is disabled, the capabilities cache will not be refreshed internally at all + * and will only be updated if the cached capabilities are stale when an application + * requests them. + */ + public static final String KEY_RCS_BULK_CAPABILITY_EXCHANGE_BOOL = + KEY_PREFIX + "rcs_bulk_capability_exchange_bool"; + + /** + * Flag indicating whether or not the carrier supports capability exchange with a list of + * contacts. When {@code true}, the device will batch together multiple requests and + * construct a RLMI document in the SIP SUBSCRIBE request (see RFC 4662). If {@code false}, + * the request will be split up into one SIP SUBSCRIBE request per contact. + */ + public static final String KEY_ENABLE_PRESENCE_GROUP_SUBSCRIBE_BOOL = + KEY_PREFIX + "enable_presence_group_subscribe_bool"; + private Ims() {} private static PersistableBundle getDefaults() { @@ -3921,6 +3966,510 @@ public class CarrierConfigManager { defaults.putInt(KEY_WIFI_OFF_DEFERRING_TIME_MILLIS_INT, 4000); defaults.putBoolean(KEY_IMS_SINGLE_REGISTRATION_REQUIRED_BOOL, false); defaults.putBoolean(KEY_ENABLE_PRESENCE_PUBLISH_BOOL, false); + 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, true); + return defaults; + } + } + + /** + * Configs used for epdg tunnel bring up. + * + * @see <a href="https://tools.ietf.org/html/rfc7296">RFC 7296, Internet Key Exchange Protocol + * Version 2 (IKEv2)</a> + */ + public static final class Iwlan { + /** Prefix of all Epdg.KEY_* constants. */ + public static final String KEY_PREFIX = "iwlan."; + + /** + * Time in seconds after which the child security association session is terminated if rekey + * procedure is not successful. If not set or set to <= 0, the default value is 3600 + * seconds. + */ + public static final String KEY_CHILD_SA_REKEY_HARD_TIMER_SEC_INT = + KEY_PREFIX + "child_sa_rekey_hard_timer_sec_int"; + + /** + * Time in seconds after which the child session rekey procedure is started. If not set or + * set to <= 0, default value is 3000 seconds. + */ + public static final String KEY_CHILD_SA_REKEY_SOFT_TIMER_SEC_INT = + KEY_PREFIX + "child_sa_rekey_soft_timer_sec_int"; + + /** + * Supported DH groups for IKE negotiation. Possible values are {@link #DH_GROUP_NONE}, + * {@link #DH_GROUP_1024_BIT_MODP}, {@link #DH_GROUP_1536_BIT_MODP}, {@link + * #DH_GROUP_2048_BIT_MODP} + */ + public static final String KEY_DIFFIE_HELLMAN_GROUPS_INT_ARRAY = + KEY_PREFIX + "diffie_hellman_groups_int_array"; + + /** + * Time in seconds after which a dead peer detection (DPD) request is sent. If not set or + * set to <= 0, default value is 120 seconds. + */ + public static final String KEY_DPD_TIMER_SEC_INT = KEY_PREFIX + "dpd_timer_sec_int"; + + /** + * Method used to authenticate epdg server. Possible values are {@link + * #AUTHENTICATION_METHOD_EAP_ONLY}, {@link #AUTHENTICATION_METHOD_CERT} + */ + public static final String KEY_EPDG_AUTHENTICATION_METHOD_INT = + KEY_PREFIX + "epdg_authentication_method_int"; + + /** + * A priority list of ePDG addresses to be used. Possible values are {@link + * #EPDG_ADDRESS_STATIC}, {@link #EPDG_ADDRESS_PLMN}, {@link #EPDG_ADDRESS_PCO}, {@link + * #EPDG_ADDRESS_CELLULAR_LOC} + */ + public static final String KEY_EPDG_ADDRESS_PRIORITY_INT_ARRAY = + KEY_PREFIX + "epdg_address_priority_int_array"; + + /** Epdg static IP address or FQDN */ + public static final String KEY_EPDG_STATIC_ADDRESS_STRING = + KEY_PREFIX + "epdg_static_address_string"; + + /** Epdg static IP address or FQDN for roaming */ + public static final String KEY_EPDG_STATIC_ADDRESS_ROAMING_STRING = + KEY_PREFIX + "epdg_static_address_roaming_string"; + + /** + * List of supported key sizes for AES Cipher Block Chaining (CBC) encryption mode of child + * session. Possible values are {@link #KEY_LEN_UNUSED}, {@link #KEY_LEN_AES_128}, {@link + * #KEY_LEN_AES_192}, {@link #KEY_LEN_AES_256} + */ + public static final String KEY_CHILD_SESSION_AES_CBC_KEY_SIZE_INT_ARRAY = + KEY_PREFIX + "child_session_aes_cbc_key_size_int_array"; + + /** + * List of supported key sizes for AES Counter (CTR) encryption mode of child session. + * Possible values are {@link #KEY_LEN_UNUSED}, + * {@link #KEY_LEN_AES_128}, {@link #KEY_LEN_AES_192}, {@link #KEY_LEN_AES_256} + */ + public static final String KEY_CHILD_SESSION_AES_CTR_KEY_SIZE_INT_ARRAY = + KEY_PREFIX + "child_session_aes_ctr_key_size_int_array"; + + /** + * List of supported encryption algorithms for child session. Possible values are + * {@link #ENCRYPTION_ALGORITHM_AES_CBC} + */ + public static final String KEY_SUPPORTED_CHILD_SESSION_ENCRYPTION_ALGORITHMS_INT_ARRAY = + KEY_PREFIX + "supported_child_session_encryption_algorithms_int_array"; + + /** + * Time in seconds after which the IKE session is terminated if rekey procedure is not + * successful. If not set or set to <= 0, default value is 3600 seconds. + */ + public static final String KEY_IKE_REKEY_HARD_TIMER_SEC_INT = + KEY_PREFIX + "ike_rekey_hard_timer_in_sec"; + + /** + * Time in seconds after which the IKE session rekey procedure is started. If not set or set + * to <= 0, default value is 3000 seconds. + */ + public static final String KEY_IKE_REKEY_SOFT_TIMER_SEC_INT = + KEY_PREFIX + "ike_rekey_soft_timer_sec_int"; + + /** + * List of supported key sizes for AES Cipher Block Chaining (CBC) encryption mode of IKE + * session. Possible values - {@link #KEY_LEN_UNUSED}, {@link #KEY_LEN_AES_128}, {@link + * #KEY_LEN_AES_192}, {@link #KEY_LEN_AES_256} + */ + 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 - {@link #KEY_LEN_UNUSED}, {@link #KEY_LEN_AES_128}, + * {@link #KEY_LEN_AES_192}, {@link #KEY_LEN_AES_256} + */ + public static final String KEY_IKE_SESSION_AES_CTR_KEY_SIZE_INT_ARRAY = + KEY_PREFIX + "ike_session_encryption_aes_ctr_key_size_int_array"; + + /** + * List of supported encryption algorithms for IKE session. Possible values are + * {@link #ENCRYPTION_ALGORITHM_AES_CBC}, {@link #ENCRYPTION_ALGORITHM_AES_CTR} + */ + public static final String KEY_SUPPORTED_IKE_SESSION_ENCRYPTION_ALGORITHMS_INT_ARRAY = + KEY_PREFIX + "supported_ike_session_encryption_algorithms_int_array"; + + /** + * List of supported integrity algorithms for IKE session Possible values are {@link + * #INTEGRITY_ALGORITHM_NONE}, {@link #INTEGRITY_ALGORITHM_HMAC_SHA1_96}, {@link + * #INTEGRITY_ALGORITHM_AES_XCBC_96}, {@link #INTEGRITY_ALGORITHM_HMAC_SHA2_256_128}, {@link + * #INTEGRITY_ALGORITHM_HMAC_SHA2_384_192}, {@link #INTEGRITY_ALGORITHM_HMAC_SHA2_512_256} + */ + public static final String KEY_SUPPORTED_INTEGRITY_ALGORITHMS_INT_ARRAY = + KEY_PREFIX + "supported_integrity_algorithms_int_array"; + + /** Maximum number of retries for tunnel establishment. */ + public static final String KEY_MAX_RETRIES_INT = KEY_PREFIX + "max_retries_int"; + + /** + * Time in seconds after which a NATT keep alive message is sent. If not set or set to <= 0, + * default value is 20 seconds. + */ + public static final String KEY_NATT_KEEP_ALIVE_TIMER_SEC_INT = + KEY_PREFIX + "natt_keep_alive_timer_sec_int"; + + /** List of '-' separated MCC/MNCs used to create ePDG FQDN as per 3GPP TS 23.003 */ + public static final String KEY_MCC_MNCS_STRING_ARRAY = KEY_PREFIX + "mcc_mncs_string_array"; + + /** + * List of supported pseudo random function algorithms for IKE session. Possible values are + * {@link #PSEUDORANDOM_FUNCTION_HMAC_SHA1}, {@link #PSEUDORANDOM_FUNCTION_AES128_XCBC}, + * {@link #PSEUDORANDOM_FUNCTION_SHA2_256}, {@link #PSEUDORANDOM_FUNCTION_SHA2_384}, + * {@link #PSEUDORANDOM_FUNCTION_SHA2_512} + */ + public static final String KEY_SUPPORTED_PRF_ALGORITHMS_INT_ARRAY = + KEY_PREFIX + "supported_prf_algorithms_int_array"; + + /** + * List of IKE message retransmission timeouts in milliseconds, where each timeout + * is the waiting time before next retry, except the last timeout which is the waiting time + * before terminating the IKE Session. Min list length = 1, Max + * list length = 10 Min timeout = 500 ms, Max timeout = 1800000 ms + */ + public static final String KEY_RETRANSMIT_TIMER_MSEC_INT_ARRAY = + KEY_PREFIX + "retransmit_timer_sec_int_array"; + + /** Controls if wifi mac Id should be added to network access identifier(NAI) */ + public static final String KEY_ADD_WIFI_MAC_ADDR_TO_NAI_BOOL = + KEY_PREFIX + "add_wifi_mac_addr_to_nai_bool"; + + /** + * Specifies the local identity type for IKE negotiations. Possible values are {@link + * #ID_TYPE_FQDN}, {@link #ID_TYPE_RFC822_ADDR}, {@link #ID_TYPE_KEY_ID} + */ + public static final String KEY_IKE_LOCAL_ID_TYPE_INT = KEY_PREFIX + "ike_local_id_type_int"; + + /** + * Specifies the remote identity type for IKE negotiations. Possible values are {@link + * #ID_TYPE_FQDN}, {@link #ID_TYPE_RFC822_ADDR}, {@link #ID_TYPE_KEY_ID} + */ + public static final String KEY_IKE_REMOTE_ID_TYPE_INT = + KEY_PREFIX + "ike_remote_id_type_int"; + + /** Controls if KE payload should be added during child session local rekey procedure. */ + public static final String KEY_ADD_KE_TO_CHILD_SESSION_REKEY_BOOL = + KEY_PREFIX + "add_ke_to_child_session_rekey_bool"; + + /** Specifies the PCO id for IPv6 Epdg server address */ + public static final String KEY_EPDG_PCO_ID_IPV6_INT = KEY_PREFIX + "epdg_pco_id_ipv6_int"; + + /** Specifies the PCO id for IPv4 Epdg server address */ + public static final String KEY_EPDG_PCO_ID_IPV4_INT = KEY_PREFIX + "epdg_pco_id_ipv4_int"; + + /** @hide */ + @IntDef({AUTHENTICATION_METHOD_EAP_ONLY, AUTHENTICATION_METHOD_CERT}) + public @interface AuthenticationMethodType {} + + /** + * Certificate sent from the server is ignored. Only Extensible Authentication Protocol + * (EAP) is used to authenticate the server. EAP_ONLY_AUTH payload is added to IKE_AUTH + * request if supported. + * + * @see <a href="https://tools.ietf.org/html/rfc5998">RFC 5998</a> + */ + public static final int AUTHENTICATION_METHOD_EAP_ONLY = 0; + /** Server is authenticated using its certificate. */ + public static final int AUTHENTICATION_METHOD_CERT = 1; + + /** @hide */ + @IntDef({ + EPDG_ADDRESS_STATIC, + EPDG_ADDRESS_PLMN, + EPDG_ADDRESS_PCO, + EPDG_ADDRESS_CELLULAR_LOC + }) + public @interface EpdgAddressType {} + + /** Use static epdg address. */ + public static final int EPDG_ADDRESS_STATIC = 0; + /** Construct the epdg address using plmn. */ + public static final int EPDG_ADDRESS_PLMN = 1; + /** + * Use the epdg address received in protocol configuration options (PCO) from the network. + */ + public static final int EPDG_ADDRESS_PCO = 2; + /** Use cellular location to chose epdg server */ + public static final int EPDG_ADDRESS_CELLULAR_LOC = 3; + + /** @hide */ + @IntDef({KEY_LEN_UNUSED, KEY_LEN_AES_128, KEY_LEN_AES_192, KEY_LEN_AES_256}) + public @interface EncrpytionKeyLengthType {} + + public static final int KEY_LEN_UNUSED = 0; + /** AES Encryption/Ciphering Algorithm key length 128 bits. */ + public static final int KEY_LEN_AES_128 = 128; + /** AES Encryption/Ciphering Algorithm key length 192 bits. */ + public static final int KEY_LEN_AES_192 = 192; + /** AES Encryption/Ciphering Algorithm key length 256 bits. */ + public static final int KEY_LEN_AES_256 = 256; + + /** @hide */ + @IntDef({ + DH_GROUP_NONE, + DH_GROUP_1024_BIT_MODP, + DH_GROUP_1536_BIT_MODP, + DH_GROUP_2048_BIT_MODP, + DH_GROUP_3072_BIT_MODP, + DH_GROUP_4096_BIT_MODP + }) + public @interface DhGroup {} + + /** None Diffie-Hellman Group. */ + public static final int DH_GROUP_NONE = 0; + /** + * 1024-bit MODP Diffie-Hellman Group. + * + * @see <a href="https://tools.ietf.org/html/rfc7296#section-3.3">RFC 7296, Internet Key + * Exchange Protocol Version 2 (IKEv2)</a> + */ + public static final int DH_GROUP_1024_BIT_MODP = 2; + /** + * 1536-bit MODP Diffie-Hellman Group. + * + * @see <a href="https://tools.ietf.org/html/rfc7296#section-3.3">RFC 7296, Internet Key + * Exchange Protocol Version 2 (IKEv2)</a> + */ + public static final int DH_GROUP_1536_BIT_MODP = 5; + /** + * 2048-bit MODP Diffie-Hellman Group. + * + * @see <a href="https://tools.ietf.org/html/rfc7296#section-3.3">RFC 7296, Internet Key + * Exchange Protocol Version 2 (IKEv2)</a> + */ + public static final int DH_GROUP_2048_BIT_MODP = 14; + /** + * 3072-bit MODP Diffie-Hellman Group. + * + * @see <a href="https://tools.ietf.org/html/rfc7296#section-3.3">RFC 7296, Internet Key + * Exchange Protocol Version 2 (IKEv2)</a> + */ + public static final int DH_GROUP_3072_BIT_MODP = 15; + /** + * 4096-bit MODP Diffie-Hellman Group. + * + * @see <a href="https://tools.ietf.org/html/rfc7296#section-3.3">RFC 7296, Internet Key + * Exchange Protocol Version 2 (IKEv2)</a> + */ + public static final int DH_GROUP_4096_BIT_MODP = 16; + + /** @hide */ + @IntDef({ENCRYPTION_ALGORITHM_AES_CBC, ENCRYPTION_ALGORITHM_AES_CTR}) + public @interface EncryptionAlgorithm {} + + /** + * AES-CBC Encryption/Ciphering Algorithm. + * + * @see <a href="https://tools.ietf.org/html/rfc7296#section-3.3">RFC 7296, Internet Key + * Exchange Protocol Version 2 (IKEv2)</a> + */ + public static final int ENCRYPTION_ALGORITHM_AES_CBC = 12; + + /** + * AES-CTR Encryption/Ciphering Algorithm. + * + * @see <a href="https://tools.ietf.org/html/rfc7296#section-3.3">RFC 7296, Internet Key + * Exchange Protocol Version 2 (IKEv2)</a> + */ + public static final int ENCRYPTION_ALGORITHM_AES_CTR = 13; + + /** @hide */ + @IntDef({ + INTEGRITY_ALGORITHM_NONE, + INTEGRITY_ALGORITHM_HMAC_SHA1_96, + INTEGRITY_ALGORITHM_AES_XCBC_96, + INTEGRITY_ALGORITHM_HMAC_SHA2_256_128, + INTEGRITY_ALGORITHM_HMAC_SHA2_384_192, + INTEGRITY_ALGORITHM_HMAC_SHA2_512_256 + }) + public @interface IntegrityAlgorithm {} + + /** None Authentication/Integrity Algorithm. */ + public static final int INTEGRITY_ALGORITHM_NONE = 0; + /** + * HMAC-SHA1 Authentication/Integrity Algorithm. + * + * @see <a href="https://tools.ietf.org/html/rfc7296#section-3.3">RFC 7296, Internet Key + * Exchange Protocol Version 2 (IKEv2)</a> + */ + public static final int INTEGRITY_ALGORITHM_HMAC_SHA1_96 = 2; + /** + * AES-XCBC-96 Authentication/Integrity Algorithm. + * + * @see <a href="https://tools.ietf.org/html/rfc7296#section-3.3">RFC 7296, Internet Key + * Exchange Protocol Version 2 (IKEv2)</a> + */ + public static final int INTEGRITY_ALGORITHM_AES_XCBC_96 = 5; + /** + * HMAC-SHA256 Authentication/Integrity Algorithm with 128-bit truncation. + * + * @see <a href="https://tools.ietf.org/html/rfc7296#section-3.3">RFC 7296, Internet Key + * Exchange Protocol Version 2 (IKEv2)</a> + */ + public static final int INTEGRITY_ALGORITHM_HMAC_SHA2_256_128 = 12; + /** + * HMAC-SHA384 Authentication/Integrity Algorithm with 192-bit truncation. + * + * @see <a href="https://tools.ietf.org/html/rfc7296#section-3.3">RFC 7296, Internet Key + * Exchange Protocol Version 2 (IKEv2)</a> + */ + public static final int INTEGRITY_ALGORITHM_HMAC_SHA2_384_192 = 13; + /** + * HMAC-SHA512 Authentication/Integrity Algorithm with 256-bit truncation. + * + * @see <a href="https://tools.ietf.org/html/rfc7296#section-3.3">RFC 7296, Internet Key + * Exchange Protocol Version 2 (IKEv2)</a> + */ + public static final int INTEGRITY_ALGORITHM_HMAC_SHA2_512_256 = 14; + + /** @hide */ + @IntDef({ + PSEUDORANDOM_FUNCTION_HMAC_SHA1, + PSEUDORANDOM_FUNCTION_AES128_XCBC, + PSEUDORANDOM_FUNCTION_SHA2_256, + PSEUDORANDOM_FUNCTION_SHA2_384, + PSEUDORANDOM_FUNCTION_SHA2_512 + }) + public @interface PseudorandomFunction {} + + /** + * HMAC-SHA1 Pseudorandom Function. + * + * @see <a href="https://tools.ietf.org/html/rfc7296#section-3.3">RFC 7296, Internet Key + * Exchange Protocol Version 2 (IKEv2)</a> + */ + public static final int PSEUDORANDOM_FUNCTION_HMAC_SHA1 = 2; + /** + * AES128-XCBC Pseudorandom Function. + * + * @see <a href="https://tools.ietf.org/html/rfc7296#section-3.3">RFC 7296, Internet Key + * Exchange Protocol Version 2 (IKEv2)</a> + */ + public static final int PSEUDORANDOM_FUNCTION_AES128_XCBC = 4; + /** + * HMAC-SHA2-256 Pseudorandom Function. + * + * @see <a href="https://tools.ietf.org/html/rfc7296#section-3.3">RFC 7296, Internet Key + * Exchange Protocol Version 2 (IKEv2)</a> + */ + public static final int PSEUDORANDOM_FUNCTION_SHA2_256 = 5; + /** + * HMAC-SHA2-384 Pseudorandom Function. + * + * @see <a href="https://tools.ietf.org/html/rfc7296#section-3.3">RFC 7296, Internet Key + * Exchange Protocol Version 2 (IKEv2)</a> + */ + public static final int PSEUDORANDOM_FUNCTION_SHA2_384 = 6; + /** + * HMAC-SHA2-384 Pseudorandom Function. + * + * @see <a href="https://tools.ietf.org/html/rfc7296#section-3.3">RFC 7296, Internet Key + * Exchange Protocol Version 2 (IKEv2)</a> + */ + public static final int PSEUDORANDOM_FUNCTION_SHA2_512 = 7; + + /** @hide */ + @IntDef({ID_TYPE_FQDN, ID_TYPE_RFC822_ADDR, ID_TYPE_KEY_ID}) + public @interface IkeIdType {} + + /** + * Ike Identification Fully Qualified Domain Name + * + * @see <a href="https://tools.ietf.org/html/rfc7296#section-3.5">RFC 7296, Internet Key + * Exchange Protocol Version 2 (IKEv2)</a> + */ + public static final int ID_TYPE_FQDN = 2; + /** + * Ike Identification Fully Qualified RFC 822 email address. + * + * @see <a href="https://tools.ietf.org/html/rfc7296#section-3.5">RFC 7296, Internet Key + * Exchange Protocol Version 2 (IKEv2)</a> + */ + public static final int ID_TYPE_RFC822_ADDR = 3; + /** + * Ike Identification opaque octet stream for vendor specific information + * + * @see <a href="https://tools.ietf.org/html/rfc7296#section-3.5">RFC 7296, Internet Key + * Exchange Protocol Version 2 (IKEv2)</a> + */ + public static final int ID_TYPE_KEY_ID = 11; + + private Iwlan() {} + + private static PersistableBundle getDefaults() { + PersistableBundle defaults = new PersistableBundle(); + defaults.putInt(KEY_IKE_REKEY_SOFT_TIMER_SEC_INT, 7200); + defaults.putInt(KEY_IKE_REKEY_HARD_TIMER_SEC_INT, 14400); + defaults.putInt(KEY_CHILD_SA_REKEY_SOFT_TIMER_SEC_INT, 3600); + defaults.putInt(KEY_CHILD_SA_REKEY_HARD_TIMER_SEC_INT, 7200); + defaults.putIntArray( + KEY_RETRANSMIT_TIMER_MSEC_INT_ARRAY, new int[] {500, 1000, 2000, 4000, 8000}); + defaults.putInt(KEY_DPD_TIMER_SEC_INT, 120); + defaults.putInt(KEY_MAX_RETRIES_INT, 3); + defaults.putIntArray( + KEY_DIFFIE_HELLMAN_GROUPS_INT_ARRAY, + new int[] { + DH_GROUP_1024_BIT_MODP, DH_GROUP_1536_BIT_MODP, DH_GROUP_2048_BIT_MODP + }); + defaults.putIntArray( + KEY_SUPPORTED_IKE_SESSION_ENCRYPTION_ALGORITHMS_INT_ARRAY, + new int[] {ENCRYPTION_ALGORITHM_AES_CBC}); + defaults.putIntArray( + KEY_SUPPORTED_CHILD_SESSION_ENCRYPTION_ALGORITHMS_INT_ARRAY, + new int[] {ENCRYPTION_ALGORITHM_AES_CBC}); + defaults.putIntArray( + KEY_SUPPORTED_INTEGRITY_ALGORITHMS_INT_ARRAY, + new int[] { + INTEGRITY_ALGORITHM_AES_XCBC_96, + INTEGRITY_ALGORITHM_HMAC_SHA1_96, + INTEGRITY_ALGORITHM_HMAC_SHA2_256_128, + INTEGRITY_ALGORITHM_HMAC_SHA2_384_192, + INTEGRITY_ALGORITHM_HMAC_SHA2_512_256, + }); + defaults.putIntArray( + KEY_SUPPORTED_PRF_ALGORITHMS_INT_ARRAY, + new int[] { + PSEUDORANDOM_FUNCTION_HMAC_SHA1, + PSEUDORANDOM_FUNCTION_AES128_XCBC, + PSEUDORANDOM_FUNCTION_SHA2_256, + PSEUDORANDOM_FUNCTION_SHA2_384, + PSEUDORANDOM_FUNCTION_SHA2_512 + }); + + defaults.putInt(KEY_EPDG_AUTHENTICATION_METHOD_INT, AUTHENTICATION_METHOD_EAP_ONLY); + defaults.putString(KEY_EPDG_STATIC_ADDRESS_STRING, ""); + defaults.putString(KEY_EPDG_STATIC_ADDRESS_ROAMING_STRING, ""); + // will be used after b/158036773 is fixed + defaults.putInt(KEY_NATT_KEEP_ALIVE_TIMER_SEC_INT, 20); + defaults.putIntArray( + KEY_IKE_SESSION_AES_CBC_KEY_SIZE_INT_ARRAY, + new int[] {KEY_LEN_AES_128, KEY_LEN_AES_192, KEY_LEN_AES_256}); + defaults.putIntArray( + KEY_CHILD_SESSION_AES_CBC_KEY_SIZE_INT_ARRAY, + new int[] {KEY_LEN_AES_128, KEY_LEN_AES_192, KEY_LEN_AES_256}); + defaults.putIntArray( + KEY_IKE_SESSION_AES_CTR_KEY_SIZE_INT_ARRAY, + new int[] {KEY_LEN_AES_128, KEY_LEN_AES_192, KEY_LEN_AES_256}); + defaults.putIntArray( + KEY_CHILD_SESSION_AES_CTR_KEY_SIZE_INT_ARRAY, + new int[] {KEY_LEN_AES_128, KEY_LEN_AES_192, KEY_LEN_AES_256}); + defaults.putIntArray( + KEY_EPDG_ADDRESS_PRIORITY_INT_ARRAY, + new int[] {EPDG_ADDRESS_PLMN, EPDG_ADDRESS_STATIC}); + defaults.putStringArray(KEY_MCC_MNCS_STRING_ARRAY, new String[] {}); + defaults.putBoolean(KEY_ADD_WIFI_MAC_ADDR_TO_NAI_BOOL, false); + 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); + defaults.putInt(KEY_EPDG_PCO_ID_IPV6_INT, 0); + defaults.putInt(KEY_EPDG_PCO_ID_IPV4_INT, 0); + return defaults; } } @@ -4074,6 +4623,12 @@ public class CarrierConfigManager { public static final String KEY_USE_LOWER_MTU_VALUE_IF_BOTH_RECEIVED = "use_lower_mtu_value_if_both_received"; + /** + * Indicates if auto-configuration server is used for the RCS config + * Reference: GSMA RCC.14 + */ + public static final String KEY_USE_ACS_FOR_RCS_BOOL = "use_acs_for_rcs_bool"; + /** * Flag indicating whether carrier supports multianchor conference. * In multianchor conference, a participant of a conference can add @@ -4616,6 +5171,7 @@ public class CarrierConfigManager { }); sDefaults.putBoolean(KEY_SUPPORT_WPS_OVER_IMS_BOOL, true); sDefaults.putAll(Ims.getDefaults()); + sDefaults.putAll(Iwlan.getDefaults()); sDefaults.putStringArray(KEY_CARRIER_CERTIFICATE_STRING_ARRAY, new String[0]); sDefaults.putBoolean(KEY_FORMAT_INCOMING_NUMBER_TO_NATIONAL_FOR_JP_BOOL, false); sDefaults.putIntArray(KEY_DISCONNECT_CAUSE_PLAY_BUSYTONE_INT_ARRAY, @@ -4642,6 +5198,7 @@ public class CarrierConfigManager { sDefaults.putBoolean(KEY_SUPPORTS_CALL_COMPOSER_BOOL, false); sDefaults.putString(KEY_CALL_COMPOSER_PICTURE_SERVER_URL_STRING, ""); sDefaults.putBoolean(KEY_USE_LOWER_MTU_VALUE_IF_BOTH_RECEIVED, false); + sDefaults.putBoolean(KEY_USE_ACS_FOR_RCS_BOOL, false); sDefaults.putBoolean(KEY_CARRIER_SUPPORTS_MULTIANCHOR_CONFERENCE, false); sDefaults.putInt(KEY_DEFAULT_RTT_MODE_INT, 0); } diff --git a/telephony/java/android/telephony/CellSignalStrengthLte.java b/telephony/java/android/telephony/CellSignalStrengthLte.java index db7d10ae8ce4..7addf334e967 100644 --- a/telephony/java/android/telephony/CellSignalStrengthLte.java +++ b/telephony/java/android/telephony/CellSignalStrengthLte.java @@ -443,10 +443,12 @@ public final class CellSignalStrengthLte extends CellSignalStrength implements P /** * Get table index for channel quality indicator * + * Reference: 3GPP TS 136.213 section 7.2.3. + * * @return the CQI table index if available or * {@link android.telephony.CellInfo#UNAVAILABLE UNAVAILABLE} if unavailable. */ - /** @hide */ + @IntRange(from = 1, to = 6) public int getCqiTableIndex() { return mCqiTableIndex; } @@ -454,9 +456,12 @@ public final class CellSignalStrengthLte extends CellSignalStrength implements P /** * Get channel quality indicator * + * Reference: 3GPP TS 136.213 section 7.2.3. + * * @return the CQI if available or * {@link android.telephony.CellInfo#UNAVAILABLE UNAVAILABLE} if unavailable. */ + @IntRange(from = 0, to = 15) public int getCqi() { return mCqi; } diff --git a/telephony/java/android/telephony/CellSignalStrengthNr.java b/telephony/java/android/telephony/CellSignalStrengthNr.java index 1518190bb7f7..bde62fb2977c 100644 --- a/telephony/java/android/telephony/CellSignalStrengthNr.java +++ b/telephony/java/android/telephony/CellSignalStrengthNr.java @@ -294,9 +294,10 @@ public final class CellSignalStrengthNr extends CellSignalStrength implements Pa * * Reference: 3GPP TS 138.214 section 5.2.2.1. * - * Range [1, 3]. + * @return the CQI table index if available or + * {@link android.telephony.CellInfo#UNAVAILABLE UNAVAILABLE} if unavailable. */ - /** @hide */ + @IntRange(from = 1, to = 3) public int getCsiCqiTableIndex() { return mCsiCqiTableIndex; } @@ -310,10 +311,10 @@ public final class CellSignalStrengthNr extends CellSignalStrength implements Pa * * Reference: 3GPP TS 138.214 section 5.2.2.1. * - * Range [0, 15] for each CQI. + * @return the CQIs for all subbands if available or empty list if unavailable. */ - /** @hide */ @NonNull + @IntRange(from = 0, to = 15) public List<Integer> getCsiCqiReport() { return mCsiCqiReport; } diff --git a/telephony/java/android/telephony/DataFailCause.java b/telephony/java/android/telephony/DataFailCause.java index 8b7a243c30e6..99a77ae5d133 100644 --- a/telephony/java/android/telephony/DataFailCause.java +++ b/telephony/java/android/telephony/DataFailCause.java @@ -915,6 +915,86 @@ public final class DataFailCause { public static final int IPV6_PREFIX_UNAVAILABLE = 0x8CA; /** System preference change back to SRAT during handoff */ public static final int HANDOFF_PREFERENCE_CHANGED = 0x8CB; + /** Data call fail due to the slice not being allowed for the data call. */ + public static final int SLICE_REJECTED = 0x8CC; + + //IKE error notifications message as specified in 3GPP TS 24.302 (Section 8.1.2.2). + + /** The PDN connection corresponding to the requested APN has been rejected. */ + public static final int IWLAN_PDN_CONNECTION_REJECTION = 0x2000; + /** + * The PDN connection has been rejected. No additional PDN connections can be established + * for the UE due to the network policies or capabilities. + */ + public static final int IWLAN_MAX_CONNECTION_REACHED = 0x2001; + /** + * The PDN connection has been rejected due to a semantic error in TFT operation. + */ + public static final int IWLAN_SEMANTIC_ERROR_IN_THE_TFT_OPERATION = 0x2031; + /** + * The PDN connection has been rejected due to a syntactic error in TFT operation. + */ + public static final int IWLAN_SYNTACTICAL_ERROR_IN_THE_TFT_OPERATION = 0x2032; + /** + * The PDN connection has been rejected due to sematic errors in the packet filter. + */ + public static final int IWLAN_SEMANTIC_ERRORS_IN_PACKET_FILTERS = 0x2034; + /** + * The PDN connection has been rejected due to syntactic errors in the packet filter. + */ + public static final int IWLAN_SYNTACTICAL_ERRORS_IN_PACKET_FILTERS = 0x2035; + /** + * No non-3GPP subscription is associated with the IMSI. + * The UE is not allowed to use non-3GPP access to EPC. + */ + public static final int IWLAN_NON_3GPP_ACCESS_TO_EPC_NOT_ALLOWED = 0x2328; + /** The user identified by the IMSI is unknown. */ + public static final int IWLAN_USER_UNKNOWN = 0x2329; + /** + * The requested APN is not included in the user's profile, + * and therefore is not authorized for that user. + */ + public static final int IWLAN_NO_APN_SUBSCRIPTION = 0x232A; + /** The user is barred from using the non-3GPP access or the subscribed APN. */ + public static final int IWLAN_AUTHORIZATION_REJECTED = 0x232B; + /** The Mobile Equipment used is not acceptable to the network */ + public static final int IWLAN_ILLEGAL_ME = 0x232E; + /** + * The network has determined that the requested procedure cannot be completed successfully + * due to network failure. + */ + public static final int IWLAN_NETWORK_FAILURE = 0x2904; + /** The access type is restricted to the user. */ + public static final int IWLAN_RAT_TYPE_NOT_ALLOWED = 0x2AF9; + /** The network does not accept emergency PDN bringup request using an IMEI */ + public static final int IWLAN_IMEI_NOT_ACCEPTED = 0x2AFD; + /** + * The ePDG performs PLMN filtering (based on roaming agreements) and rejects + * the request from the UE. + * The UE requests service in a PLMN where the UE is not allowed to operate. + */ + public static final int IWLAN_PLMN_NOT_ALLOWED = 0x2B03; + /** The ePDG does not support un-authenticated IMSI based emergency PDN bringup **/ + public static final int IWLAN_UNAUTHENTICATED_EMERGENCY_NOT_SUPPORTED = 0x2B2F; + + // Device is unable to establish an IPSec tunnel with the ePDG for any reason + // e.g authentication fail or certificate validation or DNS Resolution and timeout failure. + + /** IKE configuration error resulting in failure */ + public static final int IWLAN_IKEV2_CONFIG_FAILURE = 0x4000; + /** + * Sent in the response to an IKE_AUTH message when, for some reason, + * the authentication failed. + */ + public static final int IWLAN_IKEV2_AUTH_FAILURE = 0x4001; + /** IKE message timeout, tunnel setup failed due to no response from EPDG */ + public static final int IWLAN_IKEV2_MSG_TIMEOUT = 0x4002; + /** IKE Certification validation failure */ + public static final int IWLAN_IKEV2_CERT_INVALID = 0x4003; + /** Unable to resolve FQDN for the ePDG to an IP address */ + public static final int IWLAN_DNS_RESOLUTION_NAME_FAILURE = 0x4004; + /** No response received from the DNS Server due to a timeout*/ + public static final int IWLAN_DNS_RESOLUTION_TIMEOUT = 0x4005; // OEM sepecific error codes. To be used by OEMs when they don't // want to reveal error code which would be replaced by ERROR_UNSPECIFIED @@ -1341,6 +1421,35 @@ public final class DataFailCause { sFailCauseMap.put(VSNCP_RECONNECT_NOT_ALLOWED, "VSNCP_RECONNECT_NOT_ALLOWED"); sFailCauseMap.put(IPV6_PREFIX_UNAVAILABLE, "IPV6_PREFIX_UNAVAILABLE"); sFailCauseMap.put(HANDOFF_PREFERENCE_CHANGED, "HANDOFF_PREFERENCE_CHANGED"); + sFailCauseMap.put(SLICE_REJECTED, "SLICE_REJECTED"); + sFailCauseMap.put(IWLAN_PDN_CONNECTION_REJECTION, "IWLAN_PDN_CONNECTION_REJECTION"); + sFailCauseMap.put(IWLAN_MAX_CONNECTION_REACHED, "IWLAN_MAX_CONNECTION_REACHED"); + sFailCauseMap.put(IWLAN_SEMANTIC_ERROR_IN_THE_TFT_OPERATION, + "IWLAN_SEMANTIC_ERROR_IN_THE_TFT_OPERATION"); + sFailCauseMap.put(IWLAN_SYNTACTICAL_ERROR_IN_THE_TFT_OPERATION, + "IWLAN_SYNTACTICAL_ERROR_IN_THE_TFT_OPERATION"); + sFailCauseMap.put(IWLAN_SEMANTIC_ERRORS_IN_PACKET_FILTERS, + "IWLAN_SEMANTIC_ERRORS_IN_PACKET_FILTERS"); + sFailCauseMap.put(IWLAN_SYNTACTICAL_ERRORS_IN_PACKET_FILTERS, + "IWLAN_SYNTACTICAL_ERRORS_IN_PACKET_FILTERS"); + sFailCauseMap.put(IWLAN_NON_3GPP_ACCESS_TO_EPC_NOT_ALLOWED, + "IWLAN_NON_3GPP_ACCESS_TO_EPC_NOT_ALLOWED"); + sFailCauseMap.put(IWLAN_USER_UNKNOWN, "IWLAN_USER_UNKNOWN"); + sFailCauseMap.put(IWLAN_NO_APN_SUBSCRIPTION, "IWLAN_NO_APN_SUBSCRIPTION"); + sFailCauseMap.put(IWLAN_AUTHORIZATION_REJECTED, "IWLAN_AUTHORIZATION_REJECTED"); + sFailCauseMap.put(IWLAN_ILLEGAL_ME, "IWLAN_ILLEGAL_ME"); + sFailCauseMap.put(IWLAN_NETWORK_FAILURE, "IWLAN_NETWORK_FAILURE"); + sFailCauseMap.put(IWLAN_RAT_TYPE_NOT_ALLOWED, "IWLAN_RAT_TYPE_NOT_ALLOWED"); + sFailCauseMap.put(IWLAN_IMEI_NOT_ACCEPTED, "IWLAN_IMEI_NOT_ACCEPTED"); + sFailCauseMap.put(IWLAN_PLMN_NOT_ALLOWED, "IWLAN_PLMN_NOT_ALLOWED"); + sFailCauseMap.put(IWLAN_UNAUTHENTICATED_EMERGENCY_NOT_SUPPORTED, + "IWLAN_UNAUTHENTICATED_EMERGENCY_NOT_SUPPORTED"); + sFailCauseMap.put(IWLAN_IKEV2_CONFIG_FAILURE, "IWLAN_IKEV2_CONFIG_FAILURE"); + sFailCauseMap.put(IWLAN_IKEV2_AUTH_FAILURE, "IWLAN_IKEV2_AUTH_FAILURE"); + sFailCauseMap.put(IWLAN_IKEV2_MSG_TIMEOUT, "IWLAN_IKEV2_MSG_TIMEOUT"); + sFailCauseMap.put(IWLAN_IKEV2_CERT_INVALID, "IWLAN_IKEV2_CERT_INVALID"); + sFailCauseMap.put(IWLAN_DNS_RESOLUTION_NAME_FAILURE, "IWLAN_DNS_RESOLUTION_NAME_FAILURE"); + sFailCauseMap.put(IWLAN_DNS_RESOLUTION_TIMEOUT, "IWLAN_DNS_RESOLUTION_TIMEOUT"); sFailCauseMap.put(OEM_DCFAILCAUSE_1, "OEM_DCFAILCAUSE_1"); sFailCauseMap.put(OEM_DCFAILCAUSE_2, "OEM_DCFAILCAUSE_2"); sFailCauseMap.put(OEM_DCFAILCAUSE_3, "OEM_DCFAILCAUSE_3"); diff --git a/telephony/java/android/telephony/IBootstrapAuthenticationCallback.aidl b/telephony/java/android/telephony/IBootstrapAuthenticationCallback.aidl new file mode 100644 index 000000000000..d39ad0e9a2ef --- /dev/null +++ b/telephony/java/android/telephony/IBootstrapAuthenticationCallback.aidl @@ -0,0 +1,27 @@ +/* + * Copyright 2020 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; + +/** + * Callback to handle the response of bootstrapAuthenticationRequest + * @hide + */ +oneway interface IBootstrapAuthenticationCallback +{ + void onKeysAvailable(int token, in byte[] gbaKey, String btId); + void onAuthenticationFailure(int token, int reason); +} diff --git a/telephony/java/android/telephony/OWNERS b/telephony/java/android/telephony/OWNERS new file mode 100644 index 000000000000..6aa399d9ebfb --- /dev/null +++ b/telephony/java/android/telephony/OWNERS @@ -0,0 +1,5 @@ +# Bug component: 20868 + +rgreenwalt@google.com +tgunn@google.com +amitmahajan@google.com diff --git a/telephony/java/android/telephony/SmsManager.java b/telephony/java/android/telephony/SmsManager.java index e38e357de8a5..5775fbec8e20 100644 --- a/telephony/java/android/telephony/SmsManager.java +++ b/telephony/java/android/telephony/SmsManager.java @@ -3139,26 +3139,20 @@ public final class SmsManager { /** * Reset all cell broadcast ranges. Previously enabled ranges will become invalid after this. - * - * @return {@code true} if succeeded, otherwise {@code false}. - * - * // TODO: Unhide the API in S. * @hide */ - public boolean resetAllCellBroadcastRanges() { - boolean success = false; - + @SystemApi + @RequiresPermission(android.Manifest.permission.MODIFY_CELL_BROADCASTS) + public void resetAllCellBroadcastRanges() { try { ISms iSms = getISmsService(); if (iSms != null) { // If getSubscriptionId() returns INVALID or an inactive subscription, we will use // the default phone internally. - success = iSms.resetAllCellBroadcastRanges(getSubscriptionId()); + iSms.resetAllCellBroadcastRanges(getSubscriptionId()); } } catch (RemoteException ex) { - // ignore it + ex.rethrowFromSystemServer(); } - - return success; } } diff --git a/telephony/java/android/telephony/TelephonyDisplayInfo.java b/telephony/java/android/telephony/TelephonyDisplayInfo.java index 3d5c6aad1042..1fcb504e7895 100644 --- a/telephony/java/android/telephony/TelephonyDisplayInfo.java +++ b/telephony/java/android/telephony/TelephonyDisplayInfo.java @@ -29,6 +29,10 @@ import java.util.Objects; * information is provided in accordance with carrier policy and branding preferences; it is not * necessarily a precise or accurate representation of the current state and should be treated * accordingly. + * To be notified of changes in TelephonyDisplayInfo, use + * {@link TelephonyManager#registerPhoneStateListener} with a {@link PhoneStateListener} + * that implements {@link PhoneStateListener.DisplayInfoChangedListener}. + * Override the onDisplayInfoChanged() method to handle the broadcast. */ public final class TelephonyDisplayInfo implements Parcelable { /** diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java index d8b36791cd9a..8977cc2888a9 100644 --- a/telephony/java/android/telephony/TelephonyManager.java +++ b/telephony/java/android/telephony/TelephonyManager.java @@ -23,6 +23,7 @@ import static android.provider.Telephony.Carriers.INVALID_APN_ID; import static com.android.internal.util.Preconditions.checkNotNull; import android.Manifest; +import android.annotation.BytesLong; import android.annotation.CallbackExecutor; import android.annotation.IntDef; import android.annotation.LongDef; @@ -80,12 +81,14 @@ import android.telephony.Annotation.RadioPowerState; import android.telephony.Annotation.SimActivationState; import android.telephony.Annotation.ThermalMitigationResult; import android.telephony.Annotation.UiccAppType; +import android.telephony.Annotation.UiccAppTypeExt; import android.telephony.CallForwardingInfo.CallForwardingReason; import android.telephony.VisualVoicemailService.VisualVoicemailTask; import android.telephony.data.ApnSetting; import android.telephony.data.ApnSetting.MvnoType; import android.telephony.emergency.EmergencyNumber; import android.telephony.emergency.EmergencyNumber.EmergencyServiceCategories; +import android.telephony.gba.UaSecurityProtocolIdentifier; import android.telephony.ims.ImsMmTelManager; import android.telephony.ims.aidl.IImsConfig; import android.telephony.ims.aidl.IImsRegistration; @@ -124,7 +127,6 @@ import java.util.List; import java.util.Locale; import java.util.Map; import java.util.Objects; -import java.util.Set; import java.util.UUID; import java.util.concurrent.Executor; import java.util.function.Consumer; @@ -549,6 +551,21 @@ public class TelephonyManager { return getPhoneCount() > 1; } + private static final int MAXIMUM_CALL_COMPOSER_PICTURE_SIZE = 80000; + + // TODO(hallliu): link to upload method in docs + /** + * Indicates the maximum size of the call composure picture. + * + * Pictures sent via uploadCallComposerPicture must not exceed this size, or an + * {@link IllegalArgumentException} will be thrown. + * + * @return Maximum file size in bytes. + */ + public static @BytesLong long getMaximumCallComposerPictureSize() { + return MAXIMUM_CALL_COMPOSER_PICTURE_SIZE; + } + // // Broadcast Intent actions // @@ -1499,6 +1516,16 @@ public class TelephonyManager { public static final int EXTRA_DEFAULT_SUBSCRIPTION_SELECT_TYPE_ALL = 4; /** + * Used as an int value for {@link #EXTRA_DEFAULT_SUBSCRIPTION_SELECT_TYPE} + * to indicate that default subscription for data/sms/voice is now determined, that + * it should dismiss any dialog or pop-ups that is asking user to select default sub. + * This is used when, for example, opportunistic subscription is configured. At that + * time the primary becomes default sub there's no need to ask user to select anymore. + * @hide + */ + public static final int EXTRA_DEFAULT_SUBSCRIPTION_SELECT_TYPE_DISMISS = 5; + + /** * Integer intent extra to be used with {@link #ACTION_PRIMARY_SUBSCRIPTION_LIST_CHANGED} * to indicate if the SIM combination in DSDS has limitation or compatible issue. * e.g. two CDMA SIMs may disrupt each other's voice call in certain scenarios. @@ -2010,6 +2037,8 @@ public class TelephonyManager { * 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> * * <p>If the calling app does not meet one of these requirements then this method will behave @@ -4023,6 +4052,8 @@ public class TelephonyManager { * <li>If the calling app has carrier privileges (see {@link #hasCarrierPrivileges}). * <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> * * <p>If the calling app does not meet one of these requirements then this method will behave @@ -4047,33 +4078,8 @@ public class TelephonyManager { * for a subscription. * Return null if it is unavailable. * - * <p>Starting with API level 29, persistent device identifiers are guarded behind additional - * restrictions, and apps are recommended to use resettable identifiers (see <a - * href="/training/articles/user-data-ids">Best practices for unique identifiers</a>). This - * method can be invoked if one of the following requirements is met: - * <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 or profile owner and has been granted the - * {@link Manifest.permission#READ_PHONE_STATE} permission. 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>. - * Profile owner access is deprecated and will be removed in a future release. - * <li>If the calling app has carrier privileges (see {@link #hasCarrierPrivileges}). - * <li>If the calling app is the default SMS role holder (see {@link - * RoleManager#isRoleHeld(String)}). - * </ul> - * - * <p>If the calling app does not meet one of these requirements then this method will behave - * as follows: - * - * <ul> - * <li>If the calling app's target SDK is API level 28 or lower and the app has the - * READ_PHONE_STATE permission then null is returned.</li> - * <li>If the calling app's target SDK is API level 28 or lower and the app does not have - * the READ_PHONE_STATE permission, or if the calling app is targeting API level 29 or - * higher, then a SecurityException is thrown.</li> - * </ul> + * See {@link #getSubscriberId()} for details on the required permissions and behavior + * when the caller does not hold sufficient permissions. * * @param subId whose subscriber id is returned * @hide @@ -5600,57 +5606,6 @@ public class TelephonyManager { } } - /** - * Registers a listener object to receive notification of changes - * in specified telephony states. - * <p> - * To register a listener, pass a {@link PhoneStateListener} and specify at least one telephony - * state of interest in the events argument. - * - * At registration, and when a specified telephony state changes, the telephony manager invokes - * the appropriate callback method on the listener object and passes the current (updated) - * values. - * <p> - * To un-register a listener, pass the listener object and set the events argument to - * {@link PhoneStateListener#LISTEN_NONE LISTEN_NONE} (0). - * - * If this TelephonyManager object has been created with {@link #createForSubscriptionId}, - * applies to the given subId. Otherwise, applies to - * {@link SubscriptionManager#getDefaultSubscriptionId()}. To listen events for multiple subIds, - * pass a separate listener object to each TelephonyManager object created with - * {@link #createForSubscriptionId}. - * - * Note: if you call this method while in the middle of a binder transaction, you <b>must</b> - * call {@link android.os.Binder#clearCallingIdentity()} before calling this method. A - * {@link SecurityException} will be thrown otherwise. - * - * This API should be used sparingly -- large numbers of listeners will cause system - * instability. If a process has registered too many listeners without unregistering them, it - * may encounter an {@link IllegalStateException} when trying to register more listeners. - * - * @param events The telephony state(s) of interest to the listener, - * as a bitwise-OR combination of {@link PhoneStateListener} - * LISTEN_ flags. - * @param listener The {@link PhoneStateListener} object to register - * (or unregister) - * @deprecated Use {@link #registerPhoneStateListener(Executor, PhoneStateListener)}. - */ - @Deprecated - public void listen(long events, @NonNull PhoneStateListener listener) { - mTelephonyRegistryMgr = mContext.getSystemService(TelephonyRegistryManager.class); - if (mTelephonyRegistryMgr != null) { - if (events != PhoneStateListener.LISTEN_NONE) { - mTelephonyRegistryMgr.registerPhoneStateListenerWithEvents(mSubId, - getOpPackageName(), getAttributionTag(), listener, - Long.valueOf(events).intValue(), getITelephony() != null); - } else { - unregisterPhoneStateListener(listener); - } - } else { - throw new IllegalStateException("telephony service is null."); - } - } - /** @hide */ @Retention(RetentionPolicy.SOURCE) @IntDef(prefix = {"ERI_"}, value = { @@ -7210,6 +7165,8 @@ public class TelephonyManager { } } + /** UICC application type is unknown or not specified */ + public static final int APPTYPE_UNKNOWN = PhoneConstants.APPTYPE_UNKNOWN; /** UICC application type is SIM */ public static final int APPTYPE_SIM = PhoneConstants.APPTYPE_SIM; /** UICC application type is USIM */ @@ -7232,8 +7189,13 @@ public class TelephonyManager { * Returns the response of authentication for the default subscription. * Returns null if the authentication hasn't been successful * - * <p>Requires Permission: READ_PRIVILEGED_PHONE_STATE or that the calling - * app has carrier privileges (see {@link #hasCarrierPrivileges}). + * <p>Requires one of the following permissions: + * <ul> + * <li>READ_PRIVILEGED_PHONE_STATE + * <li>the calling app has carrier privileges (see {@link #hasCarrierPrivileges}). + * <li>the calling app has been granted the + * {@link Manifest.permission#USE_ICC_AUTH_WITH_DEVICE_IDENTIFIER} permission. + * </ul> * * @param appType the icc application type, like {@link #APPTYPE_USIM} * @param authType the authentication type, {@link #AUTHTYPE_EAP_AKA} or @@ -7258,7 +7220,8 @@ public class TelephonyManager { * Returns the response of USIM Authentication for specified subId. * Returns null if the authentication hasn't been successful * - * <p>Requires that the calling app has carrier privileges (see {@link #hasCarrierPrivileges}). + * <p>See {@link #getIccAuthentication(int, int, String)} for details on the required + * permissions. * * @param subId subscription ID used for authentication * @param appType the icc application type, like {@link #APPTYPE_USIM} @@ -7281,7 +7244,8 @@ public class TelephonyManager { IPhoneSubInfo info = getSubscriberInfoService(); if (info == null) return null; - return info.getIccSimChallengeResponse(subId, appType, authType, data); + return info.getIccSimChallengeResponse(subId, appType, authType, data, + getOpPackageName(), getAttributionTag()); } catch (RemoteException ex) { return null; } catch (NullPointerException ex) { @@ -8713,6 +8677,77 @@ public class TelephonyManager { return Collections.EMPTY_LIST; } + /** + * Call composer status OFF from user setting. + */ + public static final int CALL_COMPOSER_STATUS_OFF = 0; + + /** + * Call composer status ON from user setting. + */ + public static final int CALL_COMPOSER_STATUS_ON = 1; + + /** @hide */ + @IntDef(prefix = {"CALL_COMPOSER_STATUS_"}, + value = { + CALL_COMPOSER_STATUS_ON, + CALL_COMPOSER_STATUS_OFF, + }) + public @interface CallComposerStatus {} + + /** + * Set the user-set status for enriched calling with call composer. + * + * @param status user-set status for enriched calling with call composer; + * it must be a value of either {@link #CALL_COMPOSER_STATUS_ON} + * or {@link #CALL_COMPOSER_STATUS_OFF}. + * + * <p>If this object has been created with {@link #createForSubscriptionId}, applies to the + * given subId. Otherwise, applies to {@link SubscriptionManager#getDefaultSubscriptionId()} + * + * @throws IllegalArgumentException if requested state is invalid. + * @throws SecurityException if the caller does not have the permission. + */ + @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) + public void setCallComposerStatus(@CallComposerStatus int status) { + if (status != CALL_COMPOSER_STATUS_ON && status != CALL_COMPOSER_STATUS_OFF) { + throw new IllegalArgumentException("requested status is invalid"); + } + try { + ITelephony telephony = getITelephony(); + if (telephony != null) { + telephony.setCallComposerStatus(getSubId(), status); + } + } catch (RemoteException ex) { + Log.e(TAG, "Error calling ITelephony#setCallComposerStatus", ex); + ex.rethrowFromSystemServer(); + } + } + + /** + * Get the user-set status for enriched calling with call composer. + * + * <p>If this object has been created with {@link #createForSubscriptionId}, applies to the + * given subId. Otherwise, applies to {@link SubscriptionManager#getDefaultSubscriptionId()} + * + * @throws SecurityException if the caller does not have the permission. + * + * @return the user-set status for enriched calling with call composer either + * {@link #CALL_COMPOSER_STATUS_ON} or {@link #CALL_COMPOSER_STATUS_OFF}. + */ + @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) + public @CallComposerStatus int getCallComposerStatus() { + try { + ITelephony telephony = getITelephony(); + if (telephony != null) { + return telephony.getCallComposerStatus(getSubId()); + } + } catch (RemoteException ex) { + Log.e(TAG, "Error calling ITelephony#getCallComposerStatus", ex); + ex.rethrowFromSystemServer(); + } + return CALL_COMPOSER_STATUS_OFF; + } /** @hide */ @SystemApi @@ -9309,6 +9344,35 @@ public class TelephonyManager { } /** + * Get the mobile provisioning url that is used to launch a browser to allow users to manage + * their mobile plan. + * + * <p>Requires Permission: + * {@link android.Manifest.permission#READ_PRIVILEGED_PHONE_STATE}. + * + * TODO: The legacy design only supports single sim design. Ideally, this should support + * multi-sim design in current world. + * + * {@hide} + */ + @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) + public @Nullable String getMobileProvisioningUrl() { + try { + final ITelephony service = getITelephony(); + if (service != null) { + return service.getMobileProvisioningUrl(); + } else { + throw new IllegalStateException("telephony service is null."); + } + } catch (RemoteException ex) { + if (!isSystemProcess()) { + ex.rethrowAsRuntimeException(); + } + } + return null; + } + + /** * Turns mobile data on or off. * If this object has been created with {@link #createForSubscriptionId}, applies to the given * subId. Otherwise, applies to {@link SubscriptionManager#getDefaultDataSubscriptionId()} @@ -10029,6 +10093,16 @@ public class TelephonyManager { */ public static final int CARD_POWER_UP_PASS_THROUGH = 2; + /** @hide */ + @Retention(RetentionPolicy.SOURCE) + @IntDef(prefix = {"CARD_POWER"}, + value = { + CARD_POWER_DOWN, + CARD_POWER_UP, + CARD_POWER_UP_PASS_THROUGH, + }) + public @interface SimPowerState {} + /** * Set SIM card power state. * @@ -10039,12 +10113,17 @@ public class TelephonyManager { * Callers should monitor for {@link TelephonyIntents#ACTION_SIM_STATE_CHANGED} * broadcasts to determine success or failure and timeout if needed. * + * @deprecated prefer {@link setSimPowerState(int, Executor, Consumer<Integer>)}. + * There is no guarantee that SIM power changes will trigger ACTION_SIM_STATE_CHANGED on new + * devices. + * * <p>Requires Permission: * {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE} * * {@hide} **/ @SystemApi + @Deprecated @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setSimPowerState(int state) { setSimPowerStateForSlot(getSlotIndex(), state); @@ -10061,12 +10140,16 @@ public class TelephonyManager { * Callers should monitor for {@link TelephonyIntents#ACTION_SIM_STATE_CHANGED} * broadcasts to determine success or failure and timeout if needed. * + * @deprecated prefer {@link setSimPowerStateForSlot(int, int, Executor, Consumer<Integer>)}. + * changes will trigger ACTION_SIM_STATE_CHANGED on new devices. + * * <p>Requires Permission: * {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE} * * {@hide} **/ @SystemApi + @Deprecated @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setSimPowerStateForSlot(int slotIndex, int state) { try { @@ -10082,6 +10165,85 @@ public class TelephonyManager { } /** + * Set SIM card power state. + * + * @param state State of SIM (power down, power up, pass through) + * @see #CARD_POWER_DOWN + * @see #CARD_POWER_UP + * @see #CARD_POWER_UP_PASS_THROUGH + * @param executor The executor of where the callback will execute. + * @param callback Callback will be triggered once it succeeds or failed. + * @see #SET_SIM_POWER_STATE_SUCCESS + * @see #SET_SIM_POWER_STATE_ALREADY_IN_STATE + * @see #SET_SIM_POWER_STATE_MODEM_ERROR + * @see #SET_SIM_POWER_STATE_SIM_ERROR + * @see #SET_SIM_POWER_STATE_NOT_SUPPORTED + * @throws IllegalArgumentException if requested SIM state is invalid + * + * <p>Requires Permission: + * {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE} + * + * {@hide} + **/ + @SystemApi + @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) + public void setSimPowerState(@SimPowerState int state, @NonNull Executor executor, + @NonNull @SetSimPowerStateResult Consumer<Integer> callback) { + setSimPowerStateForSlot(getSlotIndex(), state, executor, callback); + } + + /** + * Set SIM card power state. + * + * @param slotIndex SIM slot id + * @param state State of SIM (power down, power up, pass through) + * @see #CARD_POWER_DOWN + * @see #CARD_POWER_UP + * @see #CARD_POWER_UP_PASS_THROUGH + * @param executor The executor of where the callback will execute. + * @param callback Callback will be triggered once it succeeds or failed. + * @see #SET_SIM_POWER_STATE_SUCCESS + * @see #SET_SIM_POWER_STATE_ALREADY_IN_STATE + * @see #SET_SIM_POWER_STATE_MODEM_ERROR + * @see #SET_SIM_POWER_STATE_SIM_ERROR + * @see #SET_SIM_POWER_STATE_NOT_SUPPORTED + * @throws IllegalArgumentException if requested SIM state is invalid + * + * <p>Requires Permission: + * {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE} + * + * {@hide} + **/ + @SystemApi + @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) + public void setSimPowerStateForSlot(int slotIndex, @SimPowerState int state, + @NonNull Executor executor, + @NonNull @SetSimPowerStateResult Consumer<Integer> callback) { + if (state != CARD_POWER_DOWN && state != CARD_POWER_UP + && state != CARD_POWER_UP_PASS_THROUGH) { + throw new IllegalArgumentException("requested SIM state is invalid"); + } + try { + ITelephony telephony = getITelephony(); + IIntegerConsumer internalCallback = new IIntegerConsumer.Stub() { + @Override + public void accept(int result) { + executor.execute(() -> + Binder.withCleanCallingIdentity(() -> callback.accept(result))); + } + }; + if (telephony != null) { + telephony.setSimPowerStateForSlotWithCallback(slotIndex, state, internalCallback); + } + } catch (RemoteException e) { + Log.e(TAG, "Error calling ITelephony#setSimPowerStateForSlot", e); + } catch (SecurityException e) { + Log.e(TAG, "Permission error calling ITelephony#setSimPowerStateForSlot", + e); + } + } + + /** * Set baseband version for the default phone. * * @param version baseband version @@ -11200,6 +11362,55 @@ public class TelephonyManager { public @interface SetCarrierRestrictionResult {} /** + * The SIM power state was successfully set. + * @hide + */ + @SystemApi + public static final int SET_SIM_POWER_STATE_SUCCESS = 0; + + /** + * The SIM is already in the requested power state. + * @hide + */ + @SystemApi + public static final int SET_SIM_POWER_STATE_ALREADY_IN_STATE = 1; + + /** + * Failed to connect to the modem to make the power state request. This may happen if the + * modem has an error. The user may want to make the request again later. + * @hide + */ + @SystemApi + public static final int SET_SIM_POWER_STATE_MODEM_ERROR = 2; + + /** + * Failed to connect to the SIM to make the power state request. This may happen if the + * SIM has been removed. The user may want to make the request again later. + * @hide + */ + @SystemApi + public static final int SET_SIM_POWER_STATE_SIM_ERROR = 3; + + /** + * The modem version does not support synchronous power. + * @hide + */ + @SystemApi + public static final int SET_SIM_POWER_STATE_NOT_SUPPORTED = 4; + + /** @hide */ + @Retention(RetentionPolicy.SOURCE) + @IntDef(prefix = {"SET_SIM_POWER_STATE_"}, + value = { + SET_SIM_POWER_STATE_SUCCESS, + SET_SIM_POWER_STATE_ALREADY_IN_STATE, + SET_SIM_POWER_STATE_MODEM_ERROR, + SET_SIM_POWER_STATE_SIM_ERROR, + SET_SIM_POWER_STATE_NOT_SUPPORTED + }) + public @interface SetSimPowerStateResult {} + + /** * Set the allowed carrier list and the excluded carrier list indicating the priority between * the two lists. * Requires system privileges. @@ -13821,7 +14032,8 @@ public class TelephonyManager { /** * Get carrier bandwidth. In case of Dual connected network this will report - * bandwidth per primary and secondary network. + * bandwidth per primary and secondary network. It is possible that + * some modems may not fill secondary carrier bandwidth. * @return CarrierBandwidth with bandwidth of both primary and secondary carrier. * @throws IllegalStateException if the Telephony process is not currently available. * @hide @@ -14421,4 +14633,173 @@ public class TelephonyManager { throw new IllegalStateException("telephony service is null."); } } + + /** @hide */ + @Retention(RetentionPolicy.SOURCE) + @IntDef(prefix = {"GBA_FAILURE_REASON_"}, value = { + GBA_FAILURE_REASON_UNKNOWN, + GBA_FAILURE_REASON_FEATURE_NOT_SUPPORTED, + GBA_FAILURE_REASON_FEATURE_NOT_READY, + GBA_FAILURE_REASON_NETWORK_FAILURE, + GBA_FAILURE_REASON_INCORRECT_NAF_ID, + GBA_FAILURE_REASON_SECURITY_PROTOCOL_NOT_SUPPORTED}) + public @interface AuthenticationFailureReason {} + + /** + * GBA Authentication has failed for an unknown reason. + * + * <p>The caller should retry a message that failed with this response. + * @hide + */ + @SystemApi + public static final int GBA_FAILURE_REASON_UNKNOWN = 0; + + /** + * GBA Authentication is not supported by the carrier, SIM or android. + * + * <p>Application should use other authentication mechanisms if possible. + * @hide + */ + @SystemApi + public static final int GBA_FAILURE_REASON_FEATURE_NOT_SUPPORTED = 1; + + /** + * GBA Authentication service is not ready for use. + * + * <p>Application could try again at a later time. + * @hide + */ + @SystemApi + public static final int GBA_FAILURE_REASON_FEATURE_NOT_READY = 2; + + /** + * GBA Authentication has been failed by the network. + * @hide + */ + @SystemApi + public static final int GBA_FAILURE_REASON_NETWORK_FAILURE = 3; + + /** + * GBA Authentication has failed due to incorrect NAF URL. + * @hide + */ + @SystemApi + public static final int GBA_FAILURE_REASON_INCORRECT_NAF_ID = 4; + + /** + * GBA Authentication has failed due to unsupported security protocol + * @hide + */ + @SystemApi + public static final int GBA_FAILURE_REASON_SECURITY_PROTOCOL_NOT_SUPPORTED = 5; + + /** + * The callback associated with a {@link #bootstrapAuthenticationRequest()}. + * @hide + */ + @SystemApi + public static class BootstrapAuthenticationCallback { + + /** + * Invoked when the previously requested GBA keys are available (@see + * bootstrapAuthenticationRequest()). + * @param gbaKey Ks_NAF/Ks_ext_NAF Response + * @param transactionId Bootstrapping Transaction Identifier + */ + public void onKeysAvailable(@NonNull byte[] gbaKey, @NonNull String transactionId) {} + + /** + * @param reason The reason for the authentication failure. + */ + public void onAuthenticationFailure(@AuthenticationFailureReason int reason) {} + } + + /** + * Used to get the Generic Bootstrapping Architecture authentication keys + * KsNAF/Ks_ext_NAF for a particular NAF as defined in 3GPP spec TS 33.220 for + * the specified sub id. + * + * <p>Application must be prepared to wait for receiving the Gba keys through the + * registered callback and not invoke the API on the main application thread. + * Application also must call the api to get the fresh key every time instead + * of caching the key. + * + * Following steps may be invoked on the API call depending on the state of the + * underlying GBA implementation: + * <ol> + * <li>Resolve and bind to a Gba implementation.</li> + * <li>Run bootstrapping if no valid keys are available or bootstrapping is forced.</li> + * <li>Generate the ks_NAF/ ks_Ext_NAF to be returned via the callback.</li> + * </ol> + * + * <p> Requires Permission: MODIFY_PHONE_STATE or that the calling app has carrier + * privileges (see {@link #hasCarrierPrivileges}). + * @param appType icc application type, like {@link #APPTYPE_USIM} or {@link + * #APPTYPE_ISIM} or {@link#APPTYPE_UNKNOWN} + * @param nafId Network Application Function(NAF) fully qualified domain name and + * the selected GBA mode. It shall contain two parts delimited by "@" sign. The first + * part is the constant string "3GPP-bootstrapping" (GBA_ME), + * "3GPP-bootstrapping-uicc" (GBA_ U), or "3GPP-bootstrapping-digest" (GBA_Digest), + * and the latter part shall be the FQDN of the NAF (e.g. + * "3GPP-bootstrapping@naf1.operator.com" or "3GPP-bootstrapping-uicc@naf1.operator.com", + * or "3GPP-bootstrapping-digest@naf1.operator.com"). + * @param securityProtocol Security protocol identifier between UE and NAF. See + * 3GPP TS 33.220 Annex H. Application can use + * {@link UaSecurityProtocolIdentifier#createDefaultUaSpId}, + * {@link UaSecurityProtocolIdentifier#create3GppUaSpId}, + * to create the ua security protocol identifier as needed + * @param forceBootStrapping true=force bootstrapping, false=do not force + * bootstrapping. Bootstrapping shouldn't be forced unless the application sees + * authentication errors from the server. + * @param e The {@link Executor} that will be used to call the Gba callback. + * @param callback A callback called on the supplied {@link Executor} that will + * contain the GBA Ks_NAF/Ks_ext_NAF when available. If the NAF keys are + * available and valid at the time of call and bootstrapping is not requested, + * then the callback shall be invoked with the available keys. + * @hide + */ + @SystemApi + @WorkerThread + @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) + public void bootstrapAuthenticationRequest( + @UiccAppTypeExt int appType, @NonNull Uri nafId, + @NonNull UaSecurityProtocolIdentifier securityProtocol, + boolean forceBootStrapping, @NonNull Executor e, + @NonNull BootstrapAuthenticationCallback callback) { + try { + ITelephony service = getITelephony(); + if (service == null) { + e.execute(() -> callback.onAuthenticationFailure( + GBA_FAILURE_REASON_FEATURE_NOT_READY)); + return; + } + service.bootstrapAuthenticationRequest( + getSubId(), appType, nafId, securityProtocol, forceBootStrapping, + new IBootstrapAuthenticationCallback.Stub() { + @Override + public void onKeysAvailable(int token, byte[] gbaKey, + String transactionId) { + final long identity = Binder.clearCallingIdentity(); + try { + e.execute(() -> callback.onKeysAvailable(gbaKey, transactionId)); + } finally { + Binder.restoreCallingIdentity(identity); + } + } + + @Override + public void onAuthenticationFailure(int token, int reason) { + final long identity = Binder.clearCallingIdentity(); + try { + e.execute(() -> callback.onAuthenticationFailure(reason)); + } finally { + Binder.restoreCallingIdentity(identity); + } + } + }); + } catch (RemoteException exception) { + Log.e(TAG, "Error calling ITelephony#bootstrapAuthenticationRequest", exception); + e.execute(() -> callback.onAuthenticationFailure(GBA_FAILURE_REASON_FEATURE_NOT_READY)); + } + } } diff --git a/telephony/java/android/telephony/cdma/OWNERS b/telephony/java/android/telephony/cdma/OWNERS new file mode 100644 index 000000000000..6aa399d9ebfb --- /dev/null +++ b/telephony/java/android/telephony/cdma/OWNERS @@ -0,0 +1,5 @@ +# Bug component: 20868 + +rgreenwalt@google.com +tgunn@google.com +amitmahajan@google.com diff --git a/telephony/java/android/telephony/data/ApnThrottleStatus.java b/telephony/java/android/telephony/data/ApnThrottleStatus.java index 51461d17690a..eec140869466 100644 --- a/telephony/java/android/telephony/data/ApnThrottleStatus.java +++ b/telephony/java/android/telephony/data/ApnThrottleStatus.java @@ -261,6 +261,10 @@ public final class ApnThrottleStatus implements Parcelable { private long mThrottleExpiryTimeMillis; private @RetryType int mRetryType; private @ThrottleType int mThrottleType; + + /** + * @hide + */ public static final long NO_THROTTLE_EXPIRY_TIME = DataCallResponse.RETRY_DURATION_UNDEFINED; diff --git a/telephony/java/android/telephony/data/DataCallResponse.java b/telephony/java/android/telephony/data/DataCallResponse.java index 090c970c2b53..e217e9af992c 100644 --- a/telephony/java/android/telephony/data/DataCallResponse.java +++ b/telephony/java/android/telephony/data/DataCallResponse.java @@ -137,6 +137,7 @@ public final class DataCallResponse implements Parcelable { private final int mPduSessionId; private final Qos mDefaultQos; private final List<QosSession> mQosSessions; + private final SliceInfo mSliceInfo; /** * @param cause Data call fail cause. {@link DataFailCause#NONE} indicates no error. @@ -187,6 +188,7 @@ public final class DataCallResponse implements Parcelable { mPduSessionId = PDU_SESSION_ID_NOT_SET; mDefaultQos = null; mQosSessions = new ArrayList<>(); + mSliceInfo = null; } private DataCallResponse(@DataFailureCause int cause, long suggestedRetryTime, int id, @@ -195,7 +197,8 @@ public final class DataCallResponse implements Parcelable { @Nullable List<InetAddress> dnsAddresses, @Nullable List<InetAddress> gatewayAddresses, @Nullable List<InetAddress> pcscfAddresses, int mtu, int mtuV4, int mtuV6, @HandoverFailureMode int handoverFailureMode, int pduSessionId, - @Nullable Qos defaultQos, @Nullable List<QosSession> qosSessions) { + @Nullable Qos defaultQos, @Nullable List<QosSession> qosSessions, + @Nullable SliceInfo sliceInfo) { mCause = cause; mSuggestedRetryTime = suggestedRetryTime; mId = id; @@ -217,6 +220,7 @@ public final class DataCallResponse implements Parcelable { mPduSessionId = pduSessionId; mDefaultQos = defaultQos; mQosSessions = qosSessions; + mSliceInfo = sliceInfo; } /** @hide */ @@ -244,6 +248,7 @@ public final class DataCallResponse implements Parcelable { mDefaultQos = source.readParcelable(Qos.class.getClassLoader()); mQosSessions = new ArrayList<>(); source.readList(mQosSessions, QosSession.class.getClassLoader()); + mSliceInfo = source.readParcelable(SliceInfo.class.getClassLoader()); } /** @@ -253,7 +258,9 @@ public final class DataCallResponse implements Parcelable { public int getCause() { return mCause; } /** - * @return The suggested data retry time in milliseconds. + * @return The suggested data retry time in milliseconds. 0 when network does not + * suggest a retry time (Note this is different from the replacement + * {@link #getRetryDurationMillis()}). * * @deprecated Use {@link #getRetryDurationMillis()} instead. */ @@ -368,7 +375,7 @@ public final class DataCallResponse implements Parcelable { } /** - * @return default QOS of the data call received from the network + * @return default QOS of the data connection received from the network * * @hide */ @@ -379,16 +386,24 @@ public final class DataCallResponse implements Parcelable { } /** - * @return All the dedicated bearer QOS sessions of the data call received from the network + * @return All the dedicated bearer QOS sessions of the data connection received from the + * network. * * @hide */ - @NonNull public List<QosSession> getQosSessions() { return mQosSessions; } + /** + * @return The slice info related to this data connection. + */ + @Nullable + public SliceInfo getSliceInfo() { + return mSliceInfo; + } + @NonNull @Override public String toString() { @@ -411,6 +426,7 @@ public final class DataCallResponse implements Parcelable { .append(" pduSessionId=").append(getPduSessionId()) .append(" defaultQos=").append(mDefaultQos) .append(" qosSessions=").append(mQosSessions) + .append(" sliceInfo=").append(mSliceInfo) .append("}"); return sb.toString(); } @@ -454,7 +470,8 @@ public final class DataCallResponse implements Parcelable { && mHandoverFailureMode == other.mHandoverFailureMode && mPduSessionId == other.mPduSessionId && isQosSame - && isQosSessionsSame; + && isQosSessionsSame + && Objects.equals(mSliceInfo, other.mSliceInfo); } @Override @@ -462,7 +479,7 @@ public final class DataCallResponse implements Parcelable { return Objects.hash(mCause, mSuggestedRetryTime, mId, mLinkStatus, mProtocolType, mInterfaceName, mAddresses, mDnsAddresses, mGatewayAddresses, mPcscfAddresses, mMtu, mMtuV4, mMtuV6, mHandoverFailureMode, mPduSessionId, mDefaultQos, - mQosSessions); + mQosSessions, mSliceInfo); } @Override @@ -497,6 +514,7 @@ public final class DataCallResponse implements Parcelable { dest.writeParcelable(null, flags); } dest.writeList(mQosSessions); + dest.writeParcelable(mSliceInfo, flags); } public static final @android.annotation.NonNull Parcelable.Creator<DataCallResponse> CREATOR = @@ -580,6 +598,8 @@ public final class DataCallResponse implements Parcelable { private List<QosSession> mQosSessions = new ArrayList<>(); + private SliceInfo mSliceInfo; + /** * Default constructor for Builder. */ @@ -803,6 +823,21 @@ public final class DataCallResponse implements Parcelable { } /** + * The Slice used for this data connection. + * <p/> + * If a handover occurs from EPDG to 5G, + * this is the {@link SliceInfo} used in {@link DataService#setupDataCall}. + * + * @param sliceInfo the slice info for the data call + * + * @return The same instance of the builder. + */ + public @NonNull Builder setSliceInfo(@Nullable SliceInfo sliceInfo) { + mSliceInfo = sliceInfo; + return this; + } + + /** * Build the DataCallResponse. * * @return the DataCallResponse object. @@ -811,7 +846,7 @@ public final class DataCallResponse implements Parcelable { return new DataCallResponse(mCause, mSuggestedRetryTime, mId, mLinkStatus, mProtocolType, mInterfaceName, mAddresses, mDnsAddresses, mGatewayAddresses, mPcscfAddresses, mMtu, mMtuV4, mMtuV6, mHandoverFailureMode, mPduSessionId, - mDefaultQos, mQosSessions); + mDefaultQos, mQosSessions, mSliceInfo); } } } diff --git a/telephony/java/android/telephony/data/DataService.java b/telephony/java/android/telephony/data/DataService.java index 2ec965101930..03c2ef9d9baa 100644 --- a/telephony/java/android/telephony/data/DataService.java +++ b/telephony/java/android/telephony/data/DataService.java @@ -194,13 +194,19 @@ public abstract class DataService extends Service { * The standard range of values are 1-15 while 0 means no pdu session id * was attached to this call. Reference: 3GPP TS 24.007 section * 11.2.3.1b. + * @param sliceInfo used within the data connection when a handover occurs from EPDG to 5G. + * The value is null unless the access network is + * {@link android.telephony.AccessNetworkConstants.AccessNetworkType#NGRAN} and a + * handover is occurring from EPDG to 5G. If the slice passed is rejected, then + * {@link DataCallResponse#getCause()} is + * {@link android.telephony.DataFailCause#SLICE_REJECTED}. * @param callback The result callback for this request. */ public void setupDataCall(int accessNetworkType, @NonNull DataProfile dataProfile, boolean isRoaming, boolean allowRoaming, @SetupDataReason int reason, @Nullable LinkProperties linkProperties, - @IntRange(from = 0, to = 15) int pduSessionId, + @IntRange(from = 0, to = 15) int pduSessionId, @Nullable SliceInfo sliceInfo, @NonNull DataServiceCallback callback) { /* Call the old version since the new version isn't supported */ setupDataCall(accessNetworkType, dataProfile, isRoaming, allowRoaming, reason, @@ -392,10 +398,11 @@ public abstract class DataService extends Service { public final int reason; public final LinkProperties linkProperties; public final int pduSessionId; + public final SliceInfo sliceInfo; public final IDataServiceCallback callback; SetupDataCallRequest(int accessNetworkType, DataProfile dataProfile, boolean isRoaming, boolean allowRoaming, int reason, LinkProperties linkProperties, - int pduSessionId, IDataServiceCallback callback) { + int pduSessionId, SliceInfo sliceInfo, IDataServiceCallback callback) { this.accessNetworkType = accessNetworkType; this.dataProfile = dataProfile; this.isRoaming = isRoaming; @@ -403,6 +410,7 @@ public abstract class DataService extends Service { this.linkProperties = linkProperties; this.reason = reason; this.pduSessionId = pduSessionId; + this.sliceInfo = sliceInfo; this.callback = callback; } } @@ -513,6 +521,7 @@ public abstract class DataService extends Service { setupDataCallRequest.dataProfile, setupDataCallRequest.isRoaming, setupDataCallRequest.allowRoaming, setupDataCallRequest.reason, setupDataCallRequest.linkProperties, setupDataCallRequest.pduSessionId, + setupDataCallRequest.sliceInfo, (setupDataCallRequest.callback != null) ? new DataServiceCallback(setupDataCallRequest.callback) : null); @@ -676,10 +685,12 @@ public abstract class DataService extends Service { @Override public void setupDataCall(int slotIndex, int accessNetworkType, DataProfile dataProfile, boolean isRoaming, boolean allowRoaming, int reason, - LinkProperties linkProperties, int pduSessionId, IDataServiceCallback callback) { + LinkProperties linkProperties, int pduSessionId, SliceInfo sliceInfo, + IDataServiceCallback callback) { mHandler.obtainMessage(DATA_SERVICE_REQUEST_SETUP_DATA_CALL, slotIndex, 0, new SetupDataCallRequest(accessNetworkType, dataProfile, isRoaming, - allowRoaming, reason, linkProperties, pduSessionId, callback)) + allowRoaming, reason, linkProperties, pduSessionId, sliceInfo, + callback)) .sendToTarget(); } diff --git a/telephony/java/android/telephony/data/IDataService.aidl b/telephony/java/android/telephony/data/IDataService.aidl index 3f1f033d6f11..e0b9a1a9bb5a 100644 --- a/telephony/java/android/telephony/data/IDataService.aidl +++ b/telephony/java/android/telephony/data/IDataService.aidl @@ -19,6 +19,7 @@ package android.telephony.data; import android.net.LinkProperties; import android.telephony.data.DataProfile; import android.telephony.data.IDataServiceCallback; +import android.telephony.data.SliceInfo; /** * {@hide} @@ -29,7 +30,7 @@ oneway interface IDataService void removeDataServiceProvider(int slotId); void setupDataCall(int slotId, int accessNetwork, in DataProfile dataProfile, boolean isRoaming, boolean allowRoaming, int reason, in LinkProperties linkProperties, - int pduSessionId, IDataServiceCallback callback); + int pduSessionId, in SliceInfo sliceInfo, IDataServiceCallback callback); void deactivateDataCall(int slotId, int cid, int reason, IDataServiceCallback callback); void setInitialAttachApn(int slotId, in DataProfile dataProfile, boolean isRoaming, IDataServiceCallback callback); diff --git a/telephony/java/android/telephony/data/OWNERS b/telephony/java/android/telephony/data/OWNERS new file mode 100644 index 000000000000..932b35cbdff7 --- /dev/null +++ b/telephony/java/android/telephony/data/OWNERS @@ -0,0 +1,5 @@ +# Bug component: 20868 + +rgreenwalt@google.com +tgunn@google.com +jackyu@google.com diff --git a/telephony/java/android/telephony/data/SliceInfo.aidl b/telephony/java/android/telephony/data/SliceInfo.aidl new file mode 100644 index 000000000000..286ea5e4f8c7 --- /dev/null +++ b/telephony/java/android/telephony/data/SliceInfo.aidl @@ -0,0 +1,20 @@ +/* + * Copyright 2020 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. + */ + +/** @hide */ +package android.telephony.data; + +parcelable SliceInfo; diff --git a/telephony/java/android/telephony/data/SliceInfo.java b/telephony/java/android/telephony/data/SliceInfo.java new file mode 100644 index 000000000000..51857a7b4908 --- /dev/null +++ b/telephony/java/android/telephony/data/SliceInfo.java @@ -0,0 +1,342 @@ +/* + * Copyright (C) 2020 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.data; + +import android.annotation.IntDef; +import android.annotation.IntRange; +import android.annotation.NonNull; +import android.annotation.SuppressLint; +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; + +/** + * Represents a S-NSSAI as defined in 3GPP TS 24.501. + * + * @hide + */ +@SystemApi +public final class SliceInfo implements Parcelable { + /** + * When set on a Slice Differentiator, this value indicates that there is no corresponding + * Slice. + */ + public static final int SLICE_DIFFERENTIATOR_NO_SLICE = -1; + + /** + * Indicates that the service type is not present. + */ + public static final int SLICE_SERVICE_TYPE_NONE = 0; + + /** + * Slice suitable for the handling of 5G enhanced Mobile Broadband. + */ + public static final int SLICE_SERVICE_TYPE_EMBB = 1; + + /** + * Slice suitable for the handling of ultra-reliable low latency communications. + */ + public static final int SLICE_SERVICE_TYPE_URLLC = 2; + + /** + * Slice suitable for the handling of massive IoT. + */ + public static final int SLICE_SERVICE_TYPE_MIOT = 3; + + /** + * The min acceptable value for a Slice Differentiator + */ + @SuppressLint("MinMaxConstant") + public static final int MIN_SLICE_DIFFERENTIATOR = -1; + + /** + * The max acceptable value for a Slice Differentiator + */ + @SuppressLint("MinMaxConstant") + public static final int MAX_SLICE_DIFFERENTIATOR = 0xFFFFFE; + + /** @hide */ + @IntDef(prefix = { "SLICE_SERVICE_TYPE_" }, value = { + SLICE_SERVICE_TYPE_NONE, + SLICE_SERVICE_TYPE_EMBB, + SLICE_SERVICE_TYPE_URLLC, + SLICE_SERVICE_TYPE_MIOT, + }) + @Retention(RetentionPolicy.SOURCE) + public @interface SliceServiceType {} + + + @SliceServiceType + private final int mSliceServiceType; + @IntRange(from = MIN_SLICE_DIFFERENTIATOR, to = MAX_SLICE_DIFFERENTIATOR) + private final int mSliceDifferentiator; + @SliceServiceType + private final int mMappedHplmnSliceServiceType; + @IntRange(from = MIN_SLICE_DIFFERENTIATOR, to = MAX_SLICE_DIFFERENTIATOR) + private final int mMappedHplmnSliceDifferentiator; + + private SliceInfo(@SliceServiceType int sliceServiceType, + int sliceDifferentiator, int mappedHplmnSliceServiceType, + int mappedHplmnSliceDifferentiator) { + mSliceServiceType = sliceServiceType; + mSliceDifferentiator = sliceDifferentiator; + mMappedHplmnSliceDifferentiator = mappedHplmnSliceDifferentiator; + mMappedHplmnSliceServiceType = mappedHplmnSliceServiceType; + } + + /** + * The type of service provided by the slice. + * <p/> + * see: 3GPP TS 24.501 Section 9.11.2.8. + */ + @SliceServiceType + public int getSliceServiceType() { + return mSliceServiceType; + } + + /** + * Identifies the slice from others with the same Slice Service Type. + * <p/> + * Returns {@link #SLICE_DIFFERENTIATOR_NO_SLICE} if {@link #getSliceServiceType} returns + * {@link #SLICE_SERVICE_TYPE_NONE}. + * <p/> + * see: 3GPP TS 24.501 Section 9.11.2.8. + */ + @IntRange(from = MIN_SLICE_DIFFERENTIATOR, to = MAX_SLICE_DIFFERENTIATOR) + public int getSliceDifferentiator() { + return mSliceDifferentiator; + } + + /** + * Corresponds to a Slice Info (S-NSSAI) of the HPLMN. + * <p/> + * see: 3GPP TS 24.501 Section 9.11.2.8. + */ + @SliceServiceType + public int getMappedHplmnSliceServiceType() { + return mMappedHplmnSliceServiceType; + } + + /** + * This Slice Differentiator corresponds to a {@link SliceInfo} (S-NSSAI) of the HPLMN; + * {@link #getSliceDifferentiator()} is mapped to this value. + * <p/> + * Returns {@link #SLICE_DIFFERENTIATOR_NO_SLICE} if either of the following are true: + * <ul> + * <li>{@link #getSliceDifferentiator()} returns {@link #SLICE_DIFFERENTIATOR_NO_SLICE}</li> + * <li>{@link #getMappedHplmnSliceServiceType()} returns {@link #SLICE_SERVICE_TYPE_NONE}</li> + * </ul> + * <p/> + * see: 3GPP TS 24.501 Section 9.11.2.8. + */ + @IntRange(from = MIN_SLICE_DIFFERENTIATOR, to = MAX_SLICE_DIFFERENTIATOR) + public int getMappedHplmnSliceDifferentiator() { + return mMappedHplmnSliceDifferentiator; + } + + private SliceInfo(@NonNull Parcel in) { + mSliceServiceType = in.readInt(); + mSliceDifferentiator = in.readInt(); + mMappedHplmnSliceServiceType = in.readInt(); + mMappedHplmnSliceDifferentiator = in.readInt(); + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(@NonNull Parcel dest, int flags) { + dest.writeInt(mSliceServiceType); + dest.writeInt(mSliceDifferentiator); + dest.writeInt(mMappedHplmnSliceServiceType); + dest.writeInt(mMappedHplmnSliceDifferentiator); + } + + public static final @android.annotation.NonNull Parcelable.Creator<SliceInfo> CREATOR = + new Parcelable.Creator<SliceInfo>() { + @Override + @NonNull + public SliceInfo createFromParcel(@NonNull Parcel source) { + return new SliceInfo(source); + } + + @Override + @NonNull + public SliceInfo[] newArray(int size) { + return new SliceInfo[size]; + } + }; + + @Override + public String toString() { + return "SliceInfo{" + + "mSliceServiceType=" + sliceServiceTypeToString(mSliceServiceType) + + ", mSliceDifferentiator=" + mSliceDifferentiator + + ", mMappedHplmnSliceServiceType=" + + sliceServiceTypeToString(mMappedHplmnSliceServiceType) + + ", mMappedHplmnSliceDifferentiator=" + mMappedHplmnSliceDifferentiator + + '}'; + } + + private static String sliceServiceTypeToString(@SliceServiceType int sliceServiceType) { + switch(sliceServiceType) { + case SLICE_SERVICE_TYPE_NONE: + return "NONE"; + case SLICE_SERVICE_TYPE_EMBB: + return "EMBB"; + case SLICE_SERVICE_TYPE_URLLC: + return "URLLC"; + case SLICE_SERVICE_TYPE_MIOT: + return "MIOT"; + default: + return Integer.toString(sliceServiceType); + } + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + SliceInfo sliceInfo = (SliceInfo) o; + return mSliceServiceType == sliceInfo.mSliceServiceType + && mSliceDifferentiator == sliceInfo.mSliceDifferentiator + && mMappedHplmnSliceServiceType == sliceInfo.mMappedHplmnSliceServiceType + && mMappedHplmnSliceDifferentiator == sliceInfo.mMappedHplmnSliceDifferentiator; + } + + @Override + public int hashCode() { + return Objects.hash(mSliceServiceType, mSliceDifferentiator, mMappedHplmnSliceServiceType, + mMappedHplmnSliceDifferentiator); + } + + /** + * Provides a convenient way to set the fields of a {@link SliceInfo} when creating a + * new instance. + * + * <p>The example below shows how you might create a new {@code SliceInfo}: + * + * <pre><code> + * + * SliceInfo response = new SliceInfo.Builder() + * .setSliceServiceType(SLICE_SERVICE_TYPE_URLLC) + * .build(); + * </code></pre> + */ + public static final class Builder { + @SliceServiceType + private int mSliceServiceType = SLICE_SERVICE_TYPE_NONE; + @IntRange(from = MIN_SLICE_DIFFERENTIATOR, to = MAX_SLICE_DIFFERENTIATOR) + private int mSliceDifferentiator = SLICE_DIFFERENTIATOR_NO_SLICE; + @SliceServiceType + private int mMappedHplmnSliceServiceType = SLICE_SERVICE_TYPE_NONE; + @IntRange(from = MIN_SLICE_DIFFERENTIATOR, to = MAX_SLICE_DIFFERENTIATOR) + private int mMappedHplmnSliceDifferentiator = SLICE_DIFFERENTIATOR_NO_SLICE; + + /** + * Default constructor for Builder. + */ + public Builder() { + } + + /** + * Set the Slice Service Type. + * + * @return The same instance of the builder. + */ + @NonNull + public Builder setSliceServiceType(@SliceServiceType int mSliceServiceType) { + this.mSliceServiceType = mSliceServiceType; + return this; + } + + /** + * Set the Slice Differentiator. + * <p/> + * A value of {@link #SLICE_DIFFERENTIATOR_NO_SLICE} indicates that there is no + * corresponding Slice. + * + * @throws IllegalArgumentException if the parameter is not between + * {@link #MIN_SLICE_DIFFERENTIATOR} and {@link #MAX_SLICE_DIFFERENTIATOR}. + * + * @return The same instance of the builder. + */ + @NonNull + public Builder setSliceDifferentiator( + @IntRange(from = MIN_SLICE_DIFFERENTIATOR, to = MAX_SLICE_DIFFERENTIATOR) + int sliceDifferentiator) { + if (sliceDifferentiator < MIN_SLICE_DIFFERENTIATOR + || sliceDifferentiator > MAX_SLICE_DIFFERENTIATOR) { + throw new IllegalArgumentException("The slice diffentiator value is out of range"); + } + this.mSliceDifferentiator = sliceDifferentiator; + return this; + } + + /** + * Set the HPLMN Slice Service Type. + * + * @return The same instance of the builder. + */ + @NonNull + public Builder setMappedHplmnSliceServiceType( + @SliceServiceType int mappedHplmnSliceServiceType) { + this.mMappedHplmnSliceServiceType = mappedHplmnSliceServiceType; + return this; + } + + /** + * Set the HPLMN Slice Differentiator. + * <p/> + * A value of {@link #SLICE_DIFFERENTIATOR_NO_SLICE} indicates that there is no + * corresponding Slice of the HPLMN. + * + * @throws IllegalArgumentException if the parameter is not between + * {@link #MIN_SLICE_DIFFERENTIATOR} and {@link #MAX_SLICE_DIFFERENTIATOR}. + * + * @return The same instance of the builder. + */ + @NonNull + public Builder setMappedHplmnSliceDifferentiator( + @IntRange(from = MIN_SLICE_DIFFERENTIATOR, to = MAX_SLICE_DIFFERENTIATOR) + int mappedHplmnSliceDifferentiator) { + if (mappedHplmnSliceDifferentiator < MIN_SLICE_DIFFERENTIATOR + || mappedHplmnSliceDifferentiator > MAX_SLICE_DIFFERENTIATOR) { + throw new IllegalArgumentException("The slice diffentiator value is out of range"); + } + this.mMappedHplmnSliceDifferentiator = mappedHplmnSliceDifferentiator; + return this; + } + + /** + * Build the {@link SliceInfo}. + * + * @return the {@link SliceInfo} object. + */ + @NonNull + public SliceInfo build() { + return new SliceInfo(this.mSliceServiceType, this.mSliceDifferentiator, + this.mMappedHplmnSliceServiceType, this.mMappedHplmnSliceDifferentiator); + } + } +} diff --git a/telephony/java/android/telephony/emergency/OWNERS b/telephony/java/android/telephony/emergency/OWNERS new file mode 100644 index 000000000000..fa07dce5f615 --- /dev/null +++ b/telephony/java/android/telephony/emergency/OWNERS @@ -0,0 +1,5 @@ +# Bug component: 20868 + +rgreenwalt@google.com +tgunn@google.com +shuoq@google.com diff --git a/telephony/java/android/telephony/euicc/OWNERS b/telephony/java/android/telephony/euicc/OWNERS new file mode 100644 index 000000000000..9e51a4b30516 --- /dev/null +++ b/telephony/java/android/telephony/euicc/OWNERS @@ -0,0 +1,6 @@ +# Bug component: 20868 + +rgreenwalt@google.com +tgunn@google.com +refuhoo@google.com +amitmahajan@google.com diff --git a/telephony/java/android/telephony/gba/GbaAuthRequest.aidl b/telephony/java/android/telephony/gba/GbaAuthRequest.aidl new file mode 100644 index 000000000000..ba243a27b4be --- /dev/null +++ b/telephony/java/android/telephony/gba/GbaAuthRequest.aidl @@ -0,0 +1,18 @@ +/* + * Copyright (C) 2020 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.gba; + +parcelable GbaAuthRequest; diff --git a/telephony/java/android/telephony/gba/GbaAuthRequest.java b/telephony/java/android/telephony/gba/GbaAuthRequest.java new file mode 100644 index 000000000000..5366e9af3147 --- /dev/null +++ b/telephony/java/android/telephony/gba/GbaAuthRequest.java @@ -0,0 +1,161 @@ +/* + * Copyright (C) 2020 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.gba; + +import android.annotation.NonNull; +import android.net.Uri; +import android.os.Parcel; +import android.os.Parcelable; +import android.telephony.IBootstrapAuthenticationCallback; + +import com.android.internal.telephony.uicc.IccUtils; + +import java.util.concurrent.atomic.AtomicInteger; + +/** + * GBA authentication request + * {@hide} + */ +public final class GbaAuthRequest implements Parcelable { + private int mToken; + private int mSubId; + private int mAppType; + private Uri mNafUrl; + private byte[] mSecurityProtocol; + private boolean mForceBootStrapping; + private IBootstrapAuthenticationCallback mCallback; + + private static AtomicInteger sUniqueToken = new AtomicInteger(0); + + public GbaAuthRequest(int subId, int appType, Uri nafUrl, byte[] securityProtocol, + boolean forceBootStrapping, IBootstrapAuthenticationCallback callback) { + this(nextUniqueToken(), subId, appType, nafUrl, + securityProtocol, forceBootStrapping, callback); + } + + public GbaAuthRequest(GbaAuthRequest request) { + this(request.mToken, request.mSubId, request.mAppType, request.mNafUrl, + request.mSecurityProtocol, request.mForceBootStrapping, request.mCallback); + } + + public GbaAuthRequest(int token, int subId, int appType, Uri nafUrl, byte[] securityProtocol, + boolean forceBootStrapping, IBootstrapAuthenticationCallback callback) { + mToken = token; + mSubId = subId; + mAppType = appType; + mNafUrl = nafUrl; + mSecurityProtocol = securityProtocol; + mCallback = callback; + mForceBootStrapping = forceBootStrapping; + } + + public int getToken() { + return mToken; + } + + public int getSubId() { + return mSubId; + } + + public int getAppType() { + return mAppType; + } + + public Uri getNafUrl() { + return mNafUrl; + } + + public byte[] getSecurityProtocol() { + return mSecurityProtocol; + } + + public boolean isForceBootStrapping() { + return mForceBootStrapping; + } + + public void setCallback(IBootstrapAuthenticationCallback cb) { + mCallback = cb; + } + + public IBootstrapAuthenticationCallback getCallback() { + return mCallback; + } + + /** + * {@link Parcelable#writeToParcel} + */ + public void writeToParcel(@NonNull Parcel out, int flags) { + out.writeInt(mToken); + out.writeInt(mSubId); + out.writeInt(mAppType); + out.writeParcelable(mNafUrl, 0); + out.writeInt(mSecurityProtocol.length); + out.writeByteArray(mSecurityProtocol); + out.writeBoolean(mForceBootStrapping); + out.writeStrongInterface(mCallback); + } + + /** + * {@link Parcelable.Creator} + * + */ + public static final @android.annotation.NonNull Parcelable.Creator< + GbaAuthRequest> CREATOR = new Creator<GbaAuthRequest>() { + @Override + public GbaAuthRequest createFromParcel(Parcel in) { + int token = in.readInt(); + int subId = in.readInt(); + int appType = in.readInt(); + Uri nafUrl = in.readParcelable(GbaAuthRequest.class.getClassLoader()); + int len = in.readInt(); + byte[] protocol = new byte[len]; + in.readByteArray(protocol); + boolean forceBootStrapping = in.readBoolean(); + IBootstrapAuthenticationCallback callback = + IBootstrapAuthenticationCallback.Stub + .asInterface(in.readStrongBinder()); + return new GbaAuthRequest(token, subId, appType, nafUrl, protocol, + forceBootStrapping, callback); + } + + @Override + public GbaAuthRequest[] newArray(int size) { + return new GbaAuthRequest[size]; + } + }; + + /** + * {@link Parcelable#describeContents} + */ + public int describeContents() { + return 0; + } + + private static int nextUniqueToken() { + return sUniqueToken.getAndIncrement() << 16 | (0xFFFF & (int) System.currentTimeMillis()); + } + + @Override + public String toString() { + String str = "Token: " + mToken + "SubId:" + mSubId + ", AppType:" + + mAppType + ", NafUrl:" + mNafUrl + ", SecurityProtocol:" + + IccUtils.bytesToHexString(mSecurityProtocol) + + ", ForceBootStrapping:" + mForceBootStrapping + + ", CallBack:" + mCallback; + return str; + } +} diff --git a/telephony/java/android/telephony/gba/GbaService.java b/telephony/java/android/telephony/gba/GbaService.java new file mode 100644 index 000000000000..3962aff9df4f --- /dev/null +++ b/telephony/java/android/telephony/gba/GbaService.java @@ -0,0 +1,226 @@ +/* + * Copyright (C) 2020 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.gba; + +import android.annotation.NonNull; +import android.annotation.SystemApi; +import android.app.Service; +import android.content.Intent; +import android.net.Uri; +import android.os.Build; +import android.os.Handler; +import android.os.HandlerThread; +import android.os.IBinder; +import android.os.Looper; +import android.os.Message; +import android.os.RemoteException; +import android.telephony.Annotation.UiccAppTypeExt; +import android.telephony.IBootstrapAuthenticationCallback; +import android.telephony.TelephonyManager; +import android.telephony.TelephonyManager.AuthenticationFailureReason; +import android.util.Log; +import android.util.SparseArray; + +/** + * Base class for GBA Service. Any implementation which wants to provide + * GBA service must extend this class. + * + * <p>Note that the application to implement the service must declare to use + * the permission {@link android.Manifest.permission#BIND_GBA_SERVICE}, + * and filter the intent of {@link #SERVICE_INTERFACE}. + * The manifest of the service must follow the format below: + * + * <p>... + * <service + * android:name=".EgGbaService" + * android:directBootAware="true" + * android:permission="android.permission.BIND_GBA_SERVICE" > + * ... + * <intent-filter> + * <action android:name="android.telephony.gba.GbaService"/> + * </intent-filter> + * </service> + * ... + * + * <p>The service should also be file-based encryption (FBE) aware. + * {@hide} + */ +@SystemApi +public class GbaService extends Service { + private static final boolean DBG = Build.IS_DEBUGGABLE; + private static final String TAG = "GbaService"; + + /** + * The intent must be defined as an intent-filter in the + * AndroidManifest of the GbaService. + */ + public static final String SERVICE_INTERFACE = "android.telephony.gba.GbaService"; + + private static final int EVENT_GBA_AUTH_REQUEST = 1; + + private final HandlerThread mHandlerThread; + private final GbaServiceHandler mHandler; + + private final SparseArray<IBootstrapAuthenticationCallback> mCallbacks = new SparseArray<>(); + private final IGbaServiceWrapper mBinder = new IGbaServiceWrapper(); + + /** + * Default constructor. + */ + public GbaService() { + mHandlerThread = new HandlerThread(TAG); + mHandlerThread.start(); + + mHandler = new GbaServiceHandler(mHandlerThread.getLooper()); + Log.d(TAG, "GBA service created"); + } + + private class GbaServiceHandler extends Handler { + + GbaServiceHandler(Looper looper) { + super(looper); + } + + @Override + public void handleMessage(Message msg) { + switch (msg.what) { + case EVENT_GBA_AUTH_REQUEST: + GbaAuthRequest req = (GbaAuthRequest) msg.obj; + synchronized (mCallbacks) { + mCallbacks.put(req.getToken(), req.getCallback()); + } + onAuthenticationRequest(req.getSubId(), req.getToken(), req.getAppType(), + req.getNafUrl(), req.getSecurityProtocol(), req.isForceBootStrapping()); + break; + default: + break; + } + } + } + + /** + * Called by the platform when a GBA authentication request is received from + * {@link TelephonyManager#bootstrapAuthenticationRequest} to get the KsNAF for + * a particular NAF. + * + * @param subscriptionId the ICC card to be used for the bootstrapping authentication. + * @param token the identification of the authentication request. + * @param appType icc application type, like {@link #APPTYPE_USIM} or {@link + * #APPTYPE_ISIM} or {@link#APPTYPE_UNKNOWN} + * @param nafUrl Network Application Function(NAF) fully qualified domain name and + * the selected GBA mode. It shall contain two parts delimited by "@" sign. The first + * part is the constant string "3GPP-bootstrapping" (GBA_ME), + * "3GPP-bootstrapping-uicc" (GBA_ U), or "3GPP-bootstrapping-digest" (GBA_Digest), + * and the latter part shall be the FQDN of the NAF (e.g. + * "3GPP-bootstrapping@naf1.operator.com" or "3GPP-bootstrapping-uicc@naf1.operator.com", + * or "3GPP-bootstrapping-digest@naf1.operator.com"). + * @param securityProtocol Security protocol identifier between UE and NAF. See + * 3GPP TS 33.220 Annex H. Application can use + * {@link UaSecurityProtocolIdentifier#createDefaultUaSpId}, + * {@link UaSecurityProtocolIdentifier#create3GppUaSpId}, + * to create the ua security protocol identifier as needed + * @param forceBootStrapping true=force bootstrapping, false=do not force + * bootstrapping. Bootstrapping shouldn't be forced unless the application sees + * authentication errors from the server. + * Response is returned via {@link TelephonyManager#BootstrapAuthenticationCallback} + * along with the token to identify the request. + * + * <p>Note that this is not called in the main thread. + */ + public void onAuthenticationRequest(int subscriptionId, int token, @UiccAppTypeExt int appType, + @NonNull Uri nafUrl, @NonNull byte[] securityProtocol, boolean forceBootStrapping) { + //Default implementation should be overridden by vendor Gba Service. Vendor Gba Service + //should handle the gba bootstrap authentication request, and call reportKeysAvailable or + //reportAuthenticationFailure to notify the caller accordingly. + reportAuthenticationFailure( + token, TelephonyManager.GBA_FAILURE_REASON_FEATURE_NOT_SUPPORTED); + } + + /** + * Called by {@link GbaService} when the previously requested GBA keys are available + * (@see onAuthenticationRequest()) + * + * @param token unique identifier of the request. + * @param gbaKey KsNaf Response. + * @param transactionId Bootstrapping Transaction ID. + * @throws RuntimeException when there is remote failure of callback. + */ + public final void reportKeysAvailable(int token, @NonNull byte[] gbaKey, + @NonNull String transactionId) throws RuntimeException { + IBootstrapAuthenticationCallback cb = null; + synchronized (mCallbacks) { + cb = mCallbacks.get(token); + mCallbacks.remove(token); + } + if (cb != null) { + try { + cb.onKeysAvailable(token, gbaKey, transactionId); + } catch (RemoteException exception) { + throw exception.rethrowAsRuntimeException(); + } + } + } + + /** + * Invoked when the previously requested GBA key authentication failed + * (@see onAuthenticationRequest()) + * + * @param token unique identifier of the request. + * @param reason The reason for the authentication failure. + * @throws RuntimeException when there is remote failure of callback. + */ + public final void reportAuthenticationFailure(int token, + @AuthenticationFailureReason int reason) throws RuntimeException { + IBootstrapAuthenticationCallback cb = null; + synchronized (mCallbacks) { + cb = mCallbacks.get(token); + mCallbacks.remove(token); + } + if (cb != null) { + try { + cb.onAuthenticationFailure(token, reason); + } catch (RemoteException exception) { + throw exception.rethrowAsRuntimeException(); + } + } + } + + /** @hide */ + @Override + public IBinder onBind(Intent intent) { + if (SERVICE_INTERFACE.equals(intent.getAction())) { + Log.d(TAG, "GbaService Bound."); + return mBinder; + } + return null; + } + + /** @hide */ + @Override + public void onDestroy() { + mHandlerThread.quit(); + super.onDestroy(); + } + + private class IGbaServiceWrapper extends IGbaService.Stub { + @Override + public void authenticationRequest(GbaAuthRequest request) { + if (DBG) Log.d(TAG, "receive request: " + request); + mHandler.obtainMessage(EVENT_GBA_AUTH_REQUEST, request).sendToTarget(); + } + } +} diff --git a/telephony/java/android/telephony/gba/IGbaService.aidl b/telephony/java/android/telephony/gba/IGbaService.aidl new file mode 100644 index 000000000000..b7ba5a4441ec --- /dev/null +++ b/telephony/java/android/telephony/gba/IGbaService.aidl @@ -0,0 +1,27 @@ +/* + * Copyright 2020 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.gba; + +import android.net.Uri; +import android.telephony.gba.GbaAuthRequest; + +/** + * @hide + */ +interface IGbaService +{ + oneway void authenticationRequest(in GbaAuthRequest request); +} diff --git a/telephony/java/android/telephony/gba/TlsParams.java b/telephony/java/android/telephony/gba/TlsParams.java new file mode 100644 index 000000000000..922f4bbb4dbf --- /dev/null +++ b/telephony/java/android/telephony/gba/TlsParams.java @@ -0,0 +1,281 @@ +/* + * Copyright 2020 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.gba; + +import android.annotation.IntDef; +import android.annotation.SystemApi; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.util.Arrays; + +/** + * Defines the TLS parameters for GBA as per IANA and TS 33.210, which are used + * by some UA security protocol identifiers defined in 3GPP TS 33.220 Annex H, + * and 3GPP TS 33.222. + * + * @hide + */ +@SystemApi +public class TlsParams { + + private TlsParams() {} + + /** + * TLS protocol version supported by GBA + */ + public static final int PROTOCOL_VERSION_TLS_1_2 = 0x0303; + public static final int PROTOCOL_VERSION_TLS_1_3 = 0x0304; + + /** + * TLS cipher suites are used to create {@link UaSecurityProtocolIdentifier} + * by {@link UaSecurityProtocolIdentifier#create3GppUaSpId} + * + * @hide + */ + @Retention(RetentionPolicy.SOURCE) + @IntDef( + prefix = {"TLS_"}, + value = { + TLS_NULL_WITH_NULL_NULL, + TLS_RSA_WITH_NULL_MD5, + TLS_RSA_WITH_NULL_SHA, + TLS_RSA_WITH_RC4_128_MD5, + TLS_RSA_WITH_RC4_128_SHA, + TLS_RSA_WITH_3DES_EDE_CBC_SHA, + TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA, + TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA, + TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA, + TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA, + TLS_DH_ANON_WITH_RC4_128_MD5, + TLS_DH_ANON_WITH_3DES_EDE_CBC_SHA, + TLS_RSA_WITH_AES_128_CBC_SHA, + TLS_DH_DSS_WITH_AES_128_CBC_SHA, + TLS_DH_RSA_WITH_AES_128_CBC_SHA, + TLS_DHE_DSS_WITH_AES_128_CBC_SHA, + TLS_DHE_RSA_WITH_AES_128_CBC_SHA, + TLS_DH_ANON_WITH_AES_128_CBC_SHA, + TLS_RSA_WITH_AES_256_CBC_SHA, + TLS_DH_DSS_WITH_AES_256_CBC_SHA, + TLS_DH_RSA_WITH_AES_256_CBC_SHA, + TLS_DHE_DSS_WITH_AES_256_CBC_SHA, + TLS_DHE_RSA_WITH_AES_256_CBC_SHA, + TLS_DH_ANON_WITH_AES_256_CBC_SHA, + TLS_RSA_WITH_NULL_SHA256, + TLS_RSA_WITH_AES_128_CBC_SHA256, + TLS_RSA_WITH_AES_256_CBC_SHA256, + TLS_DH_DSS_WITH_AES_128_CBC_SHA256, + TLS_DH_RSA_WITH_AES_128_CBC_SHA256, + TLS_DHE_DSS_WITH_AES_128_CBC_SHA256, + TLS_DHE_RSA_WITH_AES_128_CBC_SHA256, + TLS_DH_DSS_WITH_AES_256_CBC_SHA256, + TLS_DH_RSA_WITH_AES_256_CBC_SHA256, + TLS_DHE_DSS_WITH_AES_256_CBC_SHA256, + TLS_DHE_RSA_WITH_AES_256_CBC_SHA256, + TLS_DH_ANON_WITH_AES_128_CBC_SHA256, + TLS_DH_ANON_WITH_AES_256_CBC_SHA256, + TLS_DHE_RSA_WITH_AES_128_GCM_SHA256, + TLS_DHE_RSA_WITH_AES_256_GCM_SHA384, + TLS_DHE_PSK_WITH_AES_128_GCM_SHA256, + TLS_DHE_PSK_WITH_AES_256_GCM_SHA384, + TLS_AES_128_GCM_SHA256, + TLS_AES_256_GCM_SHA384, + TLS_CHACHA20_POLY1305_SHA256, + TLS_AES_128_CCM_SHA256, + TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, + TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, + TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, + TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, + TLS_DHE_RSA_WITH_AES_128_CCM, + TLS_DHE_RSA_WITH_AES_256_CCM, + TLS_DHE_PSK_WITH_AES_128_CCM, + TLS_DHE_PSK_WITH_AES_256_CCM, + TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, + TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, + TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256, + TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256, + TLS_DHE_PSK_WITH_CHACHA20_POLY1305_SHA256, + TLS_ECDHE_PSK_WITH_AES_128_GCM_SHA256, + TLS_ECDHE_PSK_WITH_AES_256_GCM_SHA384, + TLS_ECDHE_PSK_WITH_AES_128_CCM_SHA256 + }) + public @interface TlsCipherSuite {} + + // Cipher suites for TLS v1.2 per RFC5246 + public static final int TLS_NULL_WITH_NULL_NULL = 0x0000; + public static final int TLS_RSA_WITH_NULL_MD5 = 0x0001; + public static final int TLS_RSA_WITH_NULL_SHA = 0x0002; + public static final int TLS_RSA_WITH_RC4_128_MD5 = 0x0004; + public static final int TLS_RSA_WITH_RC4_128_SHA = 0x0005; + public static final int TLS_RSA_WITH_3DES_EDE_CBC_SHA = 0x000A; + public static final int TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA = 0x000D; + public static final int TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA = 0x0010; + public static final int TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA = 0x0013; + public static final int TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA = 0x0016; + public static final int TLS_DH_ANON_WITH_RC4_128_MD5 = 0x0018; + public static final int TLS_DH_ANON_WITH_3DES_EDE_CBC_SHA = 0x001B; + public static final int TLS_RSA_WITH_AES_128_CBC_SHA = 0x002F; + public static final int TLS_DH_DSS_WITH_AES_128_CBC_SHA = 0x0030; + public static final int TLS_DH_RSA_WITH_AES_128_CBC_SHA = 0x0031; + public static final int TLS_DHE_DSS_WITH_AES_128_CBC_SHA = 0x0032; + public static final int TLS_DHE_RSA_WITH_AES_128_CBC_SHA = 0x0033; + public static final int TLS_DH_ANON_WITH_AES_128_CBC_SHA = 0x0034; + public static final int TLS_RSA_WITH_AES_256_CBC_SHA = 0x0035; + public static final int TLS_DH_DSS_WITH_AES_256_CBC_SHA = 0x0036; + public static final int TLS_DH_RSA_WITH_AES_256_CBC_SHA = 0x0037; + public static final int TLS_DHE_DSS_WITH_AES_256_CBC_SHA = 0x0038; + public static final int TLS_DHE_RSA_WITH_AES_256_CBC_SHA = 0x0039; + public static final int TLS_DH_ANON_WITH_AES_256_CBC_SHA = 0x003A; + public static final int TLS_RSA_WITH_NULL_SHA256 = 0x003B; + public static final int TLS_RSA_WITH_AES_128_CBC_SHA256 = 0x003C; + public static final int TLS_RSA_WITH_AES_256_CBC_SHA256 = 0x003D; + public static final int TLS_DH_DSS_WITH_AES_128_CBC_SHA256 = 0x003E; + public static final int TLS_DH_RSA_WITH_AES_128_CBC_SHA256 = 0x003F; + public static final int TLS_DHE_DSS_WITH_AES_128_CBC_SHA256 = 0x0040; + public static final int TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 = 0x0067; + public static final int TLS_DH_DSS_WITH_AES_256_CBC_SHA256 = 0x0068; + public static final int TLS_DH_RSA_WITH_AES_256_CBC_SHA256 = 0x0069; + public static final int TLS_DHE_DSS_WITH_AES_256_CBC_SHA256 = 0x006A; + public static final int TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 = 0x006B; + public static final int TLS_DH_ANON_WITH_AES_128_CBC_SHA256 = 0x006C; + public static final int TLS_DH_ANON_WITH_AES_256_CBC_SHA256 = 0x006D; + + // Cipher suites for TLS v1.3 per RFC8446 and recommended by IANA + public static final int TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 = 0x009E; + public static final int TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 = 0x009F; + public static final int TLS_DHE_PSK_WITH_AES_128_GCM_SHA256 = 0x00AA; + public static final int TLS_DHE_PSK_WITH_AES_256_GCM_SHA384 = 0x00AB; + public static final int TLS_AES_128_GCM_SHA256 = 0x1301; + public static final int TLS_AES_256_GCM_SHA384 = 0x1302; + public static final int TLS_CHACHA20_POLY1305_SHA256 = 0x1303; + public static final int TLS_AES_128_CCM_SHA256 = 0x1304; + public static final int TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 = 0xC02B; + public static final int TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 = 0xC02C; + public static final int TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 = 0xC02F; + public static final int TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 = 0xC030; + public static final int TLS_DHE_RSA_WITH_AES_128_CCM = 0xC09E; + public static final int TLS_DHE_RSA_WITH_AES_256_CCM = 0xC09F; + public static final int TLS_DHE_PSK_WITH_AES_128_CCM = 0xC0A6; + public static final int TLS_DHE_PSK_WITH_AES_256_CCM = 0xC0A7; + public static final int TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 = 0xCCA8; + public static final int TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 = 0xCCA9; + public static final int TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256 = 0xCCAA; + public static final int TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256 = 0xCCAC; + public static final int TLS_DHE_PSK_WITH_CHACHA20_POLY1305_SHA256 = 0xCCAD; + public static final int TLS_ECDHE_PSK_WITH_AES_128_GCM_SHA256 = 0xD001; + public static final int TLS_ECDHE_PSK_WITH_AES_256_GCM_SHA384 = 0xD002; + public static final int TLS_ECDHE_PSK_WITH_AES_128_CCM_SHA256 = 0xD005; + + private static final int[] CS_EXPECTED = { + TLS_NULL_WITH_NULL_NULL, + TLS_RSA_WITH_NULL_MD5, + TLS_RSA_WITH_NULL_SHA, + TLS_RSA_WITH_RC4_128_MD5, + TLS_RSA_WITH_RC4_128_SHA, + TLS_RSA_WITH_3DES_EDE_CBC_SHA, + TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA, + TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA, + TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA, + TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA, + TLS_DH_ANON_WITH_RC4_128_MD5, + TLS_DH_ANON_WITH_3DES_EDE_CBC_SHA, + TLS_RSA_WITH_AES_128_CBC_SHA, + TLS_DH_DSS_WITH_AES_128_CBC_SHA, + TLS_DH_RSA_WITH_AES_128_CBC_SHA, + TLS_DHE_DSS_WITH_AES_128_CBC_SHA, + TLS_DHE_RSA_WITH_AES_128_CBC_SHA, + TLS_DH_ANON_WITH_AES_128_CBC_SHA, + TLS_RSA_WITH_AES_256_CBC_SHA, + TLS_DH_DSS_WITH_AES_256_CBC_SHA, + TLS_DH_RSA_WITH_AES_256_CBC_SHA, + TLS_DHE_DSS_WITH_AES_256_CBC_SHA, + TLS_DHE_RSA_WITH_AES_256_CBC_SHA, + TLS_DH_ANON_WITH_AES_256_CBC_SHA, + TLS_RSA_WITH_NULL_SHA256, + TLS_RSA_WITH_AES_128_CBC_SHA256, + TLS_RSA_WITH_AES_256_CBC_SHA256, + TLS_DH_DSS_WITH_AES_128_CBC_SHA256, + TLS_DH_RSA_WITH_AES_128_CBC_SHA256, + TLS_DHE_DSS_WITH_AES_128_CBC_SHA256, + TLS_DHE_RSA_WITH_AES_128_CBC_SHA256, + TLS_DH_DSS_WITH_AES_256_CBC_SHA256, + TLS_DH_RSA_WITH_AES_256_CBC_SHA256, + TLS_DHE_DSS_WITH_AES_256_CBC_SHA256, + TLS_DHE_RSA_WITH_AES_256_CBC_SHA256, + TLS_DH_ANON_WITH_AES_128_CBC_SHA256, + TLS_DH_ANON_WITH_AES_256_CBC_SHA256, + TLS_DHE_RSA_WITH_AES_128_GCM_SHA256, + TLS_DHE_RSA_WITH_AES_256_GCM_SHA384, + TLS_DHE_PSK_WITH_AES_128_GCM_SHA256, + TLS_DHE_PSK_WITH_AES_256_GCM_SHA384, + TLS_AES_128_GCM_SHA256, + TLS_AES_256_GCM_SHA384, + TLS_CHACHA20_POLY1305_SHA256, + TLS_AES_128_CCM_SHA256, + TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, + TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, + TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, + TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, + TLS_DHE_RSA_WITH_AES_128_CCM, + TLS_DHE_RSA_WITH_AES_256_CCM, + TLS_DHE_PSK_WITH_AES_128_CCM, + TLS_DHE_PSK_WITH_AES_256_CCM, + TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, + TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, + TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256, + TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256, + TLS_DHE_PSK_WITH_CHACHA20_POLY1305_SHA256, + TLS_ECDHE_PSK_WITH_AES_128_GCM_SHA256, + TLS_ECDHE_PSK_WITH_AES_256_GCM_SHA384, + TLS_ECDHE_PSK_WITH_AES_128_CCM_SHA256 + }; + + /** + * TLS supported groups required by TS 33.210 + */ + public static final int GROUP_SECP256R1 = 23; + public static final int GROUP_SECP384R1 = 24; + public static final int GROUP_X25519 = 29; + public static final int GROUP_X448 = 30; + + /** + * Signature algorithms shall be supported as per TS 33.210 + */ + public static final int SIG_RSA_PKCS1_SHA1 = 0X0201; + public static final int SIG_ECDSA_SHA1 = 0X0203; + public static final int SIG_RSA_PKCS1_SHA256 = 0X0401; + public static final int SIG_ECDSA_SECP256R1_SHA256 = 0X0403; + public static final int SIG_RSA_PKCS1_SHA256_LEGACY = 0X0420; + public static final int SIG_RSA_PKCS1_SHA384 = 0X0501; + public static final int SIG_ECDSA_SECP384R1_SHA384 = 0X0503; + public static final int SIG_RSA_PKCS1_SHA384_LEGACY = 0X0520; + public static final int SIG_RSA_PKCS1_SHA512 = 0X0601; + public static final int SIG_ECDSA_SECP521R1_SHA512 = 0X0603; + public static final int SIG_RSA_PKCS1_SHA512_LEGACY = 0X0620; + public static final int SIG_RSA_PSS_RSAE_SHA256 = 0X0804; + public static final int SIG_RSA_PSS_RSAE_SHA384 = 0X0805; + public static final int SIG_RSA_PSS_RSAE_SHA512 = 0X0806; + public static final int SIG_ECDSA_BRAINPOOLP256R1TLS13_SHA256 = 0X081A; + public static final int SIG_ECDSA_BRAINPOOLP384R1TLS13_SHA384 = 0X081B; + public static final int SIG_ECDSA_BRAINPOOLP512R1TLS13_SHA512 = 0X081C; + + /** + * Returns whether the TLS cipher suite id is supported + */ + public static boolean isTlsCipherSuiteSupported(int csId) { + return Arrays.binarySearch(CS_EXPECTED, csId) >= 0; + } +} diff --git a/telephony/java/android/telephony/gba/UaSecurityProtocolIdentifier.aidl b/telephony/java/android/telephony/gba/UaSecurityProtocolIdentifier.aidl new file mode 100644 index 000000000000..a71e860fd54c --- /dev/null +++ b/telephony/java/android/telephony/gba/UaSecurityProtocolIdentifier.aidl @@ -0,0 +1,18 @@ +/* + * Copyright (C) 2020 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.gba; + +parcelable UaSecurityProtocolIdentifier; diff --git a/telephony/java/android/telephony/gba/UaSecurityProtocolIdentifier.java b/telephony/java/android/telephony/gba/UaSecurityProtocolIdentifier.java new file mode 100644 index 000000000000..c1418758f64f --- /dev/null +++ b/telephony/java/android/telephony/gba/UaSecurityProtocolIdentifier.java @@ -0,0 +1,436 @@ +/* + * Copyright (C) 2020 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.gba; + +import android.annotation.IntDef; +import android.annotation.NonNull; +import android.annotation.Nullable; +import android.annotation.SystemApi; +import android.os.Parcel; +import android.os.Parcelable; +import android.telephony.gba.TlsParams.TlsCipherSuite; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.nio.ByteBuffer; +import java.util.Objects; + +/** + * Description of ua security protocol identifier defined in 3GPP TS 33.220 H.2 + * @hide + */ +@SystemApi +public final class UaSecurityProtocolIdentifier implements Parcelable { + + /** + * Organization code defined in 3GPP TS 33.220 H.3 + * + * @hide + */ + @Retention(RetentionPolicy.SOURCE) + @IntDef(prefix = {"ORG_"}, value = { + ORG_NONE, + ORG_3GPP, + ORG_3GPP2, + ORG_OMA, + ORG_GSMA, + ORG_LOCAL}) + public @interface OrganizationCode {} + + /** + * Organization octet value for default ua security protocol + */ + public static final int ORG_NONE = 0; + /** + * Organization octet value for 3GPP ua security protocol + */ + public static final int ORG_3GPP = 0x01; + /** + * Organization octet value for 3GPP2 ua security protocol + */ + public static final int ORG_3GPP2 = 0x02; + /** + * Organization octet value for OMA ua security protocol + */ + public static final int ORG_OMA = 0x03; + /** + * Organization octet value for GSMA ua security protocol + */ + public static final int ORG_GSMA = 0x04; + /** + * Internal organization octet value for local/experimental protocols + */ + public static final int ORG_LOCAL = 0xFF; + + /** + * 3GPP UA Security Protocol ID defined in 3GPP TS 33.220 H.3 + * + * @hide + */ + @Retention(RetentionPolicy.SOURCE) + @IntDef(prefix = {"UA_SECURITY_PROTOCOL_3GPP_"}, value = { + UA_SECURITY_PROTOCOL_3GPP_SUBSCRIBER_CERTIFICATE, + UA_SECURITY_PROTOCOL_3GPP_MBMS, + UA_SECURITY_PROTOCOL_3GPP_HTTP_DIGEST_AUTHENTICATION, + UA_SECURITY_PROTOCOL_3GPP_HTTP_BASED_MBMS, + UA_SECURITY_PROTOCOL_3GPP_SIP_BASED_MBMS, + UA_SECURITY_PROTOCOL_3GPP_GENERIC_PUSH_LAYER, + UA_SECURITY_PROTOCOL_3GPP_IMS_MEDIA_PLANE, + UA_SECURITY_PROTOCOL_3GPP_GENERATION_TMPI, + UA_SECURITY_PROTOCOL_3GPP_TLS_DEFAULT, + UA_SECURITY_PROTOCOL_3GPP_TLS_BROWSER}) + public @interface UaSecurityProtocol3gpp {} + + /** + * Security protocol param according to TS 33.221 as described in TS + * 33.220 Annex H. Mapped to byte stream "0x01,0x00,0x00,0x00,0x00". + */ + public static final int UA_SECURITY_PROTOCOL_3GPP_SUBSCRIBER_CERTIFICATE = 0; + + /** + * Security protocol param according to TS 33.246 for Multimedia + * broadcast/Multimedia services (MBMS) as described in TS + * 33.220 Annex H. Mapped to byte stream "0x01,0x00,0x00,0x00,0x01". + */ + public static final int UA_SECURITY_PROTOCOL_3GPP_MBMS = 1; + + /** + * Security protocol param based on HTTP digest authentication + * according to TS 24.109 as described in TS 33.220 Annex H. Mapped to + * byte stream "0x01,0x00,0x00,0x00,0x02". + */ + public static final int UA_SECURITY_PROTOCOL_3GPP_HTTP_DIGEST_AUTHENTICATION = 2; + + /** + * Security protocol param used with HTTP-based security procedures for + * Multimedia broadcast/Multimedia services (MBMS) user services + * according to TS 26.237 as described in TS 33.220 Annex H. + * Mapped to byte stream "0x01,0x00,0x00,0x00,0x03". + */ + public static final int UA_SECURITY_PROTOCOL_3GPP_HTTP_BASED_MBMS = 3; + + /** + * Security protocol param used with SIP-based security procedures for + * Multimedia broadcast/Multimedia services (MBMS) user services + * according to TS 26.237 as described in TS 33.220 Annex H. + * Mapped to byte stream "0x01,0x00,0x00,0x00,0x04". + */ + public static final int UA_SECURITY_PROTOCOL_3GPP_SIP_BASED_MBMS = 4; + + /** + * Security protocol param used with Generic Push Layer according to TS + * 33.224 as described in TS 33.220 Annex H. Mapped to byte stream + * "0x01,0x00,0x00,0x00,0x05". + */ + public static final int UA_SECURITY_PROTOCOL_3GPP_GENERIC_PUSH_LAYER = 5; + + /** + * Security protocol param used for IMS UE to KMS http based message + * exchanges according to "IMS media plane security", TS 33.328 as + * described in TS 33.220 Annex H. Mapped to byte stream + * "0x01,0x00,0x00,0x00,0x06". + */ + public static final int UA_SECURITY_PROTOCOL_3GPP_IMS_MEDIA_PLANE = 6; + + /** + * Security protocol param used for Generation of Temporary IP + * Multimedia Private Identity (TMPI) according to TS 33.220 Annex B.4 + * Mapped to byte stream "0x01,0x00,0x00,0x01,0x00". + */ + public static final int UA_SECURITY_PROTOCOL_3GPP_GENERATION_TMPI = 0x0100; + + /** + * Security protocol param used for Shared key-based UE authentication with + * certificate-based NAF authentication, according to TS 33.222 section 5.3, + * or Shared key-based mutual authentication between UE and NAF, according to + * TS 33.222 section 5.4. Mapped to byte stream "0x01,0x00,0x01,yy,zz". + * "yy, zz" is the TLS CipherSuite code. + */ + public static final int UA_SECURITY_PROTOCOL_3GPP_TLS_DEFAULT = 0x010000; + + /** + * Security protocol param used for Shared key-based UE authentication with + * certificate-based NAF authentication, according to TS 33.222 Annex D. + * Mapped to byte stream "0x01,0x00,0x02,yy,zz". + * "yy, zz" is the TLS CipherSuite code. + */ + public static final int UA_SECURITY_PROTOCOL_3GPP_TLS_BROWSER = 0x020000; + + private static final int PROTOCOL_SIZE = 5; + private static final int[] sUaSp3gppIds = new int[] { + UA_SECURITY_PROTOCOL_3GPP_SUBSCRIBER_CERTIFICATE, + UA_SECURITY_PROTOCOL_3GPP_MBMS, + UA_SECURITY_PROTOCOL_3GPP_HTTP_DIGEST_AUTHENTICATION, + UA_SECURITY_PROTOCOL_3GPP_HTTP_BASED_MBMS, + UA_SECURITY_PROTOCOL_3GPP_SIP_BASED_MBMS, + UA_SECURITY_PROTOCOL_3GPP_GENERIC_PUSH_LAYER, + UA_SECURITY_PROTOCOL_3GPP_IMS_MEDIA_PLANE, + UA_SECURITY_PROTOCOL_3GPP_GENERATION_TMPI, + UA_SECURITY_PROTOCOL_3GPP_TLS_DEFAULT, + UA_SECURITY_PROTOCOL_3GPP_TLS_BROWSER}; + + private int mOrg; + private int mProtocol; + private int mTlsCipherSuite; + + private UaSecurityProtocolIdentifier() {} + + private UaSecurityProtocolIdentifier(UaSecurityProtocolIdentifier sp) { + mOrg = sp.mOrg; + mProtocol = sp.mProtocol; + mTlsCipherSuite = sp.mTlsCipherSuite; + } + + /** + * Returns the byte array representing the ua security protocol + */ + @NonNull + public byte[] toByteArray() { + byte[] data = new byte[PROTOCOL_SIZE]; + ByteBuffer buf = ByteBuffer.wrap(data); + buf.put((byte) mOrg); + buf.putInt(mProtocol | mTlsCipherSuite); + return data; + } + + /** + * Returns the organization code + */ + public @OrganizationCode int getOrg() { + return mOrg; + } + + /** + * Returns the security procotol id + * + * <p>Note that only 3GPP UA Security Protocols are supported for now + */ + public @UaSecurityProtocol3gpp int getProtocol() { + return mProtocol; + } + + /** + * Returns the TLS cipher suite + */ + public @TlsCipherSuite int getTlsCipherSuite() { + return mTlsCipherSuite; + } + + /** + * {@link Parcelable#writeToParcel} + */ + @Override + public void writeToParcel(@NonNull Parcel out, int flags) { + out.writeInt(mOrg); + out.writeInt(mProtocol); + out.writeInt(mTlsCipherSuite); + } + + /** + * {@link Parcelable.Creator} + * + */ + public static final @NonNull Parcelable.Creator< + UaSecurityProtocolIdentifier> CREATOR = new Creator<UaSecurityProtocolIdentifier>() { + @Nullable + @Override + public UaSecurityProtocolIdentifier createFromParcel(Parcel in) { + int org = in.readInt(); + int protocol = in.readInt(); + int cs = in.readInt(); + if (org < 0 || protocol < 0 || cs < 0) { + return null; + } + Builder builder = new Builder(); + try { + if (org > 0) { + builder.setOrg(org); + } + if (protocol > 0) { + builder.setProtocol(protocol); + } + if (cs > 0) { + builder.setTlsCipherSuite(cs); + } + } catch (IllegalArgumentException e) { + return null; + } + return builder.build(); + } + + @NonNull + @Override + public UaSecurityProtocolIdentifier[] newArray(int size) { + return new UaSecurityProtocolIdentifier[size]; + } + }; + + /** + * {@link Parcelable#describeContents} + */ + @Override + public int describeContents() { + return 0; + } + + @Override + public String toString() { + return "UaSecurityProtocolIdentifier[" + mOrg + " , " + (mProtocol | mTlsCipherSuite) + "]"; + } + + @Override + public boolean equals(Object obj) { + if (!(obj instanceof UaSecurityProtocolIdentifier)) { + return false; + } + + UaSecurityProtocolIdentifier other = (UaSecurityProtocolIdentifier) obj; + + return mOrg == other.mOrg && mProtocol == other.mProtocol + && mTlsCipherSuite == other.mTlsCipherSuite; + } + + @Override + public int hashCode() { + return Objects.hash(mOrg, mProtocol, mTlsCipherSuite); + } + + private boolean isTlsSupported() { + //TODO May update to support non 3gpp protocol in the future + if (mOrg == ORG_3GPP && (mProtocol == UA_SECURITY_PROTOCOL_3GPP_TLS_DEFAULT + || mProtocol == UA_SECURITY_PROTOCOL_3GPP_TLS_BROWSER)) { + return true; + } + + return false; + } + + /** + * Builder class for UaSecurityProtocolIdentifier + */ + public static final class Builder { + private final UaSecurityProtocolIdentifier mSp; + + /** + * Creates a Builder with default UaSecurityProtocolIdentifier, a.k.a 0x00 00 00 00 00 + */ + public Builder() { + mSp = new UaSecurityProtocolIdentifier(); + } + + /** + * Creates a Builder from a UaSecurityProtocolIdentifier + */ + public Builder(@NonNull final UaSecurityProtocolIdentifier sp) { + Objects.requireNonNull(sp); + mSp = new UaSecurityProtocolIdentifier(sp); + } + + /** + * Sets the organization code + * + * @param orgCode the organization code with the following value + * <ol> + * <li>{@link #ORG_NONE} </li> + * <li>{@link #ORG_3GPP} </li> + * <li>{@link #ORG_3GPP2} </li> + * <li>{@link #ORG_OMA} </li> + * <li>{@link #ORG_GSMA} </li> + * <li>{@link #ORG_LOCAL} </li> + * </ol> + * @throws IllegalArgumentException if it is not one of the value above. + * + * <p>Note that this method will reset the security protocol and TLS cipher suite + * if they have been set. + */ + @NonNull + public Builder setOrg(@OrganizationCode int orgCode) { + if (orgCode < ORG_NONE || orgCode > ORG_LOCAL) { + throw new IllegalArgumentException("illegal organization code"); + } + mSp.mOrg = orgCode; + mSp.mProtocol = 0; + mSp.mTlsCipherSuite = 0; + return this; + } + + /** + * Sets the UA security protocol for 3GPP + * + * @param protocol only 3GPP ua security protocol ID is supported for now, which + * is one of the following value + * <ol> + * <li>{@link #UA_SECURITY_PROTOCOL_3GPP_SUBSCRIBER_CERTIFICATE} </li> + * <li>{@link #UA_SECURITY_PROTOCOL_3GPP_MBMS} </li> + * <li>{@link #UA_SECURITY_PROTOCOL_3GPP_HTTP_DIGEST_AUTHENTICATION} </li> + * <li>{@link #UA_SECURITY_PROTOCOL_3GPP_HTTP_BASED_MBMS} </li> + * <li>{@link #UA_SECURITY_PROTOCOL_3GPP_SIP_BASED_MBMS} </li> + * <li>{@link #UA_SECURITY_PROTOCOL_3GPP_GENERIC_PUSH_LAYER} </li> + * <li>{@link #UA_SECURITY_PROTOCOL_3GPP_IMS_MEDIA_PLANE} </li> + * <li>{@link #UA_SECURITY_PROTOCOL_3GPP_GENERATION_TMPI} </li> + * <li>{@link #UA_SECURITY_PROTOCOL_3GPP_TLS_DEFAULT} </li> + * <li>{@link #UA_SECURITY_PROTOCOL_3GPP_TLS_BROWSER} </li> + * </ol> + * @throws IllegalArgumentException if the protocol is not one of the value above. + * + * <p>Note that this method will reset TLS cipher suite if it has been set. + */ + @NonNull + public Builder setProtocol(@UaSecurityProtocol3gpp int protocol) { + //TODO May update to support non 3gpp protocol in the future + if (protocol < UA_SECURITY_PROTOCOL_3GPP_SUBSCRIBER_CERTIFICATE + || (protocol > UA_SECURITY_PROTOCOL_3GPP_IMS_MEDIA_PLANE + && protocol != UA_SECURITY_PROTOCOL_3GPP_GENERATION_TMPI + && protocol != UA_SECURITY_PROTOCOL_3GPP_TLS_DEFAULT + && protocol != UA_SECURITY_PROTOCOL_3GPP_TLS_BROWSER) + || mSp.mOrg != ORG_3GPP) { + throw new IllegalArgumentException("illegal protocol code"); + } + mSp.mProtocol = protocol; + mSp.mTlsCipherSuite = 0; + return this; + } + + /** + * Sets the UA security protocol for 3GPP + * + * @param cs TLS cipher suite value defined by {@link TlsParams#TlsCipherSuite} + * @throws IllegalArgumentException if it is not a 3GPP ua security protocol, + * the protocol does not support TLS, or does not support the cipher suite. + */ + @NonNull + public Builder setTlsCipherSuite(@TlsCipherSuite int cs) { + if (!mSp.isTlsSupported()) { + throw new IllegalArgumentException("The protocol does not support TLS"); + } + if (!TlsParams.isTlsCipherSuiteSupported(cs)) { + throw new IllegalArgumentException("TLS cipher suite is not supported"); + } + mSp.mTlsCipherSuite = cs; + return this; + } + + /** + * Builds the instance of UaSecurityProtocolIdentifier + * + * @return the built instance of UaSecurityProtocolIdentifier + */ + @NonNull + public UaSecurityProtocolIdentifier build() { + return new UaSecurityProtocolIdentifier(mSp); + } + } +} diff --git a/telephony/java/android/telephony/gsm/OWNERS b/telephony/java/android/telephony/gsm/OWNERS new file mode 100644 index 000000000000..6aa399d9ebfb --- /dev/null +++ b/telephony/java/android/telephony/gsm/OWNERS @@ -0,0 +1,5 @@ +# Bug component: 20868 + +rgreenwalt@google.com +tgunn@google.com +amitmahajan@google.com diff --git a/telephony/java/android/telephony/ims/DelegateRegistrationState.java b/telephony/java/android/telephony/ims/DelegateRegistrationState.java index 3558a9b79ce0..66281edc0de1 100644 --- a/telephony/java/android/telephony/ims/DelegateRegistrationState.java +++ b/telephony/java/android/telephony/ims/DelegateRegistrationState.java @@ -62,7 +62,8 @@ public final class DelegateRegistrationState implements Parcelable { /** * This feature tag is being deregistered because the PDN that the IMS registration is on is *changing. - * All open SIP dialogs need to be closed before the PDN change can proceed. + * All open SIP dialogs need to be closed before the PDN change can proceed using + * {@link SipDelegateConnection#closeDialog(String)}. */ public static final int DEREGISTERING_REASON_PDN_CHANGE = 3; @@ -73,7 +74,8 @@ public final class DelegateRegistrationState implements Parcelable { * a user triggered hange, such as data being enabled/disabled. * <p> * All open SIP dialogs associated with the new deprovisioned feature tag need to be closed - * before the IMS registration modification can proceed. + * using {@link SipDelegateConnection#closeDialog(String)} before the IMS registration + * modification can proceed. */ public static final int DEREGISTERING_REASON_PROVISIONING_CHANGE = 4; @@ -81,8 +83,8 @@ public final class DelegateRegistrationState implements Parcelable { * This feature tag is deregistering because the SipDelegate associated with this feature tag * needs to change its supported feature set. * <p> - * All open SIP Dialogs associated with this feature tag must be closed before this operation - * can proceed. + * All open SIP Dialogs associated with this feature tag must be closed + * using {@link SipDelegateConnection#closeDialog(String)} before this operation can proceed. */ public static final int DEREGISTERING_REASON_FEATURE_TAGS_CHANGING = 5; @@ -90,8 +92,8 @@ public final class DelegateRegistrationState implements Parcelable { * This feature tag is deregistering because the SipDelegate is in the process of being * destroyed. * <p> - * All open SIP Dialogs associated with this feature tag must be closed before this operation - * can proceed. + * All open SIP Dialogs associated with this feature tag must be closed + * using {@link SipDelegateConnection#closeDialog(String)} before this operation can proceed. */ public static final int DEREGISTERING_REASON_DESTROY_PENDING = 6; diff --git a/telephony/java/android/telephony/ims/ImsCallProfile.java b/telephony/java/android/telephony/ims/ImsCallProfile.java index 66d18048b1f8..dace99932ca6 100644 --- a/telephony/java/android/telephony/ims/ImsCallProfile.java +++ b/telephony/java/android/telephony/ims/ImsCallProfile.java @@ -138,10 +138,26 @@ public final class ImsCallProfile implements Parcelable { * the video during voice call. * conference_avail : Indicates if the session can be extended to the conference. */ + /** + * Indicates if the session is for a conference call or not. If not defined, should be + * considered {@code false}. + * Boolean extra properties - {@code true} / {@code false}. + * @hide + */ + @SystemApi + public static final String EXTRA_CONFERENCE = "android.telephony.ims.extra.CONFERENCE"; + + /** + * The previous string of EXTRA_CONFERENCE. Use EXTRA_CONFERENCE whenever possible. + * For external app or vendor code backward compatibility, we should always set value for both + * EXTRA_CONFERENCE_DEPRECATED and EXTRA_CONFERENCE. + * + * @deprecated Remove when not needed anymore. + * * @hide */ - public static final String EXTRA_CONFERENCE = "conference"; + public static final String EXTRA_CONFERENCE_DEPRECATED = "conference"; /** * Boolean extra property set on an {@link ImsCallProfile} to indicate that this call is an @@ -158,7 +174,25 @@ public final class ImsCallProfile implements Parcelable { * @hide */ public static final String EXTRA_CALL_MODE_CHANGEABLE = "call_mode_changeable"; + /** + * Indicates if the session can be extended to a conference call. If not defined, should be + * considered {@code false}. + * Boolean extra properties - {@code true} / {@code false}. + * @hide + */ + @SystemApi + public static final String EXTRA_EXTENDING_TO_CONFERENCE_SUPPORTED = + "android.telephony.ims.extra.EXTENDING_TO_CONFERENCE_SUPPORTED"; + + /** + * The previous string of EXTRA_EXTENDING_TO_CONFERENCE_SUPPORTED. + * Use EXTRA_EXTENDING_TO_CONFERENCE_SUPPORTED whenever possible. + * For backward compatibility, we should always set value for both + * EXTRA_EXTENDING_TO_CONFERENCE_SUPPORTED and EXTRA_CONFERENCE_AVAIL. + * + * @deprecated Remove when not needed anymore. + * * @hide */ public static final String EXTRA_CONFERENCE_AVAIL = "conference_avail"; diff --git a/telephony/java/android/telephony/ims/ImsRcsManager.java b/telephony/java/android/telephony/ims/ImsRcsManager.java index 885ff9be550c..ad461c091493 100644 --- a/telephony/java/android/telephony/ims/ImsRcsManager.java +++ b/telephony/java/android/telephony/ims/ImsRcsManager.java @@ -30,7 +30,6 @@ import android.os.ServiceSpecificException; import android.provider.Settings; import android.telephony.AccessNetworkConstants; import android.telephony.BinderCacheManager; -import android.telephony.CarrierConfigManager; import android.telephony.TelephonyFrameworkInitializer; import android.telephony.ims.aidl.IImsCapabilityCallback; import android.telephony.ims.aidl.IImsRcsController; @@ -62,9 +61,10 @@ public class ImsRcsManager { * been enabled by the user can be queried using {@link RcsUceAdapter#isUceSettingEnabled()}. * <p> * This intent will always be handled by the system, however the application should only send - * this Intent if the carrier supports RCS contact discovery, which can be queried using the key - * {@link CarrierConfigManager#KEY_USE_RCS_PRESENCE_BOOL}. Otherwise, the RCS contact discovery - * opt-in dialog will not be shown. + * this Intent if the carrier supports bulk RCS contact exchange, which will be true if either + * key {@link android.telephony.CarrierConfigManager.Ims#KEY_RCS_BULK_CAPABILITY_EXCHANGE_BOOL} + * or {@link android.telephony.CarrierConfigManager#KEY_USE_RCS_PRESENCE_BOOL} is set to true. + * Otherwise, the RCS contact discovery opt-in dialog will not be shown. * <p> * Input: A mandatory {@link Settings#EXTRA_SUB_ID} extra containing the subscription that the * setting will be be shown for. @@ -396,6 +396,7 @@ public class ImsRcsManager { * rather the subscription is capable of this service over IMS. * @see #isAvailable(int) * @see android.telephony.CarrierConfigManager#KEY_USE_RCS_PRESENCE_BOOL + * @see android.telephony.CarrierConfigManager.Ims#KEY_ENABLE_PRESENCE_CAPABILITY_EXCHANGE_BOOL * @throws ImsException if the IMS service is not available when calling this method. * See {@link ImsException#getCode()} for more information on the error codes. * @hide diff --git a/telephony/java/android/telephony/ims/ImsReasonInfo.java b/telephony/java/android/telephony/ims/ImsReasonInfo.java index 184477af0b46..c14024975cf5 100644 --- a/telephony/java/android/telephony/ims/ImsReasonInfo.java +++ b/telephony/java/android/telephony/ims/ImsReasonInfo.java @@ -1322,6 +1322,13 @@ public final class ImsReasonInfo implements Parcelable { */ public static final int EXTRA_CODE_CALL_RETRY_BY_SETTINGS = 3; + /** + * An extra that may be populated when the {@link #CODE_LOCAL_CALL_CS_RETRY_REQUIRED} result has + * been returned. + * <p> + * Try to connect the call using CS as emergency + */ + public static final int EXTRA_CODE_CALL_RETRY_EMERGENCY = 4; // For main reason code /** @hide */ diff --git a/telephony/java/android/telephony/ims/OWNERS b/telephony/java/android/telephony/ims/OWNERS new file mode 100644 index 000000000000..0854c5d45603 --- /dev/null +++ b/telephony/java/android/telephony/ims/OWNERS @@ -0,0 +1,5 @@ +# Bug component: 20868 + +rgreenwalt@google.com +tgunn@google.com +breadley@google.com diff --git a/telephony/java/android/telephony/ims/ProvisioningManager.java b/telephony/java/android/telephony/ims/ProvisioningManager.java index 24ae979bb08d..f444c628cee3 100644 --- a/telephony/java/android/telephony/ims/ProvisioningManager.java +++ b/telephony/java/android/telephony/ims/ProvisioningManager.java @@ -21,6 +21,7 @@ import android.annotation.CallbackExecutor; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.RequiresPermission; +import android.annotation.SdkConstant; import android.annotation.StringDef; import android.annotation.SystemApi; import android.annotation.WorkerThread; @@ -31,6 +32,7 @@ import android.telephony.CarrierConfigManager; import android.telephony.SubscriptionManager; import android.telephony.TelephonyFrameworkInitializer; import android.telephony.ims.aidl.IImsConfigCallback; +import android.telephony.ims.aidl.IRcsConfigCallback; import android.telephony.ims.feature.MmTelFeature; import android.telephony.ims.feature.RcsFeature; import android.telephony.ims.stub.ImsConfigImplBase; @@ -936,6 +938,115 @@ public class ProvisioningManager { private int mSubId; /** + * The callback for RCS provisioning changes. + */ + public static class RcsProvisioningCallback { + private static class CallbackBinder extends IRcsConfigCallback.Stub { + + private final RcsProvisioningCallback mLocalCallback; + private Executor mExecutor; + + private CallbackBinder(RcsProvisioningCallback localCallback) { + mLocalCallback = localCallback; + } + + @Override + public void onConfigurationChanged(byte[] configXml) { + final long identity = Binder.clearCallingIdentity(); + try { + mExecutor.execute(() -> mLocalCallback.onConfigurationChanged(configXml)); + } finally { + Binder.restoreCallingIdentity(identity); + } + } + + @Override + public void onAutoConfigurationErrorReceived(int errorCode, String errorString) { + final long identity = Binder.clearCallingIdentity(); + try { + mExecutor.execute(() -> mLocalCallback.onAutoConfigurationErrorReceived( + errorCode, errorString)); + } finally { + Binder.restoreCallingIdentity(identity); + } + } + + @Override + public void onConfigurationReset() { + final long identity = Binder.clearCallingIdentity(); + try { + mExecutor.execute(() -> mLocalCallback.onConfigurationReset()); + } finally { + Binder.restoreCallingIdentity(identity); + } + } + + @Override + public void onRemoved() { + final long identity = Binder.clearCallingIdentity(); + try { + mExecutor.execute(() -> mLocalCallback.onRemoved()); + } finally { + Binder.restoreCallingIdentity(identity); + } + } + + private void setExecutor(Executor executor) { + mExecutor = executor; + } + } + + private final CallbackBinder mBinder = new CallbackBinder(this); + + /** + * RCS configuration received via OTA provisioning. Configuration may change + * due to various triggers defined in GSMA RCC.14 for ACS(auto configuration + * server) or other operator defined triggers. If RCS provisioning is already + * completed at the time of callback registration, then this method shall be + * invoked with the current configuration + * @param configXml The RCS configurationXML received OTA. + */ + public void onConfigurationChanged(@NonNull byte[] configXml) {} + + /** + * Errors during autoconfiguration connection setup are notified by the + * ACS(auto configuration server) client using this interface. + * @param errorCode HTTP error received during connection setup defined in + * GSMA RCC.14 2.4.3, like {@link java.net.HttpURLConnection#HTTP_UNAUTHORIZED}, + * {@link java.net.HttpURLConnection#HTTP_FORBIDDEN}, etc. + * @param errorString reason phrase received with the error + */ + public void onAutoConfigurationErrorReceived(int errorCode, + @NonNull String errorString) {} + + /** + * When the previously valid RCS configuration is cleaned up by telephony for + * any case like SIM removed, default messaging application changed, etc., + * this method will be invoked to notify the application regarding this change. + */ + public void onConfigurationReset() {} + + /** + * When the RCS application is no longer the Default messaging application, + * or when the subscription associated with this callback is removed (SIM + * removed, ESIM swap,etc...), callback will automatically be removed and + * the below method is invoked. There is a possibility that the method is + * invoked after the subscription has become inactive + */ + public void onRemoved() {} + + /**@hide*/ + public final IRcsConfigCallback getBinder() { + return mBinder; + } + + /**@hide*/ + public void setExecutor(Executor executor) { + mBinder.setExecutor(executor); + } + } + + /** * Create a new {@link ProvisioningManager} for the subscription specified. * * @param subId The ID of the subscription that this ProvisioningManager will use. @@ -1207,6 +1318,174 @@ public class ProvisioningManager { } + /** + * Provides the single registration capability of the device and the carrier. + * + * <p>This intent only provides the capability and not the current provisioning status of + * the RCS VoLTE single registration feature. Only default messaging application may receive + * the intent. + * + * <p>Contains {@link #EXTRA_SUBSCRIPTION_INDEX} to specify the subscription index for which + * the intent is valid. and {@link #EXTRA_STATUS} to specify RCS VoLTE single registration + * status. + */ + @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE) + @SdkConstant(SdkConstant.SdkConstantType.BROADCAST_INTENT_ACTION) + public static final String ACTION_RCS_SINGLE_REGISTRATION_CAPABILITY_UPDATE = + "android.telephony.ims.action.RCS_SINGLE_REGISTRATION_CAPABILITY_UPDATE"; + + /** + * Integer extra to specify subscription index. + */ + public static final String EXTRA_SUBSCRIPTION_ID = + "android.telephony.ims.extra.SUBSCRIPTION_ID"; + + /** + * Integer extra to specify RCS single registration status + * + * <p>The value can be {@link #STATUS_CAPABLE}, {@link #STATUS_DEVICE_NOT_CAPABLE}, + * {@link #STATUS_CARRIER_NOT_CAPABLE}, or bitwise OR of + * {@link #STATUS_DEVICE_NOT_CAPABLE} and {@link #STATUS_CARRIER_NOT_CAPABLE}. + */ + public static final String EXTRA_STATUS = "android.telephony.ims.extra.STATUS"; + + /** + * RCS VoLTE single registration is supported by the device and carrier. + */ + public static final int STATUS_CAPABLE = 0; + + /** + * RCS VoLTE single registration is not supported by the device. + */ + public static final int STATUS_DEVICE_NOT_CAPABLE = 0x01; + + /** + * RCS VoLTE single registration is not supported by the carrier + */ + public static final int STATUS_CARRIER_NOT_CAPABLE = 0x01 << 1; + + /** + * Provide the client configuration parameters of the RCS application. + * + * <p>When this application is also the default messaging application, and RCS + * provisioning is done using autoconfiguration, then these parameters shall be + * sent in the HTTP get request to fetch the RCS provisioning. RCS client + * configuration must be provided by the application before registering for the + * provisioning status events {@link #registerRcsProvisioningChangedCallback()} + * @param rcc RCS client configuration {@link RcsClientConfiguration} + */ + @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE) + public void setRcsClientConfiguration( + @NonNull RcsClientConfiguration rcc) throws ImsException { + try { + getITelephony().setRcsClientConfiguration(mSubId, rcc); + } catch (ServiceSpecificException e) { + throw new ImsException(e.getMessage(), e.errorCode); + } catch (RemoteException | IllegalStateException e) { + throw new ImsException(e.getMessage(), ImsException.CODE_ERROR_SERVICE_UNAVAILABLE); + } + } + + /** + * Returns a flag to indicate if the device software and the carrier + * have the capability to support RCS Volte single IMS registration. + * @return true if this single registration is capable, false otherwise + * @throws ImsException If the remote ImsService is not available for + * any reason or the subscription associated with this instance is no + * longer active. See {@link ImsException#getCode()} for more + * information. + */ + @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE) + public boolean isRcsVolteSingleRegistrationCapable() throws ImsException { + try { + return getITelephony().isRcsVolteSingleRegistrationCapable(mSubId); + } catch (RemoteException | IllegalStateException e) { + throw new ImsException(e.getMessage(), ImsException.CODE_ERROR_SERVICE_UNAVAILABLE); + } + } + + /** + * Registers a new {@link RcsProvisioningCallback} to listen to changes to + * RCS provisioning xml. + * + * <p>RCS application must be the default messaging application and must + * have already registered its {@link RcsClientConfiguration} by using + * {@link #setRcsClientConfiguration} before it registers the provisioning + * callback. If ProvisioningManager has a valid RCS configuration at the + * time of callback registration and a reconfiguration is not required + * due to RCS client parameters change, then the callback shall be invoked + * immediately with the xml. + * When the subscription associated with this callback is removed (SIM removed, + * ESIM swap,etc...), this callback will automatically be removed. + * + * @param executor The {@link Executor} to call the callback methods on + * @param callback The rcs provisioning callback to be registered. + * @see #unregisterRcsProvisioningChangedCallback(RcsProvisioningCallback) + * @see SubscriptionManager.OnSubscriptionsChangedListener + * @throws IllegalArgumentException if the subscription associated with this + * callback is not active (SIM is not inserted, ESIM inactive) or the + * subscription is invalid. + * @throws ImsException if the subscription associated with this callback is + * valid, but the {@link ImsService} associated with the subscription is not + * available. This can happen if the service crashed, for example. + * It shall also throw this exception when the RCS client parameters for the + * application are not valid. In that case application must set the client + * params (See {@link #setRcsClientConfiguration()}) and re register the + * callback. + * See {@link ImsException#getCode()} for a more detailed reason. + */ + @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE) + public void registerRcsProvisioningChangedCallback( + @NonNull @CallbackExecutor Executor executor, + @NonNull RcsProvisioningCallback callback) throws ImsException { + callback.setExecutor(executor); + try { + getITelephony().registerRcsProvisioningChangedCallback(mSubId, callback.getBinder()); + } catch (ServiceSpecificException e) { + throw new ImsException(e.getMessage(), e.errorCode); + } catch (RemoteException | IllegalStateException e) { + throw new ImsException(e.getMessage(), ImsException.CODE_ERROR_SERVICE_UNAVAILABLE); + } + } + + /** + * Unregister an existing {@link RcsProvisioningCallback}. Application can + * unregister when its no longer interested in the provisioning updates + * like when a user disables RCS from the UI/settings. + * When the subscription associated with this callback is removed (SIM + * removed, ESIM swap, etc...), this callback will automatically be + * removed. If this method is called for an inactive subscription, it + * will result in a no-op. + * @param callback The existing {@link RcsProvisioningCallback} to be + * removed. + * @see #registerRcsProvisioningChangedCallback(RcsClientConfiguration, + * Executor, RcsProvisioningCallback) @throws IllegalArgumentException + * if the subscription associated with this callback is invalid. + */ + @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE) + public void unregisterRcsProvisioningChangedCallback( + @NonNull RcsProvisioningCallback callback) { + try { + getITelephony().unregisterRcsProvisioningChangedCallback( + mSubId, callback.getBinder()); + } catch (RemoteException e) { + throw e.rethrowAsRuntimeException(); + } + } + + /** + * Reconfiguration triggered by the RCS application. Most likely cause + * is the 403 forbidden to a HTTP request. + */ + @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE) + public void triggerRcsReconfiguration() { + try { + getITelephony().triggerRcsReconfiguration(mSubId); + } catch (RemoteException e) { + throw e.rethrowAsRuntimeException(); + } + } + private static ITelephony getITelephony() { ITelephony binder = ITelephony.Stub.asInterface( TelephonyFrameworkInitializer diff --git a/telephony/java/android/telephony/ims/RcsClientConfiguration.aidl b/telephony/java/android/telephony/ims/RcsClientConfiguration.aidl new file mode 100644 index 000000000000..a702f0f42c54 --- /dev/null +++ b/telephony/java/android/telephony/ims/RcsClientConfiguration.aidl @@ -0,0 +1,19 @@ +/* + * Copyright (C) 2020 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 RcsClientConfiguration; diff --git a/telephony/java/android/telephony/ims/RcsClientConfiguration.java b/telephony/java/android/telephony/ims/RcsClientConfiguration.java new file mode 100644 index 000000000000..793c37745de6 --- /dev/null +++ b/telephony/java/android/telephony/ims/RcsClientConfiguration.java @@ -0,0 +1,162 @@ +/* + * 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.ims; + +import android.annotation.NonNull; +import android.annotation.StringDef; +import android.annotation.SystemApi; +import android.os.Parcel; +import android.os.Parcelable; + +import java.util.Objects; + +/** + * The container of RCS application related configs. + * + * @hide + */ +@SystemApi +public final class RcsClientConfiguration implements Parcelable { + + /**@hide*/ + @StringDef(prefix = "RCS_PROFILE_", + value = {RCS_PROFILE_1_0, RCS_PROFILE_2_3}) + public @interface StringRcsProfile {} + + /** + * RCS profile UP 1.0 + */ + public static final String RCS_PROFILE_1_0 = "UP_1.0"; + /** + * RCS profile UP 2.3 + */ + public static final String RCS_PROFILE_2_3 = "UP_2.3"; + + private String mRcsVersion; + private String mRcsProfile; + private String mClientVendor; + private String mClientVersion; + + /** + * Create a RcsClientConfiguration object. + * Default messaging application must pass a valid configuration object + * @param rcsVersion The parameter identifies the RCS version supported + * by the client. Refer to GSMA RCC.07 "rcs_version" parameter. + * @param rcsProfile Identifies a fixed set of RCS services that are + * supported by the client. See {@link #RCS_PROFILE_1_0 } or + * {@link #RCS_PROFILE_2_3 } + * @param clientVendor Identifies the vendor providing the RCS client. + * @param clientVersion Identifies the RCS client version. Refer to GSMA + * RCC.07 "client_version" parameter. + * Example:client_version=RCSAndrd-1.0 + */ + public RcsClientConfiguration(@NonNull String rcsVersion, + @NonNull @StringRcsProfile String rcsProfile, + @NonNull String clientVendor, @NonNull String clientVersion) { + mRcsVersion = rcsVersion; + mRcsProfile = rcsProfile; + mClientVendor = clientVendor; + mClientVersion = clientVersion; + } + + /** + * Returns RCS version supported. + */ + public @NonNull String getRcsVersion() { + return mRcsVersion; + } + + /** + * Returns RCS profile supported. + */ + public @NonNull @StringRcsProfile String getRcsProfile() { + return mRcsProfile; + } + + /** + * Returns the name of the vendor providing the RCS client. + */ + public @NonNull String getClientVendor() { + return mClientVendor; + } + + /** + * Returns the RCS client version. + */ + public @NonNull String getClientVersion() { + return mClientVersion; + } + + /** + * {@link Parcelable#writeToParcel} + */ + @Override + public void writeToParcel(@NonNull Parcel out, int flags) { + out.writeString(mRcsVersion); + out.writeString(mRcsProfile); + out.writeString(mClientVendor); + out.writeString(mClientVersion); + } + + /** + * {@link Parcelable.Creator} + * + */ + public static final @android.annotation.NonNull Parcelable.Creator< + RcsClientConfiguration> CREATOR = new Creator<RcsClientConfiguration>() { + @Override + public RcsClientConfiguration createFromParcel(Parcel in) { + String rcsVersion = in.readString(); + String rcsProfile = in.readString(); + String clientVendor = in.readString(); + String clientVersion = in.readString(); + return new RcsClientConfiguration(rcsVersion, rcsProfile, + clientVendor, clientVersion); + } + + @Override + public RcsClientConfiguration[] newArray(int size) { + return new RcsClientConfiguration[size]; + } + }; + + /** + * {@link Parcelable#describeContents} + */ + @Override + public int describeContents() { + return 0; + } + + @Override + public boolean equals(Object obj) { + if (!(obj instanceof RcsClientConfiguration)) { + return false; + } + + RcsClientConfiguration other = (RcsClientConfiguration) obj; + + return mRcsVersion.equals(other.mRcsVersion) && mRcsProfile.equals(other.mRcsProfile) + && mClientVendor.equals(other.mClientVendor) + && mClientVersion.equals(other.mClientVersion); + } + + @Override + public int hashCode() { + return Objects.hash(mRcsVersion, mRcsProfile, mClientVendor, mClientVersion); + } +} diff --git a/telephony/java/android/telephony/ims/RcsConfig.aidl b/telephony/java/android/telephony/ims/RcsConfig.aidl new file mode 100644 index 000000000000..cfd93fbe2edb --- /dev/null +++ b/telephony/java/android/telephony/ims/RcsConfig.aidl @@ -0,0 +1,19 @@ +/* + * Copyright (C) 2020 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 RcsConfig; diff --git a/telephony/java/android/telephony/ims/RcsConfig.java b/telephony/java/android/telephony/ims/RcsConfig.java new file mode 100644 index 000000000000..07e95cc99290 --- /dev/null +++ b/telephony/java/android/telephony/ims/RcsConfig.java @@ -0,0 +1,306 @@ +/* + * Copyright (C) 2020 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.content.ContentValues; +import android.content.Context; +import android.database.Cursor; +import android.os.Build; +import android.os.Parcel; +import android.os.Parcelable; +import android.provider.Telephony.SimInfo; +import android.text.TextUtils; + +import com.android.telephony.Rlog; + +import org.xmlpull.v1.XmlPullParser; +import org.xmlpull.v1.XmlPullParserException; +import org.xmlpull.v1.XmlPullParserFactory; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.util.HashMap; +import java.util.zip.GZIPInputStream; +import java.util.zip.GZIPOutputStream; + +/** + * RCS config data and methods to process the config + * @hide + */ +public final class RcsConfig implements Parcelable { + private static final String LOG_TAG = "RcsConfig"; + private static final boolean DBG = Build.IS_ENG; + + private final HashMap<String, String> mValues = new HashMap<>(); + + private RcsConfig(HashMap<String, String> values) { + mValues.putAll(values); + } + + public RcsConfig(byte[] data) throws IllegalArgumentException { + if (data == null || data.length == 0) { + throw new IllegalArgumentException("Empty data"); + } + ByteArrayInputStream inputStream = new ByteArrayInputStream(data); + try { + XmlPullParserFactory factory = XmlPullParserFactory.newInstance(); + factory.setNamespaceAware(true); + XmlPullParser xpp = factory.newPullParser(); + xpp.setInput(inputStream, null); + int eventType = xpp.getEventType(); + String tag = null; + while (eventType != XmlPullParser.END_DOCUMENT) { + if (eventType == XmlPullParser.START_TAG) { + tag = xpp.getName().trim(); + } else if (eventType == XmlPullParser.END_TAG) { + tag = null; + } else if (eventType == XmlPullParser.TEXT) { + String value = xpp.getText().trim(); + if (!TextUtils.isEmpty(tag) && !TextUtils.isEmpty(value)) { + mValues.put(tag, value); + } + } + eventType = xpp.next(); + } + } catch (IOException | XmlPullParserException e) { + throw new IllegalArgumentException(e); + } finally { + try { + inputStream.close(); + } catch (IOException e) { + loge("error to close input stream, skip."); + } + } + } + + /** + * Retrieve a String value of the config item with the tag + * + * @param tag The name of the config to retrieve. + * @param defaultVal Value to return if the config does not exist. + * + * @return Returns the config value if it exists, or defaultVal. + */ + public @Nullable String getString(@NonNull String tag, @Nullable String defaultVal) { + return mValues.containsKey(tag) ? mValues.get(tag) : defaultVal; + } + + /** + * Retrieve a int value of the config item with the tag + * + * @param tag The name of the config to retrieve. + * @param defaultVal Value to return if the config does not exist or not valid. + * + * @return Returns the config value if it exists and is a valid int, or defaultVal. + */ + public int getInteger(@NonNull String tag, int defaultVal) { + try { + return Integer.parseInt(mValues.get(tag)); + } catch (NumberFormatException e) { + logd("error to getInteger for " + tag + " due to " + e); + } + return defaultVal; + } + + /** + * Retrieve a boolean value of the config item with the tag + * + * @param tag The name of the config to retrieve. + * @param defaultVal Value to return if the config does not exist. + * + * @return Returns the config value if it exists, or defaultVal. + */ + public boolean getBoolean(@NonNull String tag, boolean defaultVal) { + if (!mValues.containsKey(tag)) { + return defaultVal; + } + return Boolean.parseBoolean(mValues.get(tag)); + } + + /** + * Check whether the config item exists + * + * @param tag The name of the config to retrieve. + * + * @return Returns true if it exists, or false. + */ + public boolean hasConfig(@NonNull String tag) { + return mValues.containsKey(tag); + } + + @Override + public String toString() { + final StringBuilder sb = new StringBuilder(); + sb.append("[RCS Config]"); + if (DBG) { + mValues.forEach((t, v) -> { + sb.append("\n"); + sb.append(t); + sb.append(" : "); + sb.append(v); + }); + } + return sb.toString(); + } + + @Override + public boolean equals(Object obj) { + if (!(obj instanceof RcsConfig)) { + return false; + } + + RcsConfig other = (RcsConfig) obj; + + return mValues.equals(other.mValues); + } + + @Override + public int hashCode() { + return mValues.hashCode(); + } + + /** + * compress the gzip format data + */ + public static @Nullable byte[] compressGzip(@NonNull byte[] data) { + if (data == null || data.length == 0) { + return data; + } + byte[] out = null; + try { + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(data.length); + GZIPOutputStream gzipCompressingStream = + new GZIPOutputStream(outputStream); + gzipCompressingStream.write(data); + gzipCompressingStream.close(); + out = outputStream.toByteArray(); + outputStream.close(); + } catch (IOException e) { + loge("Error to compressGzip due to " + e); + } + return out; + } + + /** + * decompress the gzip format data + */ + public static @Nullable byte[] decompressGzip(@NonNull byte[] data) { + if (data == null || data.length == 0) { + return data; + } + byte[] out = null; + try { + ByteArrayInputStream inputStream = new ByteArrayInputStream(data); + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + GZIPInputStream gzipDecompressingStream = + new GZIPInputStream(inputStream); + byte[] buf = new byte[1024]; + int size = gzipDecompressingStream.read(buf); + while (size >= 0) { + outputStream.write(buf, 0, size); + size = gzipDecompressingStream.read(buf); + } + gzipDecompressingStream.close(); + inputStream.close(); + out = outputStream.toByteArray(); + outputStream.close(); + } catch (IOException e) { + loge("Error to decompressGzip due to " + e); + } + return out; + } + + /** + * save the config to siminfo db. It is only used internally. + */ + public static void updateConfigForSub(@NonNull Context cxt, int subId, + @NonNull byte[] config, boolean isCompressed) { + //always store gzip compressed data + byte[] data = isCompressed ? config : compressGzip(config); + ContentValues values = new ContentValues(); + values.put(SimInfo.COLUMN_RCS_CONFIG, data); + cxt.getContentResolver().update(SimInfo.CONTENT_URI, values, + SimInfo.COLUMN_UNIQUE_KEY_SUBSCRIPTION_ID + "=" + subId, null); + } + + /** + * load the config from siminfo db. It is only used internally. + */ + public static @Nullable byte[] loadRcsConfigForSub(@NonNull Context cxt, + int subId, boolean isCompressed) { + + byte[] data = null; + + Cursor cursor = cxt.getContentResolver().query(SimInfo.CONTENT_URI, null, + SimInfo.COLUMN_UNIQUE_KEY_SUBSCRIPTION_ID + "=" + subId, null, null); + try { + if (cursor != null && cursor.moveToFirst()) { + data = cursor.getBlob(cursor.getColumnIndexOrThrow(SimInfo.COLUMN_RCS_CONFIG)); + } + } catch (Exception e) { + loge("error to load rcs config for sub:" + subId + " due to " + e); + } finally { + if (cursor != null) { + cursor.close(); + } + } + return isCompressed ? data : decompressGzip(data); + } + + /** + * {@link Parcelable#writeToParcel} + */ + public void writeToParcel(@NonNull Parcel out, int flags) { + out.writeMap(mValues); + } + + /** + * {@link Parcelable.Creator} + * + */ + public static final @NonNull Parcelable.Creator<RcsConfig> + CREATOR = new Creator<RcsConfig>() { + @Override + public RcsConfig createFromParcel(Parcel in) { + HashMap<String, String> values = in.readHashMap(null); + return values == null ? null : new RcsConfig(values); + } + + @Override + public RcsConfig[] newArray(int size) { + return new RcsConfig[size]; + } + }; + + /** + * {@link Parcelable#describeContents} + */ + public int describeContents() { + return 0; + } + + private static void logd(String msg) { + Rlog.d(LOG_TAG, msg); + } + + private static void loge(String msg) { + Rlog.e(LOG_TAG, msg); + } +} diff --git a/telephony/java/android/telephony/ims/RcsContactPresenceTuple.java b/telephony/java/android/telephony/ims/RcsContactPresenceTuple.java index b0aaa92dd0ac..e4d20e965c49 100644 --- a/telephony/java/android/telephony/ims/RcsContactPresenceTuple.java +++ b/telephony/java/android/telephony/ims/RcsContactPresenceTuple.java @@ -39,6 +39,10 @@ public class RcsContactPresenceTuple implements Parcelable { /** The service id of the MMTEL */ public static final String SERVICE_ID_MMTEL = "org.3gpp.urn:urn-7:3gpp-service.ims.icsi.mmtel"; + /** The service id of the Call Composer */ + public static final String SERVICE_ID_CALL_COMPOSER = + "org.3gpp.urn:urn-7:3gppservice.ims.icsi.gsma.callcomposer"; + /** The service capabilities is available. */ public static final String TUPLE_BASIC_STATUS_OPEN = "open"; diff --git a/telephony/java/android/telephony/ims/SipDelegateConnection.java b/telephony/java/android/telephony/ims/SipDelegateConnection.java index c3cc1edf590b..04a772cd873d 100644 --- a/telephony/java/android/telephony/ims/SipDelegateConnection.java +++ b/telephony/java/android/telephony/ims/SipDelegateConnection.java @@ -62,6 +62,22 @@ public interface SipDelegateConnection { void notifyMessageReceived(@NonNull String viaTransactionId); /** + * The SIP Dialog associated with the provided Call-ID is being closed and routing resources + * associated with the SIP dialog are free to be released. + * <p> + * Calling this method is also mandatory for situations where the framework IMS stack is waiting + * for pending SIP dialogs to be closed before it can perform a handover or apply a provisioning + * change. See {@link DelegateRegistrationState} for more information about + * the scenarios where this can occur. + * <p> + * This method will need to be called for each SIP dialog managed by this application when it is + * closed. + * @param callId The call-ID header value associated with the ongoing SIP Dialog that is + * closing. + */ + void closeDialog(@NonNull String callId); + + /** * Notify the SIP delegate that the SIP message has been received from * {@link DelegateMessageCallback#onMessageReceived(SipMessage)}, however there was an error * processing it. diff --git a/telephony/java/android/telephony/ims/SipDelegateManager.java b/telephony/java/android/telephony/ims/SipDelegateManager.java index 2ec88ff27f93..2e9eb94605a5 100644 --- a/telephony/java/android/telephony/ims/SipDelegateManager.java +++ b/telephony/java/android/telephony/ims/SipDelegateManager.java @@ -18,7 +18,9 @@ package android.telephony.ims; import android.Manifest; import android.annotation.IntDef; +import android.annotation.IntRange; import android.annotation.NonNull; +import android.annotation.Nullable; import android.annotation.RequiresPermission; import android.annotation.SystemApi; import android.content.Context; @@ -372,4 +374,37 @@ public class SipDelegateManager { + " into this method"); } } + + /** + * Trigger a full network registration as required by receiving a SIP message containing a + * permanent error from the network or never receiving a response to a SIP transaction request. + * + * @param connection The {@link SipDelegateConnection} that was being used when this error was + * received. + * @param sipCode The SIP code response associated with the SIP message request that + * triggered this condition. + * @param sipReason The SIP reason code associated with the SIP message request that triggered + * this condition. May be {@code null} if there was no reason String provided from the + * network. + */ + public void triggerFullNetworkRegistration(@NonNull SipDelegateConnection connection, + @IntRange(from = 100, to = 699) int sipCode, @Nullable String sipReason) { + if (connection == null) { + throw new IllegalArgumentException("invalid connection."); + } + if (connection instanceof SipDelegateConnectionAidlWrapper) { + SipDelegateConnectionAidlWrapper w = (SipDelegateConnectionAidlWrapper) connection; + try { + IImsRcsController controller = mBinderCache.getBinder(); + controller.triggerNetworkRegistration(mSubId, w.getSipDelegateBinder(), sipCode, + sipReason); + } catch (RemoteException e) { + // Connection to telephony died, but this will signal destruction of SipDelegate + // eventually anyway, so return. + } + } else { + throw new IllegalArgumentException("Unknown SipDelegateConnection implementation passed" + + " into this method"); + } + } } diff --git a/telephony/java/android/telephony/ims/aidl/IImsConfig.aidl b/telephony/java/android/telephony/ims/aidl/IImsConfig.aidl index 57206c9f059a..5eee3890f1dc 100644 --- a/telephony/java/android/telephony/ims/aidl/IImsConfig.aidl +++ b/telephony/java/android/telephony/ims/aidl/IImsConfig.aidl @@ -18,8 +18,9 @@ package android.telephony.ims.aidl; import android.os.PersistableBundle; - import android.telephony.ims.aidl.IImsConfigCallback; +import android.telephony.ims.aidl.IRcsConfigCallback; +import android.telephony.ims.RcsClientConfiguration; import com.android.ims.ImsConfigListener; @@ -41,4 +42,9 @@ interface IImsConfig { int setConfigString(int item, String value); void updateImsCarrierConfigs(in PersistableBundle bundle); void notifyRcsAutoConfigurationReceived(in byte[] config, boolean isCompressed); + void notifyRcsAutoConfigurationRemoved(); + void addRcsConfigCallback(IRcsConfigCallback c); + void removeRcsConfigCallback(IRcsConfigCallback c); + void triggerRcsReconfiguration(); + void setRcsClientConfiguration(in RcsClientConfiguration rcc); } diff --git a/telephony/java/android/telephony/ims/aidl/IImsRcsController.aidl b/telephony/java/android/telephony/ims/aidl/IImsRcsController.aidl index c6d9a8629556..36349895c35b 100644 --- a/telephony/java/android/telephony/ims/aidl/IImsRcsController.aidl +++ b/telephony/java/android/telephony/ims/aidl/IImsRcsController.aidl @@ -67,6 +67,8 @@ interface IImsRcsController { ISipDelegateConnectionStateCallback delegateState, ISipDelegateMessageCallback delegateMessage); void destroySipDelegate(int subId, ISipDelegate connection, int reason); + void triggerNetworkRegistration(int subId, ISipDelegate connection, int sipCode, + String sipReason); // Internal commands that should not be made public void registerRcsFeatureCallback(int slotId, in IImsServiceFeatureCallback callback); diff --git a/telephony/java/android/telephony/ims/aidl/IImsRcsFeature.aidl b/telephony/java/android/telephony/ims/aidl/IImsRcsFeature.aidl index b47e3c75b558..10c50bed34d7 100644 --- a/telephony/java/android/telephony/ims/aidl/IImsRcsFeature.aidl +++ b/telephony/java/android/telephony/ims/aidl/IImsRcsFeature.aidl @@ -22,7 +22,6 @@ import android.telephony.ims.aidl.ICapabilityExchangeEventListener; import android.telephony.ims.aidl.IImsCapabilityCallback; import android.telephony.ims.aidl.IOptionsResponseCallback; import android.telephony.ims.aidl.IPublishResponseCallback; -import android.telephony.ims.aidl.IRcsFeatureListener; import android.telephony.ims.aidl.ISubscribeResponseCallback; import android.telephony.ims.feature.CapabilityChangeRequest; @@ -34,7 +33,6 @@ import java.util.List; */ interface IImsRcsFeature { // Not oneway because we need to verify this completes before doing anything else. - void setListener(IRcsFeatureListener listener); int queryCapabilityStatus(); // Inherited from ImsFeature int getFeatureState(); @@ -50,14 +48,4 @@ interface IImsRcsFeature { oneway void subscribeForCapabilities(in List<Uri> uris, ISubscribeResponseCallback cb); oneway void sendOptionsCapabilityRequest(in Uri contactUri, in List<String> myCapabilities, IOptionsResponseCallback cb); - // RcsPresenceExchangeImplBase specific api - oneway void requestCapabilities(in List<Uri> uris, int operationToken); - oneway void updateCapabilities(in RcsContactUceCapability capabilities, int operationToken); - // RcsSipOptionsImplBase specific api - oneway void sendCapabilityRequest(in Uri contactUri, - in RcsContactUceCapability capabilities, int operationToken); - oneway void respondToCapabilityRequest(in String contactUri, - in RcsContactUceCapability ownCapabilities, int operationToken); - oneway void respondToCapabilityRequestWithError(in Uri contactUri, int code, in String reason, - int operationToken); } diff --git a/telephony/java/android/telephony/ims/aidl/IImsRegistration.aidl b/telephony/java/android/telephony/ims/aidl/IImsRegistration.aidl index 4ae0a75ad027..4fd904041365 100644 --- a/telephony/java/android/telephony/ims/aidl/IImsRegistration.aidl +++ b/telephony/java/android/telephony/ims/aidl/IImsRegistration.aidl @@ -28,4 +28,7 @@ interface IImsRegistration { int getRegistrationTechnology(); oneway void addRegistrationCallback(IImsRegistrationCallback c); oneway void removeRegistrationCallback(IImsRegistrationCallback c); -}
\ No newline at end of file + oneway void triggerFullNetworkRegistration(int sipCode, String sipReason); + oneway void triggerUpdateSipDelegateRegistration(); + oneway void triggerSipDelegateDeregistration(); +} diff --git a/telephony/java/android/telephony/ims/aidl/IRcsConfigCallback.aidl b/telephony/java/android/telephony/ims/aidl/IRcsConfigCallback.aidl new file mode 100644 index 000000000000..5a8973e37bce --- /dev/null +++ b/telephony/java/android/telephony/ims/aidl/IRcsConfigCallback.aidl @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2020 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; + +/** + * The callback for RCS provisioning changes. + * {@hide} + */ +oneway interface IRcsConfigCallback { + void onConfigurationChanged(in byte[] config); + void onAutoConfigurationErrorReceived(int errorCode, String errorString); + void onConfigurationReset(); + void onRemoved(); +} + diff --git a/telephony/java/android/telephony/ims/aidl/IRcsFeatureListener.aidl b/telephony/java/android/telephony/ims/aidl/IRcsFeatureListener.aidl deleted file mode 100644 index 70cf651d3924..000000000000 --- a/telephony/java/android/telephony/ims/aidl/IRcsFeatureListener.aidl +++ /dev/null @@ -1,42 +0,0 @@ -/* - * 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.ims.aidl; - -import android.net.Uri; -import android.telephony.ims.RcsContactUceCapability; - -import java.util.List; - -/** - * Listener interface for updates from the RcsFeature back to the framework. - * {@hide} - */ -interface IRcsFeatureListener { - //RcsCapabilityExchange specific - oneway void onCommandUpdate(int commandCode, int operationToken); - // RcsPresenceExchangeImplBase Specific - oneway void onNetworkResponse(int code, in String reason, int operationToken); - oneway void onCapabilityRequestResponsePresence(in List<RcsContactUceCapability> infos, - int operationToken); - oneway void onNotifyUpdateCapabilities(int publishTriggerType); - oneway void onUnpublish(); - // RcsSipOptionsImplBase specific - oneway void onCapabilityRequestResponseOptions(int code, in String reason, - in RcsContactUceCapability info, int operationToken); - oneway void onRemoteCapabilityRequest(in Uri contactUri, in RcsContactUceCapability remoteInfo, - int operationToken); -} diff --git a/telephony/java/android/telephony/ims/aidl/ISipDelegate.aidl b/telephony/java/android/telephony/ims/aidl/ISipDelegate.aidl index 5d6766a65155..ad75be439da8 100644 --- a/telephony/java/android/telephony/ims/aidl/ISipDelegate.aidl +++ b/telephony/java/android/telephony/ims/aidl/ISipDelegate.aidl @@ -26,7 +26,5 @@ oneway interface ISipDelegate { void sendMessage(in SipMessage sipMessage, long configVersion); void notifyMessageReceived(in String viaTransactionId); void notifyMessageReceiveError(in String viaTransactionId, int reason); - - // only used by SipDelegate. void closeDialog(in String callId); } diff --git a/telephony/java/android/telephony/ims/aidl/OWNERS b/telephony/java/android/telephony/ims/aidl/OWNERS new file mode 100644 index 000000000000..0854c5d45603 --- /dev/null +++ b/telephony/java/android/telephony/ims/aidl/OWNERS @@ -0,0 +1,5 @@ +# Bug component: 20868 + +rgreenwalt@google.com +tgunn@google.com +breadley@google.com diff --git a/telephony/java/android/telephony/ims/aidl/SipDelegateConnectionAidlWrapper.java b/telephony/java/android/telephony/ims/aidl/SipDelegateConnectionAidlWrapper.java index 29ba8e2d50c4..a35039bd7668 100644 --- a/telephony/java/android/telephony/ims/aidl/SipDelegateConnectionAidlWrapper.java +++ b/telephony/java/android/telephony/ims/aidl/SipDelegateConnectionAidlWrapper.java @@ -199,6 +199,19 @@ public class SipDelegateConnectionAidlWrapper implements SipDelegateConnection, } } + @Override + public void closeDialog(String callId) { + try { + ISipDelegate conn = getSipDelegateBinder(); + if (conn == null) { + return; + } + conn.closeDialog(callId); + } catch (RemoteException e) { + // Nothing to do here, app will eventually get remote death callback. + } + } + // Also called upon IImsRcsController death (telephony process dies). @Override public void binderDied() { diff --git a/telephony/java/android/telephony/ims/compat/OWNERS b/telephony/java/android/telephony/ims/compat/OWNERS new file mode 100644 index 000000000000..0854c5d45603 --- /dev/null +++ b/telephony/java/android/telephony/ims/compat/OWNERS @@ -0,0 +1,5 @@ +# Bug component: 20868 + +rgreenwalt@google.com +tgunn@google.com +breadley@google.com diff --git a/telephony/java/android/telephony/ims/compat/feature/OWNERS b/telephony/java/android/telephony/ims/compat/feature/OWNERS new file mode 100644 index 000000000000..0854c5d45603 --- /dev/null +++ b/telephony/java/android/telephony/ims/compat/feature/OWNERS @@ -0,0 +1,5 @@ +# Bug component: 20868 + +rgreenwalt@google.com +tgunn@google.com +breadley@google.com diff --git a/telephony/java/android/telephony/ims/compat/stub/OWNERS b/telephony/java/android/telephony/ims/compat/stub/OWNERS new file mode 100644 index 000000000000..0854c5d45603 --- /dev/null +++ b/telephony/java/android/telephony/ims/compat/stub/OWNERS @@ -0,0 +1,5 @@ +# Bug component: 20868 + +rgreenwalt@google.com +tgunn@google.com +breadley@google.com diff --git a/telephony/java/android/telephony/ims/feature/OWNERS b/telephony/java/android/telephony/ims/feature/OWNERS new file mode 100644 index 000000000000..0854c5d45603 --- /dev/null +++ b/telephony/java/android/telephony/ims/feature/OWNERS @@ -0,0 +1,5 @@ +# Bug component: 20868 + +rgreenwalt@google.com +tgunn@google.com +breadley@google.com diff --git a/telephony/java/android/telephony/ims/feature/RcsFeature.java b/telephony/java/android/telephony/ims/feature/RcsFeature.java index 5de2ddc578a1..cde7067e8bf3 100644 --- a/telephony/java/android/telephony/ims/feature/RcsFeature.java +++ b/telephony/java/android/telephony/ims/feature/RcsFeature.java @@ -19,17 +19,16 @@ 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.net.Uri; import android.os.RemoteException; -import android.telephony.ims.RcsContactUceCapability; import android.telephony.ims.RcsUceAdapter; import android.telephony.ims.aidl.ICapabilityExchangeEventListener; import android.telephony.ims.aidl.IImsCapabilityCallback; import android.telephony.ims.aidl.IImsRcsFeature; import android.telephony.ims.aidl.IOptionsResponseCallback; import android.telephony.ims.aidl.IPublishResponseCallback; -import android.telephony.ims.aidl.IRcsFeatureListener; import android.telephony.ims.aidl.ISubscribeResponseCallback; import android.telephony.ims.aidl.RcsOptionsResponseAidlWrapper; import android.telephony.ims.aidl.RcsPublishResponseAidlWrapper; @@ -74,16 +73,6 @@ public class RcsFeature extends ImsFeature { mExecutor = executor; } - /** - * @deprecated This method is deprecated. Please call the method - * setCapabilityExchangeEventListener instead. - */ - @Override - @Deprecated - public void setListener(IRcsFeatureListener listener) { - Log.w(LOG_TAG, "The method setListener is deprecated"); - } - @Override public int queryCapabilityStatus() throws RemoteException { return executeMethodAsyncForResult( @@ -124,7 +113,7 @@ public class RcsFeature extends ImsFeature { // RcsCapabilityExchangeImplBase specific APIs @Override public void setCapabilityExchangeEventListener( - @NonNull ICapabilityExchangeEventListener listener) throws RemoteException { + @Nullable ICapabilityExchangeEventListener listener) throws RemoteException { executeMethodAsync(() -> mReference.setCapabilityExchangeEventListener(listener), "setCapabilityExchangeEventListener"); } @@ -155,34 +144,6 @@ public class RcsFeature extends ImsFeature { "sendOptionsCapabilityRequest"); } - // RcsPresenceExchangeImplBase specific APIS - @Override - public void requestCapabilities(List<Uri> uris, int operationToken) throws RemoteException { - throw new RemoteException("Unsupported operation: requestCapabilities"); - } - @Override - public void updateCapabilities(RcsContactUceCapability capabilities, int operationToken) - throws RemoteException { - throw new RemoteException("Unsupported operation: updateCapabilities"); - } - // RcsSipOptionsImplBase specific APIS - @Override - public void sendCapabilityRequest(Uri contactUri, RcsContactUceCapability capabilities, - int operationToken) throws RemoteException { - throw new RemoteException("Unsupported operation: sendCapabilityRequest"); - } - @Override - public void respondToCapabilityRequest(String contactUri, - RcsContactUceCapability ownCapabilities, int operationToken) - throws RemoteException { - throw new RemoteException("Unsupported operation: respondToCapabilityRequest"); - } - @Override - public void respondToCapabilityRequestWithError(Uri contactUri, int code, String reason, - int operationToken) throws RemoteException { - throw new RemoteException("Unsupported operation: respondToCapabilityRequestWithError"); - } - // 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) diff --git a/telephony/java/android/telephony/ims/stub/ImsConfigImplBase.java b/telephony/java/android/telephony/ims/stub/ImsConfigImplBase.java index e757d9f70ccc..cc050becfb25 100644 --- a/telephony/java/android/telephony/ims/stub/ImsConfigImplBase.java +++ b/telephony/java/android/telephony/ims/stub/ImsConfigImplBase.java @@ -23,8 +23,11 @@ import android.content.Context; import android.os.PersistableBundle; import android.os.RemoteException; import android.telephony.ims.ProvisioningManager; +import android.telephony.ims.RcsClientConfiguration; +import android.telephony.ims.RcsConfig; import android.telephony.ims.aidl.IImsConfig; import android.telephony.ims.aidl.IImsConfigCallback; +import android.telephony.ims.aidl.IRcsConfigCallback; import android.util.Log; import com.android.ims.ImsConfig; @@ -202,7 +205,13 @@ public class ImsConfigImplBase { @Override public void notifyRcsAutoConfigurationReceived(byte[] config, boolean isCompressed) throws RemoteException { - getImsConfigImpl().notifyRcsAutoConfigurationReceived(config, isCompressed); + getImsConfigImpl().onNotifyRcsAutoConfigurationReceived(config, isCompressed); + } + + @Override + public void notifyRcsAutoConfigurationRemoved() + throws RemoteException { + getImsConfigImpl().onNotifyRcsAutoConfigurationRemoved(); } private void notifyImsConfigChanged(int item, int value) throws RemoteException { @@ -228,6 +237,26 @@ public class ImsConfigImplBase { notifyImsConfigChanged(item, value); } } + + @Override + public void addRcsConfigCallback(IRcsConfigCallback c) throws RemoteException { + getImsConfigImpl().addRcsConfigCallback(c); + } + + @Override + public void removeRcsConfigCallback(IRcsConfigCallback c) throws RemoteException { + getImsConfigImpl().removeRcsConfigCallback(c); + } + + @Override + public void triggerRcsReconfiguration() throws RemoteException { + getImsConfigImpl().triggerAutoConfiguration(); + } + + @Override + public void setRcsClientConfiguration(RcsClientConfiguration rcc) throws RemoteException { + getImsConfigImpl().setRcsClientConfiguration(rcc); + } } /** @@ -257,6 +286,9 @@ public class ImsConfigImplBase { private final RemoteCallbackListExt<IImsConfigCallback> mCallbacks = new RemoteCallbackListExt<>(); + private final RemoteCallbackListExt<IRcsConfigCallback> mRcsCallbacks = + new RemoteCallbackListExt<>(); + private byte[] mRcsConfigData; ImsConfigStub mImsConfigStub; /** @@ -320,6 +352,50 @@ 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."); + } + } + } + + private void removeRcsConfigCallback(IRcsConfigCallback c) { + mRcsCallbacks.unregister(c); + } + + private void onNotifyRcsAutoConfigurationReceived(byte[] config, boolean isCompressed) { + mRcsConfigData = isCompressed ? RcsConfig.decompressGzip(config) : config; + // can be null in testing + if (mRcsCallbacks != null) { + mRcsCallbacks.broadcastAction(c -> { + try { + c.onConfigurationChanged(mRcsConfigData); + } catch (RemoteException e) { + Log.w(TAG, "dead binder in notifyRcsAutoConfigurationReceived, skipping."); + } + }); + } + notifyRcsAutoConfigurationReceived(config, isCompressed); + } + + private void onNotifyRcsAutoConfigurationRemoved() { + mRcsConfigData = null; + if (mRcsCallbacks != null) { + mRcsCallbacks.broadcastAction(c -> { + try { + c.onConfigurationReset(); + } catch (RemoteException e) { + Log.w(TAG, "dead binder in notifyRcsAutoConfigurationRemoved, skipping."); + } + }); + } + notifyRcsAutoConfigurationRemoved(); + } + /** * @hide */ @@ -369,6 +445,12 @@ public class ImsConfigImplBase { } /** + * The RCS autoconfiguration XML file is removed or invalid. + */ + public void notifyRcsAutoConfigurationRemoved() { + } + + /** * Sets the configuration value for this ImsService. * * @param item an integer key. @@ -421,4 +503,43 @@ public class ImsConfigImplBase { public void updateImsCarrierConfigs(PersistableBundle bundle) { // Base Implementation - Should be overridden } + + /** + * Default messaging application parameters are sent to the ACS client + * using this interface. + * @param rcc RCS client configuration {@link RcsClientConfiguration} + */ + public void setRcsClientConfiguration(@NonNull RcsClientConfiguration rcc) { + // Base Implementation - Should be overridden + } + + /** + * Reconfiguration triggered by the RCS application. Most likely cause + * is the 403 forbidden to a SIP/HTTP request + */ + public void triggerAutoConfiguration() { + // Base Implementation - Should be overridden + } + + /** + * Errors during autoconfiguration connection setup are notified by the + * ACS client using this interface. + * @param errorCode HTTP error received during connection setup. + * @param errorString reason phrase received with the error + */ + public final void notifyAutoConfigurationErrorReceived(int errorCode, + @NonNull String errorString) { + // can be null in testing + if (mRcsCallbacks == null) { + return; + } + mRcsCallbacks.broadcastAction(c -> { + try { + //TODO compressed by default? + c.onAutoConfigurationErrorReceived(errorCode, errorString); + } catch (RemoteException e) { + Log.w(TAG, "dead binder in notifyAutoConfigurationErrorReceived, skipping."); + } + }); + } } diff --git a/telephony/java/android/telephony/ims/stub/ImsRegistrationImplBase.java b/telephony/java/android/telephony/ims/stub/ImsRegistrationImplBase.java index 153d687dd84f..088a7e26a9d0 100644 --- a/telephony/java/android/telephony/ims/stub/ImsRegistrationImplBase.java +++ b/telephony/java/android/telephony/ims/stub/ImsRegistrationImplBase.java @@ -38,6 +38,9 @@ import java.lang.annotation.RetentionPolicy; /** * Controls IMS registration for this ImsService and notifies the framework when the IMS * registration for this ImsService has changed status. + * <p> + * Note: There is no guarantee on the thread that the calls from the framework will be called on. It + * is the implementors responsibility to handle moving the calls to a working thread if required. * @hide */ @SystemApi @@ -92,6 +95,21 @@ public class ImsRegistrationImplBase { public void removeRegistrationCallback(IImsRegistrationCallback c) throws RemoteException { ImsRegistrationImplBase.this.removeRegistrationCallback(c); } + + @Override + public void triggerFullNetworkRegistration(int sipCode, String sipReason) { + ImsRegistrationImplBase.this.triggerFullNetworkRegistration(sipCode, sipReason); + } + + @Override + public void triggerUpdateSipDelegateRegistration() { + ImsRegistrationImplBase.this.updateSipDelegateRegistration(); + } + + @Override + public void triggerSipDelegateDeregistration() { + ImsRegistrationImplBase.this.triggerSipDelegateDeregistration(); + } }; private final RemoteCallbackListExt<IImsRegistrationCallback> mCallbacks = @@ -133,7 +151,6 @@ public class ImsRegistrationImplBase { * If the SIP delegate feature tag configuration has changed, then this method will be * called in order to let the ImsService know that it can pick up these changes in the IMS * registration. - * @hide */ public void updateSipDelegateRegistration() { // Stub implementation, ImsService should implement this @@ -150,7 +167,6 @@ public class ImsRegistrationImplBase { * <p> * This should not affect the registration of features managed by the ImsService itself, such as * feature tags related to MMTEL registration. - * @hide */ public void triggerSipDelegateDeregistration() { // Stub implementation, ImsService should implement this @@ -169,9 +185,8 @@ public class ImsRegistrationImplBase { * be carrier specific. * @param sipReason The reason associated with the SIP error code. {@code null} if there was no * reason associated with the error. - * @hide */ - public void triggerNetworkReregistration(@IntRange(from = 100, to = 699) int sipCode, + public void triggerFullNetworkRegistration(@IntRange(from = 100, to = 699) int sipCode, @Nullable String sipReason) { // Stub implementation, ImsService should implement this } diff --git a/telephony/java/android/telephony/ims/stub/OWNERS b/telephony/java/android/telephony/ims/stub/OWNERS new file mode 100644 index 000000000000..0854c5d45603 --- /dev/null +++ b/telephony/java/android/telephony/ims/stub/OWNERS @@ -0,0 +1,5 @@ +# Bug component: 20868 + +rgreenwalt@google.com +tgunn@google.com +breadley@google.com diff --git a/telephony/java/android/telephony/ims/stub/RcsCapabilityExchange.java b/telephony/java/android/telephony/ims/stub/RcsCapabilityExchange.java deleted file mode 100644 index 0b13efb7b4b4..000000000000 --- a/telephony/java/android/telephony/ims/stub/RcsCapabilityExchange.java +++ /dev/null @@ -1,118 +0,0 @@ -/* - * 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.ims.stub; - -import android.annotation.IntDef; -import android.os.RemoteException; -import android.telephony.ims.ImsException; -import android.telephony.ims.aidl.IRcsFeatureListener; -import android.telephony.ims.feature.ImsFeature; -import android.telephony.ims.feature.RcsFeature; - -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; - -/** - * Base class for different types of Capability exchange, presence using - * {@link RcsPresenceExchangeImplBase} and SIP OPTIONS exchange using {@link RcsSipOptionsImplBase}. - * - * @hide - */ -public class RcsCapabilityExchange { - - /** Service is unknown. */ - public static final int COMMAND_CODE_SERVICE_UNKNOWN = 0; - /** The command completed successfully. */ - public static final int COMMAND_CODE_SUCCESS = 1; - /** The command failed with an unknown error. */ - public static final int COMMAND_CODE_GENERIC_FAILURE = 2; - /** Invalid parameter(s). */ - public static final int COMMAND_CODE_INVALID_PARAM = 3; - /** Fetch error. */ - public static final int COMMAND_CODE_FETCH_ERROR = 4; - /** Request timed out. */ - public static final int COMMAND_CODE_REQUEST_TIMEOUT = 5; - /** Failure due to insufficient memory available. */ - public static final int COMMAND_CODE_INSUFFICIENT_MEMORY = 6; - /** Network connection is lost. */ - public static final int COMMAND_CODE_LOST_NETWORK_CONNECTION = 7; - /** Requested feature/resource is not supported. */ - public static final int COMMAND_CODE_NOT_SUPPORTED = 8; - /** Contact or resource is not found. */ - public static final int COMMAND_CODE_NOT_FOUND = 9; - /** Service is not available. */ - public static final int COMMAND_CODE_SERVICE_UNAVAILABLE = 10; - /** No Change in Capabilities */ - public static final int COMMAND_CODE_NO_CHANGE_IN_CAP = 11; - - /** @hide*/ - @Retention(RetentionPolicy.SOURCE) - @IntDef(prefix = "COMMAND_CODE_", value = { - COMMAND_CODE_SERVICE_UNKNOWN, - COMMAND_CODE_SUCCESS, - COMMAND_CODE_GENERIC_FAILURE, - COMMAND_CODE_INVALID_PARAM, - COMMAND_CODE_FETCH_ERROR, - COMMAND_CODE_REQUEST_TIMEOUT, - COMMAND_CODE_INSUFFICIENT_MEMORY, - COMMAND_CODE_LOST_NETWORK_CONNECTION, - COMMAND_CODE_NOT_SUPPORTED, - COMMAND_CODE_NOT_FOUND, - COMMAND_CODE_SERVICE_UNAVAILABLE, - COMMAND_CODE_NO_CHANGE_IN_CAP - }) - public @interface CommandCode {} - - - private RcsFeature mFeature; - - /** @hide */ - public final void initialize(RcsFeature feature) { - mFeature = feature; - } - - /** @hide */ - protected final IRcsFeatureListener getListener() throws ImsException { - throw new ImsException("This method is deprecated.", - ImsException.CODE_ERROR_UNSUPPORTED_OPERATION); - } - - /** - * Provides the framework with an update as to whether or not a command completed successfully - * locally. This includes capabilities requests and updates from the network. If it does not - * complete successfully, then the framework may retry the command again later, depending on the - * error. If the command does complete successfully, the framework will then wait for network - * updates. - * - * @param code The result of the pending command. If {@link #COMMAND_CODE_SUCCESS}, further - * updates will be sent for this command using the associated operationToken. - * @param operationToken the token associated with the pending command. - * @throws ImsException If this {@link RcsCapabilityExchange} 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. - */ - public final void onCommandUpdate(@CommandCode int code, int operationToken) - throws ImsException { - try { - getListener().onCommandUpdate(code, operationToken); - } catch (RemoteException e) { - throw new ImsException(e.getMessage(), ImsException.CODE_ERROR_SERVICE_UNAVAILABLE); - } - } -} diff --git a/telephony/java/android/telephony/ims/stub/RcsPresenceExchangeImplBase.java b/telephony/java/android/telephony/ims/stub/RcsPresenceExchangeImplBase.java deleted file mode 100644 index bb034489a296..000000000000 --- a/telephony/java/android/telephony/ims/stub/RcsPresenceExchangeImplBase.java +++ /dev/null @@ -1,294 +0,0 @@ -/* - * 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.ims.stub; - -import android.annotation.IntDef; -import android.annotation.NonNull; -import android.net.Uri; -import android.os.RemoteException; -import android.telephony.ims.ImsException; -import android.telephony.ims.RcsContactUceCapability; -import android.telephony.ims.feature.ImsFeature; -import android.telephony.ims.feature.RcsFeature; -import android.util.Log; - -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.util.List; - -/** - * Base implementation for RCS User Capability Exchange using Presence. Any ImsService implementing - * this service must implement the stub methods {@link #requestCapabilities(List, int)} and - * {@link #updateCapabilities(RcsContactUceCapability, int)}. - * - * @hide - */ -public class RcsPresenceExchangeImplBase extends RcsCapabilityExchange { - - private static final String LOG_TAG = "RcsPresenceExchangeIB"; - - /** - * The request has resulted in any other 4xx/5xx/6xx that is not covered below. No retry will be - * attempted. - */ - public static final int RESPONSE_SUBSCRIBE_GENERIC_FAILURE = -1; - - /** - * The request has succeeded with a “200” message from the network. - */ - public static final int RESPONSE_SUCCESS = 0; - - /** - * The request has resulted in a “403” (User Not Registered) error from the network. Will retry - * capability polling with an exponential backoff. - */ - public static final int RESPONSE_NOT_REGISTERED = 1; - - /** - * The request has resulted in a “403” (not authorized (Requestor)) error from the network. No - * retry will be attempted. - */ - public static final int RESPONSE_NOT_AUTHORIZED_FOR_PRESENCE = 2; - - /** - * The request has resulted in a "403” (Forbidden) or other “403” error from the network and - * will be handled the same as “404” Not found. No retry will be attempted. - */ - public static final int RESPONSE_FORBIDDEN = 3; - - /** - * The request has resulted in a “404” (Not found) result from the network. No retry will be - * attempted. - */ - public static final int RESPONSE_NOT_FOUND = 4; - - /** - * The request has resulted in a “408” response. Retry after exponential backoff. - */ - public static final int RESPONSE_SIP_REQUEST_TIMEOUT = 5; - - /** - * The network has responded with a “413” (Too Large) response from the network. Capability - * request contains too many items and must be shrunk before the request will be accepted. - */ - public static final int RESPONSE_SUBSCRIBE_TOO_LARGE = 6; - - /** - * The request has resulted in a “423” response. Retry after exponential backoff. - */ - public static final int RESPONSE_SIP_INTERVAL_TOO_SHORT = 7; - - /** - * The request has resulted in a “503” response. Retry after exponential backoff. - */ - public static final int RESPONSE_SIP_SERVICE_UNAVAILABLE = 8; - - /** @hide*/ - @Retention(RetentionPolicy.SOURCE) - @IntDef(prefix = "RESPONSE_", value = { - RESPONSE_SUBSCRIBE_GENERIC_FAILURE, - RESPONSE_SUCCESS, - RESPONSE_NOT_REGISTERED, - RESPONSE_NOT_AUTHORIZED_FOR_PRESENCE, - RESPONSE_FORBIDDEN, - RESPONSE_NOT_FOUND, - RESPONSE_SIP_REQUEST_TIMEOUT, - RESPONSE_SUBSCRIBE_TOO_LARGE, - RESPONSE_SIP_INTERVAL_TOO_SHORT, - RESPONSE_SIP_SERVICE_UNAVAILABLE - }) - public @interface PresenceResponseCode {} - - - /** A capability update has been requested due to the Entity Tag (ETag) expiring. */ - public static final int CAPABILITY_UPDATE_TRIGGER_ETAG_EXPIRED = 0; - /** A capability update has been requested due to moving to LTE with VoPS disabled. */ - public static final int CAPABILITY_UPDATE_TRIGGER_MOVE_TO_LTE_VOPS_DISABLED = 1; - /** A capability update has been requested due to moving to LTE with VoPS enabled. */ - public static final int CAPABILITY_UPDATE_TRIGGER_MOVE_TO_LTE_VOPS_ENABLED = 2; - /** A capability update has been requested due to moving to eHRPD. */ - public static final int CAPABILITY_UPDATE_TRIGGER_MOVE_TO_EHRPD = 3; - /** A capability update has been requested due to moving to HSPA+. */ - public static final int CAPABILITY_UPDATE_TRIGGER_MOVE_TO_HSPAPLUS = 4; - /** A capability update has been requested due to moving to 3G. */ - public static final int CAPABILITY_UPDATE_TRIGGER_MOVE_TO_3G = 5; - /** A capability update has been requested due to moving to 2G. */ - public static final int CAPABILITY_UPDATE_TRIGGER_MOVE_TO_2G = 6; - /** A capability update has been requested due to moving to WLAN */ - public static final int CAPABILITY_UPDATE_TRIGGER_MOVE_TO_WLAN = 7; - /** A capability update has been requested due to moving to IWLAN */ - public static final int CAPABILITY_UPDATE_TRIGGER_MOVE_TO_IWLAN = 8; - /** A capability update has been requested but the reason is unknown. */ - public static final int CAPABILITY_UPDATE_TRIGGER_UNKNOWN = 9; - /** A capability update has been requested due to moving to 5G NR with VoPS disabled. */ - public static final int CAPABILITY_UPDATE_TRIGGER_MOVE_TO_NR5G_VOPS_DISABLED = 10; - /** A capability update has been requested due to moving to 5G NR with VoPS enabled. */ - public static final int CAPABILITY_UPDATE_TRIGGER_MOVE_TO_NR5G_VOPS_ENABLED = 11; - - /** @hide*/ - @IntDef(value = { - CAPABILITY_UPDATE_TRIGGER_ETAG_EXPIRED, - CAPABILITY_UPDATE_TRIGGER_MOVE_TO_LTE_VOPS_DISABLED, - CAPABILITY_UPDATE_TRIGGER_MOVE_TO_LTE_VOPS_ENABLED, - CAPABILITY_UPDATE_TRIGGER_MOVE_TO_EHRPD, - CAPABILITY_UPDATE_TRIGGER_MOVE_TO_HSPAPLUS, - CAPABILITY_UPDATE_TRIGGER_MOVE_TO_3G, - CAPABILITY_UPDATE_TRIGGER_MOVE_TO_2G, - CAPABILITY_UPDATE_TRIGGER_MOVE_TO_WLAN, - CAPABILITY_UPDATE_TRIGGER_MOVE_TO_IWLAN, - CAPABILITY_UPDATE_TRIGGER_UNKNOWN, - CAPABILITY_UPDATE_TRIGGER_MOVE_TO_NR5G_VOPS_DISABLED, - CAPABILITY_UPDATE_TRIGGER_MOVE_TO_NR5G_VOPS_ENABLED - }, prefix = "CAPABILITY_UPDATE_TRIGGER_") - @Retention(RetentionPolicy.SOURCE) - public @interface StackPublishTriggerType { - } - - /** - * Provide the framework with a subsequent network response update to - * {@link #updateCapabilities(RcsContactUceCapability, int)} and - * {@link #requestCapabilities(List, int)} operations. - * - * @param code The SIP response code sent from the network for the operation token specified. - * @param reason The optional reason response from the network. If the network provided no - * reason with the code, the string should be empty. - * @param operationToken The token associated with the operation this service is providing a - * response for. - * @throws ImsException If this {@link RcsPresenceExchangeImplBase} 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. - */ - public final void onNetworkResponse(@PresenceResponseCode int code, @NonNull String reason, - int operationToken) throws ImsException { - try { - getListener().onNetworkResponse(code, reason, operationToken); - } catch (RemoteException e) { - throw new ImsException(e.getMessage(), ImsException.CODE_ERROR_SERVICE_UNAVAILABLE); - } - } - - /** - * Provides the framework with the requested contacts’ capabilities requested by the framework - * using {@link #requestCapabilities(List, int)}. - * - * @throws ImsException If this {@link RcsPresenceExchangeImplBase} 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. - */ - public final void onCapabilityRequestResponse(@NonNull List<RcsContactUceCapability> infos, - int operationToken) throws ImsException { - try { - getListener().onCapabilityRequestResponsePresence(infos, operationToken); - } catch (RemoteException e) { - throw new ImsException(e.getMessage(), ImsException.CODE_ERROR_SERVICE_UNAVAILABLE); - } - } - - /** - * Trigger the framework to provide a capability update using - * {@link #updateCapabilities(RcsContactUceCapability, int)}. - * <p> - * This is typically used when trying to generate an initial PUBLISH for a new subscription to - * the network. The device will cache all presence publications after boot until this method is - * called once. - * @param publishTriggerType {@link StackPublishTriggerType} The reason for the capability - * update request. - * @throws ImsException If this {@link RcsPresenceExchangeImplBase} 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. - */ - public final void onNotifyUpdateCapabilites(@StackPublishTriggerType int publishTriggerType) - throws ImsException { - try { - getListener().onNotifyUpdateCapabilities(publishTriggerType); - } catch (RemoteException e) { - throw new ImsException(e.getMessage(), ImsException.CODE_ERROR_SERVICE_UNAVAILABLE); - } - } - - /** - * Notify the framework that the device’s capabilities have been unpublished from the network. - * - * @throws ImsException If this {@link RcsPresenceExchangeImplBase} 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. - */ - public final void onUnpublish() throws ImsException { - try { - getListener().onUnpublish(); - } catch (RemoteException e) { - throw new ImsException(e.getMessage(), ImsException.CODE_ERROR_SERVICE_UNAVAILABLE); - } - } - - /** - * The user capabilities of one or multiple contacts have been requested by the framework. - * <p> - * The implementer must follow up this call with an {@link #onCommandUpdate(int, int)} call to - * indicate whether or not this operation succeeded. If this operation succeeds, network - * response updates should be sent to the framework using - * {@link #onNetworkResponse(int, String, int)}. When the operation is completed, - * {@link #onCapabilityRequestResponse(List, int)} should be called with the presence - * information for the contacts specified. - * @param uris A {@link List} of the {@link Uri}s that the framework is requesting the UCE - * capabilities for. - * @param operationToken The token associated with this operation. Updates to this request using - * {@link #onCommandUpdate(int, int)}, {@link #onNetworkResponse(int, String, int)}, and - * {@link #onCapabilityRequestResponse(List, int)} must use the same operation token - * in response. - */ - public void requestCapabilities(@NonNull List<Uri> uris, int operationToken) { - // Stub - to be implemented by service - Log.w(LOG_TAG, "requestCapabilities called with no implementation."); - try { - getListener().onCommandUpdate(COMMAND_CODE_NOT_SUPPORTED, operationToken); - } catch (RemoteException | ImsException e) { - // Do not do anything, this is a stub implementation. - } - } - - /** - * The capabilities of this device have been updated and should be published to the network. - * <p> - * The implementer must follow up this call with an {@link #onCommandUpdate(int, int)} call to - * indicate whether or not this operation succeeded. If this operation succeeds, network - * response updates should be sent to the framework using - * {@link #onNetworkResponse(int, String, int)}. - * @param capabilities The capabilities for this device. - * @param operationToken The token associated with this operation. Any subsequent - * {@link #onCommandUpdate(int, int)} or {@link #onNetworkResponse(int, String, int)} - * calls regarding this update must use the same token. - */ - public void updateCapabilities(@NonNull RcsContactUceCapability capabilities, - int operationToken) { - // Stub - to be implemented by service - Log.w(LOG_TAG, "updateCapabilities called with no implementation."); - try { - getListener().onCommandUpdate(COMMAND_CODE_NOT_SUPPORTED, operationToken); - } catch (RemoteException | ImsException e) { - // Do not do anything, this is a stub implementation. - } - } -} diff --git a/telephony/java/android/telephony/ims/stub/RcsSipOptionsImplBase.java b/telephony/java/android/telephony/ims/stub/RcsSipOptionsImplBase.java deleted file mode 100644 index 2035fac4fae0..000000000000 --- a/telephony/java/android/telephony/ims/stub/RcsSipOptionsImplBase.java +++ /dev/null @@ -1,208 +0,0 @@ -/* - * 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.ims.stub; - -import android.annotation.IntDef; -import android.annotation.NonNull; -import android.annotation.Nullable; -import android.net.Uri; -import android.os.RemoteException; -import android.telephony.ims.ImsException; -import android.telephony.ims.RcsContactUceCapability; -import android.telephony.ims.feature.ImsFeature; -import android.telephony.ims.feature.RcsFeature; -import android.util.Log; - -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; - -/** - * Base implementation for RCS User Capability Exchange using SIP OPTIONS. - * - * @hide - */ -public class RcsSipOptionsImplBase extends RcsCapabilityExchange { - - private static final String LOG_TAG = "RcsSipOptionsImplBase"; - - /** - * Indicates a SIP response from the remote user other than 200, 480, 408, 404, or 604. - */ - public static final int RESPONSE_GENERIC_FAILURE = -1; - - /** - * Indicates that the remote user responded with a 200 OK response. - */ - public static final int RESPONSE_SUCCESS = 0; - - /** - * Indicates that the remote user responded with a 480 TEMPORARY UNAVAILABLE response. - */ - public static final int RESPONSE_TEMPORARILY_UNAVAILABLE = 1; - - /** - * Indicates that the remote user responded with a 408 REQUEST TIMEOUT response. - */ - public static final int RESPONSE_REQUEST_TIMEOUT = 2; - - /** - * Indicates that the remote user responded with a 404 NOT FOUND response. - */ - public static final int RESPONSE_NOT_FOUND = 3; - - /** - * Indicates that the remote user responded with a 604 DOES NOT EXIST ANYWHERE response. - */ - public static final int RESPONSE_DOES_NOT_EXIST_ANYWHERE = 4; - - /** - * Indicates that the remote user responded with a 400 BAD REQUEST response. - */ - public static final int RESPONSE_BAD_REQUEST = 5; - - /** @hide*/ - @Retention(RetentionPolicy.SOURCE) - @IntDef(prefix = "RESPONSE_", value = { - RESPONSE_GENERIC_FAILURE, - RESPONSE_SUCCESS, - RESPONSE_TEMPORARILY_UNAVAILABLE, - RESPONSE_REQUEST_TIMEOUT, - RESPONSE_NOT_FOUND, - RESPONSE_DOES_NOT_EXIST_ANYWHERE, - RESPONSE_BAD_REQUEST - }) - public @interface SipResponseCode {} - - /** - * Send the response of a SIP OPTIONS capability exchange to the framework. If {@code code} is - * {@link #RESPONSE_SUCCESS}, info must be non-null. - * @param code The SIP response code that was sent by the network in response to the request - * sent by {@link #sendCapabilityRequest(Uri, RcsContactUceCapability, int)}. - * @param reason The optional SIP response reason sent by the network. If none was sent, this - * should be an empty string. - * @param info the contact's UCE capabilities associated with the capability request. - * @param operationToken The token associated with the original capability request, set by - * {@link #sendCapabilityRequest(Uri, RcsContactUceCapability, int)}. - * @throws ImsException If this {@link RcsSipOptionsImplBase} 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. - */ - public final void onCapabilityRequestResponse(@SipResponseCode int code, @NonNull String reason, - @Nullable RcsContactUceCapability info, int operationToken) throws ImsException { - try { - getListener().onCapabilityRequestResponseOptions(code, reason, info, operationToken); - } catch (RemoteException e) { - throw new ImsException(e.getMessage(), ImsException.CODE_ERROR_SERVICE_UNAVAILABLE); - } - } - - /** - * Inform the framework of a query for this device's UCE capabilities. - * <p> - * The framework will respond via the - * {@link #respondToCapabilityRequest(String, RcsContactUceCapability, int)} or - * {@link #respondToCapabilityRequestWithError(Uri, int, String, int)} method. - * @param contactUri The URI associated with the remote contact that is requesting capabilities. - * @param remoteInfo The remote contact's capability information. - * @param operationToken An unique operation token that you have generated that will be returned - * by the framework in - * {@link #respondToCapabilityRequest(String, RcsContactUceCapability, int)}. - * @throws ImsException If this {@link RcsSipOptionsImplBase} 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. - */ - public final void onRemoteCapabilityRequest(@NonNull Uri contactUri, - @NonNull RcsContactUceCapability remoteInfo, int operationToken) throws ImsException { - try { - getListener().onRemoteCapabilityRequest(contactUri, remoteInfo, operationToken); - } catch (RemoteException e) { - throw new ImsException(e.getMessage(), ImsException.CODE_ERROR_SERVICE_UNAVAILABLE); - } - } - - /** - * Push one's own capabilities to a remote user via the SIP OPTIONS presence exchange mechanism - * in order to receive the capabilities of the remote user in response. - * <p> - * The implementer must call - * {@link #onCapabilityRequestResponse(int, String, RcsContactUceCapability, int)} to send the - * response of this query back to the framework. - * @param contactUri The URI of the remote user that we wish to get the capabilities of. - * @param capabilities The capabilities of this device to send to the remote user. - * @param operationToken A token generated by the framework that will be passed through - * {@link #onCapabilityRequestResponse(int, String, RcsContactUceCapability, int)} when this - * operation has succeeded. - */ - public void sendCapabilityRequest(@NonNull Uri contactUri, - @NonNull RcsContactUceCapability capabilities, int operationToken) { - // Stub - to be implemented by service - Log.w(LOG_TAG, "sendCapabilityRequest called with no implementation."); - try { - getListener().onCommandUpdate(COMMAND_CODE_NOT_SUPPORTED, operationToken); - } catch (RemoteException | ImsException e) { - // Do not do anything, this is a stub implementation. - } - } - - /** - * Respond to a remote capability request from the contact specified with the capabilities of - * this device. - * <p> - * The framework will use the same token and uri as what was passed in to - * {@link #onRemoteCapabilityRequest(Uri, RcsContactUceCapability, int)}. - * @param contactUri The URI of the remote contact. - * @param ownCapabilities The capabilities of this device. - * @param operationToken The token generated by the framework that this service obtained when - * {@link #onRemoteCapabilityRequest(Uri, RcsContactUceCapability, int)} was called. - */ - public void respondToCapabilityRequest(@NonNull String contactUri, - @NonNull RcsContactUceCapability ownCapabilities, int operationToken) { - // Stub - to be implemented by service - Log.w(LOG_TAG, "respondToCapabilityRequest called with no implementation."); - try { - getListener().onCommandUpdate(COMMAND_CODE_NOT_SUPPORTED, operationToken); - } catch (RemoteException | ImsException e) { - // Do not do anything, this is a stub implementation. - } - } - - /** - * Respond to a remote capability request from the contact specified with the specified error. - * <p> - * The framework will use the same token and uri as what was passed in to - * {@link #onRemoteCapabilityRequest(Uri, RcsContactUceCapability, int)}. - * @param contactUri A URI containing the remote contact. - * @param code The SIP response code to respond with. - * @param reason A non-null String containing the reason associated with the SIP code. - * @param operationToken The token provided by the framework when - * {@link #onRemoteCapabilityRequest(Uri, RcsContactUceCapability, int)} was called. - */ - public void respondToCapabilityRequestWithError(@NonNull Uri contactUri, - @SipResponseCode int code, @NonNull String reason, int operationToken) { - // Stub - to be implemented by service - Log.w(LOG_TAG, "respondToCapabiltyRequestWithError called with no implementation."); - try { - getListener().onCommandUpdate(COMMAND_CODE_NOT_SUPPORTED, operationToken); - } catch (RemoteException | ImsException e) { - // Do not do anything, this is a stub implementation. - } - } -} diff --git a/telephony/java/android/telephony/ims/stub/SipDelegate.java b/telephony/java/android/telephony/ims/stub/SipDelegate.java index d7e7b62dd550..b036b5e71125 100644 --- a/telephony/java/android/telephony/ims/stub/SipDelegate.java +++ b/telephony/java/android/telephony/ims/stub/SipDelegate.java @@ -19,7 +19,9 @@ package android.telephony.ims.stub; import android.annotation.NonNull; import android.annotation.SystemApi; import android.telephony.ims.DelegateMessageCallback; +import android.telephony.ims.DelegateRegistrationState; import android.telephony.ims.ImsService; +import android.telephony.ims.SipDelegateConnection; import android.telephony.ims.SipDelegateImsConfiguration; import android.telephony.ims.SipDelegateManager; import android.telephony.ims.SipMessage; @@ -65,10 +67,13 @@ public interface SipDelegate { * The framework is requesting that routing resources associated with the SIP dialog using the * provided Call-ID to be cleaned up. * <p> - * Typically a SIP Dialog close event will be signalled by that dialog receiving a BYE or 200 OK - * message, however, in some cases, the framework will request that the ImsService close the + * Typically, a SIP Dialog close event will be signalled by that dialog receiving a BYE or + * 200 OK message, however, the IMS application will still call + * {@link SipDelegateConnection#closeDialog(String)} to signal to the framework that resources + * can be released. In some cases, the framework will request that the ImsService close the * dialog due to the open dialog holding up an event such as applying a provisioning change or - * handing over to another transport type. + * handing over to another transport type. See {@link DelegateRegistrationState}. + * * @param callId The call-ID header value associated with the ongoing SIP Dialog that the * framework is requesting be closed. */ diff --git a/telephony/java/android/telephony/mbms/OWNERS b/telephony/java/android/telephony/mbms/OWNERS new file mode 100644 index 000000000000..718e0a292605 --- /dev/null +++ b/telephony/java/android/telephony/mbms/OWNERS @@ -0,0 +1,5 @@ +# Bug component: 20868 + +rgreenwalt@google.com +tgunn@google.com +hallliu@google.com diff --git a/telephony/java/android/telephony/mbms/vendor/OWNERS b/telephony/java/android/telephony/mbms/vendor/OWNERS new file mode 100644 index 000000000000..718e0a292605 --- /dev/null +++ b/telephony/java/android/telephony/mbms/vendor/OWNERS @@ -0,0 +1,5 @@ +# Bug component: 20868 + +rgreenwalt@google.com +tgunn@google.com +hallliu@google.com diff --git a/telephony/java/com/android/internal/telephony/IPhoneSubInfo.aidl b/telephony/java/com/android/internal/telephony/IPhoneSubInfo.aidl index 09f9b4212c03..ce2017bb9a35 100644 --- a/telephony/java/com/android/internal/telephony/IPhoneSubInfo.aidl +++ b/telephony/java/com/android/internal/telephony/IPhoneSubInfo.aidl @@ -216,5 +216,6 @@ interface IPhoneSubInfo { * @param data authentication challenge data * @return challenge response */ - String getIccSimChallengeResponse(int subId, int appType, int authType, String data); + String getIccSimChallengeResponse(int subId, int appType, int authType, String data, + String callingPackage, String callingFeatureId); } diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl index 5d4fdd0ff556..74753ca1560a 100644 --- a/telephony/java/com/android/internal/telephony/ITelephony.aidl +++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl @@ -37,6 +37,8 @@ import android.telephony.CellIdentity; import android.telephony.CellInfo; import android.telephony.ClientRequestStats; import android.telephony.ThermalMitigationRequest; +import android.telephony.gba.UaSecurityProtocolIdentifier; +import android.telephony.IBootstrapAuthenticationCallback; import android.telephony.IccOpenLogicalChannelResponse; import android.telephony.ICellInfoCallback; import android.telephony.ModemActivityInfo; @@ -50,6 +52,7 @@ import android.telephony.SignalStrength; import android.telephony.TelephonyHistogram; import android.telephony.VisualVoicemailSmsFilterSettings; import android.telephony.emergency.EmergencyNumber; +import android.telephony.ims.RcsClientConfiguration; import android.telephony.ims.aidl.IImsCapabilityCallback; import android.telephony.ims.aidl.IImsConfig; import android.telephony.ims.aidl.IImsConfigCallback; @@ -57,6 +60,7 @@ import android.telephony.ims.aidl.IImsMmTelFeature; 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 com.android.ims.internal.IImsServiceFeatureCallback; import com.android.internal.telephony.CellNetworkScanResult; import com.android.internal.telephony.IBooleanConsumer; @@ -124,6 +128,15 @@ interface ITelephony { */ boolean isRadioOnForSubscriberWithFeature(int subId, String callingPackage, String callingFeatureId); + /** + * Set the user-set status for enriched calling with call composer. + */ + void setCallComposerStatus(int subId, int status); + + /** + * Get the user-set status for enriched calling with call composer. + */ + int getCallComposerStatus(int subId); /** * Supply a pin to unlock the SIM for particular subId. @@ -1674,10 +1687,19 @@ interface ITelephony { * @param slotIndex SIM slot id * @param state State of SIM (power down, power up, pass through) * @hide - * */ + */ void setSimPowerStateForSlot(int slotIndex, int state); /** + * Set SIM card power state. + * @param slotIndex SIM slot id + * @param state State of SIM (power down, power up, pass through) + * @param callback callback to receive result info + * @hide + */ + void setSimPowerStateForSlotWithCallback(int slotIndex, int state, IIntegerConsumer callback); + + /** * Returns a list of Forbidden PLMNs from the specified SIM App * Returns null if the query fails. * @@ -2273,4 +2295,84 @@ interface ITelephony { */ int sendThermalMitigationRequest(int subId, in ThermalMitigationRequest thermalMitigationRequest); + + /** + * get the Generic Bootstrapping Architecture authentication keys + */ + void bootstrapAuthenticationRequest(int subId, int appType, in Uri nafUrl, + in UaSecurityProtocolIdentifier securityProtocol, + boolean forceBootStrapping, IBootstrapAuthenticationCallback callback); + + /** + * Set the GbaService Package Name that Telephony will bind to. + */ + boolean setBoundGbaServiceOverride(int subId, String packageName); + + /** + * Return the package name of the currently bound GbaService. + */ + String getBoundGbaService(int subId); + + /** + * Set the release time for telephony to unbind GbaService. + */ + boolean setGbaReleaseTimeOverride(int subId, int interval); + + /** + * Return the release time for telephony to unbind GbaService. + */ + int getGbaReleaseTime(int subId); + + /** + * Provide the client configuration parameters of the RCS application. + */ + void setRcsClientConfiguration(int subId, in RcsClientConfiguration rcc); + + /** + * return value to indicate whether the device and the carrier can support RCS VoLTE + * single registration. + */ + boolean isRcsVolteSingleRegistrationCapable(int subId); + + /** + * Register RCS provisioning callback. + */ + void registerRcsProvisioningChangedCallback(int subId, + IRcsConfigCallback callback); + + /** + * Unregister RCS provisioning callback. + */ + void unregisterRcsProvisioningChangedCallback(int subId, IRcsConfigCallback callback); + + /** + * trigger RCS reconfiguration. + */ + void triggerRcsReconfiguration(int subId); + + /** + * Overrides the config of RCS VoLTE single registration enabled for the device. + */ + void setDeviceSingleRegistrationEnabledOverride(String enabled); + + /** + * Gets the config of RCS VoLTE single registration enabled for the device. + */ + boolean getDeviceSingleRegistrationEnabled(); + + /** + * Overrides the config of RCS VoLTE single registration enabled for the carrier/subscription. + */ + boolean setCarrierSingleRegistrationEnabledOverride(int subId, String enabled); + + /** + * Gets the config of RCS VoLTE single registration enabled for the carrier/subscription. + */ + boolean getCarrierSingleRegistrationEnabled(int subId); + + /** + * Return the mobile provisioning url that is used to launch a browser to allow users to manage + * their mobile plan. + */ + String getMobileProvisioningUrl(); } diff --git a/telephony/java/com/android/internal/telephony/RILConstants.java b/telephony/java/com/android/internal/telephony/RILConstants.java index 42dee0e4060b..76243a5799c3 100644 --- a/telephony/java/com/android/internal/telephony/RILConstants.java +++ b/telephony/java/com/android/internal/telephony/RILConstants.java @@ -522,6 +522,8 @@ public interface RILConstants { int RIL_REQUEST_GET_SYSTEM_SELECTION_CHANNELS = 219; int RIL_REQUEST_GET_HAL_DEVICE_CAPABILITIES = 220; int RIL_REQUEST_SET_DATA_THROTTLING = 221; + int RIL_REQUEST_SET_ALLOWED_NETWORK_TYPE_BITMAP = 222; + int RIL_REQUEST_GET_ALLOWED_NETWORK_TYPE_BITMAP = 223; /* Responses begin */ int RIL_RESPONSE_ACKNOWLEDGEMENT = 800; |