diff options
Diffstat (limited to 'telephony/java/android')
30 files changed, 1004 insertions, 525 deletions
diff --git a/telephony/java/android/telephony/Annotation.java b/telephony/java/android/telephony/Annotation.java index 99f2e5ee0755..4a53a8023792 100644 --- a/telephony/java/android/telephony/Annotation.java +++ b/telephony/java/android/telephony/Annotation.java @@ -111,6 +111,7 @@ public class Annotation { public @interface NetworkType { } + // TODO(b/180542000): remove and replace references with @ApnSetting.ApnType @IntDef(flag = true, prefix = {"TYPE_"}, value = { ApnSetting.TYPE_DEFAULT, ApnSetting.TYPE_MMS, @@ -124,6 +125,7 @@ public class Annotation { ApnSetting.TYPE_EMERGENCY, ApnSetting.TYPE_MCX, ApnSetting.TYPE_XCAP, + // ApnSetting.TYPE_ENTERPRISE }) @Retention(RetentionPolicy.SOURCE) public @interface ApnType { diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java index 04e8f6345dee..9c9670c99c2d 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; @@ -37,6 +38,8 @@ import android.telephony.ims.ImsSsData; import com.android.internal.telephony.ICarrierConfigLoader; import com.android.telephony.Rlog; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; import java.util.concurrent.TimeUnit; /** @@ -103,6 +106,32 @@ public class CarrierConfigManager { */ public static final int USSD_OVER_IMS_ONLY = 3; + /** @hide */ + @Retention(RetentionPolicy.SOURCE) + @IntDef(prefix = { "CARRIER_NR_AVAILABILITY_" }, value = { + CARRIER_NR_AVAILABILITY_NONE, + CARRIER_NR_AVAILABILITY_NSA, + CARRIER_NR_AVAILABILITY_SA, + }) + public @interface DeviceNrCapability {} + + /** + * Indicates CARRIER_NR_AVAILABILITY_NONE determine that the carrier does not enable 5G NR. + */ + public static final int CARRIER_NR_AVAILABILITY_NONE = 0; + + /** + * Indicates CARRIER_NR_AVAILABILITY_NSA determine that the carrier enable the non-standalone + * (NSA) mode of 5G NR. + */ + public static final int CARRIER_NR_AVAILABILITY_NSA = 1 << 0; + + /** + * Indicates CARRIER_NR_AVAILABILITY_SA determine that the carrier enable the standalone (SA) + * mode of 5G NR. + */ + public static final int CARRIER_NR_AVAILABILITY_SA = 1 << 1; + private final Context mContext; /** @@ -1774,10 +1803,23 @@ public class CarrierConfigManager { "show_precise_failed_cause_bool"; /** - * Boolean to decide whether NR is enabled. - * @hide + * Bit-field integer to determine whether the carrier enable the non-standalone (NSA) mode of + * 5G NR, standalone (SA) mode of 5G NR + * + * <UL> + * <LI>CARRIER_NR_AVAILABILITY_NONE: non-NR = 0 </LI> + * <LI>CARRIER_NR_AVAILABILITY_NSA: NSA = 1 << 0</LI> + * <LI>CARRIER_NR_AVAILABILITY_SA: SA = 1 << 1</LI> + * </UL> + * <p> The value of this key must be bitwise OR of + * {@link #CARRIER_NR_AVAILABILITY_NONE}, {@link #CARRIER_NR_AVAILABILITY_NSA}, + * {@link #CARRIER_NR_AVAILABILITY_SA}. + * + * <p> For example, if both NSA and SA are used, the value of key is 3 (1 << 0 | 1 << 1). + * If the carrier doesn't support 5G NR, the value of key is 0 (non-NR). + * If the key is invalid or not configured, a default value 3 (NSA|SA = 3) will apply. */ - public static final String KEY_NR_ENABLED_BOOL = "nr_enabled_bool"; + public static final String KEY_CARRIER_NR_AVAILABILITY_INT = "carrier_nr_availability_int"; /** * Boolean to decide whether LTE is enabled. @@ -1881,9 +1923,8 @@ public class CarrierConfigManager { * "APN_1, ERROR_CODE_1 : CARRIER_ACTION_IDX_1, CARRIER_ACTION_IDX_2...", * "APN_1, ERROR_CODE_2 : CARRIER_ACTION_IDX_1 " * } - * Where {@code APN_1} is a string defined in - * com.android.internal.telephony.PhoneConstants - * Example: "default" + * Where {@code APN_1} is an integer defined in {@link android.telephony.data.ApnSetting} + * (e.g. {@link android.telephony.data.ApnSetting#TYPE_DEFAULT} * * {@code ERROR_CODE_1} is an integer defined in android.telephony.DataFailCause * Example: @@ -4547,7 +4588,8 @@ public class CarrierConfigManager { sDefaults.putString(KEY_SHOW_CARRIER_DATA_ICON_PATTERN_STRING, ""); sDefaults.putBoolean(KEY_HIDE_LTE_PLUS_DATA_ICON_BOOL, true); sDefaults.putInt(KEY_LTE_PLUS_THRESHOLD_BANDWIDTH_KHZ_INT, 20000); - sDefaults.putBoolean(KEY_NR_ENABLED_BOOL, true); + sDefaults.putInt(KEY_CARRIER_NR_AVAILABILITY_INT, + CARRIER_NR_AVAILABILITY_NSA | CARRIER_NR_AVAILABILITY_SA); sDefaults.putBoolean(KEY_LTE_ENABLED_BOOL, true); sDefaults.putBoolean(KEY_SUPPORT_TDSCDMA_BOOL, false); sDefaults.putStringArray(KEY_SUPPORT_TDSCDMA_ROAMING_NETWORKS_STRING_ARRAY, null); @@ -4711,7 +4753,7 @@ public class CarrierConfigManager { sDefaults.putStringArray(KEY_MISSED_INCOMING_CALL_SMS_ORIGINATOR_STRING_ARRAY, new String[0]); sDefaults.putStringArray(KEY_APN_PRIORITY_STRING_ARRAY, new String[] { - "default:0", "mms:2", "supl:2", "dun:2", "hipri:3", "fota:2", + "default:0", "enterprise:1", "mms:2", "supl:2", "dun:2", "hipri:3", "fota:2", "ims:2", "cbs:2", "ia:2", "emergency:2", "mcx:3", "xcap:3" }); sDefaults.putStringArray(KEY_MISSED_INCOMING_CALL_SMS_PATTERN_STRING_ARRAY, new String[0]); diff --git a/telephony/java/android/telephony/DataFailCause.java b/telephony/java/android/telephony/DataFailCause.java index 99a77ae5d133..c8ed82cd2a3f 100644 --- a/telephony/java/android/telephony/DataFailCause.java +++ b/telephony/java/android/telephony/DataFailCause.java @@ -917,6 +917,10 @@ public final class DataFailCause { 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; + /** No matching rule available for the request, and match-all rule is not allowed for it. */ + public static final int MATCH_ALL_RULE_NOT_ALLOWED = 0x8CD; + /** If connection failed for all matching URSP rules. */ + public static final int ALL_MATCHING_RULES_FAILED = 0x8CE; //IKE error notifications message as specified in 3GPP TS 24.302 (Section 8.1.2.2). diff --git a/telephony/java/android/telephony/NetworkRegistrationInfo.java b/telephony/java/android/telephony/NetworkRegistrationInfo.java index 706e3cb93a0f..a78f81331c8c 100644 --- a/telephony/java/android/telephony/NetworkRegistrationInfo.java +++ b/telephony/java/android/telephony/NetworkRegistrationInfo.java @@ -371,6 +371,7 @@ public final class NetworkRegistrationInfo implements Parcelable { * Get the 5G NR connection state. * * @return the 5G NR connection state. + * @hide */ public @NRState int getNrState() { return mNrState; diff --git a/telephony/java/android/telephony/RadioInterfaceCapabilities.java b/telephony/java/android/telephony/RadioInterfaceCapabilities.java deleted file mode 100644 index 7c7eb9fbbeb2..000000000000 --- a/telephony/java/android/telephony/RadioInterfaceCapabilities.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * 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; - -import android.util.ArraySet; - -/** - * Contains the set of supported capabilities that the Radio Interface supports on this device. - * - * @hide - */ -public class RadioInterfaceCapabilities { - - private final ArraySet<String> mSupportedCapabilities; - - - public RadioInterfaceCapabilities() { - mSupportedCapabilities = new ArraySet<>(); - } - - /** - * Marks a capability as supported - * - * @param capabilityName the name of the capability - */ - public void addSupportedCapability( - @TelephonyManager.RadioInterfaceCapability String capabilityName) { - mSupportedCapabilities.add(capabilityName); - } - - /** - * Whether the capability is supported - * - * @param capabilityName the name of the capability - */ - public boolean isSupported(String capabilityName) { - return mSupportedCapabilities.contains(capabilityName); - } -} diff --git a/telephony/java/android/telephony/SubscriptionManager.java b/telephony/java/android/telephony/SubscriptionManager.java index 4e481b3ad837..85fe14ef8062 100644 --- a/telephony/java/android/telephony/SubscriptionManager.java +++ b/telephony/java/android/telephony/SubscriptionManager.java @@ -907,7 +907,8 @@ public class SubscriptionManager { * Indicate which network type is allowed. By default it's enabled. * @hide */ - public static final String ALLOWED_NETWORK_TYPES = SimInfo.COLUMN_ALLOWED_NETWORK_TYPES; + public static final String ALLOWED_NETWORK_TYPES = + SimInfo.COLUMN_ALLOWED_NETWORK_TYPES_FOR_REASONS; /** * Broadcast Action: The user has changed one of the default subs related to diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java index 8bf55ccd9d41..f12ff93ecb36 100644 --- a/telephony/java/android/telephony/TelephonyManager.java +++ b/telephony/java/android/telephony/TelephonyManager.java @@ -28,6 +28,7 @@ import android.annotation.IntDef; import android.annotation.LongDef; import android.annotation.NonNull; import android.annotation.Nullable; +import android.annotation.RequiresFeature; import android.annotation.RequiresPermission; import android.annotation.SdkConstant; import android.annotation.SdkConstant.SdkConstantType; @@ -121,12 +122,10 @@ import java.lang.annotation.RetentionPolicy; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; -import java.util.HashSet; 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; @@ -1586,177 +1585,157 @@ public class TelephonyManager { "android.telephony.extra.PHONE_IN_ECM_STATE"; /** - * <p>Broadcast Action: when data connections get redirected with validation failure. - * intended for sim/account status checks and only sent to the specified carrier app - * The intent will have the following extra values:</p> + * Broadcast action sent when a data connection is redirected with validation failure. + * + * This action is intended for sim/account status checks and only sent to the carrier apps + * specified in the carrier config for the subscription ID that's attached to this intent. + * + * The intent will have the following extra values: * <ul> - * <li>{@link #EXTRA_APN_TYPE}</li><dd>A string with the apn type.</dd> - * <li>{@link #EXTRA_APN_TYPE_INT}</li><dd>A integer with the apn type.</dd> - * <li>{@link #EXTRA_REDIRECTION_URL}</li><dd>redirection url string</dd> - * <li>subId</li><dd>Sub Id which associated the data connection failure.</dd> + * <li>{@link #EXTRA_APN_TYPE}</li><dd>An integer indicating the apn type.</dd> + * <li>{@link #EXTRA_REDIRECTION_URL}</li><dd>A string indicating the redirection url</dd> + * <li>{@link SubscriptionManager#EXTRA_SUBSCRIPTION_INDEX}</li> + * <dd>The subscription ID on which the validation failure happened.</dd> * </ul> * <p class="note">This is a protected intent that can only be sent by the system.</p> - * @hide */ - @SuppressLint("ActionValue") + @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) public static final String ACTION_CARRIER_SIGNAL_REDIRECTED = - "com.android.internal.telephony.CARRIER_SIGNAL_REDIRECTED"; + "android.telephony.action.CARRIER_SIGNAL_REDIRECTED"; /** - * <p>Broadcast Action: when data connections setup fails. - * intended for sim/account status checks and only sent to the specified carrier app - * The intent will have the following extra values:</p> + * Broadcast action sent when a data connection setup fails. + * + * This action is intended for sim/account status checks and only sent to the carrier apps + * specified in the carrier config for the subscription ID that's attached to this intent. + * + * The intent will have the following extra values: * <ul> - * <li>{@link #EXTRA_APN_TYPE}</li><dd>A string with the apn type.</dd> - * <li>{@link #EXTRA_APN_TYPE_INT}</li><dd>A integer with the apn type.</dd> - * <li>{@link #EXTRA_ERROR_CODE}</li><dd>A integer with dataFailCause.</dd> - * <li>subId</li><dd>Sub Id which associated the data connection failure.</dd> + * <li>{@link #EXTRA_APN_TYPE}</li><dd>An integer indicating the apn type.</dd> + * <li>{@link #EXTRA_DATA_FAIL_CAUSE}</li><dd>A integer indicating the data fail cause.</dd> + * <li>{@link SubscriptionManager#EXTRA_SUBSCRIPTION_INDEX}</li> + * <dd>The subscription ID on which the data setup failure happened.</dd> * </ul> * <p class="note">This is a protected intent that can only be sent by the system. </p> - * @hide */ - @SuppressLint("ActionValue") + @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) public static final String ACTION_CARRIER_SIGNAL_REQUEST_NETWORK_FAILED = - "com.android.internal.telephony.CARRIER_SIGNAL_REQUEST_NETWORK_FAILED"; + "android.telephony.action.CARRIER_SIGNAL_REQUEST_NETWORK_FAILED"; /** - * <p>Broadcast Action: when pco value is available. - * intended for sim/account status checks and only sent to the specified carrier app + * Broadcast action sent when a PCO value becomes available from the modem. + * + * This action is intended for sim/account status checks and only sent to the carrier apps + * specified in the carrier config for the subscription ID that's attached to this intent. + * * The intent will have the following extra values:</p> * <ul> - * <li>{@link #EXTRA_APN_TYPE}</li><dd>A string with the apn type.</dd> - * <li>{@link #EXTRA_APN_TYPE_INT}</li><dd>A integer with the apn type.</dd> - * <li>{@link #EXTRA_APN_PROTOCOL}</li><dd>A string with the protocol of the apn connection - * (IP,IPV6, IPV4V6)</dd> - * <li>{@link #EXTRA_APN_PROTOCOL_INT}</li><dd>A integer with the protocol of the apn - * connection (IP,IPV6, IPV4V6)</dd> - * <li>{@link #EXTRA_PCO_ID}</li><dd>An integer indicating the pco id for the data.</dd> - * <li>{@link #EXTRA_PCO_VALUE}</li><dd>A byte array of pco data read from modem.</dd> - * <li>subId</li><dd>Sub Id which associated the data connection.</dd> + * <li>{@link #EXTRA_APN_TYPE}</li><dd>An integer indicating the apn type.</dd> + * <li>{@link #EXTRA_APN_PROTOCOL}</li><dd>An integer indicating the protocol of the apn + * connection</dd> + * <li>{@link #EXTRA_PCO_ID}</li><dd>An integer indicating the PCO id for the data.</dd> + * <li>{@link #EXTRA_PCO_VALUE}</li><dd>A byte array of PCO data read from modem.</dd> + * <li>{@link SubscriptionManager#EXTRA_SUBSCRIPTION_INDEX}</li> + * <dd>The subscription ID for which the PCO info was received.</dd> * </ul> * <p class="note">This is a protected intent that can only be sent by the system. </p> - * @hide */ - @SuppressLint("ActionValue") + @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) public static final String ACTION_CARRIER_SIGNAL_PCO_VALUE = - "com.android.internal.telephony.CARRIER_SIGNAL_PCO_VALUE"; + "android.telephony.action.CARRIER_SIGNAL_PCO_VALUE"; /** - * <p>Broadcast Action: when system default network available/unavailable with - * carrier-disabled mobile data. Intended for carrier apps to set/reset carrier actions when - * other network becomes system default network, Wi-Fi for example. + * Broadcast action sent when the availability of the system default network changes. + * + * @see ConnectivityManager#registerDefaultNetworkCallback(ConnectivityManager.NetworkCallback) + * + * This action is intended for carrier apps to set/reset carrier actions. It is only sent to the + * carrier apps specified in the carrier config for the subscription ID attached to this intent. + * * The intent will have the following extra values:</p> * <ul> * <li>{@link #EXTRA_DEFAULT_NETWORK_AVAILABLE}</li> - * <dd>A boolean indicates default network available.</dd> - * <li>subId</li><dd>Sub Id which associated the default data.</dd> + * <dd>{@code true} if the default network is now available, {@code false} otherwise.</dd> + * <li>{@link SubscriptionManager#EXTRA_SUBSCRIPTION_INDEX}</li> + * <dd>The subscription ID on which the default network availability changed.</dd> * </ul> * <p class="note">This is a protected intent that can only be sent by the system. </p> - * @hide */ - @SuppressLint("ActionValue") + @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) public static final String ACTION_CARRIER_SIGNAL_DEFAULT_NETWORK_AVAILABLE = - "com.android.internal.telephony.CARRIER_SIGNAL_DEFAULT_NETWORK_AVAILABLE"; + "android.telephony.action.CARRIER_SIGNAL_DEFAULT_NETWORK_AVAILABLE"; /** - * <p>Broadcast Action: when framework reset all carrier actions on sim load or absent. - * intended for carrier apps clean up (clear UI e.g.) and only sent to the specified carrier app + * Broadcast action sent when carrier apps should reset their internal state. + * + * Sent when certain events such as turning on/off mobile data, removing the SIM, etc. require + * carrier apps to reset their state. + * + * This action is intended to signal carrier apps to perform cleanup operations. It is only sent + * to the carrier apps specified in the carrier config for the subscription ID attached to + * this intent. + * * The intent will have the following extra values:</p> * <ul> - * <li>subId</li><dd>Sub Id which associated the data connection failure.</dd> + * <li>{@link SubscriptionManager#EXTRA_SUBSCRIPTION_INDEX}</li> + * <dd>The subscription ID for which state should be reset.</dd> * </ul> * <p class="note">This is a protected intent that can only be sent by the system.</p> - * @hide */ - @SuppressLint("ActionValue") + @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) public static final String ACTION_CARRIER_SIGNAL_RESET = - "com.android.internal.telephony.CARRIER_SIGNAL_RESET"; + "android.telephony.action.CARRIER_SIGNAL_RESET"; - // CARRIER_SIGNAL_ACTION extra keys /** - * An string extra of redirected url upon {@link #ACTION_CARRIER_SIGNAL_REDIRECTED}. - * @hide + * String extra containing the redirection URL sent with + * {@link #ACTION_CARRIER_SIGNAL_REDIRECTED}. */ - @SuppressLint("ActionValue") - public static final String EXTRA_REDIRECTION_URL = "redirectionUrl"; + public static final String EXTRA_REDIRECTION_URL = "android.telephony.extra.REDIRECTION_URL"; /** - * An integer extra of error code upon {@link #ACTION_CARRIER_SIGNAL_REQUEST_NETWORK_FAILED}. - * Check {@link DataFailCause} for all possible values. - * @hide - */ - @SuppressLint("ActionValue") - public static final String EXTRA_ERROR_CODE = "errorCode"; - - /** - * An string extra of corresponding apn type upon - * {@link #ACTION_CARRIER_SIGNAL_REQUEST_NETWORK_FAILED}, - * {@link #ACTION_CARRIER_SIGNAL_REDIRECTED} and - * {@link #ACTION_CARRIER_SIGNAL_PCO_VALUE} broadcasts. - * @deprecated This is kept for backward compatibility reason. Use {@link #EXTRA_APN_TYPE_INT} - * instead. + * An integer extra containing the data fail cause. * - * @hide + * Sent with {@link #ACTION_CARRIER_SIGNAL_REQUEST_NETWORK_FAILED}. See {@link DataFailCause} + * for a list of possible values. */ - @Deprecated - @SuppressLint("ActionValue") - public static final String EXTRA_APN_TYPE = "apnType"; - - /** - * An string integer of corresponding apn type upon - * {@link #ACTION_CARRIER_SIGNAL_REQUEST_NETWORK_FAILED}, - * {@link #ACTION_CARRIER_SIGNAL_REDIRECTED} and - * {@link #ACTION_CARRIER_SIGNAL_PCO_VALUE} broadcasts. - * Check {@link ApnSetting} TYPE_* for its values. - * @hide - */ - @SuppressLint("ActionValue") - public static final String EXTRA_APN_TYPE_INT = "apnTypeInt"; + public static final String EXTRA_DATA_FAIL_CAUSE = "android.telephony.extra.DATA_FAIL_CAUSE"; /** - * An string extra with the protocol of the apn connection (IP,IPV6, IPV4V6) upon - * {@link #ACTION_CARRIER_SIGNAL_PCO_VALUE} broadcasts. - * @deprecated This is kept for backward compatibility reason. - * Use {@link #EXTRA_APN_PROTOCOL_INT} instead. + * An integer extra containing the APN type. * - * @hide + * Sent with the {@link #ACTION_CARRIER_SIGNAL_REQUEST_NETWORK_FAILED}, + * {@link #ACTION_CARRIER_SIGNAL_REDIRECTED}, and {@link #ACTION_CARRIER_SIGNAL_PCO_VALUE} + * broadcasts. + * See the {@code TYPE_} constants in {@link ApnSetting} for a list of possible values. */ - @Deprecated - @SuppressLint("ActionValue") - public static final String EXTRA_APN_PROTOCOL = "apnProto"; + public static final String EXTRA_APN_TYPE = "android.telephony.extra.APN_TYPE"; /** - * An integer extra with the protocol of the apn connection (IP,IPV6, IPV4V6) upon - * {@link #ACTION_CARRIER_SIGNAL_PCO_VALUE} broadcasts. - * Check {@link ApnSetting} PROTOCOL_* for its values. - * @hide + * An integer extra containing the protocol of the apn connection. + * + * Sent with the {@link #ACTION_CARRIER_SIGNAL_PCO_VALUE} broadcast. + * See the {@code PROTOCOL_*} constants in {@link ApnSetting} for a list of possible values. */ - @SuppressLint("ActionValue") - public static final String EXTRA_APN_PROTOCOL_INT = "apnProtoInt"; + public static final String EXTRA_APN_PROTOCOL = "android.telephony.extra.APN_PROTOCOL"; /** - * An integer extra indicating the pco id for the data upon - * {@link #ACTION_CARRIER_SIGNAL_PCO_VALUE} broadcasts. - * @hide + * An integer extra indicating the ID for the PCO data. + * Sent with the {@link #ACTION_CARRIER_SIGNAL_PCO_VALUE} broadcast. */ - @SuppressLint("ActionValue") - public static final String EXTRA_PCO_ID = "pcoId"; + public static final String EXTRA_PCO_ID = "android.telephony.extra.PCO_ID"; /** - * An extra of byte array of pco data read from modem upon - * {@link #ACTION_CARRIER_SIGNAL_PCO_VALUE} broadcasts. - * @hide + * A byte array extra containing PCO data read from the modem. + * Sent with the {@link #ACTION_CARRIER_SIGNAL_PCO_VALUE} broadcast. */ - @SuppressLint("ActionValue") - public static final String EXTRA_PCO_VALUE = "pcoValue"; + public static final String EXTRA_PCO_VALUE = "android.telephony.extra.PCO_VALUE"; /** - * An boolean extra indicating default network available upon - * {@link #ACTION_CARRIER_SIGNAL_DEFAULT_NETWORK_AVAILABLE} broadcasts. - * @hide + * A boolean extra indicating the availability of the default network. + * Sent with the {@link #ACTION_CARRIER_SIGNAL_DEFAULT_NETWORK_AVAILABLE} broadcast. */ - @SuppressLint("ActionValue") - public static final String EXTRA_DEFAULT_NETWORK_AVAILABLE = "defaultNetworkAvailable"; + public static final String EXTRA_DEFAULT_NETWORK_AVAILABLE = + "android.telephony.extra.DEFAULT_NETWORK_AVAILABLE"; /** * <p>Broadcast Action: The emergency call state is changed. @@ -7756,21 +7735,13 @@ public class TelephonyManager { * * @return the preferred network type. * @hide - * @deprecated Use {@link #getPreferredNetworkTypeBitmask} instead. + * @deprecated Use {@link #getAllowedNetworkTypesBitmask} instead. */ @Deprecated @RequiresPermission((android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)) @UnsupportedAppUsage public @PrefNetworkMode int getPreferredNetworkType(int subId) { - try { - ITelephony telephony = getITelephony(); - if (telephony != null) { - return telephony.getPreferredNetworkType(subId); - } - } catch (RemoteException ex) { - Rlog.e(TAG, "getPreferredNetworkType RemoteException", ex); - } - return -1; + return RadioAccessFamily.getNetworkTypeFromRaf((int) getAllowedNetworkTypesBitmask()); } /** @@ -7786,24 +7757,47 @@ public class TelephonyManager { * @return The bitmask of preferred network types. * * @hide + * @deprecated Use {@link #getAllowedNetworkTypesBitmask} instead. */ + @Deprecated @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) @SystemApi public @NetworkTypeBitMask long getPreferredNetworkTypeBitmask() { + return getAllowedNetworkTypesBitmask(); + } + + /** + * Get the allowed network type bitmask. + * Note that the device can only register on the network of {@link NetworkTypeBitmask} + * (except for emergency call cases). + * + * <p>If this object has been created with {@link #createForSubscriptionId}, applies to the + * given subId. Otherwise, applies to {@link SubscriptionManager#getDefaultSubscriptionId()} + * + * <p>Requires Permission: + * {@link android.Manifest.permission#READ_PRIVILEGED_PHONE_STATE READ_PRIVILEGED_PHONE_STATE} + * or that the calling app has carrier privileges (see {@link #hasCarrierPrivileges}). + * + * @return The bitmask of allowed network types. + * + * @hide + */ + @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) + @SystemApi + public @NetworkTypeBitMask long getAllowedNetworkTypesBitmask() { try { ITelephony telephony = getITelephony(); if (telephony != null) { - return (long) RadioAccessFamily.getRafFromNetworkType( - telephony.getPreferredNetworkType(getSubId())); + return (long) telephony.getAllowedNetworkTypesBitmask(getSubId()); } } catch (RemoteException ex) { - Rlog.e(TAG, "getPreferredNetworkTypeBitmask RemoteException", ex); + Rlog.e(TAG, "getAllowedNetworkTypesBitmask RemoteException", ex); } return 0; } /** - * Get the allowed network types. + * Get the allowed network types by carriers. * * <p>Requires Permission: * {@link android.Manifest.permission#READ_PRIVILEGED_PHONE_STATE READ_PRIVILEGED_PHONE_STATE} @@ -7811,14 +7805,17 @@ public class TelephonyManager { * * @return the allowed network type bitmask * @hide + * @deprecated Use {@link #getAllowedNetworkTypesForReason} instead. */ @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) @SystemApi + @Deprecated public @NetworkTypeBitMask long getAllowedNetworkTypes() { try { ITelephony telephony = getITelephony(); if (telephony != null) { - return telephony.getAllowedNetworkTypes(getSubId()); + return telephony.getAllowedNetworkTypesForReason(getSubId(), + TelephonyManager.ALLOWED_NETWORK_TYPES_REASON_CARRIER); } } catch (RemoteException ex) { Rlog.e(TAG, "getAllowedNetworkTypes RemoteException", ex); @@ -8040,7 +8037,7 @@ public class TelephonyManager { return false; } - /** + /** * Get the network selection mode. * * <p>If this object has been created with {@link #createForSubscriptionId}, applies to the @@ -8127,12 +8124,17 @@ public class TelephonyManager { * <p>Requires Permission: * {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE} or that the calling * app has carrier privileges (see {@link #hasCarrierPrivileges}). + * <p> + * If {@link android.telephony.TelephonyManager#isRadioInterfaceCapabilitySupported} + * ({@link TelephonyManager#CAPABILITY_ALLOWED_NETWORK_TYPES_USED}) returns true, then + * setAllowedNetworkTypesBitmap is used on the radio interface. Otherwise, + * setPreferredNetworkTypesBitmap is used instead. * * @param subId the id of the subscription to set the preferred network type for. * @param networkType the preferred network type * @return true on success; false on any failure. * @hide - * @deprecated Use {@link #setPreferredNetworkTypeBitmask} instead. + * @deprecated Use {@link #setAllowedNetworkTypesForReason} instead. */ @Deprecated @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) @@ -8140,7 +8142,9 @@ public class TelephonyManager { try { ITelephony telephony = getITelephony(); if (telephony != null) { - return telephony.setPreferredNetworkType(subId, networkType); + return telephony.setAllowedNetworkTypesForReason(subId, + TelephonyManager.ALLOWED_NETWORK_TYPES_REASON_USER, + RadioAccessFamily.getRafFromNetworkType(networkType)); } } catch (RemoteException ex) { Rlog.e(TAG, "setPreferredNetworkType RemoteException", ex); @@ -8158,20 +8162,26 @@ public class TelephonyManager { * <p>Requires Permission: * {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE} or that the calling * app has carrier privileges (see {@link #hasCarrierPrivileges}). + * <p> + * If {@link android.telephony.TelephonyManager#isRadioInterfaceCapabilitySupported} + * ({@link TelephonyManager#CAPABILITY_ALLOWED_NETWORK_TYPES_USED}) returns true, then + * setAllowedNetworkTypesBitmap is used on the radio interface. Otherwise, + * setPreferredNetworkTypesBitmap is used instead. * * @param networkTypeBitmask The bitmask of preferred network types. * @return true on success; false on any failure. * @hide + * @deprecated Use {@link #setAllowedNetworkTypesForReason} instead. */ + @Deprecated @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) @SystemApi public boolean setPreferredNetworkTypeBitmask(@NetworkTypeBitMask long networkTypeBitmask) { try { ITelephony telephony = getITelephony(); if (telephony != null) { - return telephony.setPreferredNetworkType( - getSubId(), RadioAccessFamily.getNetworkTypeFromRaf( - (int) networkTypeBitmask)); + return telephony.setAllowedNetworkTypesForReason(getSubId(), + TelephonyManager.ALLOWED_NETWORK_TYPES_REASON_USER, networkTypeBitmask); } } catch (RemoteException ex) { Rlog.e(TAG, "setPreferredNetworkTypeBitmask RemoteException", ex); @@ -8183,18 +8193,29 @@ public class TelephonyManager { * Set the allowed network types of the device. This is for carrier or privileged apps to * enable/disable certain network types on the device. The user preferred network types should * be set through {@link #setPreferredNetworkTypeBitmask}. + * <p> + * If {@link android.telephony.TelephonyManager#isRadioInterfaceCapabilitySupported} + * ({@link TelephonyManager#CAPABILITY_ALLOWED_NETWORK_TYPES_USED}) returns true, then + * setAllowedNetworkTypesBitmap is used on the radio interface. Otherwise, + * setPreferredNetworkTypesBitmap is used instead. * * @param allowedNetworkTypes The bitmask of allowed network types. * @return true on success; false on any failure. * @hide + * @deprecated Use {@link #setAllowedNetworkTypesForReason} instead. */ + @Deprecated @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) + @RequiresFeature( + enforcement = "android.telephony.TelephonyManager#isRadioInterfaceCapabilitySupported", + value = TelephonyManager.CAPABILITY_ALLOWED_NETWORK_TYPES_USED) @SystemApi public boolean setAllowedNetworkTypes(@NetworkTypeBitMask long allowedNetworkTypes) { try { ITelephony telephony = getITelephony(); if (telephony != null) { - return telephony.setAllowedNetworkTypes(getSubId(), allowedNetworkTypes); + return telephony.setAllowedNetworkTypesForReason(getSubId(), + TelephonyManager.ALLOWED_NETWORK_TYPES_REASON_CARRIER, allowedNetworkTypes); } } catch (RemoteException ex) { Rlog.e(TAG, "setAllowedNetworkTypes RemoteException", ex); @@ -8204,35 +8225,61 @@ public class TelephonyManager { /** @hide */ @IntDef({ - ALLOWED_NETWORK_TYPES_REASON_POWER + ALLOWED_NETWORK_TYPES_REASON_USER, + ALLOWED_NETWORK_TYPES_REASON_POWER, + ALLOWED_NETWORK_TYPES_REASON_CARRIER }) @Retention(RetentionPolicy.SOURCE) - public @interface AllowedNetworkTypesReason{} + public @interface AllowedNetworkTypesReason { + } + + /** + * To indicate allowed network type change is requested by user. + * + * @hide + */ + @SystemApi + public static final int ALLOWED_NETWORK_TYPES_REASON_USER = 0; /** * To indicate allowed network type change is requested by power manager. * Power Manger configuration won't affect the settings configured through - * {@link setAllowedNetworkTypes} and will result in allowing network types that are in both + * other reasons and will result in allowing network types that are in both + * configurations (i.e intersection of both sets). + * + * @hide + */ + @SystemApi + public static final int ALLOWED_NETWORK_TYPES_REASON_POWER = 1; + + /** + * To indicate allowed network type change is requested by carrier. + * Carrier configuration won't affect the settings configured through + * other reasons and will result in allowing network types that are in both * configurations (i.e intersection of both sets). + * * @hide */ - public static final int ALLOWED_NETWORK_TYPES_REASON_POWER = 0; + @SystemApi + public static final int ALLOWED_NETWORK_TYPES_REASON_CARRIER = 2; /** * Set the allowed network types of the device and * provide the reason triggering the allowed network change. * This can be called for following reasons * <ol> + * <li>Allowed network types control by USER {@link #ALLOWED_NETWORK_TYPES_REASON_USER} * <li>Allowed network types control by power manager * {@link #ALLOWED_NETWORK_TYPES_REASON_POWER} + * <li>Allowed network types control by carrier {@link #ALLOWED_NETWORK_TYPES_REASON_CARRIER} * </ol> * This API will result in allowing an intersection of allowed network types for all reasons, - * including the configuration done through {@link setAllowedNetworkTypes}. - * While this API and {@link setAllowedNetworkTypes} is controlling allowed network types - * on device, user preference will still be set through {@link #setPreferredNetworkTypeBitmask}. - * Thus resultant network type configured on modem will be an intersection of the network types - * from setAllowedNetworkTypesForReason, {@link setAllowedNetworkTypes} - * and {@link #setPreferredNetworkTypeBitmask}. + * including the configuration done through other reasons. + * <p> + * If {@link android.telephony.TelephonyManager#isRadioInterfaceCapabilitySupported} + * ({@link TelephonyManager#CAPABILITY_ALLOWED_NETWORK_TYPES_USED}) returns true, then + * setAllowedNetworkTypesBitmap is used on the radio interface. Otherwise, + * setPreferredNetworkTypesBitmap is used instead. * * @param reason the reason the allowed network type change is taking place * @param allowedNetworkTypes The bitmask of allowed network types. @@ -8240,12 +8287,17 @@ public class TelephonyManager { * @throws IllegalArgumentException if invalid AllowedNetworkTypesReason is passed. * @hide */ + @SystemApi @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) + @RequiresFeature( + enforcement = "android.telephony.TelephonyManager#isRadioInterfaceCapabilitySupported", + value = TelephonyManager.CAPABILITY_ALLOWED_NETWORK_TYPES_USED) public void setAllowedNetworkTypesForReason(@AllowedNetworkTypesReason int reason, @NetworkTypeBitMask long allowedNetworkTypes) { - if (reason != ALLOWED_NETWORK_TYPES_REASON_POWER) { + if (!isValidAllowedNetworkTypesReason(reason)) { throw new IllegalArgumentException("invalid AllowedNetworkTypesReason."); } + try { ITelephony telephony = getITelephony(); if (telephony != null) { @@ -8264,25 +8316,29 @@ public class TelephonyManager { * Get the allowed network types for certain reason. * * {@link #getAllowedNetworkTypesForReason} returns allowed network type for a - * specific reason. For effective allowed network types configured on device, - * query {@link getEffectiveAllowedNetworkTypes} + * specific reason. * * <p>Requires Permission: * {@link android.Manifest.permission#READ_PRIVILEGED_PHONE_STATE READ_PRIVILEGED_PHONE_STATE} * or that the calling app has carrier privileges (see {@link #hasCarrierPrivileges}). - *s + * * @param reason the reason the allowed network type change is taking place * @return the allowed network type bitmask - * @throws IllegalStateException if the Telephony process is not currently available. + * @throws IllegalStateException if the Telephony process is not currently available. * @throws IllegalArgumentException if invalid AllowedNetworkTypesReason is passed. * @hide */ + @SystemApi @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) + @RequiresFeature( + enforcement = "android.telephony.TelephonyManager#isRadioInterfaceCapabilitySupported", + value = TelephonyManager.CAPABILITY_ALLOWED_NETWORK_TYPES_USED) public @NetworkTypeBitMask long getAllowedNetworkTypesForReason( @AllowedNetworkTypesReason int reason) { - if (reason != ALLOWED_NETWORK_TYPES_REASON_POWER) { + if (!isValidAllowedNetworkTypesReason(reason)) { throw new IllegalArgumentException("invalid AllowedNetworkTypesReason."); } + try { ITelephony telephony = getITelephony(); if (telephony != null) { @@ -8296,44 +8352,27 @@ public class TelephonyManager { } return -1; } - /** - * Get bit mask of all network types. - * - * @return bit mask of all network types + * Verifies that the reason provided is valid. * @hide */ - public static @NetworkTypeBitMask long getAllNetworkTypesBitmask() { - return NETWORK_STANDARDS_FAMILY_BITMASK_3GPP | NETWORK_STANDARDS_FAMILY_BITMASK_3GPP2; + public static boolean isValidAllowedNetworkTypesReason(@AllowedNetworkTypesReason int reason) { + switch (reason) { + case TelephonyManager.ALLOWED_NETWORK_TYPES_REASON_USER: + case TelephonyManager.ALLOWED_NETWORK_TYPES_REASON_POWER: + case TelephonyManager.ALLOWED_NETWORK_TYPES_REASON_CARRIER: + return true; + } + return false; } - /** - * Get the allowed network types configured on the device. - * This API will return an intersection of allowed network types for all reasons, - * including the configuration done through setAllowedNetworkTypes - * - * <p>Requires Permission: - * {@link android.Manifest.permission#READ_PRIVILEGED_PHONE_STATE READ_PRIVILEGED_PHONE_STATE} - * or that the calling app has carrier privileges (see {@link #hasCarrierPrivileges}). + * Get bit mask of all network types. * - * @return the allowed network type bitmask - * @throws IllegalStateException if the Telephony process is not currently available. + * @return bit mask of all network types * @hide */ - @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) - public @NetworkTypeBitMask long getEffectiveAllowedNetworkTypes() { - try { - ITelephony telephony = getITelephony(); - if (telephony != null) { - return telephony.getEffectiveAllowedNetworkTypes(getSubId()); - } else { - throw new IllegalStateException("telephony service is null."); - } - } catch (RemoteException ex) { - Rlog.e(TAG, "getEffectiveAllowedNetworkTypes RemoteException", ex); - ex.rethrowFromSystemServer(); - } - return -1; + public static @NetworkTypeBitMask long getAllNetworkTypesBitmask() { + return NETWORK_STANDARDS_FAMILY_BITMASK_3GPP | NETWORK_STANDARDS_FAMILY_BITMASK_3GPP2; } /** @@ -14356,10 +14395,24 @@ public class TelephonyManager { public static final String CAPABILITY_SECONDARY_LINK_BANDWIDTH_VISIBLE = "CAPABILITY_SECONDARY_LINK_BANDWIDTH_VISIBLE"; + /** + * Indicates whether {@link #setPreferredNetworkType}, {@link + * #setPreferredNetworkTypeBitmask}, {@link #setAllowedNetworkTypes} and + * {@link #setAllowedNetworkTypesForReason} rely on + * setAllowedNetworkTypesBitmap instead of setPreferredNetworkTypesBitmap on the radio + * interface. + * + * @hide + */ + @SystemApi + public static final String CAPABILITY_ALLOWED_NETWORK_TYPES_USED = + "CAPABILITY_ALLOWED_NETWORK_TYPES_USED"; + /** @hide */ @Retention(RetentionPolicy.SOURCE) @StringDef(prefix = "CAPABILITY_", value = { CAPABILITY_SECONDARY_LINK_BANDWIDTH_VISIBLE, + CAPABILITY_ALLOWED_NETWORK_TYPES_USED, }) public @interface RadioInterfaceCapability {} @@ -14593,8 +14646,13 @@ public class TelephonyManager { * <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}). + * <p> Requires Permission: + * <ul> + * <li>{@link android.Manifest.permission#MODIFY_PHONE_STATE},</li> + * <li>{@link android.Manifest.permission#PERFORM_IMS_SINGLE_REGISTRATION},</li> + * <li>or that the caller has carrier privileges (see + * {@link TelephonyManager#hasCarrierPrivileges()}).</li> + * </ul> * @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 @@ -14621,7 +14679,8 @@ public class TelephonyManager { */ @SystemApi @WorkerThread - @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) + @RequiresPermission(anyOf = {android.Manifest.permission.MODIFY_PHONE_STATE, + Manifest.permission.PERFORM_IMS_SINGLE_REGISTRATION}) public void bootstrapAuthenticationRequest( @UiccAppTypeExt int appType, @NonNull Uri nafId, @NonNull UaSecurityProtocolIdentifier securityProtocol, diff --git a/telephony/java/android/telephony/data/ApnSetting.java b/telephony/java/android/telephony/data/ApnSetting.java index ff9329ef9742..b503733f8de9 100644 --- a/telephony/java/android/telephony/data/ApnSetting.java +++ b/telephony/java/android/telephony/data/ApnSetting.java @@ -18,6 +18,8 @@ package android.telephony.data; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; +import android.annotation.StringDef; +import android.annotation.SystemApi; import android.content.ContentValues; import android.database.Cursor; import android.hardware.radio.V1_5.ApnTypes; @@ -26,7 +28,6 @@ import android.os.Parcel; import android.os.Parcelable; import android.provider.Telephony; import android.provider.Telephony.Carriers; -import android.telephony.Annotation.ApnType; import android.telephony.Annotation.NetworkType; import android.telephony.ServiceState; import android.telephony.TelephonyManager; @@ -113,6 +114,31 @@ public class ApnSetting implements Parcelable { public static final int TYPE_MCX = ApnTypes.MCX; /** APN type for XCAP. */ public static final int TYPE_XCAP = ApnTypes.XCAP; + /** + * APN type for ENTERPRISE. + * @hide + */ + public static final int TYPE_ENTERPRISE = TYPE_XCAP << 1; + + /** @hide */ + @IntDef(flag = true, prefix = {"TYPE_"}, value = { + TYPE_DEFAULT, + TYPE_MMS, + TYPE_SUPL, + TYPE_DUN, + TYPE_HIPRI, + TYPE_FOTA, + TYPE_IMS, + TYPE_CBS, + TYPE_IA, + TYPE_EMERGENCY, + TYPE_MCX, + TYPE_XCAP, + TYPE_ENTERPRISE, + }) + @Retention(RetentionPolicy.SOURCE) + public @interface ApnType { + } // Possible values for authentication types. /** No authentication type. */ @@ -133,6 +159,26 @@ public class ApnSetting implements Parcelable { @Retention(RetentionPolicy.SOURCE) public @interface Skip464XlatStatus {} + /** @hide */ + @StringDef(value = { + TYPE_ALL_STRING, + TYPE_CBS_STRING, + TYPE_DEFAULT_STRING, + TYPE_DUN_STRING, + TYPE_EMERGENCY_STRING, + TYPE_FOTA_STRING, + TYPE_HIPRI_STRING, + TYPE_IA_STRING, + TYPE_IMS_STRING, + TYPE_MCX_STRING, + TYPE_MMS_STRING, + TYPE_SUPL_STRING, + TYPE_XCAP_STRING, + TYPE_ENTERPRISE_STRING, + }, prefix = "TYPE_", suffix = "_STRING") + @Retention(RetentionPolicy.SOURCE) + public @interface ApnTypeString {} + /** * APN types for data connections. These are usage categories for an APN * entry. One APN entry may support multiple APN types, eg, a single APN @@ -140,101 +186,141 @@ public class ApnSetting implements Parcelable { * connections.<br/> * APN_TYPE_ALL is a special type to indicate that this APN entry can * service all data connections. - * <p> - * Note: The goal is to deprecate this. Due to the Carrier Table being used - * directly, this isn't feasible right now. * * @hide */ + @SystemApi public static final String TYPE_ALL_STRING = "*"; /** * APN type for default data traffic * + * Note: String representations of APN types are intended for system apps to communicate with + * modem components or carriers. Non-system apps should use the integer variants instead. * @hide */ + @SystemApi public static final String TYPE_DEFAULT_STRING = "default"; /** - * APN type for MMS traffic + * APN type for MMS (Multimedia Messaging Service) traffic. * + * Note: String representations of APN types are intended for system apps to communicate with + * modem components or carriers. Non-system apps should use the integer variants instead. * @hide */ + @SystemApi public static final String TYPE_MMS_STRING = "mms"; /** - * APN type for SUPL assisted GPS + * APN type for SUPL (Secure User Plane Location) assisted GPS. * + * Note: String representations of APN types are intended for system apps to communicate with + * modem components or carriers. Non-system apps should use the integer variants instead. * @hide */ + @SystemApi public static final String TYPE_SUPL_STRING = "supl"; /** - * APN type for DUN traffic + * APN type for DUN (Dial-up networking) traffic * + * Note: String representations of APN types are intended for system apps to communicate with + * modem components or carriers. Non-system apps should use the integer variants instead. * @hide */ + @SystemApi public static final String TYPE_DUN_STRING = "dun"; /** - * APN type for HiPri traffic + * APN type for high-priority traffic * + * Note: String representations of APN types are intended for system apps to communicate with + * modem components or carriers. Non-system apps should use the integer variants instead. * @hide */ + @SystemApi public static final String TYPE_HIPRI_STRING = "hipri"; /** - * APN type for FOTA + * APN type for FOTA (Firmware over-the-air) traffic. * + * Note: String representations of APN types are intended for system apps to communicate with + * modem components or carriers. Non-system apps should use the integer variants instead. * @hide */ + @SystemApi public static final String TYPE_FOTA_STRING = "fota"; /** - * APN type for IMS + * APN type for IMS (IP Multimedia Subsystem) traffic. * + * Note: String representations of APN types are intended for system apps to communicate with + * modem components or carriers. Non-system apps should use the integer variants instead. * @hide */ + @SystemApi public static final String TYPE_IMS_STRING = "ims"; /** - * APN type for CBS + * APN type for CBS (Carrier Branded Services) traffic. * + * Note: String representations of APN types are intended for system apps to communicate with + * modem components or carriers. Non-system apps should use the integer variants instead. * @hide */ + @SystemApi public static final String TYPE_CBS_STRING = "cbs"; /** - * APN type for IA Initial Attach APN + * APN type for the IA (Initial Attach) APN * + * Note: String representations of APN types are intended for system apps to communicate with + * modem components or carriers. Non-system apps should use the integer variants instead. * @hide */ + @SystemApi public static final String TYPE_IA_STRING = "ia"; /** * APN type for Emergency PDN. This is not an IA apn, but is used * for access to carrier services in an emergency call situation. * + * Note: String representations of APN types are intended for system apps to communicate with + * modem components or carriers. Non-system apps should use the integer variants instead. * @hide */ + @SystemApi public static final String TYPE_EMERGENCY_STRING = "emergency"; /** - * APN type for Mission Critical Services + * APN type for Mission Critical Services. * + * Note: String representations of APN types are intended for system apps to communicate with + * modem components or carriers. Non-system apps should use the integer variants instead. * @hide */ + @SystemApi public static final String TYPE_MCX_STRING = "mcx"; /** - * APN type for XCAP + * APN type for XCAP (XML Configuration Access Protocol) traffic. * + * Note: String representations of APN types are intended for system apps to communicate with + * modem components or carriers. Non-system apps should use the integer variants instead. * @hide */ + @SystemApi public static final String TYPE_XCAP_STRING = "xcap"; + /** + * APN type for ENTERPRISE traffic. + * @hide + */ + public static final String TYPE_ENTERPRISE_STRING = "enterprise"; + /** @hide */ @IntDef(prefix = { "AUTH_TYPE_" }, value = { @@ -314,6 +400,7 @@ public class ApnSetting implements Parcelable { APN_TYPE_STRING_MAP.put(TYPE_EMERGENCY_STRING, TYPE_EMERGENCY); APN_TYPE_STRING_MAP.put(TYPE_MCX_STRING, TYPE_MCX); APN_TYPE_STRING_MAP.put(TYPE_XCAP_STRING, TYPE_XCAP); + APN_TYPE_STRING_MAP.put(TYPE_ENTERPRISE_STRING, TYPE_ENTERPRISE); APN_TYPE_INT_MAP = new ArrayMap<>(); APN_TYPE_INT_MAP.put(TYPE_DEFAULT, TYPE_DEFAULT_STRING); @@ -328,6 +415,7 @@ public class ApnSetting implements Parcelable { APN_TYPE_INT_MAP.put(TYPE_EMERGENCY, TYPE_EMERGENCY_STRING); APN_TYPE_INT_MAP.put(TYPE_MCX, TYPE_MCX_STRING); APN_TYPE_INT_MAP.put(TYPE_XCAP, TYPE_XCAP_STRING); + APN_TYPE_INT_MAP.put(TYPE_ENTERPRISE, TYPE_ENTERPRISE_STRING); PROTOCOL_STRING_MAP = new ArrayMap<>(); PROTOCOL_STRING_MAP.put("IP", PROTOCOL_IP); @@ -1426,16 +1514,43 @@ public class ApnSetting implements Parcelable { } /** - * @param apnType APN type - * @return APN type in string format + * Converts the integer representation of APN type to its string representation. + * + * @param apnType APN type as an integer + * @return String representation of the APN type, or an empty string if the provided integer is + * not a valid APN type. * @hide */ - public static String getApnTypeString(int apnType) { + @SystemApi + public static @NonNull @ApnTypeString String getApnTypeString(@ApnType int apnType) { if (apnType == TYPE_ALL) { return "*"; } String apnTypeString = APN_TYPE_INT_MAP.get(apnType); - return apnTypeString == null ? "Unknown" : apnTypeString; + return apnTypeString == null ? "" : apnTypeString; + } + + /** + * Same as {@link #getApnTypeString(int)}, but returns "Unknown" instead of an empty string + * when provided with an invalid int for compatibility purposes. + * @hide + */ + public static @NonNull String getApnTypeStringInternal(@ApnType int apnType) { + String result = getApnTypeString(apnType); + return TextUtils.isEmpty(result) ? "Unknown" : result; + } + + /** + * Converts the string representation of an APN type to its integer representation. + * + * @param apnType APN type as a string + * @return Integer representation of the APN type, or 0 if the provided string is not a valid + * APN type. + * @hide + */ + @SystemApi + public static @ApnType int getApnTypeInt(@NonNull @ApnTypeString String apnType) { + return APN_TYPE_STRING_MAP.getOrDefault(apnType.toLowerCase(), 0); } /** @@ -2079,7 +2194,7 @@ public class ApnSetting implements Parcelable { public ApnSetting build() { if ((mApnTypeBitmask & (TYPE_DEFAULT | TYPE_MMS | TYPE_SUPL | TYPE_DUN | TYPE_HIPRI | TYPE_FOTA | TYPE_IMS | TYPE_CBS | TYPE_IA | TYPE_EMERGENCY | TYPE_MCX - | TYPE_XCAP)) == 0 + | TYPE_XCAP | TYPE_ENTERPRISE)) == 0 || TextUtils.isEmpty(mApnName) || TextUtils.isEmpty(mEntryName)) { return null; } diff --git a/telephony/java/android/telephony/data/DataCallResponse.java b/telephony/java/android/telephony/data/DataCallResponse.java index 46940dc6a0a5..a5e5ab01810f 100644 --- a/telephony/java/android/telephony/data/DataCallResponse.java +++ b/telephony/java/android/telephony/data/DataCallResponse.java @@ -136,8 +136,9 @@ public final class DataCallResponse implements Parcelable { private final @HandoverFailureMode int mHandoverFailureMode; private final int mPduSessionId; private final Qos mDefaultQos; - private final List<QosSession> mQosSessions; + private final List<QosBearerSession> mQosBearerSessions; private final SliceInfo mSliceInfo; + private final List<TrafficDescriptor> mTrafficDescriptors; /** * @param cause Data call fail cause. {@link DataFailCause#NONE} indicates no error. @@ -187,8 +188,9 @@ public final class DataCallResponse implements Parcelable { mHandoverFailureMode = HANDOVER_FAILURE_MODE_LEGACY; mPduSessionId = PDU_SESSION_ID_NOT_SET; mDefaultQos = null; - mQosSessions = new ArrayList<>(); + mQosBearerSessions = new ArrayList<>(); mSliceInfo = null; + mTrafficDescriptors = new ArrayList<>(); } private DataCallResponse(@DataFailureCause int cause, long suggestedRetryTime, int id, @@ -197,8 +199,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 SliceInfo sliceInfo) { + @Nullable Qos defaultQos, @Nullable List<QosBearerSession> qosBearerSessions, + @Nullable SliceInfo sliceInfo, @Nullable List<TrafficDescriptor> trafficDescriptors) { mCause = cause; mSuggestedRetryTime = suggestedRetryTime; mId = id; @@ -219,8 +221,11 @@ public final class DataCallResponse implements Parcelable { mHandoverFailureMode = handoverFailureMode; mPduSessionId = pduSessionId; mDefaultQos = defaultQos; - mQosSessions = qosSessions; + mQosBearerSessions = (qosBearerSessions == null) + ? new ArrayList<>() : new ArrayList<>(qosBearerSessions); mSliceInfo = sliceInfo; + mTrafficDescriptors = (trafficDescriptors == null) + ? new ArrayList<>() : new ArrayList<>(trafficDescriptors); } /** @hide */ @@ -246,9 +251,11 @@ public final class DataCallResponse implements Parcelable { mHandoverFailureMode = source.readInt(); mPduSessionId = source.readInt(); mDefaultQos = source.readParcelable(Qos.class.getClassLoader()); - mQosSessions = new ArrayList<>(); - source.readList(mQosSessions, QosSession.class.getClassLoader()); + mQosBearerSessions = new ArrayList<>(); + source.readList(mQosBearerSessions, QosBearerSession.class.getClassLoader()); mSliceInfo = source.readParcelable(SliceInfo.class.getClassLoader()); + mTrafficDescriptors = new ArrayList<>(); + source.readList(mTrafficDescriptors, TrafficDescriptor.class.getClassLoader()); } /** @@ -380,7 +387,6 @@ public final class DataCallResponse implements Parcelable { * * @hide */ - @Nullable public Qos getDefaultQos() { return mDefaultQos; @@ -393,8 +399,8 @@ public final class DataCallResponse implements Parcelable { * @hide */ @NonNull - public List<QosSession> getQosSessions() { - return mQosSessions; + public List<QosBearerSession> getQosBearerSessions() { + return mQosBearerSessions; } /** @@ -405,6 +411,14 @@ public final class DataCallResponse implements Parcelable { return mSliceInfo; } + /** + * @return The traffic descriptors related to this data connection. + */ + @NonNull + public List<TrafficDescriptor> getTrafficDescriptors() { + return mTrafficDescriptors; + } + @NonNull @Override public String toString() { @@ -426,8 +440,9 @@ public final class DataCallResponse implements Parcelable { .append(" handoverFailureMode=").append(getHandoverFailureMode()) .append(" pduSessionId=").append(getPduSessionId()) .append(" defaultQos=").append(mDefaultQos) - .append(" qosSessions=").append(mQosSessions) + .append(" qosBearerSessions=").append(mQosBearerSessions) .append(" sliceInfo=").append(mSliceInfo) + .append(" trafficDescriptors=").append(mTrafficDescriptors) .append("}"); return sb.toString(); } @@ -442,14 +457,21 @@ public final class DataCallResponse implements Parcelable { DataCallResponse other = (DataCallResponse) o; - final boolean isQosSame = (mDefaultQos == null || other.mDefaultQos == null) ? - mDefaultQos == other.mDefaultQos : - mDefaultQos.equals(other.mDefaultQos); + final boolean isQosSame = (mDefaultQos == null || other.mDefaultQos == null) + ? mDefaultQos == other.mDefaultQos + : mDefaultQos.equals(other.mDefaultQos); - final boolean isQosSessionsSame = (mQosSessions == null || mQosSessions == null) ? - mQosSessions == other.mQosSessions : - mQosSessions.size() == other.mQosSessions.size() - && mQosSessions.containsAll(other.mQosSessions); + final boolean isQosBearerSessionsSame = + (mQosBearerSessions == null || other.mQosBearerSessions == null) + ? mQosBearerSessions == other.mQosBearerSessions + : mQosBearerSessions.size() == other.mQosBearerSessions.size() + && mQosBearerSessions.containsAll(other.mQosBearerSessions); + + final boolean isTrafficDescriptorsSame = + (mTrafficDescriptors == null || other.mTrafficDescriptors == null) + ? mTrafficDescriptors == other.mTrafficDescriptors + : mTrafficDescriptors.size() == other.mTrafficDescriptors.size() + && mTrafficDescriptors.containsAll(other.mTrafficDescriptors); return mCause == other.mCause && mSuggestedRetryTime == other.mSuggestedRetryTime @@ -471,8 +493,9 @@ public final class DataCallResponse implements Parcelable { && mHandoverFailureMode == other.mHandoverFailureMode && mPduSessionId == other.mPduSessionId && isQosSame - && isQosSessionsSame - && Objects.equals(mSliceInfo, other.mSliceInfo); + && isQosBearerSessionsSame + && Objects.equals(mSliceInfo, other.mSliceInfo) + && isTrafficDescriptorsSame; } @Override @@ -480,7 +503,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, mSliceInfo); + mQosBearerSessions, mSliceInfo, mTrafficDescriptors); } @Override @@ -510,8 +533,9 @@ public final class DataCallResponse implements Parcelable { } else { dest.writeParcelable((NrQos)mDefaultQos, flags); } - dest.writeList(mQosSessions); + dest.writeList(mQosBearerSessions); dest.writeParcelable(mSliceInfo, flags); + dest.writeList(mTrafficDescriptors); } public static final @android.annotation.NonNull Parcelable.Creator<DataCallResponse> CREATOR = @@ -593,10 +617,12 @@ public final class DataCallResponse implements Parcelable { private Qos mDefaultQos; - private List<QosSession> mQosSessions = new ArrayList<>(); + private List<QosBearerSession> mQosBearerSessions = new ArrayList<>(); private SliceInfo mSliceInfo; + private List<TrafficDescriptor> mTrafficDescriptors = new ArrayList<>(); + /** * Default constructor for Builder. */ @@ -807,15 +833,16 @@ public final class DataCallResponse implements Parcelable { /** * Set the dedicated bearer QOS sessions for this data connection. * - * @param qosSessions Dedicated bearer QOS (Quality Of Service) sessions received + * @param qosBearerSessions Dedicated bearer QOS (Quality Of Service) sessions received * from network. * * @return The same instance of the builder. * * @hide */ - public @NonNull Builder setQosSessions(@NonNull List<QosSession> qosSessions) { - mQosSessions = qosSessions; + public @NonNull Builder setQosBearerSessions( + @NonNull List<QosBearerSession> qosBearerSessions) { + mQosBearerSessions = qosBearerSessions; return this; } @@ -835,6 +862,24 @@ public final class DataCallResponse implements Parcelable { } /** + * The traffic descriptors for this data connection, as defined in 3GPP TS 24.526 + * Section 5.2. They are used for URSP traffic matching as described in 3GPP TS 24.526 + * Section 4.2.2. They includes an optional DNN, which, if present, must be used for traffic + * matching; it does not specify the end point to be used for the data call. The end point + * is specified by {@link DataProfile}, which must be used as the end point if one is not + * specified through URSP rules. + * + * @param trafficDescriptors the traffic descriptors for the data call. + * + * @return The same instance of the builder. + */ + public @NonNull Builder setTrafficDescriptors( + @NonNull List<TrafficDescriptor> trafficDescriptors) { + mTrafficDescriptors = trafficDescriptors; + return this; + } + + /** * Build the DataCallResponse. * * @return the DataCallResponse object. @@ -843,7 +888,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, mSliceInfo); + mDefaultQos, mQosBearerSessions, mSliceInfo, mTrafficDescriptors); } } } diff --git a/telephony/java/android/telephony/data/DataService.java b/telephony/java/android/telephony/data/DataService.java index 03c2ef9d9baa..f5f29c65b7cd 100644 --- a/telephony/java/android/telephony/data/DataService.java +++ b/telephony/java/android/telephony/data/DataService.java @@ -200,6 +200,17 @@ public abstract class DataService extends Service { * 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 trafficDescriptor {@link TrafficDescriptor} for which data connection needs to be + * established. It is used for URSP traffic matching as described in 3GPP TS 24.526 + * Section 4.2.2. It includes an optional DNN which, if present, must be used for + * traffic matching; it does not specify the end point to be used for the data call. + * @param matchAllRuleAllowed Indicates if using default match-all URSP rule for this + * request is allowed. If false, this request must not use the match-all URSP rule + * and if a non-match-all rule is not found (or if URSP rules are not available) then + * {@link DataCallResponse#getCause()} is + * {@link android.telephony.DataFailCause#MATCH_ALL_RULE_NOT_ALLOWED}. This is needed + * as some requests need to have a hard failure if the intention cannot be met, + * for example, a zero-rating slice. * @param callback The result callback for this request. */ public void setupDataCall(int accessNetworkType, @NonNull DataProfile dataProfile, @@ -207,6 +218,7 @@ public abstract class DataService extends Service { @SetupDataReason int reason, @Nullable LinkProperties linkProperties, @IntRange(from = 0, to = 15) int pduSessionId, @Nullable SliceInfo sliceInfo, + @Nullable TrafficDescriptor trafficDescriptor, boolean matchAllRuleAllowed, @NonNull DataServiceCallback callback) { /* Call the old version since the new version isn't supported */ setupDataCall(accessNetworkType, dataProfile, isRoaming, allowRoaming, reason, @@ -283,6 +295,8 @@ public abstract class DataService extends Service { * * @param cid The identifier of the data call which is provided in {@link DataCallResponse} * @param callback The result callback for this request. + * + * @hide */ public void startHandover(int cid, @NonNull DataServiceCallback callback) { // The default implementation is to return unsupported. @@ -303,6 +317,8 @@ public abstract class DataService extends Service { * * @param cid The identifier of the data call which is provided in {@link DataCallResponse} * @param callback The result callback for this request. + * + * @hide */ public void cancelHandover(int cid, @NonNull DataServiceCallback callback) { // The default implementation is to return unsupported. @@ -399,10 +415,13 @@ public abstract class DataService extends Service { public final LinkProperties linkProperties; public final int pduSessionId; public final SliceInfo sliceInfo; + public final TrafficDescriptor trafficDescriptor; + public final boolean matchAllRuleAllowed; public final IDataServiceCallback callback; SetupDataCallRequest(int accessNetworkType, DataProfile dataProfile, boolean isRoaming, - boolean allowRoaming, int reason, LinkProperties linkProperties, - int pduSessionId, SliceInfo sliceInfo, IDataServiceCallback callback) { + boolean allowRoaming, int reason, LinkProperties linkProperties, int pduSessionId, + SliceInfo sliceInfo, TrafficDescriptor trafficDescriptor, + boolean matchAllRuleAllowed, IDataServiceCallback callback) { this.accessNetworkType = accessNetworkType; this.dataProfile = dataProfile; this.isRoaming = isRoaming; @@ -411,6 +430,8 @@ public abstract class DataService extends Service { this.reason = reason; this.pduSessionId = pduSessionId; this.sliceInfo = sliceInfo; + this.trafficDescriptor = trafficDescriptor; + this.matchAllRuleAllowed = matchAllRuleAllowed; this.callback = callback; } } @@ -521,7 +542,8 @@ public abstract class DataService extends Service { setupDataCallRequest.dataProfile, setupDataCallRequest.isRoaming, setupDataCallRequest.allowRoaming, setupDataCallRequest.reason, setupDataCallRequest.linkProperties, setupDataCallRequest.pduSessionId, - setupDataCallRequest.sliceInfo, + setupDataCallRequest.sliceInfo, setupDataCallRequest.trafficDescriptor, + setupDataCallRequest.matchAllRuleAllowed, (setupDataCallRequest.callback != null) ? new DataServiceCallback(setupDataCallRequest.callback) : null); @@ -686,11 +708,12 @@ public abstract class DataService extends Service { public void setupDataCall(int slotIndex, int accessNetworkType, DataProfile dataProfile, boolean isRoaming, boolean allowRoaming, int reason, LinkProperties linkProperties, int pduSessionId, SliceInfo sliceInfo, + TrafficDescriptor trafficDescriptor, boolean matchAllRuleAllowed, IDataServiceCallback callback) { mHandler.obtainMessage(DATA_SERVICE_REQUEST_SETUP_DATA_CALL, slotIndex, 0, new SetupDataCallRequest(accessNetworkType, dataProfile, isRoaming, allowRoaming, reason, linkProperties, pduSessionId, sliceInfo, - callback)) + trafficDescriptor, matchAllRuleAllowed, callback)) .sendToTarget(); } diff --git a/telephony/java/android/telephony/data/DataServiceCallback.java b/telephony/java/android/telephony/data/DataServiceCallback.java index f56c19b78a16..ca1f861f9808 100644 --- a/telephony/java/android/telephony/data/DataServiceCallback.java +++ b/telephony/java/android/telephony/data/DataServiceCallback.java @@ -191,6 +191,8 @@ public class DataServiceCallback { * Called to indicate result for the request {@link DataService#startHandover}. * * @param result The result code. Must be one of the {@link ResultCode} + * + * @hide */ public void onHandoverStarted(@ResultCode int result) { if (mCallback != null) { @@ -209,6 +211,8 @@ public class DataServiceCallback { * Called to indicate result for the request {@link DataService#cancelHandover}. * * @param result The result code. Must be one of the {@link ResultCode} + * + * @hide */ public void onHandoverCancelled(@ResultCode int result) { if (mCallback != null) { diff --git a/telephony/java/android/telephony/data/EpsQos.java b/telephony/java/android/telephony/data/EpsQos.java index ad43068b2f11..22c8b0a0a74f 100644 --- a/telephony/java/android/telephony/data/EpsQos.java +++ b/telephony/java/android/telephony/data/EpsQos.java @@ -48,6 +48,10 @@ public final class EpsQos extends Qos implements Parcelable { qosClassId = source.readInt(); } + public int getQci() { + return qosClassId; + } + public static @NonNull EpsQos createFromParcelBody(@NonNull Parcel in) { return new EpsQos(in); } diff --git a/telephony/java/android/telephony/data/IDataService.aidl b/telephony/java/android/telephony/data/IDataService.aidl index e0b9a1a9bb5a..81f5fd3b69a9 100644 --- a/telephony/java/android/telephony/data/IDataService.aidl +++ b/telephony/java/android/telephony/data/IDataService.aidl @@ -20,6 +20,7 @@ import android.net.LinkProperties; import android.telephony.data.DataProfile; import android.telephony.data.IDataServiceCallback; import android.telephony.data.SliceInfo; +import android.telephony.data.TrafficDescriptor; /** * {@hide} @@ -30,7 +31,9 @@ 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, in SliceInfo sliceInfo, IDataServiceCallback callback); + int pduSessionId, in SliceInfo sliceInfo, + in TrafficDescriptor trafficDescriptor, boolean matchAllRuleAllowed, + 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/Qos.java b/telephony/java/android/telephony/data/Qos.java index c8bb91e28bf2..c286c6217450 100644 --- a/telephony/java/android/telephony/data/Qos.java +++ b/telephony/java/android/telephony/data/Qos.java @@ -56,7 +56,15 @@ public abstract class Qos { this.uplink = new QosBandwidth(uplink.maxBitrateKbps, uplink.guaranteedBitrateKbps); } - static class QosBandwidth implements Parcelable { + public QosBandwidth getDownlinkBandwidth() { + return downlink; + } + + public QosBandwidth getUplinkBandwidth() { + return uplink; + } + + public static class QosBandwidth implements Parcelable { int maxBitrateKbps; int guaranteedBitrateKbps; @@ -73,6 +81,14 @@ public abstract class Qos { guaranteedBitrateKbps = source.readInt(); } + public int getMaxBitrateKbps() { + return maxBitrateKbps; + } + + public int getGuaranteedBitrateKbps() { + return guaranteedBitrateKbps; + } + @Override public void writeToParcel(Parcel dest, int flags) { dest.writeInt(maxBitrateKbps); diff --git a/telephony/java/android/telephony/data/QosFilter.java b/telephony/java/android/telephony/data/QosBearerFilter.java index 69277445634d..6c1c653f13d0 100644 --- a/telephony/java/android/telephony/data/QosFilter.java +++ b/telephony/java/android/telephony/data/QosBearerFilter.java @@ -38,7 +38,7 @@ import java.util.Objects; * * @hide */ -public final class QosFilter implements Parcelable { +public final class QosBearerFilter implements Parcelable { private List<LinkAddress> localAddresses; private List<LinkAddress> remoteAddresses; @@ -74,7 +74,7 @@ public final class QosFilter implements Parcelable { @IntDef(prefix = "QOS_FILTER_DIRECTION_", value = {QOS_FILTER_DIRECTION_DOWNLINK, QOS_FILTER_DIRECTION_UPLINK, QOS_FILTER_DIRECTION_BIDIRECTIONAL}) - public @interface QosFilterDirection {} + public @interface QosBearerFilterDirection {} public static final int QOS_FILTER_DIRECTION_DOWNLINK = android.hardware.radio.V1_6.QosFilterDirection.DOWNLINK; @@ -83,7 +83,7 @@ public final class QosFilter implements Parcelable { public static final int QOS_FILTER_DIRECTION_BIDIRECTIONAL = android.hardware.radio.V1_6.QosFilterDirection.BIDIRECTIONAL; - @QosFilterDirection + @QosBearerFilterDirection private int filterDirection; /** @@ -92,7 +92,7 @@ public final class QosFilter implements Parcelable { */ private int precedence; - QosFilter() { + QosBearerFilter() { localAddresses = new ArrayList<>(); remoteAddresses = new ArrayList<>(); localPort = new PortRange(); @@ -101,7 +101,7 @@ public final class QosFilter implements Parcelable { filterDirection = QOS_FILTER_DIRECTION_BIDIRECTIONAL; } - public QosFilter(List<LinkAddress> localAddresses, List<LinkAddress> remoteAddresses, + public QosBearerFilter(List<LinkAddress> localAddresses, List<LinkAddress> remoteAddresses, PortRange localPort, PortRange remotePort, int protocol, int tos, long flowLabel, long spi, int direction, int precedence) { this.localAddresses = localAddresses; @@ -116,10 +116,30 @@ public final class QosFilter implements Parcelable { this.precedence = precedence; } + public List<LinkAddress> getLocalAddresses() { + return localAddresses; + } + + public List<LinkAddress> getRemoteAddresses() { + return remoteAddresses; + } + + public PortRange getLocalPortRange() { + return localPort; + } + + public PortRange getRemotePortRange() { + return remotePort; + } + + public int getPrecedence() { + return precedence; + } + /** @hide */ - public static @NonNull QosFilter create( + public static @NonNull QosBearerFilter create( @NonNull android.hardware.radio.V1_6.QosFilter qosFilter) { - QosFilter ret = new QosFilter(); + QosBearerFilter ret = new QosBearerFilter(); String[] localAddresses = qosFilter.localAddresses.stream().toArray(String[]::new); if (localAddresses != null) { @@ -202,6 +222,14 @@ public final class QosFilter implements Parcelable { this.end = end; } + public int getStart() { + return start; + } + + public int getEnd() { + return end; + } + @Override public void writeToParcel(@NonNull Parcel dest, int flags) { dest.writeInt(start); @@ -254,7 +282,7 @@ public final class QosFilter implements Parcelable { @Override public String toString() { - return "QosFilter {" + return "QosBearerFilter {" + " localAddresses=" + localAddresses + " remoteAddresses=" + remoteAddresses + " localPort=" + localPort @@ -278,11 +306,11 @@ public final class QosFilter implements Parcelable { public boolean equals(Object o) { if (this == o) return true; - if (o == null || !(o instanceof QosFilter)) { + if (o == null || !(o instanceof QosBearerFilter)) { return false; } - QosFilter other = (QosFilter) o; + QosBearerFilter other = (QosBearerFilter) o; return localAddresses.size() == other.localAddresses.size() && localAddresses.containsAll(other.localAddresses) @@ -324,7 +352,7 @@ public final class QosFilter implements Parcelable { LinkAddress.LIFETIME_UNKNOWN, LinkAddress.LIFETIME_UNKNOWN); } - private QosFilter(Parcel source) { + private QosBearerFilter(Parcel source) { localAddresses = new ArrayList<>(); source.readList(localAddresses, LinkAddress.class.getClassLoader()); remoteAddresses = new ArrayList<>(); @@ -358,16 +386,16 @@ public final class QosFilter implements Parcelable { return 0; } - public static final @NonNull Parcelable.Creator<QosFilter> CREATOR = - new Parcelable.Creator<QosFilter>() { + public static final @NonNull Parcelable.Creator<QosBearerFilter> CREATOR = + new Parcelable.Creator<QosBearerFilter>() { @Override - public QosFilter createFromParcel(Parcel source) { - return new QosFilter(source); + public QosBearerFilter createFromParcel(Parcel source) { + return new QosBearerFilter(source); } @Override - public QosFilter[] newArray(int size) { - return new QosFilter[size]; + public QosBearerFilter[] newArray(int size) { + return new QosBearerFilter[size]; } }; } diff --git a/telephony/java/android/telephony/data/QosBearerSession.java b/telephony/java/android/telephony/data/QosBearerSession.java new file mode 100644 index 000000000000..30effc9273d7 --- /dev/null +++ b/telephony/java/android/telephony/data/QosBearerSession.java @@ -0,0 +1,137 @@ +/** + * 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.data; + +import android.annotation.NonNull; +import android.os.Parcel; +import android.os.Parcelable; + +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; + + +/** + * Class that stores information specific to QOS session. + * + * @hide + */ +public final class QosBearerSession implements Parcelable{ + + final int qosBearerSessionId; + final Qos qos; + final List<QosBearerFilter> qosBearerFilterList; + + public QosBearerSession(int qosBearerSessionId, @NonNull Qos qos, @NonNull List<QosBearerFilter> qosBearerFilterList) { + this.qosBearerSessionId = qosBearerSessionId; + this.qos = qos; + this.qosBearerFilterList = qosBearerFilterList; + } + + private QosBearerSession(Parcel source) { + qosBearerSessionId = source.readInt(); + qos = source.readParcelable(Qos.class.getClassLoader()); + qosBearerFilterList = new ArrayList<>(); + source.readList(qosBearerFilterList, QosBearerFilter.class.getClassLoader()); + } + + public int getQosBearerSessionId() { + return qosBearerSessionId; + } + + public Qos getQos() { + return qos; + } + + public List<QosBearerFilter> getQosBearerFilterList() { + return qosBearerFilterList; + } + + @Override + public void writeToParcel(@NonNull Parcel dest, int flags) { + dest.writeInt(qosBearerSessionId); + if (qos.getType() == Qos.QOS_TYPE_EPS) { + dest.writeParcelable((EpsQos)qos, flags); + } else { + dest.writeParcelable((NrQos)qos, flags); + } + dest.writeList(qosBearerFilterList); + } + + public static @NonNull QosBearerSession create( + @NonNull android.hardware.radio.V1_6.QosSession qosSession) { + List<QosBearerFilter> qosBearerFilters = new ArrayList<>(); + + if (qosSession.qosFilters != null) { + for (android.hardware.radio.V1_6.QosFilter filter : qosSession.qosFilters) { + qosBearerFilters.add(QosBearerFilter.create(filter)); + } + } + + return new QosBearerSession( + qosSession.qosSessionId, + Qos.create(qosSession.qos), + qosBearerFilters); + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public String toString() { + return "QosBearerSession {" + + " qosBearerSessionId=" + qosBearerSessionId + + " qos=" + qos + + " qosBearerFilterList=" + qosBearerFilterList + "}"; + } + + @Override + public int hashCode() { + return Objects.hash(qosBearerSessionId, qos, qosBearerFilterList); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + + if (o == null || !(o instanceof QosBearerSession)) { + return false; + } + + QosBearerSession other = (QosBearerSession) o; + return this.qosBearerSessionId == other.qosBearerSessionId + && this.qos.equals(other.qos) + && this.qosBearerFilterList.size() == other.qosBearerFilterList.size() + && this.qosBearerFilterList.containsAll(other.qosBearerFilterList); + } + + + public static final @NonNull Parcelable.Creator<QosBearerSession> CREATOR = + new Parcelable.Creator<QosBearerSession>() { + @Override + public QosBearerSession createFromParcel(Parcel source) { + return new QosBearerSession(source); + } + + @Override + public QosBearerSession[] newArray(int size) { + return new QosBearerSession[size]; + } + }; +} diff --git a/telephony/java/android/telephony/data/QosSession.java b/telephony/java/android/telephony/data/QosSession.java deleted file mode 100644 index f07b6a9f6725..000000000000 --- a/telephony/java/android/telephony/data/QosSession.java +++ /dev/null @@ -1,125 +0,0 @@ -/** - * 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.data; - -import android.annotation.NonNull; -import android.os.Parcel; -import android.os.Parcelable; - -import java.util.ArrayList; -import java.util.List; -import java.util.Objects; - - -/** - * Class that stores information specific to QOS session. - * - * @hide - */ -public final class QosSession implements Parcelable{ - - final int qosSessionId; - final Qos qos; - final List<QosFilter> qosFilterList; - - public QosSession(int qosSessionId, @NonNull Qos qos, @NonNull List<QosFilter> qosFilterList) { - this.qosSessionId = qosSessionId; - this.qos = qos; - this.qosFilterList = qosFilterList; - } - - private QosSession(Parcel source) { - qosSessionId = source.readInt(); - qos = source.readParcelable(Qos.class.getClassLoader()); - qosFilterList = new ArrayList<>(); - source.readList(qosFilterList, QosFilter.class.getClassLoader()); - } - - @Override - public void writeToParcel(@NonNull Parcel dest, int flags) { - dest.writeInt(qosSessionId); - if (qos.getType() == Qos.QOS_TYPE_EPS) { - dest.writeParcelable((EpsQos)qos, flags); - } else { - dest.writeParcelable((NrQos)qos, flags); - } - dest.writeList(qosFilterList); - } - - public static @NonNull QosSession create( - @NonNull android.hardware.radio.V1_6.QosSession qosSession) { - List<QosFilter> qosFilters = new ArrayList<>(); - - if (qosSession.qosFilters != null) { - for (android.hardware.radio.V1_6.QosFilter filter : qosSession.qosFilters) { - qosFilters.add(QosFilter.create(filter)); - } - } - - return new QosSession( - qosSession.qosSessionId, - Qos.create(qosSession.qos), - qosFilters); - } - - @Override - public int describeContents() { - return 0; - } - - @Override - public String toString() { - return "QosSession {" - + " qosSessionId=" + qosSessionId - + " qos=" + qos - + " qosFilterList=" + qosFilterList + "}"; - } - - @Override - public int hashCode() { - return Objects.hash(qosSessionId, qos, qosFilterList); - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - - if (o == null || !(o instanceof QosSession)) { - return false; - } - - QosSession other = (QosSession) o; - return this.qosSessionId == other.qosSessionId - && this.qos.equals(other.qos) - && this.qosFilterList.size() == other.qosFilterList.size() - && this.qosFilterList.containsAll(other.qosFilterList); - } - - - public static final @NonNull Parcelable.Creator<QosSession> CREATOR = - new Parcelable.Creator<QosSession>() { - @Override - public QosSession createFromParcel(Parcel source) { - return new QosSession(source); - } - - @Override - public QosSession[] newArray(int size) { - return new QosSession[size]; - } - }; -} diff --git a/telephony/java/android/telephony/data/TrafficDescriptor.aidl b/telephony/java/android/telephony/data/TrafficDescriptor.aidl new file mode 100644 index 000000000000..a9c7604a91b6 --- /dev/null +++ b/telephony/java/android/telephony/data/TrafficDescriptor.aidl @@ -0,0 +1,20 @@ +/* + * Copyright (C) 2021 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 TrafficDescriptor; diff --git a/telephony/java/android/telephony/data/TrafficDescriptor.java b/telephony/java/android/telephony/data/TrafficDescriptor.java new file mode 100644 index 000000000000..480379d641b6 --- /dev/null +++ b/telephony/java/android/telephony/data/TrafficDescriptor.java @@ -0,0 +1,111 @@ +/* + * Copyright (C) 2021 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.NonNull; +import android.annotation.Nullable; +import android.annotation.SystemApi; +import android.os.Parcel; +import android.os.Parcelable; + +import java.util.Objects; + +/** + * A traffic descriptor, as defined in 3GPP TS 24.526 Section 5.2. It is used for URSP traffic + * matching as described in 3GPP TS 24.526 Section 4.2.2. It includes an optional DNN, which, + * if present, must be used for traffic matching; it does not specify the end point to be used for + * the data call. + * @hide + */ +@SystemApi +public final class TrafficDescriptor implements Parcelable { + private final String mDnn; + private final String mOsAppId; + + private TrafficDescriptor(@NonNull Parcel in) { + mDnn = in.readString(); + mOsAppId = in.readString(); + } + + /** + * Create a traffic descriptor, as defined in 3GPP TS 24.526 Section 5.2 + * @param dnn optional DNN, which must be used for traffic matching, if present + * @param osAppId OsId + osAppId of the traffic descriptor + */ + public TrafficDescriptor(@Nullable String dnn, @Nullable String osAppId) { + mDnn = dnn; + mOsAppId = osAppId; + } + + /** + * DNN stands for Data Network Name and represents an APN as defined in 3GPP TS 23.003. + * @return the DNN of this traffic descriptor. + */ + public @Nullable String getDnn() { + return mDnn; + } + + /** + * OsAppId represents the OsId + OsAppId as defined in 3GPP TS 24.526 Section 5.2. + * @return the OS App ID of this traffic descriptor. + */ + public @Nullable String getOsAppId() { + return mOsAppId; + } + + @Override + public int describeContents() { + return 0; + } + + @NonNull @Override + public String toString() { + return "TrafficDescriptor={mDnn=" + mDnn + ", mOsAppId=" + mOsAppId + "}"; + } + + @Override + public void writeToParcel(@NonNull Parcel dest, int flags) { + dest.writeString(mDnn); + dest.writeString(mOsAppId); + } + + public static final @NonNull Parcelable.Creator<TrafficDescriptor> CREATOR = + new Parcelable.Creator<TrafficDescriptor>() { + @Override + public @NonNull TrafficDescriptor createFromParcel(@NonNull Parcel source) { + return new TrafficDescriptor(source); + } + + @Override + public @NonNull TrafficDescriptor[] newArray(int size) { + return new TrafficDescriptor[size]; + } + }; + + @Override + public boolean equals(@Nullable Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + TrafficDescriptor that = (TrafficDescriptor) o; + return Objects.equals(mDnn, that.mDnn) && Objects.equals(mOsAppId, that.mOsAppId); + } + + @Override + public int hashCode() { + return Objects.hash(mDnn, mOsAppId); + } +} diff --git a/telephony/java/android/telephony/ims/ProvisioningManager.java b/telephony/java/android/telephony/ims/ProvisioningManager.java index 08eec29d5ac2..a9ccb6aa64f2 100644 --- a/telephony/java/android/telephony/ims/ProvisioningManager.java +++ b/telephony/java/android/telephony/ims/ProvisioningManager.java @@ -32,6 +32,7 @@ import android.os.ServiceSpecificException; import android.telephony.CarrierConfigManager; import android.telephony.SubscriptionManager; import android.telephony.TelephonyFrameworkInitializer; +import android.telephony.TelephonyManager; import android.telephony.ims.aidl.IImsConfigCallback; import android.telephony.ims.aidl.IRcsConfigCallback; import android.telephony.ims.feature.MmTelFeature; @@ -1300,7 +1301,7 @@ public class ProvisioningManager { * provisioning. * <p> * Requires Permission: Manifest.permission.MODIFY_PHONE_STATE or that the calling app has - * carrier privileges (see {@link #hasCarrierPrivileges}). + * carrier privileges (see {@link TelephonyManager#hasCarrierPrivileges}). * @param config The XML file to be read. ASCII/UTF8 encoded text if not compressed. * @param isCompressed The XML file is compressed in gzip format and must be decompressed * before being read. @@ -1330,7 +1331,7 @@ public class ProvisioningManager { * the intent is valid. and {@link #EXTRA_STATUS} to specify RCS VoLTE single registration * status. */ - @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE) + @RequiresPermission(Manifest.permission.PERFORM_IMS_SINGLE_REGISTRATION) @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"; @@ -1375,7 +1376,7 @@ public class ProvisioningManager { * provisioning status events {@link #registerRcsProvisioningChangedCallback} * @param rcc RCS client configuration {@link RcsClientConfiguration} */ - @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE) + @RequiresPermission(Manifest.permission.PERFORM_IMS_SINGLE_REGISTRATION) public void setRcsClientConfiguration( @NonNull RcsClientConfiguration rcc) throws ImsException { try { @@ -1390,6 +1391,14 @@ public class ProvisioningManager { /** * Returns a flag to indicate whether or not the device supports IMS single registration for * MMTEL and RCS features as well as if the carrier has provisioned the feature. + * + * <p> Requires Permission: + * <ul> + * <li>{@link android.Manifest.permission#READ_PRIVILEGED_PHONE_STATE},</li> + * <li>{@link android.Manifest.permission#PERFORM_IMS_SINGLE_REGISTRATION},</li> + * <li>or that the caller has carrier privileges (see + * {@link TelephonyManager#hasCarrierPrivileges()}).</li> + * </ul> * @return true if IMS single registration is capable at this time, or false otherwise * @throws ImsException If the remote ImsService is not available for * any reason or the subscription associated with this instance is no @@ -1398,7 +1407,8 @@ public class ProvisioningManager { * @see PackageManager#FEATURE_TELEPHONY_IMS_SINGLE_REGISTRATION for whether or not this * device supports IMS single registration. */ - @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE) + @RequiresPermission(anyOf = {Manifest.permission.READ_PRIVILEGED_PHONE_STATE, + Manifest.permission.PERFORM_IMS_SINGLE_REGISTRATION}) public boolean isRcsVolteSingleRegistrationCapable() throws ImsException { try { return getITelephony().isRcsVolteSingleRegistrationCapable(mSubId); @@ -1408,36 +1418,44 @@ public class ProvisioningManager { } /** - * 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) + * 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. + * <p> Requires Permission: + * <ul> + * <li>{@link android.Manifest.permission#READ_PRIVILEGED_PHONE_STATE},</li> + * <li>{@link android.Manifest.permission#PERFORM_IMS_SINGLE_REGISTRATION},</li> + * <li>or that the caller has carrier privileges (see + * {@link TelephonyManager#hasCarrierPrivileges()}).</li> + * </ul> + * + * @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(anyOf = {Manifest.permission.READ_PRIVILEGED_PHONE_STATE, + Manifest.permission.PERFORM_IMS_SINGLE_REGISTRATION}) public void registerRcsProvisioningChangedCallback( @NonNull @CallbackExecutor Executor executor, @NonNull RcsProvisioningCallback callback) throws ImsException { @@ -1459,13 +1477,22 @@ public class ProvisioningManager { * 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. + * <p> Requires Permission: + * <ul> + * <li>{@link android.Manifest.permission#READ_PRIVILEGED_PHONE_STATE},</li> + * <li>{@link android.Manifest.permission#PERFORM_IMS_SINGLE_REGISTRATION},</li> + * <li>or that the caller has carrier privileges (see + * {@link TelephonyManager#hasCarrierPrivileges()}).</li> + * </ul> + * * @param callback The existing {@link RcsProvisioningCallback} to be * removed. * @see #registerRcsProvisioningChangedCallback * @throws IllegalArgumentException if the subscription associated with this callback is * invalid. */ - @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE) + @RequiresPermission(anyOf = {Manifest.permission.READ_PRIVILEGED_PHONE_STATE, + Manifest.permission.PERFORM_IMS_SINGLE_REGISTRATION}) public void unregisterRcsProvisioningChangedCallback( @NonNull RcsProvisioningCallback callback) { try { @@ -1480,7 +1507,7 @@ public class ProvisioningManager { * Reconfiguration triggered by the RCS application. Most likely cause * is the 403 forbidden to a HTTP request. */ - @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE) + @RequiresPermission(Manifest.permission.PERFORM_IMS_SINGLE_REGISTRATION) public void triggerRcsReconfiguration() { try { getITelephony().triggerRcsReconfiguration(mSubId); diff --git a/telephony/java/android/telephony/ims/RcsUceAdapter.java b/telephony/java/android/telephony/ims/RcsUceAdapter.java index 070fd799d6cc..ce8bd7d8c28e 100644 --- a/telephony/java/android/telephony/ims/RcsUceAdapter.java +++ b/telephony/java/android/telephony/ims/RcsUceAdapter.java @@ -467,7 +467,7 @@ public class RcsUceAdapter { * poll on the network unless there are contacts being queried with stale information. * <p> * Be sure to check the availability of this feature using - * {@link ImsRcsManager#isAvailable(int)} and ensuring + * {@link ImsRcsManager#isAvailable(int, int)} and ensuring * {@link RcsFeature.RcsImsCapabilities#CAPABILITY_TYPE_OPTIONS_UCE} or * {@link RcsFeature.RcsImsCapabilities#CAPABILITY_TYPE_PRESENCE_UCE} is enabled or else * this operation will fail with {@link #ERROR_NOT_AVAILABLE} or {@link #ERROR_NOT_ENABLED}. @@ -484,7 +484,8 @@ public class RcsUceAdapter { * @hide */ @SystemApi - @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE) + @RequiresPermission(allOf = {Manifest.permission.ACCESS_RCS_USER_CAPABILITY_EXCHANGE, + Manifest.permission.READ_CONTACTS}) public void requestCapabilities(@NonNull List<Uri> contactNumbers, @NonNull @CallbackExecutor Executor executor, @NonNull CapabilitiesCallback c) throws ImsException { @@ -557,7 +558,7 @@ public class RcsUceAdapter { * * <p> * Be sure to check the availability of this feature using - * {@link ImsRcsManager#isAvailable(int)} and ensuring + * {@link ImsRcsManager#isAvailable(int, int)} and ensuring * {@link RcsFeature.RcsImsCapabilities#CAPABILITY_TYPE_OPTIONS_UCE} or * {@link RcsFeature.RcsImsCapabilities#CAPABILITY_TYPE_PRESENCE_UCE} is * enabled or else this operation will fail with @@ -571,7 +572,8 @@ public class RcsUceAdapter { * @hide */ @SystemApi - @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE) + @RequiresPermission(allOf = {Manifest.permission.ACCESS_RCS_USER_CAPABILITY_EXCHANGE, + Manifest.permission.READ_CONTACTS}) public void requestAvailability(@NonNull Uri contactNumber, @NonNull @CallbackExecutor Executor executor, @NonNull CapabilitiesCallback c) throws ImsException { diff --git a/telephony/java/android/telephony/ims/SipDelegateManager.java b/telephony/java/android/telephony/ims/SipDelegateManager.java index 04421c9a2449..399b6dc88cef 100644 --- a/telephony/java/android/telephony/ims/SipDelegateManager.java +++ b/telephony/java/android/telephony/ims/SipDelegateManager.java @@ -28,7 +28,6 @@ import android.content.pm.PackageManager; import android.os.RemoteException; import android.os.ServiceSpecificException; import android.telephony.BinderCacheManager; -import android.telephony.CarrierConfigManager; import android.telephony.ims.aidl.IImsRcsController; import android.telephony.ims.aidl.SipDelegateConnectionAidlWrapper; import android.telephony.ims.stub.DelegateConnectionMessageCallback; @@ -275,7 +274,8 @@ public class SipDelegateManager { * @see CarrierConfigManager.Ims#KEY_IMS_SINGLE_REGISTRATION_REQUIRED_BOOL * @see PackageManager#FEATURE_TELEPHONY_IMS_SINGLE_REGISTRATION */ - @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE) + @RequiresPermission(anyOf = {Manifest.permission.READ_PRIVILEGED_PHONE_STATE, + Manifest.permission.PERFORM_IMS_SINGLE_REGISTRATION}) public boolean isSupported() throws ImsException { try { IImsRcsController controller = mBinderCache.getBinder(); @@ -317,7 +317,7 @@ public class SipDelegateManager { * @throws ImsException Thrown if there was a problem communicating with the ImsService * associated with this SipDelegateManager. See {@link ImsException#getCode()}. */ - @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE) + @RequiresPermission(Manifest.permission.PERFORM_IMS_SINGLE_REGISTRATION) public void createSipDelegate(@NonNull DelegateRequest request, @NonNull Executor executor, @NonNull DelegateConnectionStateCallback dc, @NonNull DelegateConnectionMessageCallback mc) throws ImsException { @@ -351,7 +351,7 @@ public class SipDelegateManager { * @param delegateConnection The SipDelegateConnection to destroy. * @param reason The reason for why this SipDelegateConnection was destroyed. */ - @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE) + @RequiresPermission(Manifest.permission.PERFORM_IMS_SINGLE_REGISTRATION) public void destroySipDelegate(@NonNull SipDelegateConnection delegateConnection, @SipDelegateDestroyReason int reason) { @@ -392,6 +392,7 @@ public class SipDelegateManager { * this condition. May be {@code null} if there was no reason String provided from the * network. */ + @RequiresPermission(Manifest.permission.PERFORM_IMS_SINGLE_REGISTRATION) public void triggerFullNetworkRegistration(@NonNull SipDelegateConnection connection, @IntRange(from = 100, to = 699) int sipCode, @Nullable String sipReason) { if (connection == null) { diff --git a/telephony/java/android/telephony/ims/SipMessage.java b/telephony/java/android/telephony/ims/SipMessage.java index 9cfa640fce18..ad6d73c39962 100644 --- a/telephony/java/android/telephony/ims/SipMessage.java +++ b/telephony/java/android/telephony/ims/SipMessage.java @@ -19,6 +19,7 @@ package android.telephony.ims; import static java.nio.charset.StandardCharsets.UTF_8; import android.annotation.NonNull; +import android.annotation.Nullable; import android.annotation.SystemApi; import android.os.Build; import android.os.Parcel; @@ -46,6 +47,8 @@ public final class SipMessage implements Parcelable { private final String mStartLine; private final String mHeaderSection; private final byte[] mContent; + private final String mViaBranchParam; + private final String mCallIdParam; /** * Represents a partially encoded SIP message. @@ -63,6 +66,9 @@ public final class SipMessage implements Parcelable { mStartLine = startLine; mHeaderSection = headerSection; mContent = content; + + mViaBranchParam = SipMessageParsingUtils.getTransactionId(mHeaderSection); + mCallIdParam = SipMessageParsingUtils.getCallId(mHeaderSection); } /** @@ -73,6 +79,8 @@ public final class SipMessage implements Parcelable { mHeaderSection = source.readString(); mContent = new byte[source.readInt()]; source.readByteArray(mContent); + mViaBranchParam = source.readString(); + mCallIdParam = source.readString(); } /** @@ -97,6 +105,25 @@ public final class SipMessage implements Parcelable { return mContent; } + /** + * @return the branch parameter enclosed in the Via header key's value. See RFC 3261 section + * 20.42 for more information on the Via header. If {@code null}, then there was either no + * Via parameter found in this SIP message's headers or no branch parameter found in the + * Via header. + */ + public @Nullable String getViaBranchParameter() { + return mViaBranchParam; + } + + /** + * @return the value associated with the call-id header of this SIP message. See RFC 3261 + * section 20.8 for more information on the call-id header. If {@code null}, then there was no + * call-id header found in this SIP message's headers. + */ + public @Nullable String getCallIdParameter() { + return mCallIdParam; + } + @Override public int describeContents() { return 0; @@ -108,6 +135,8 @@ public final class SipMessage implements Parcelable { dest.writeString(mHeaderSection); dest.writeInt(mContent.length); dest.writeByteArray(mContent); + dest.writeString(mViaBranchParam); + dest.writeString(mCallIdParam); } public static final @NonNull Creator<SipMessage> CREATOR = new Creator<SipMessage>() { diff --git a/telephony/java/android/telephony/ims/aidl/SipDelegateAidlWrapper.java b/telephony/java/android/telephony/ims/aidl/SipDelegateAidlWrapper.java index 9d919015087d..739946be2e5b 100644 --- a/telephony/java/android/telephony/ims/aidl/SipDelegateAidlWrapper.java +++ b/telephony/java/android/telephony/ims/aidl/SipDelegateAidlWrapper.java @@ -31,8 +31,6 @@ import android.telephony.ims.stub.SipDelegate; import android.text.TextUtils; import android.util.Log; -import com.android.internal.telephony.SipMessageParsingUtils; - import java.util.ArrayList; import java.util.Set; import java.util.concurrent.Executor; @@ -188,7 +186,7 @@ public class SipDelegateAidlWrapper implements DelegateStateCallback, DelegateMe } private void notifyLocalMessageFailedToBeReceived(SipMessage m, int reason) { - String transactionId = SipMessageParsingUtils.getTransactionId(m.getHeaderSection()); + String transactionId = m.getViaBranchParameter(); if (TextUtils.isEmpty(transactionId)) { Log.w(LOG_TAG, "failure to parse SipMessage."); throw new IllegalArgumentException("Malformed SipMessage, can not determine " diff --git a/telephony/java/android/telephony/ims/aidl/SipDelegateConnectionAidlWrapper.java b/telephony/java/android/telephony/ims/aidl/SipDelegateConnectionAidlWrapper.java index c877aca8ba96..3cd27264295c 100644 --- a/telephony/java/android/telephony/ims/aidl/SipDelegateConnectionAidlWrapper.java +++ b/telephony/java/android/telephony/ims/aidl/SipDelegateConnectionAidlWrapper.java @@ -32,8 +32,6 @@ import android.text.TextUtils; import android.util.ArraySet; import android.util.Log; -import com.android.internal.telephony.SipMessageParsingUtils; - import java.util.List; import java.util.NoSuchElementException; import java.util.concurrent.Executor; @@ -268,7 +266,7 @@ public class SipDelegateConnectionAidlWrapper implements SipDelegateConnection, } private void notifyLocalMessageFailedToSend(SipMessage m, int reason) { - String transactionId = SipMessageParsingUtils.getTransactionId(m.getHeaderSection()); + String transactionId = m.getViaBranchParameter(); if (TextUtils.isEmpty(transactionId)) { Log.w(LOG_TAG, "sendMessage detected a malformed SipMessage and can not get a " + "transaction ID."); diff --git a/telephony/java/android/telephony/ims/stub/CapabilityExchangeEventListener.java b/telephony/java/android/telephony/ims/stub/CapabilityExchangeEventListener.java index 4967e5da7c9a..62955487897f 100644 --- a/telephony/java/android/telephony/ims/stub/CapabilityExchangeEventListener.java +++ b/telephony/java/android/telephony/ims/stub/CapabilityExchangeEventListener.java @@ -25,7 +25,6 @@ import android.telephony.ims.RcsContactUceCapability; import android.telephony.ims.RcsUceAdapter; import android.telephony.ims.feature.ImsFeature; import android.telephony.ims.feature.RcsFeature; -import android.util.Log; import java.util.List; @@ -44,30 +43,12 @@ public interface CapabilityExchangeEventListener { * Respond to a remote capability request from the contact specified with the * capabilities of this device. * @param ownCapabilities The capabilities of this device. - * @hide - */ - default void onRespondToCapabilityRequest( - @NonNull RcsContactUceCapability ownCapabilities) {} - - /** - * Respond to a remote capability request from the contact specified with the - * capabilities of this device. - * @param ownCapabilities The capabilities of this device. * @param isBlocked Whether or not the user has blocked the number requesting the * capabilities of this device. If true, the device should respond to the OPTIONS * request with a 200 OK response and no capabilities. */ - default void onRespondToCapabilityRequest(@NonNull RcsContactUceCapability ownCapabilities, - boolean isBlocked) { - Log.w("CapabilityExchangeEventListener", "implement " - + "onRespondToCapabilityRequest(RcsContactUceCapability, boolean) instead!"); - // Fall back to old implementation - if (isBlocked) { - onRespondToCapabilityRequestWithError(200, "OK"); - } else { - onRespondToCapabilityRequest(ownCapabilities); - } - } + void onRespondToCapabilityRequest(@NonNull RcsContactUceCapability ownCapabilities, + boolean isBlocked); /** * Respond to a remote capability request from the contact specified with the diff --git a/telephony/java/android/telephony/ims/stub/ImsConfigImplBase.java b/telephony/java/android/telephony/ims/stub/ImsConfigImplBase.java index cc050becfb25..34984e05e181 100644 --- a/telephony/java/android/telephony/ims/stub/ImsConfigImplBase.java +++ b/telephony/java/android/telephony/ims/stub/ImsConfigImplBase.java @@ -37,6 +37,7 @@ import com.android.internal.telephony.util.RemoteCallbackListExt; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.ref.WeakReference; +import java.util.Arrays; import java.util.HashMap; /** @@ -368,7 +369,13 @@ public class ImsConfigImplBase { } private void onNotifyRcsAutoConfigurationReceived(byte[] config, boolean isCompressed) { - mRcsConfigData = isCompressed ? RcsConfig.decompressGzip(config) : config; + // cache uncompressed config + config = isCompressed ? RcsConfig.decompressGzip(config) : config; + if (Arrays.equals(mRcsConfigData, config)) { + return; + } + mRcsConfigData = config; + // can be null in testing if (mRcsCallbacks != null) { mRcsCallbacks.broadcastAction(c -> { diff --git a/telephony/java/android/telephony/ims/stub/ImsEcbmImplBase.java b/telephony/java/android/telephony/ims/stub/ImsEcbmImplBase.java index 5f8e93d02a00..8ad40ed1032c 100644 --- a/telephony/java/android/telephony/ims/stub/ImsEcbmImplBase.java +++ b/telephony/java/android/telephony/ims/stub/ImsEcbmImplBase.java @@ -57,10 +57,10 @@ public class ImsEcbmImplBase { } else if (listener != null && mListener == null) { mListener = listener; } else { - // Fail fast here instead of silently overwriting the listener to another - // listener due to another connection connecting. - throw new IllegalStateException("ImsEcbmImplBase: Listener already set by " - + "another connection."); + // Warn that the listener is being replaced while active + Log.w(TAG, "setListener is being called when there is already an active " + + "listener"); + mListener = listener; } } } diff --git a/telephony/java/android/telephony/ims/stub/ImsMultiEndpointImplBase.java b/telephony/java/android/telephony/ims/stub/ImsMultiEndpointImplBase.java index 8e961acc7b36..ec1c7b3a92a8 100644 --- a/telephony/java/android/telephony/ims/stub/ImsMultiEndpointImplBase.java +++ b/telephony/java/android/telephony/ims/stub/ImsMultiEndpointImplBase.java @@ -62,10 +62,10 @@ public class ImsMultiEndpointImplBase { } else if (listener != null && mListener == null) { mListener = listener; } else { - // Fail fast here instead of silently overwriting the listener to another - // listener due to another connection connecting. - throw new IllegalStateException("ImsMultiEndpointImplBase: Listener already" - + " set by another connection."); + // Warn that the listener is being replaced while active + Log.w(TAG, "setListener is being called when there is already an active " + + "listener"); + mListener = listener; } } } diff --git a/telephony/java/android/telephony/ims/stub/ImsUtImplBase.java b/telephony/java/android/telephony/ims/stub/ImsUtImplBase.java index 83b89aa8e814..eb3e8ed5a8e4 100644 --- a/telephony/java/android/telephony/ims/stub/ImsUtImplBase.java +++ b/telephony/java/android/telephony/ims/stub/ImsUtImplBase.java @@ -224,11 +224,10 @@ public class ImsUtImplBase { } else if (listener != null && mUtListener == null) { mUtListener = new ImsUtListener(listener); } else { - // This is a limitation of the current API surface, there can only be one - // listener connected. Fail fast instead of silently overwriting the other - // listener. - throw new IllegalStateException("ImsUtImplBase#setListener: listener already " - + "set by another connected interface!"); + // Warn that the listener is being replaced while active + Log.w(TAG, "setListener is being called when there is already an active " + + "listener"); + mUtListener = new ImsUtListener(listener); } } |