diff options
Diffstat (limited to 'telephony/java')
24 files changed, 501 insertions, 211 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 fc0bff8c254e..9c9670c99c2d 100644 --- a/telephony/java/android/telephony/CarrierConfigManager.java +++ b/telephony/java/android/telephony/CarrierConfigManager.java @@ -4753,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/CellIdentity.java b/telephony/java/android/telephony/CellIdentity.java index 1e5ce05ff28a..518fabc09838 100644 --- a/telephony/java/android/telephony/CellIdentity.java +++ b/telephony/java/android/telephony/CellIdentity.java @@ -37,7 +37,7 @@ import java.util.UUID; public abstract class CellIdentity implements Parcelable { /** @hide */ - public static final int INVALID_CHANNEL_NUMBER = -1; + public static final int INVALID_CHANNEL_NUMBER = Integer.MAX_VALUE; /** * parameters for validation 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/PhysicalChannelConfig.java b/telephony/java/android/telephony/PhysicalChannelConfig.java index 9fb098ea8758..dfe269cbb0d9 100644 --- a/telephony/java/android/telephony/PhysicalChannelConfig.java +++ b/telephony/java/android/telephony/PhysicalChannelConfig.java @@ -50,7 +50,7 @@ public final class PhysicalChannelConfig implements Parcelable { public static final int CONNECTION_UNKNOWN = -1; /** Channel number is unknown. */ - public static final int CHANNEL_NUMBER_UNKNOWN = -1; + public static final int CHANNEL_NUMBER_UNKNOWN = Integer.MAX_VALUE; /** Physical Cell Id is unknown. */ public static final int PHYSICAL_CELL_ID_UNKNOWN = -1; diff --git a/telephony/java/android/telephony/TelephonyDisplayInfo.java b/telephony/java/android/telephony/TelephonyDisplayInfo.java index 1fcb504e7895..877827578760 100644 --- a/telephony/java/android/telephony/TelephonyDisplayInfo.java +++ b/telephony/java/android/telephony/TelephonyDisplayInfo.java @@ -30,8 +30,8 @@ import java.util.Objects; * necessarily a precise or accurate representation of the current state and should be treated * accordingly. * To be notified of changes in TelephonyDisplayInfo, use - * {@link TelephonyManager#registerPhoneStateListener} with a {@link PhoneStateListener} - * that implements {@link PhoneStateListener.DisplayInfoChangedListener}. + * {@link TelephonyManager#registerTelephonyCallback} with a {@link TelephonyCallback} + * that implements {@link TelephonyCallback.DisplayInfoListener}. * Override the onDisplayInfoChanged() method to handle the broadcast. */ public final class TelephonyDisplayInfo implements Parcelable { diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java index 12c1bb05a2d3..e3853fabfd7a 100644 --- a/telephony/java/android/telephony/TelephonyManager.java +++ b/telephony/java/android/telephony/TelephonyManager.java @@ -5580,28 +5580,25 @@ public class TelephonyManager { * instability. If a process has registered too many listeners without unregistering them, it * may encounter an {@link IllegalStateException} when trying to register more listeners. * - * @param listener The {@link PhoneStateListener} object to register (or unregister) - * @param events The telephony state(s) of interest to the listener, as a bitwise-OR combination - * of {@link PhoneStateListener} LISTEN_ flags. - * @deprecated Use {@link #registerPhoneStateListener(Executor, PhoneStateListener)}. + * @param listener The {@link PhoneStateListener} object to register + * (or unregister) + * @param events The telephony state(s) of interest to the listener, + * as a bitwise-OR combination of {@link PhoneStateListener} + * LISTEN_ flags. + * @deprecated Use {@link #registerTelephonyCallback(Executor, TelephonyCallback)}. */ @Deprecated public void listen(PhoneStateListener listener, int events) { - if (!listener.isExecutorSet()) { - throw new IllegalStateException("PhoneStateListener should be created on a thread " - + "with Looper.myLooper() != null"); - } - boolean notifyNow = getITelephony() != null; - mTelephonyRegistryMgr = mContext.getSystemService(TelephonyRegistryManager.class); - if (mTelephonyRegistryMgr != null) { - if (events != PhoneStateListener.LISTEN_NONE) { - mTelephonyRegistryMgr.registerPhoneStateListenerWithEvents(mSubId, - getOpPackageName(), getAttributionTag(), listener, events, notifyNow); - } else { - unregisterPhoneStateListener(listener); - } + if (mContext == null) return; + boolean notifyNow = (getITelephony() != null); + TelephonyRegistryManager telephonyRegistry = + (TelephonyRegistryManager) + mContext.getSystemService(Context.TELEPHONY_REGISTRY_SERVICE); + if (telephonyRegistry != null) { + telephonyRegistry.listenFromListener(mSubId, getOpPackageName(), + getAttributionTag(), listener, events, notifyNow); } else { - throw new IllegalStateException("telephony service is null."); + Rlog.w(TAG, "telephony registry not ready."); } } @@ -14548,6 +14545,75 @@ public class TelephonyManager { return THERMAL_MITIGATION_RESULT_UNKNOWN_ERROR; } + /** + * Registers a callback object to receive notification of changes in specified telephony states. + * <p> + * To register a callback, pass a {@link TelephonyCallback} which implements + * interfaces of events. For example, + * FakeServiceStateCallback extends {@link TelephonyCallback} implements + * {@link TelephonyCallback.ServiceStateListener}. + * + * At registration, and when a specified telephony state changes, the telephony manager invokes + * the appropriate callback method on the callback object and passes the current (updated) + * values. + * <p> + * + * If this TelephonyManager object has been created with {@link #createForSubscriptionId}, + * applies to the given subId. Otherwise, applies to + * {@link SubscriptionManager#getDefaultSubscriptionId()}. To register events for multiple + * subIds, pass a separate callback object to each TelephonyManager object created with + * {@link #createForSubscriptionId}. + * + * Note: if you call this method while in the middle of a binder transaction, you <b>must</b> + * call {@link android.os.Binder#clearCallingIdentity()} before calling this method. A + * {@link SecurityException} will be thrown otherwise. + * + * This API should be used sparingly -- large numbers of callbacks will cause system + * instability. If a process has registered too many callbacks without unregistering them, it + * may encounter an {@link IllegalStateException} when trying to register more callbacks. + * + * @param executor The executor of where the callback will execute. + * @param callback The {@link TelephonyCallback} object to register. + */ + public void registerTelephonyCallback(@NonNull @CallbackExecutor Executor executor, + @NonNull TelephonyCallback callback) { + if (executor == null || callback == null) { + throw new IllegalArgumentException("TelephonyCallback and executor must be non-null"); + } + mTelephonyRegistryMgr = (TelephonyRegistryManager) + mContext.getSystemService(Context.TELEPHONY_REGISTRY_SERVICE); + if (mTelephonyRegistryMgr != null) { + mTelephonyRegistryMgr.registerTelephonyCallback(executor, mSubId, getOpPackageName(), + getAttributionTag(), callback, getITelephony() != null); + } else { + throw new IllegalStateException("telephony service is null."); + } + } + + /** + * Unregister an existing {@link TelephonyCallback}. + * + * @param callback The {@link TelephonyCallback} object to unregister. + */ + public void unregisterTelephonyCallback(@NonNull TelephonyCallback callback) { + + if (mContext == null) { + throw new IllegalStateException("telephony service is null."); + } + + if (callback.callback == null) { + return; + } + + mTelephonyRegistryMgr = mContext.getSystemService(TelephonyRegistryManager.class); + if (mTelephonyRegistryMgr != null) { + mTelephonyRegistryMgr.unregisterTelephonyCallback(mSubId, getOpPackageName(), + getAttributionTag(), callback, getITelephony() != null); + } else { + throw new IllegalStateException("telephony service is null."); + } + } + /** @hide */ @Retention(RetentionPolicy.SOURCE) @IntDef(prefix = {"GBA_FAILURE_REASON_"}, value = { @@ -14646,8 +14712,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 @@ -14674,7 +14745,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, @@ -14718,73 +14790,6 @@ public class TelephonyManager { } /** - * Registers a listener object to receive notification of changes in specified telephony states. - * <p> - * To register a listener, pass a {@link PhoneStateListener} which implements - * interfaces of events. For example, - * FakeServiceStateChangedListener extends {@link PhoneStateListener} implements - * {@link PhoneStateListener.ServiceStateChangedListener}. - * - * At registration, and when a specified telephony state changes, the telephony manager invokes - * the appropriate callback method on the listener object and passes the current (updated) - * values. - * <p> - * - * If this TelephonyManager object has been created with {@link #createForSubscriptionId}, - * applies to the given subId. Otherwise, applies to - * {@link SubscriptionManager#DEFAULT_SUBSCRIPTION_ID}. To listen events for multiple subIds, - * pass a separate listener object to each TelephonyManager object created with - * {@link #createForSubscriptionId}. Only {@link PhoneStateListener.CallStateChangedListener} - * can be used to receive changes for all subIds through - * {@link SubscriptionManager#DEFAULT_SUBSCRIPTION_ID}. - * - * Note: if you call this method while in the middle of a binder transaction, you <b>must</b> - * call {@link android.os.Binder#clearCallingIdentity()} before calling this method. A - * {@link SecurityException} will be thrown otherwise. - * - * This API should be used sparingly -- large numbers of listeners will cause system - * instability. If a process has registered too many listeners without unregistering them, it - * may encounter an {@link IllegalStateException} when trying to register more listeners. - * - * @param executor The executor of where the callback will execute. - * @param listener The {@link PhoneStateListener} object to register. - */ - public void registerPhoneStateListener(@NonNull @CallbackExecutor Executor executor, - @NonNull PhoneStateListener listener) { - if (executor == null || listener == null) { - throw new IllegalArgumentException("PhoneStateListener and executor must be non-null"); - } - mTelephonyRegistryMgr = (TelephonyRegistryManager) - mContext.getSystemService(Context.TELEPHONY_REGISTRY_SERVICE); - if (mTelephonyRegistryMgr != null) { - mTelephonyRegistryMgr.registerPhoneStateListener(executor, mSubId, - getOpPackageName(), getAttributionTag(), listener, getITelephony() != null); - } else { - throw new IllegalStateException("telephony service is null."); - } - } - - /** - * Unregister an existing {@link PhoneStateListener}. - * - * @param listener The {@link PhoneStateListener} object to unregister. - */ - public void unregisterPhoneStateListener(@NonNull PhoneStateListener listener) { - - if (mContext == null) { - throw new IllegalStateException("telephony service is null."); - } - - mTelephonyRegistryMgr = mContext.getSystemService(TelephonyRegistryManager.class); - if (mTelephonyRegistryMgr != null) { - mTelephonyRegistryMgr.unregisterPhoneStateListener(mSubId, getOpPackageName(), - getAttributionTag(), listener, getITelephony() != null); - } else { - throw new IllegalStateException("telephony service is null."); - } - } - - /** * The network type is valid or not. * * @param networkType The network type {@link NetworkType}. diff --git a/telephony/java/android/telephony/data/ApnSetting.java b/telephony/java/android/telephony/data/ApnSetting.java index d58fa912dce2..b503733f8de9 100644 --- a/telephony/java/android/telephony/data/ApnSetting.java +++ b/telephony/java/android/telephony/data/ApnSetting.java @@ -28,8 +28,6 @@ import android.os.Parcel; import android.os.Parcelable; import android.provider.Telephony; import android.provider.Telephony.Carriers; -import android.telephony.Annotation; -import android.telephony.Annotation.ApnType; import android.telephony.Annotation.NetworkType; import android.telephony.ServiceState; import android.telephony.TelephonyManager; @@ -116,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. */ @@ -151,6 +174,7 @@ public class ApnSetting implements Parcelable { TYPE_MMS_STRING, TYPE_SUPL_STRING, TYPE_XCAP_STRING, + TYPE_ENTERPRISE_STRING, }, prefix = "TYPE_", suffix = "_STRING") @Retention(RetentionPolicy.SOURCE) public @interface ApnTypeString {} @@ -291,6 +315,12 @@ public class ApnSetting implements Parcelable { @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 = { @@ -370,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); @@ -384,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); @@ -1490,7 +1522,7 @@ public class ApnSetting implements Parcelable { * @hide */ @SystemApi - public static @NonNull @ApnTypeString String getApnTypeString(@Annotation.ApnType int apnType) { + public static @NonNull @ApnTypeString String getApnTypeString(@ApnType int apnType) { if (apnType == TYPE_ALL) { return "*"; } @@ -1503,7 +1535,7 @@ public class ApnSetting implements Parcelable { * when provided with an invalid int for compatibility purposes. * @hide */ - public static @NonNull String getApnTypeStringInternal(@Annotation.ApnType int apnType) { + public static @NonNull String getApnTypeStringInternal(@ApnType int apnType) { String result = getApnTypeString(apnType); return TextUtils.isEmpty(result) ? "Unknown" : result; } @@ -1517,7 +1549,7 @@ public class ApnSetting implements Parcelable { * @hide */ @SystemApi - public static @Annotation.ApnType int getApnTypeInt(@NonNull @ApnTypeString String apnType) { + public static @ApnType int getApnTypeInt(@NonNull @ApnTypeString String apnType) { return APN_TYPE_STRING_MAP.getOrDefault(apnType.toLowerCase(), 0); } @@ -2162,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 1edacd9429f1..a5e5ab01810f 100644 --- a/telephony/java/android/telephony/data/DataCallResponse.java +++ b/telephony/java/android/telephony/data/DataCallResponse.java @@ -138,6 +138,7 @@ public final class DataCallResponse implements Parcelable { private final Qos mDefaultQos; 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. @@ -189,6 +190,7 @@ public final class DataCallResponse implements Parcelable { mDefaultQos = null; mQosBearerSessions = new ArrayList<>(); mSliceInfo = null; + mTrafficDescriptors = new ArrayList<>(); } private DataCallResponse(@DataFailureCause int cause, long suggestedRetryTime, int id, @@ -198,7 +200,7 @@ public final class DataCallResponse implements Parcelable { @Nullable List<InetAddress> pcscfAddresses, int mtu, int mtuV4, int mtuV6, @HandoverFailureMode int handoverFailureMode, int pduSessionId, @Nullable Qos defaultQos, @Nullable List<QosBearerSession> qosBearerSessions, - @Nullable SliceInfo sliceInfo) { + @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; - mQosBearerSessions = qosBearerSessions; + mQosBearerSessions = (qosBearerSessions == null) + ? new ArrayList<>() : new ArrayList<>(qosBearerSessions); mSliceInfo = sliceInfo; + mTrafficDescriptors = (trafficDescriptors == null) + ? new ArrayList<>() : new ArrayList<>(trafficDescriptors); } /** @hide */ @@ -249,6 +254,8 @@ public final class DataCallResponse implements Parcelable { 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; @@ -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() { @@ -428,6 +442,7 @@ public final class DataCallResponse implements Parcelable { .append(" defaultQos=").append(mDefaultQos) .append(" qosBearerSessions=").append(mQosBearerSessions) .append(" sliceInfo=").append(mSliceInfo) + .append(" trafficDescriptors=").append(mTrafficDescriptors) .append("}"); return sb.toString(); } @@ -442,15 +457,22 @@ 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 isQosBearerSessionsSame = (mQosBearerSessions == null || mQosBearerSessions == null) ? - mQosBearerSessions == other.mQosBearerSessions : - mQosBearerSessions.size() == other.mQosBearerSessions.size() + 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 && mId == other.mId @@ -472,7 +494,8 @@ public final class DataCallResponse implements Parcelable { && mPduSessionId == other.mPduSessionId && isQosSame && isQosBearerSessionsSame - && Objects.equals(mSliceInfo, other.mSliceInfo); + && 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, - mQosBearerSessions, mSliceInfo); + mQosBearerSessions, mSliceInfo, mTrafficDescriptors); } @Override @@ -512,6 +535,7 @@ public final class DataCallResponse implements Parcelable { } dest.writeList(mQosBearerSessions); dest.writeParcelable(mSliceInfo, flags); + dest.writeList(mTrafficDescriptors); } public static final @android.annotation.NonNull Parcelable.Creator<DataCallResponse> CREATOR = @@ -597,6 +621,8 @@ public final class DataCallResponse implements Parcelable { private SliceInfo mSliceInfo; + private List<TrafficDescriptor> mTrafficDescriptors = new ArrayList<>(); + /** * Default constructor for Builder. */ @@ -836,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. @@ -844,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, mQosBearerSessions, 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/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/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..aa9145b01be9 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; @@ -1005,7 +1006,8 @@ public class ProvisioningManager { * server) or other operator defined triggers. If RCS provisioning is already * completed at the time of callback registration, then this method shall be * invoked with the current configuration - * @param configXml The RCS configurationXML received OTA. + * @param configXml The RCS configuration XML received by OTA. It is defined + * by GSMA RCC.07. */ public void onConfigurationChanged(@NonNull byte[] configXml) {} @@ -1300,7 +1302,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 +1332,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"; @@ -1372,10 +1374,12 @@ public class ProvisioningManager { * provisioning is done using autoconfiguration, then these parameters shall be * sent in the HTTP get request to fetch the RCS provisioning. RCS client * configuration must be provided by the application before registering for the - * provisioning status events {@link #registerRcsProvisioningChangedCallback} + * provisioning status events {@link #registerRcsProvisioningCallback()} + * When the IMS/RCS service receives the RCS client configuration, it will detect + * the change in the configuration, and trigger the auto-configuration as needed. * @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 +1394,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 +1410,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,42 +1421,50 @@ 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) - public void registerRcsProvisioningChangedCallback( + * 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 #unregisterRcsProvisioningCallback(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 registerRcsProvisioningCallback( @NonNull @CallbackExecutor Executor executor, @NonNull RcsProvisioningCallback callback) throws ImsException { callback.setExecutor(executor); try { - getITelephony().registerRcsProvisioningChangedCallback(mSubId, callback.getBinder()); + getITelephony().registerRcsProvisioningCallback(mSubId, callback.getBinder()); } catch (ServiceSpecificException e) { throw new ImsException(e.getMessage(), e.errorCode); } catch (RemoteException | IllegalStateException e) { @@ -1459,17 +1480,26 @@ 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. + * @see #registerRcsProvisioningCallback(Executor, RcsProvisioningCallback) + * @throws IllegalArgumentException if the subscription associated with + * this callback is invalid. */ - @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE) - public void unregisterRcsProvisioningChangedCallback( + @RequiresPermission(anyOf = {Manifest.permission.READ_PRIVILEGED_PHONE_STATE, + Manifest.permission.PERFORM_IMS_SINGLE_REGISTRATION}) + public void unregisterRcsProvisioningCallback( @NonNull RcsProvisioningCallback callback) { try { - getITelephony().unregisterRcsProvisioningChangedCallback( + getITelephony().unregisterRcsProvisioningCallback( mSubId, callback.getBinder()); } catch (RemoteException e) { throw e.rethrowAsRuntimeException(); @@ -1479,8 +1509,16 @@ 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) + * + * <p>When this api is called, the RCS configuration for the associated + * subscription will be removed, and the application which has registered + * {@link RcsProvisioningCallback} may expect to receive + * {@link RcsProvisioningCallback#onConfigurationReset}, then + * {@link RcsProvisioningCallback#onConfigurationChanged} when the new + * RCS configuration is received and notified by + * {@link #notifyRcsAutoConfigurationReceived} + */ + @RequiresPermission(Manifest.permission.PERFORM_IMS_SINGLE_REGISTRATION) public void triggerRcsReconfiguration() { try { getITelephony().triggerRcsReconfiguration(mSubId); 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/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); } } diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl index a05374c63052..f74484bd4fd8 100644 --- a/telephony/java/com/android/internal/telephony/ITelephony.aidl +++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl @@ -1199,15 +1199,6 @@ interface ITelephony { void shutdownMobileRadios(); /** - * Set phone radio type and access technology. - * - * @param rafs an RadioAccessFamily array to indicate all phone's - * new radio access family. The length of RadioAccessFamily - * must equ]]al to phone count. - */ - void setRadioCapability(in RadioAccessFamily[] rafs); - - /** * Get phone radio type and access technology. * * @param phoneId which phone you want to get @@ -2292,13 +2283,12 @@ interface ITelephony { /** * Register RCS provisioning callback. */ - void registerRcsProvisioningChangedCallback(int subId, - IRcsConfigCallback callback); + void registerRcsProvisioningCallback(int subId, IRcsConfigCallback callback); /** * Unregister RCS provisioning callback. */ - void unregisterRcsProvisioningChangedCallback(int subId, IRcsConfigCallback callback); + void unregisterRcsProvisioningCallback(int subId, IRcsConfigCallback callback); /** * trigger RCS reconfiguration. diff --git a/telephony/java/com/android/internal/telephony/PhoneConstants.java b/telephony/java/com/android/internal/telephony/PhoneConstants.java index 151187c5071f..3a99f0e010c6 100644 --- a/telephony/java/com/android/internal/telephony/PhoneConstants.java +++ b/telephony/java/com/android/internal/telephony/PhoneConstants.java @@ -126,6 +126,7 @@ public class PhoneConstants { * connections.<br/> * APN_TYPE_ALL is a special type to indicate that this APN entry can * service all data connections. + * TODO: remove these and use the reference to ApnSetting.TYPE_XXX_STRING instead */ public static final String APN_TYPE_ALL = ApnSetting.TYPE_ALL_STRING; /** APN type for default data traffic */ @@ -153,20 +154,8 @@ public class PhoneConstants { public static final String APN_TYPE_MCX = ApnSetting.TYPE_MCX_STRING; /** APN type for XCAP */ public static final String APN_TYPE_XCAP = ApnSetting.TYPE_XCAP_STRING; - /** Array of all APN types */ - public static final String[] APN_TYPES = {APN_TYPE_DEFAULT, - APN_TYPE_MMS, - APN_TYPE_SUPL, - APN_TYPE_DUN, - APN_TYPE_HIPRI, - APN_TYPE_FOTA, - APN_TYPE_IMS, - APN_TYPE_CBS, - APN_TYPE_IA, - APN_TYPE_EMERGENCY, - APN_TYPE_MCX, - APN_TYPE_XCAP, - }; + // /** APN type for enterprise */ + // public static final String APN_TYPE_ENTERPRISE = ApnSetting.TYPE_ENTERPRISE_STRING; public static final int RIL_CARD_MAX_APPS = 8; |