diff options
Diffstat (limited to 'telephony/java')
22 files changed, 914 insertions, 121 deletions
diff --git a/telephony/java/android/telephony/CarrierBandwidth.java b/telephony/java/android/telephony/CarrierBandwidth.java index 17747a3919ee..b153fefce6e3 100644 --- a/telephony/java/android/telephony/CarrierBandwidth.java +++ b/telephony/java/android/telephony/CarrierBandwidth.java @@ -18,6 +18,7 @@ package android.telephony; import android.annotation.NonNull; import android.annotation.Nullable; +import android.annotation.RequiresFeature; import android.annotation.SystemApi; import android.os.Parcel; import android.os.Parcelable; @@ -102,7 +103,7 @@ public final class CarrierBandwidth implements Parcelable { /** * Retrieves the upstream bandwidth for the primary network in Kbps. This always only refers to * the estimated first hop transport bandwidth. - * This will be INVALID if the network is not connected + * This will be {@link #INVALID} if the network is not connected * * @return The estimated first hop upstream (device to network) bandwidth. */ @@ -113,7 +114,7 @@ public final class CarrierBandwidth implements Parcelable { /** * Retrieves the downstream bandwidth for the primary network in Kbps. This always only refers * to the estimated first hop transport bandwidth. - * This will be INVALID if the network is not connected + * This will be {@link #INVALID} if the network is not connected * * @return The estimated first hop downstream (network to device) bandwidth. */ @@ -124,10 +125,19 @@ public final class CarrierBandwidth implements Parcelable { /** * Retrieves the upstream bandwidth for the secondary network in Kbps. This always only refers * to the estimated first hop transport bandwidth. - * This will be INVALID if the network is not connected + * <p/> + * This will be {@link #INVALID} if either are the case: + * <ol> + * <li>The network is not connected</li> + * <li>The device does not support + * {@link android.telephony.TelephonyManager#CAPABILITY_SECONDARY_LINK_BANDWIDTH_VISIBLE}.</li> + * </ol> * * @return The estimated first hop upstream (device to network) bandwidth. */ + @RequiresFeature( + enforcement = "android.telephony.TelephonyManager#isRadioInterfaceCapabilitySupported", + value = TelephonyManager.CAPABILITY_SECONDARY_LINK_BANDWIDTH_VISIBLE) public int getSecondaryDownlinkCapacityKbps() { return mSecondaryDownlinkCapacityKbps; } @@ -135,10 +145,18 @@ public final class CarrierBandwidth implements Parcelable { /** * Retrieves the downstream bandwidth for the secondary network in Kbps. This always only * refers to the estimated first hop transport bandwidth. - * This will be INVALID if the network is not connected - * + * <p/> + * This will be {@link #INVALID} if either are the case: + * <ol> + * <li>The network is not connected</li> + * <li>The device does not support + * {@link android.telephony.TelephonyManager#CAPABILITY_SECONDARY_LINK_BANDWIDTH_VISIBLE}.</li> + * </ol> * @return The estimated first hop downstream (network to device) bandwidth. */ + @RequiresFeature( + enforcement = "android.telephony.TelephonyManager#isRadioInterfaceCapabilitySupported", + value = TelephonyManager.CAPABILITY_SECONDARY_LINK_BANDWIDTH_VISIBLE) public int getSecondaryUplinkCapacityKbps() { return mSecondaryUplinkCapacityKbps; } diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java index a49bece89f0c..a42e3642c0d0 100644 --- a/telephony/java/android/telephony/CarrierConfigManager.java +++ b/telephony/java/android/telephony/CarrierConfigManager.java @@ -4113,11 +4113,24 @@ public class CarrierConfigManager { "default_rtt_mode_int"; /** + * Indicates whether RTT is supported while roaming. + */ + public static final String KEY_RTT_SUPPORTED_WHILE_ROAMING_BOOL = + "rtt_supported_while_roaming_bool"; + + /** * Indicates if auto-configuration server is used for the RCS config * Reference: GSMA RCC.14 */ public static final String KEY_USE_ACS_FOR_RCS_BOOL = "use_acs_for_rcs_bool"; + /** + * Indicates temporarily unmetered mobile data is supported by the carrier. + * @hide + */ + public static final String KEY_NETWORK_TEMP_NOT_METERED_SUPPORTED_BOOL = + "network_temp_not_metered_supported_bool"; + /** The default value for every variable. */ private final static PersistableBundle sDefaults; @@ -4479,6 +4492,7 @@ public class CarrierConfigManager { sDefaults.putBoolean(KEY_RTT_SUPPORTED_BOOL, false); sDefaults.putBoolean(KEY_TTY_SUPPORTED_BOOL, true); sDefaults.putBoolean(KEY_HIDE_TTY_HCO_VCO_WITH_RTT_BOOL, false); + sDefaults.putBoolean(KEY_RTT_SUPPORTED_WHILE_ROAMING_BOOL, false); sDefaults.putBoolean(KEY_DISABLE_CHARGE_INDICATION_BOOL, false); sDefaults.putBoolean(KEY_SUPPORT_NO_REPLY_TIMER_FOR_CFNRY_BOOL, true); sDefaults.putStringArray(KEY_FEATURE_ACCESS_CODES_STRING_ARRAY, null); @@ -4666,6 +4680,7 @@ public class CarrierConfigManager { sDefaults.putString(KEY_CALL_COMPOSER_PICTURE_SERVER_URL_STRING, ""); sDefaults.putBoolean(KEY_USE_LOWER_MTU_VALUE_IF_BOTH_RECEIVED, false); sDefaults.putBoolean(KEY_USE_ACS_FOR_RCS_BOOL, false); + sDefaults.putBoolean(KEY_NETWORK_TEMP_NOT_METERED_SUPPORTED_BOOL, false); sDefaults.putInt(KEY_DEFAULT_RTT_MODE_INT, 0); } diff --git a/telephony/java/android/telephony/DataFailCause.java b/telephony/java/android/telephony/DataFailCause.java index d502da9fb9ec..99a77ae5d133 100644 --- a/telephony/java/android/telephony/DataFailCause.java +++ b/telephony/java/android/telephony/DataFailCause.java @@ -915,6 +915,8 @@ public final class DataFailCause { public static final int IPV6_PREFIX_UNAVAILABLE = 0x8CA; /** System preference change back to SRAT during handoff */ public static final int HANDOFF_PREFERENCE_CHANGED = 0x8CB; + /** Data call fail due to the slice not being allowed for the data call. */ + public static final int SLICE_REJECTED = 0x8CC; //IKE error notifications message as specified in 3GPP TS 24.302 (Section 8.1.2.2). @@ -985,7 +987,7 @@ public final class DataFailCause { * the authentication failed. */ public static final int IWLAN_IKEV2_AUTH_FAILURE = 0x4001; - /** IKE message timeout, tunnel setup failed due to no response from EPDG */ + /** IKE message timeout, tunnel setup failed due to no response from EPDG */ public static final int IWLAN_IKEV2_MSG_TIMEOUT = 0x4002; /** IKE Certification validation failure */ public static final int IWLAN_IKEV2_CERT_INVALID = 0x4003; @@ -1419,6 +1421,7 @@ public final class DataFailCause { sFailCauseMap.put(VSNCP_RECONNECT_NOT_ALLOWED, "VSNCP_RECONNECT_NOT_ALLOWED"); sFailCauseMap.put(IPV6_PREFIX_UNAVAILABLE, "IPV6_PREFIX_UNAVAILABLE"); sFailCauseMap.put(HANDOFF_PREFERENCE_CHANGED, "HANDOFF_PREFERENCE_CHANGED"); + sFailCauseMap.put(SLICE_REJECTED, "SLICE_REJECTED"); sFailCauseMap.put(IWLAN_PDN_CONNECTION_REJECTION, "IWLAN_PDN_CONNECTION_REJECTION"); sFailCauseMap.put(IWLAN_MAX_CONNECTION_REACHED, "IWLAN_MAX_CONNECTION_REACHED"); sFailCauseMap.put(IWLAN_SEMANTIC_ERROR_IN_THE_TFT_OPERATION, diff --git a/telephony/java/android/telephony/NetworkRegistrationInfo.java b/telephony/java/android/telephony/NetworkRegistrationInfo.java index 8507d8512a5c..706e3cb93a0f 100644 --- a/telephony/java/android/telephony/NetworkRegistrationInfo.java +++ b/telephony/java/android/telephony/NetworkRegistrationInfo.java @@ -344,6 +344,7 @@ public final class NetworkRegistrationInfo implements Parcelable { // TODO: Instead of doing this, we should create a formal way for cloning cell identity. // Cell identity is not an immutable object so we have to deep copy it. mCellIdentity = CellIdentity.CREATOR.createFromParcel(p); + p.recycle(); } if (nri.mVoiceSpecificInfo != null) { diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java index 646744da5336..e8ace34793db 100644 --- a/telephony/java/android/telephony/TelephonyManager.java +++ b/telephony/java/android/telephony/TelephonyManager.java @@ -31,6 +31,7 @@ import android.annotation.Nullable; import android.annotation.RequiresPermission; import android.annotation.SdkConstant; import android.annotation.SdkConstant.SdkConstantType; +import android.annotation.StringDef; import android.annotation.SuppressAutoDoc; import android.annotation.SuppressLint; import android.annotation.SystemApi; @@ -14344,9 +14345,22 @@ public class TelephonyManager { return Collections.emptyList(); } + /** + * Indicates whether {@link CarrierBandwidth#getSecondaryDownlinkCapacityKbps()} and + * {@link CarrierBandwidth#getSecondaryUplinkCapacityKbps()} are visible. See comments + * on respective methods for more information. + * + * @hide + */ + @SystemApi + public static final String CAPABILITY_SECONDARY_LINK_BANDWIDTH_VISIBLE = + "CAPABILITY_SECONDARY_LINK_BANDWIDTH_VISIBLE"; + /** @hide */ - @IntDef(prefix = {"RADIO_INTERFACE_CAPABILITY_"}, - value = {}) + @Retention(RetentionPolicy.SOURCE) + @StringDef(prefix = "CAPABILITY_", value = { + CAPABILITY_SECONDARY_LINK_BANDWIDTH_VISIBLE, + }) public @interface RadioInterfaceCapability {} /** @@ -14359,6 +14373,7 @@ public class TelephonyManager { * * @hide */ + @SystemApi public boolean isRadioInterfaceCapabilitySupported( @NonNull @RadioInterfaceCapability String capability) { try { diff --git a/telephony/java/android/telephony/data/DataCallResponse.java b/telephony/java/android/telephony/data/DataCallResponse.java index 8348502586a5..46ec4a39fd21 100644 --- a/telephony/java/android/telephony/data/DataCallResponse.java +++ b/telephony/java/android/telephony/data/DataCallResponse.java @@ -136,6 +136,7 @@ public final class DataCallResponse implements Parcelable { private final int mPduSessionId; private final Qos mDefaultQos; private final List<QosSession> mQosSessions; + private final SliceInfo mSliceInfo; /** * @param cause Data call fail cause. {@link DataFailCause#NONE} indicates no error. @@ -186,6 +187,7 @@ public final class DataCallResponse implements Parcelable { mPduSessionId = PDU_SESSION_ID_NOT_SET; mDefaultQos = null; mQosSessions = new ArrayList<>(); + mSliceInfo = null; } private DataCallResponse(@DataFailureCause int cause, long suggestedRetryTime, int id, @@ -194,7 +196,8 @@ public final class DataCallResponse implements Parcelable { @Nullable List<InetAddress> dnsAddresses, @Nullable List<InetAddress> gatewayAddresses, @Nullable List<InetAddress> pcscfAddresses, int mtu, int mtuV4, int mtuV6, @HandoverFailureMode int handoverFailureMode, int pduSessionId, - @Nullable Qos defaultQos, @Nullable List<QosSession> qosSessions) { + @Nullable Qos defaultQos, @Nullable List<QosSession> qosSessions, + @Nullable SliceInfo sliceInfo) { mCause = cause; mSuggestedRetryTime = suggestedRetryTime; mId = id; @@ -216,6 +219,7 @@ public final class DataCallResponse implements Parcelable { mPduSessionId = pduSessionId; mDefaultQos = defaultQos; mQosSessions = qosSessions; + mSliceInfo = sliceInfo; } /** @hide */ @@ -243,6 +247,7 @@ public final class DataCallResponse implements Parcelable { mDefaultQos = source.readParcelable(Qos.class.getClassLoader()); mQosSessions = new ArrayList<>(); source.readList(mQosSessions, QosSession.class.getClassLoader()); + mSliceInfo = source.readParcelable(SliceInfo.class.getClassLoader()); } /** @@ -368,7 +373,7 @@ public final class DataCallResponse implements Parcelable { } /** - * @return default QOS of the data call received from the network + * @return default QOS of the data connection received from the network * * @hide */ @@ -379,16 +384,24 @@ public final class DataCallResponse implements Parcelable { } /** - * @return All the dedicated bearer QOS sessions of the data call received from the network + * @return All the dedicated bearer QOS sessions of the data connection received from the + * network. * * @hide */ - @NonNull public List<QosSession> getQosSessions() { return mQosSessions; } + /** + * @return The slice info related to this data connection. + */ + @Nullable + public SliceInfo getSliceInfo() { + return mSliceInfo; + } + @NonNull @Override public String toString() { @@ -411,6 +424,7 @@ public final class DataCallResponse implements Parcelable { .append(" pduSessionId=").append(getPduSessionId()) .append(" defaultQos=").append(mDefaultQos) .append(" qosSessions=").append(mQosSessions) + .append(" sliceInfo=").append(mSliceInfo) .append("}"); return sb.toString(); } @@ -454,7 +468,8 @@ public final class DataCallResponse implements Parcelable { && mHandoverFailureMode == other.mHandoverFailureMode && mPduSessionId == other.mPduSessionId && isQosSame - && isQosSessionsSame; + && isQosSessionsSame + && Objects.equals(mSliceInfo, other.mSliceInfo); } @Override @@ -462,7 +477,7 @@ public final class DataCallResponse implements Parcelable { return Objects.hash(mCause, mSuggestedRetryTime, mId, mLinkStatus, mProtocolType, mInterfaceName, mAddresses, mDnsAddresses, mGatewayAddresses, mPcscfAddresses, mMtu, mMtuV4, mMtuV6, mHandoverFailureMode, mPduSessionId, mDefaultQos, - mQosSessions); + mQosSessions, mSliceInfo); } @Override @@ -493,6 +508,7 @@ public final class DataCallResponse implements Parcelable { dest.writeParcelable((NrQos)mDefaultQos, flags); } dest.writeList(mQosSessions); + dest.writeParcelable(mSliceInfo, flags); } public static final @android.annotation.NonNull Parcelable.Creator<DataCallResponse> CREATOR = @@ -576,6 +592,8 @@ public final class DataCallResponse implements Parcelable { private List<QosSession> mQosSessions = new ArrayList<>(); + private SliceInfo mSliceInfo; + /** * Default constructor for Builder. */ @@ -799,6 +817,21 @@ public final class DataCallResponse implements Parcelable { } /** + * The Slice used for this data connection. + * <p/> + * If a handover occurs from EPDG to 5G, + * this is the {@link SliceInfo} used in {@link DataService#setupDataCall}. + * + * @param sliceInfo the slice info for the data call + * + * @return The same instance of the builder. + */ + public @NonNull Builder setSliceInfo(@Nullable SliceInfo sliceInfo) { + mSliceInfo = sliceInfo; + return this; + } + + /** * Build the DataCallResponse. * * @return the DataCallResponse object. @@ -807,7 +840,7 @@ public final class DataCallResponse implements Parcelable { return new DataCallResponse(mCause, mSuggestedRetryTime, mId, mLinkStatus, mProtocolType, mInterfaceName, mAddresses, mDnsAddresses, mGatewayAddresses, mPcscfAddresses, mMtu, mMtuV4, mMtuV6, mHandoverFailureMode, mPduSessionId, - mDefaultQos, mQosSessions); + mDefaultQos, mQosSessions, mSliceInfo); } } } diff --git a/telephony/java/android/telephony/data/DataService.java b/telephony/java/android/telephony/data/DataService.java index 2ec965101930..03c2ef9d9baa 100644 --- a/telephony/java/android/telephony/data/DataService.java +++ b/telephony/java/android/telephony/data/DataService.java @@ -194,13 +194,19 @@ public abstract class DataService extends Service { * The standard range of values are 1-15 while 0 means no pdu session id * was attached to this call. Reference: 3GPP TS 24.007 section * 11.2.3.1b. + * @param sliceInfo used within the data connection when a handover occurs from EPDG to 5G. + * The value is null unless the access network is + * {@link android.telephony.AccessNetworkConstants.AccessNetworkType#NGRAN} and a + * handover is occurring from EPDG to 5G. If the slice passed is rejected, then + * {@link DataCallResponse#getCause()} is + * {@link android.telephony.DataFailCause#SLICE_REJECTED}. * @param callback The result callback for this request. */ public void setupDataCall(int accessNetworkType, @NonNull DataProfile dataProfile, boolean isRoaming, boolean allowRoaming, @SetupDataReason int reason, @Nullable LinkProperties linkProperties, - @IntRange(from = 0, to = 15) int pduSessionId, + @IntRange(from = 0, to = 15) int pduSessionId, @Nullable SliceInfo sliceInfo, @NonNull DataServiceCallback callback) { /* Call the old version since the new version isn't supported */ setupDataCall(accessNetworkType, dataProfile, isRoaming, allowRoaming, reason, @@ -392,10 +398,11 @@ public abstract class DataService extends Service { public final int reason; public final LinkProperties linkProperties; public final int pduSessionId; + public final SliceInfo sliceInfo; public final IDataServiceCallback callback; SetupDataCallRequest(int accessNetworkType, DataProfile dataProfile, boolean isRoaming, boolean allowRoaming, int reason, LinkProperties linkProperties, - int pduSessionId, IDataServiceCallback callback) { + int pduSessionId, SliceInfo sliceInfo, IDataServiceCallback callback) { this.accessNetworkType = accessNetworkType; this.dataProfile = dataProfile; this.isRoaming = isRoaming; @@ -403,6 +410,7 @@ public abstract class DataService extends Service { this.linkProperties = linkProperties; this.reason = reason; this.pduSessionId = pduSessionId; + this.sliceInfo = sliceInfo; this.callback = callback; } } @@ -513,6 +521,7 @@ public abstract class DataService extends Service { setupDataCallRequest.dataProfile, setupDataCallRequest.isRoaming, setupDataCallRequest.allowRoaming, setupDataCallRequest.reason, setupDataCallRequest.linkProperties, setupDataCallRequest.pduSessionId, + setupDataCallRequest.sliceInfo, (setupDataCallRequest.callback != null) ? new DataServiceCallback(setupDataCallRequest.callback) : null); @@ -676,10 +685,12 @@ public abstract class DataService extends Service { @Override public void setupDataCall(int slotIndex, int accessNetworkType, DataProfile dataProfile, boolean isRoaming, boolean allowRoaming, int reason, - LinkProperties linkProperties, int pduSessionId, IDataServiceCallback callback) { + LinkProperties linkProperties, int pduSessionId, SliceInfo sliceInfo, + IDataServiceCallback callback) { mHandler.obtainMessage(DATA_SERVICE_REQUEST_SETUP_DATA_CALL, slotIndex, 0, new SetupDataCallRequest(accessNetworkType, dataProfile, isRoaming, - allowRoaming, reason, linkProperties, pduSessionId, callback)) + allowRoaming, reason, linkProperties, pduSessionId, sliceInfo, + callback)) .sendToTarget(); } diff --git a/telephony/java/android/telephony/data/IDataService.aidl b/telephony/java/android/telephony/data/IDataService.aidl index 3f1f033d6f11..e0b9a1a9bb5a 100644 --- a/telephony/java/android/telephony/data/IDataService.aidl +++ b/telephony/java/android/telephony/data/IDataService.aidl @@ -19,6 +19,7 @@ package android.telephony.data; import android.net.LinkProperties; import android.telephony.data.DataProfile; import android.telephony.data.IDataServiceCallback; +import android.telephony.data.SliceInfo; /** * {@hide} @@ -29,7 +30,7 @@ oneway interface IDataService void removeDataServiceProvider(int slotId); void setupDataCall(int slotId, int accessNetwork, in DataProfile dataProfile, boolean isRoaming, boolean allowRoaming, int reason, in LinkProperties linkProperties, - int pduSessionId, IDataServiceCallback callback); + int pduSessionId, in SliceInfo sliceInfo, IDataServiceCallback callback); void deactivateDataCall(int slotId, int cid, int reason, IDataServiceCallback callback); void setInitialAttachApn(int slotId, in DataProfile dataProfile, boolean isRoaming, IDataServiceCallback callback); diff --git a/telephony/java/android/telephony/data/SliceInfo.aidl b/telephony/java/android/telephony/data/SliceInfo.aidl new file mode 100644 index 000000000000..286ea5e4f8c7 --- /dev/null +++ b/telephony/java/android/telephony/data/SliceInfo.aidl @@ -0,0 +1,20 @@ +/* + * Copyright 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** @hide */ +package android.telephony.data; + +parcelable SliceInfo; diff --git a/telephony/java/android/telephony/data/SliceInfo.java b/telephony/java/android/telephony/data/SliceInfo.java new file mode 100644 index 000000000000..51857a7b4908 --- /dev/null +++ b/telephony/java/android/telephony/data/SliceInfo.java @@ -0,0 +1,342 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.telephony.data; + +import android.annotation.IntDef; +import android.annotation.IntRange; +import android.annotation.NonNull; +import android.annotation.SuppressLint; +import android.annotation.SystemApi; +import android.os.Parcel; +import android.os.Parcelable; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.util.Objects; + +/** + * Represents a S-NSSAI as defined in 3GPP TS 24.501. + * + * @hide + */ +@SystemApi +public final class SliceInfo implements Parcelable { + /** + * When set on a Slice Differentiator, this value indicates that there is no corresponding + * Slice. + */ + public static final int SLICE_DIFFERENTIATOR_NO_SLICE = -1; + + /** + * Indicates that the service type is not present. + */ + public static final int SLICE_SERVICE_TYPE_NONE = 0; + + /** + * Slice suitable for the handling of 5G enhanced Mobile Broadband. + */ + public static final int SLICE_SERVICE_TYPE_EMBB = 1; + + /** + * Slice suitable for the handling of ultra-reliable low latency communications. + */ + public static final int SLICE_SERVICE_TYPE_URLLC = 2; + + /** + * Slice suitable for the handling of massive IoT. + */ + public static final int SLICE_SERVICE_TYPE_MIOT = 3; + + /** + * The min acceptable value for a Slice Differentiator + */ + @SuppressLint("MinMaxConstant") + public static final int MIN_SLICE_DIFFERENTIATOR = -1; + + /** + * The max acceptable value for a Slice Differentiator + */ + @SuppressLint("MinMaxConstant") + public static final int MAX_SLICE_DIFFERENTIATOR = 0xFFFFFE; + + /** @hide */ + @IntDef(prefix = { "SLICE_SERVICE_TYPE_" }, value = { + SLICE_SERVICE_TYPE_NONE, + SLICE_SERVICE_TYPE_EMBB, + SLICE_SERVICE_TYPE_URLLC, + SLICE_SERVICE_TYPE_MIOT, + }) + @Retention(RetentionPolicy.SOURCE) + public @interface SliceServiceType {} + + + @SliceServiceType + private final int mSliceServiceType; + @IntRange(from = MIN_SLICE_DIFFERENTIATOR, to = MAX_SLICE_DIFFERENTIATOR) + private final int mSliceDifferentiator; + @SliceServiceType + private final int mMappedHplmnSliceServiceType; + @IntRange(from = MIN_SLICE_DIFFERENTIATOR, to = MAX_SLICE_DIFFERENTIATOR) + private final int mMappedHplmnSliceDifferentiator; + + private SliceInfo(@SliceServiceType int sliceServiceType, + int sliceDifferentiator, int mappedHplmnSliceServiceType, + int mappedHplmnSliceDifferentiator) { + mSliceServiceType = sliceServiceType; + mSliceDifferentiator = sliceDifferentiator; + mMappedHplmnSliceDifferentiator = mappedHplmnSliceDifferentiator; + mMappedHplmnSliceServiceType = mappedHplmnSliceServiceType; + } + + /** + * The type of service provided by the slice. + * <p/> + * see: 3GPP TS 24.501 Section 9.11.2.8. + */ + @SliceServiceType + public int getSliceServiceType() { + return mSliceServiceType; + } + + /** + * Identifies the slice from others with the same Slice Service Type. + * <p/> + * Returns {@link #SLICE_DIFFERENTIATOR_NO_SLICE} if {@link #getSliceServiceType} returns + * {@link #SLICE_SERVICE_TYPE_NONE}. + * <p/> + * see: 3GPP TS 24.501 Section 9.11.2.8. + */ + @IntRange(from = MIN_SLICE_DIFFERENTIATOR, to = MAX_SLICE_DIFFERENTIATOR) + public int getSliceDifferentiator() { + return mSliceDifferentiator; + } + + /** + * Corresponds to a Slice Info (S-NSSAI) of the HPLMN. + * <p/> + * see: 3GPP TS 24.501 Section 9.11.2.8. + */ + @SliceServiceType + public int getMappedHplmnSliceServiceType() { + return mMappedHplmnSliceServiceType; + } + + /** + * This Slice Differentiator corresponds to a {@link SliceInfo} (S-NSSAI) of the HPLMN; + * {@link #getSliceDifferentiator()} is mapped to this value. + * <p/> + * Returns {@link #SLICE_DIFFERENTIATOR_NO_SLICE} if either of the following are true: + * <ul> + * <li>{@link #getSliceDifferentiator()} returns {@link #SLICE_DIFFERENTIATOR_NO_SLICE}</li> + * <li>{@link #getMappedHplmnSliceServiceType()} returns {@link #SLICE_SERVICE_TYPE_NONE}</li> + * </ul> + * <p/> + * see: 3GPP TS 24.501 Section 9.11.2.8. + */ + @IntRange(from = MIN_SLICE_DIFFERENTIATOR, to = MAX_SLICE_DIFFERENTIATOR) + public int getMappedHplmnSliceDifferentiator() { + return mMappedHplmnSliceDifferentiator; + } + + private SliceInfo(@NonNull Parcel in) { + mSliceServiceType = in.readInt(); + mSliceDifferentiator = in.readInt(); + mMappedHplmnSliceServiceType = in.readInt(); + mMappedHplmnSliceDifferentiator = in.readInt(); + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(@NonNull Parcel dest, int flags) { + dest.writeInt(mSliceServiceType); + dest.writeInt(mSliceDifferentiator); + dest.writeInt(mMappedHplmnSliceServiceType); + dest.writeInt(mMappedHplmnSliceDifferentiator); + } + + public static final @android.annotation.NonNull Parcelable.Creator<SliceInfo> CREATOR = + new Parcelable.Creator<SliceInfo>() { + @Override + @NonNull + public SliceInfo createFromParcel(@NonNull Parcel source) { + return new SliceInfo(source); + } + + @Override + @NonNull + public SliceInfo[] newArray(int size) { + return new SliceInfo[size]; + } + }; + + @Override + public String toString() { + return "SliceInfo{" + + "mSliceServiceType=" + sliceServiceTypeToString(mSliceServiceType) + + ", mSliceDifferentiator=" + mSliceDifferentiator + + ", mMappedHplmnSliceServiceType=" + + sliceServiceTypeToString(mMappedHplmnSliceServiceType) + + ", mMappedHplmnSliceDifferentiator=" + mMappedHplmnSliceDifferentiator + + '}'; + } + + private static String sliceServiceTypeToString(@SliceServiceType int sliceServiceType) { + switch(sliceServiceType) { + case SLICE_SERVICE_TYPE_NONE: + return "NONE"; + case SLICE_SERVICE_TYPE_EMBB: + return "EMBB"; + case SLICE_SERVICE_TYPE_URLLC: + return "URLLC"; + case SLICE_SERVICE_TYPE_MIOT: + return "MIOT"; + default: + return Integer.toString(sliceServiceType); + } + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + SliceInfo sliceInfo = (SliceInfo) o; + return mSliceServiceType == sliceInfo.mSliceServiceType + && mSliceDifferentiator == sliceInfo.mSliceDifferentiator + && mMappedHplmnSliceServiceType == sliceInfo.mMappedHplmnSliceServiceType + && mMappedHplmnSliceDifferentiator == sliceInfo.mMappedHplmnSliceDifferentiator; + } + + @Override + public int hashCode() { + return Objects.hash(mSliceServiceType, mSliceDifferentiator, mMappedHplmnSliceServiceType, + mMappedHplmnSliceDifferentiator); + } + + /** + * Provides a convenient way to set the fields of a {@link SliceInfo} when creating a + * new instance. + * + * <p>The example below shows how you might create a new {@code SliceInfo}: + * + * <pre><code> + * + * SliceInfo response = new SliceInfo.Builder() + * .setSliceServiceType(SLICE_SERVICE_TYPE_URLLC) + * .build(); + * </code></pre> + */ + public static final class Builder { + @SliceServiceType + private int mSliceServiceType = SLICE_SERVICE_TYPE_NONE; + @IntRange(from = MIN_SLICE_DIFFERENTIATOR, to = MAX_SLICE_DIFFERENTIATOR) + private int mSliceDifferentiator = SLICE_DIFFERENTIATOR_NO_SLICE; + @SliceServiceType + private int mMappedHplmnSliceServiceType = SLICE_SERVICE_TYPE_NONE; + @IntRange(from = MIN_SLICE_DIFFERENTIATOR, to = MAX_SLICE_DIFFERENTIATOR) + private int mMappedHplmnSliceDifferentiator = SLICE_DIFFERENTIATOR_NO_SLICE; + + /** + * Default constructor for Builder. + */ + public Builder() { + } + + /** + * Set the Slice Service Type. + * + * @return The same instance of the builder. + */ + @NonNull + public Builder setSliceServiceType(@SliceServiceType int mSliceServiceType) { + this.mSliceServiceType = mSliceServiceType; + return this; + } + + /** + * Set the Slice Differentiator. + * <p/> + * A value of {@link #SLICE_DIFFERENTIATOR_NO_SLICE} indicates that there is no + * corresponding Slice. + * + * @throws IllegalArgumentException if the parameter is not between + * {@link #MIN_SLICE_DIFFERENTIATOR} and {@link #MAX_SLICE_DIFFERENTIATOR}. + * + * @return The same instance of the builder. + */ + @NonNull + public Builder setSliceDifferentiator( + @IntRange(from = MIN_SLICE_DIFFERENTIATOR, to = MAX_SLICE_DIFFERENTIATOR) + int sliceDifferentiator) { + if (sliceDifferentiator < MIN_SLICE_DIFFERENTIATOR + || sliceDifferentiator > MAX_SLICE_DIFFERENTIATOR) { + throw new IllegalArgumentException("The slice diffentiator value is out of range"); + } + this.mSliceDifferentiator = sliceDifferentiator; + return this; + } + + /** + * Set the HPLMN Slice Service Type. + * + * @return The same instance of the builder. + */ + @NonNull + public Builder setMappedHplmnSliceServiceType( + @SliceServiceType int mappedHplmnSliceServiceType) { + this.mMappedHplmnSliceServiceType = mappedHplmnSliceServiceType; + return this; + } + + /** + * Set the HPLMN Slice Differentiator. + * <p/> + * A value of {@link #SLICE_DIFFERENTIATOR_NO_SLICE} indicates that there is no + * corresponding Slice of the HPLMN. + * + * @throws IllegalArgumentException if the parameter is not between + * {@link #MIN_SLICE_DIFFERENTIATOR} and {@link #MAX_SLICE_DIFFERENTIATOR}. + * + * @return The same instance of the builder. + */ + @NonNull + public Builder setMappedHplmnSliceDifferentiator( + @IntRange(from = MIN_SLICE_DIFFERENTIATOR, to = MAX_SLICE_DIFFERENTIATOR) + int mappedHplmnSliceDifferentiator) { + if (mappedHplmnSliceDifferentiator < MIN_SLICE_DIFFERENTIATOR + || mappedHplmnSliceDifferentiator > MAX_SLICE_DIFFERENTIATOR) { + throw new IllegalArgumentException("The slice diffentiator value is out of range"); + } + this.mMappedHplmnSliceDifferentiator = mappedHplmnSliceDifferentiator; + return this; + } + + /** + * Build the {@link SliceInfo}. + * + * @return the {@link SliceInfo} object. + */ + @NonNull + public SliceInfo build() { + return new SliceInfo(this.mSliceServiceType, this.mSliceDifferentiator, + this.mMappedHplmnSliceServiceType, this.mMappedHplmnSliceDifferentiator); + } + } +} diff --git a/telephony/java/android/telephony/euicc/DownloadableSubscription.java b/telephony/java/android/telephony/euicc/DownloadableSubscription.java index 52b31d7f9611..a5150b010f57 100644 --- a/telephony/java/android/telephony/euicc/DownloadableSubscription.java +++ b/telephony/java/android/telephony/euicc/DownloadableSubscription.java @@ -15,6 +15,7 @@ */ package android.telephony.euicc; +import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SystemApi; import android.app.PendingIntent; @@ -102,44 +103,81 @@ public final class DownloadableSubscription implements Parcelable { this.accessRules = accessRules; } - /** @hide */ - @SystemApi public static final class Builder { @Nullable private String encodedActivationCode; @Nullable private String confirmationCode; @Nullable private String carrierName; List<UiccAccessRule> accessRules; + /** @hide */ + @SystemApi public Builder() {} - public Builder(DownloadableSubscription baseSubscription) { + public Builder(@NonNull DownloadableSubscription baseSubscription) { encodedActivationCode = baseSubscription.getEncodedActivationCode(); confirmationCode = baseSubscription.getConfirmationCode(); carrierName = baseSubscription.getCarrierName(); accessRules = baseSubscription.getAccessRules(); } + public Builder(@NonNull String encodedActivationCode) { + this.encodedActivationCode = encodedActivationCode; + } + + /** + * Builds a {@link DownloadableSubscription} object. + * @return a non-null {@link DownloadableSubscription} object. + */ + @NonNull public DownloadableSubscription build() { return new DownloadableSubscription(encodedActivationCode, confirmationCode, carrierName, accessRules); } - public Builder setEncodedActivationCode(String value) { + /** + * Sets the encoded activation code. + * @param value the activation code to use. An activation code can be parsed from a user + * scanned QR code. The format of activation code is defined in SGP.22. For + * example, "1$SMDP.GSMA.COM$04386-AGYFT-A74Y8-3F815$1.3.6.1.4.1.31746". For + * detail, see {@code com.android.euicc.data.ActivationCode}. Must not be null. + */ + @NonNull + public Builder setEncodedActivationCode(@NonNull String value) { encodedActivationCode = value; return this; } - public Builder setConfirmationCode(String value) { + /** + * Sets the confirmation code. + * @param value the confirmation code to use to authenticate the carrier server got + * subscription download. + */ + @NonNull + public Builder setConfirmationCode(@NonNull String value) { confirmationCode = value; return this; } - public Builder setCarrierName(String value) { + /** + * Sets the user-visible carrier name. + * @param value carrier name. + * @hide + */ + @NonNull + @SystemApi + public Builder setCarrierName(@NonNull String value) { carrierName = value; return this; } - public Builder setAccessRules(List<UiccAccessRule> value) { + /** + * Sets the {@link UiccAccessRule}s dictating access to this subscription. + * @param value A list of {@link UiccAccessRule}s. + * @hide + */ + @NonNull + @SystemApi + public Builder setAccessRules(@NonNull List<UiccAccessRule> value) { accessRules = value; return this; } diff --git a/telephony/java/android/telephony/ims/ImsUtListener.java b/telephony/java/android/telephony/ims/ImsUtListener.java index baa0576cdf13..754814facb71 100644 --- a/telephony/java/android/telephony/ims/ImsUtListener.java +++ b/telephony/java/android/telephony/ims/ImsUtListener.java @@ -178,4 +178,11 @@ public class ImsUtListener { public ImsUtListener(IImsUtListener serviceInterface) { mServiceInterface = serviceInterface; } + + /** + * @hide + */ + public IImsUtListener getListenerInterface() { + return mServiceInterface; + } } diff --git a/telephony/java/android/telephony/ims/RcsContactPresenceTuple.java b/telephony/java/android/telephony/ims/RcsContactPresenceTuple.java index 519d0164b0d6..5eb75e762fc9 100644 --- a/telephony/java/android/telephony/ims/RcsContactPresenceTuple.java +++ b/telephony/java/android/telephony/ims/RcsContactPresenceTuple.java @@ -19,6 +19,7 @@ package android.telephony.ims; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.StringDef; +import android.annotation.SystemApi; import android.net.Uri; import android.os.Parcel; import android.os.Parcelable; @@ -34,14 +35,135 @@ import java.util.List; * network during a SUBSCRIBE request. See RFC3863 for more information. * @hide */ +@SystemApi public final class RcsContactPresenceTuple implements Parcelable { - /** The service id of the MMTEL */ + /** + * The service ID used to indicate that MMTEL service is available. + * <p> + * See the GSMA RCC.07 specification for more information. + */ public static final String SERVICE_ID_MMTEL = "org.3gpp.urn:urn-7:3gpp-service.ims.icsi.mmtel"; - /** The service id of the Call Composer */ + /** + * The service ID used to indicate that the chat(v1.0) is available. + * <p> + * See the GSMA RCC.07 specification for more information. + */ + public static final String SERVICE_ID_CHAT_V1 = "org.openmobilealliance:IM-session"; + + /** + * The service ID used to indicate that the chat(v2.0) is available. + * <p> + * See the GSMA RCC.07 specification for more information. + */ + public static final String SERVICE_ID_CHAT_V2 = "org.openmobilealliance:ChatSession"; + + /** + * The service ID used to indicate that the File Transfer is available. + * <p> + * See the GSMA RCC.07 specification for more information. + */ + public static final String SERVICE_ID_FT = "org.openmobilealliance:File-Transfer-HTTP"; + + /** + * The service ID used to indicate that the File Transfer over SMS is available. + * <p> + * See the GSMA RCC.07 specification for more information. + */ + public static final String SERVICE_ID_FT_OVER_SMS = + "org.3gpp.urn:urn-7:3gpp-application.ims.iari.rcs.ftsms"; + + /** + * The service ID used to indicate that the Geolocation Push is available. + * <p> + * See the GSMA RCC.07 specification for more information. + */ + public static final String SERVICE_ID_GEO_PUSH = + "org.3gpp.urn:urn-7:3gpp-application.ims.iari.rcs.geopush"; + + /** + * The service ID used to indicate that the Geolocation Push via SMS is available. + * <p> + * See the GSMA RCC.07 specification for more information. + */ + public static final String SERVICE_ID_GEO_PUSH_VIA_SMS = + "org.3gpp.urn:urn-7:3gpp-application.ims.iari.rcs.geosms"; + + /** + * The service ID used to indicate that the Call Composer is available. + * <p> + * See the GSMA RCC.07 specification for more information. + */ public static final String SERVICE_ID_CALL_COMPOSER = - "org.3gpp.urn:urn-7:3gppservice.ims.icsi.gsma.callcomposer"; + "org.3gpp.urn:urn-7:3gpp-service.ims.icsi.gsma.callcomposer"; + + /** + * The service ID used to indicate that the Post Call is available. + * <p> + * See the GSMA RCC.07 specification for more information. + */ + public static final String SERVICE_ID_POST_CALL = + "org.3gpp.urn:urn-7:3gpp-service.ims.icsi.gsma.callunanswered"; + + /** + * The service ID used to indicate that the Shared Map is available. + * <p> + * See the GSMA RCC.07 specification for more information. + */ + public static final String SERVICE_ID_SHARED_MAP = + "org.3gpp.urn:urn-7:3gpp-service.ims.icsi.gsma.sharedmap"; + + /** + * The service ID used to indicate that the Shared Sketch is available. + * <p> + * See the GSMA RCC.07 specification for more information. + */ + public static final String SERVICE_ID_SHARED_SKETCH = + "org.3gpp.urn:urn-7:3gpp-service.ims.icsi.gsma.sharedsketch"; + + /** + * The service ID used to indicate that the Chatbot using Session is available. + * <p> + * See the GSMA RCC.07 specification for more information. + */ + public static final String SERVICE_ID_CHATBOT = + "org.3gpp.urn:urn-7:3gpp-application.ims.iari.rcs.chatbot"; + + /** + * The service ID used to indicate that the Standalone Messaging is available. + * <p> + * See the GSMA RCC.07 specification for more information. + */ + public static final String SERVICE_ID_CHATBOT_STANDALONE = + " org.3gpp.urn:urn-7:3gpp-application.ims.iari.rcs.chatbot.sa"; + + /** + * The service ID used to indicate that the Chatbot Role is available. + * <p> + * See the GSMA RCC.07 specification for more information. + */ + public static final String SERVICE_ID_CHATBOT_ROLE = "org.gsma.rcs.isbot"; + + /** @hide */ + @Retention(RetentionPolicy.SOURCE) + @StringDef(prefix = "SERVICE_ID_", value = { + SERVICE_ID_MMTEL, + SERVICE_ID_CHAT_V1, + SERVICE_ID_CHAT_V2, + SERVICE_ID_FT, + SERVICE_ID_FT_OVER_SMS, + SERVICE_ID_GEO_PUSH, + SERVICE_ID_GEO_PUSH_VIA_SMS, + SERVICE_ID_CALL_COMPOSER, + SERVICE_ID_POST_CALL, + SERVICE_ID_SHARED_MAP, + SERVICE_ID_SHARED_SKETCH, + SERVICE_ID_CHATBOT, + SERVICE_ID_CHATBOT_STANDALONE, + SERVICE_ID_CHATBOT_ROLE + }) + public @interface ServiceId {} /** The service capabilities is available. */ public static final String TUPLE_BASIC_STATUS_OPEN = "open"; @@ -149,6 +271,7 @@ public final class RcsContactPresenceTuple implements Parcelable { in.readStringList(mSupportedDuplexModeList); in.readStringList(mUnsupportedDuplexModeList); } + @Override public void writeToParcel(@NonNull Parcel out, int flags) { out.writeBoolean(mIsAudioCapable); @@ -217,12 +340,14 @@ public final class RcsContactPresenceTuple implements Parcelable { /** * Builds a RcsContactPresenceTuple instance. + * @param status The status associated with the service capability. See RFC3865 for more + * information. * @param serviceId The OMA Presence service-id associated with this capability. See the * OMA Presence SIMPLE specification v1.1, section 10.5.1. * @param serviceVersion The OMA Presence version associated with the service capability. * See the OMA Presence SIMPLE specification v1.1, section 10.5.1. */ - public Builder(@NonNull @BasicStatus String status, @NonNull String serviceId, + public Builder(@NonNull @BasicStatus String status, @NonNull @ServiceId String serviceId, @NonNull String serviceVersion) { mPresenceTuple = new RcsContactPresenceTuple(status, serviceId, serviceVersion); } @@ -230,16 +355,17 @@ public final class RcsContactPresenceTuple implements Parcelable { /** * The optional SIP Contact URI associated with the PIDF tuple element. */ - public @NonNull Builder addContactUri(@NonNull Uri contactUri) { + public @NonNull Builder setContactUri(@NonNull Uri contactUri) { mPresenceTuple.mContactUri = contactUri; return this; } /** * The optional timestamp indicating the data and time of the status change of this tuple. - * See RFC3863, section 4.1.7 for more information on the expected format. + * Per RFC3863 section 4.1.7, the timestamp is formatted as an IMPP datetime format + * string per RFC3339. */ - public @NonNull Builder addTimeStamp(@NonNull String timestamp) { + public @NonNull Builder setTimestamp(@NonNull String timestamp) { mPresenceTuple.mTimestamp = timestamp; return this; } @@ -248,7 +374,7 @@ public final class RcsContactPresenceTuple implements Parcelable { * An optional parameter containing the description element of the service-description. See * OMA Presence SIMPLE specification v1.1 */ - public @NonNull Builder addDescription(@NonNull String description) { + public @NonNull Builder setServiceDescription(@NonNull String description) { mPresenceTuple.mServiceDescription = description; return this; } @@ -257,7 +383,7 @@ public final class RcsContactPresenceTuple implements Parcelable { * An optional parameter containing the service capabilities of the presence tuple if they * are present in the servcaps element. */ - public @NonNull Builder addServiceCapabilities(@NonNull ServiceCapabilities caps) { + public @NonNull Builder setServiceCapabilities(@NonNull ServiceCapabilities caps) { mPresenceTuple.mServiceCapabilities = caps; return this; } diff --git a/telephony/java/android/telephony/ims/RcsContactUceCapability.java b/telephony/java/android/telephony/ims/RcsContactUceCapability.java index d4715bfeeb3e..fe855023f5d0 100644 --- a/telephony/java/android/telephony/ims/RcsContactUceCapability.java +++ b/telephony/java/android/telephony/ims/RcsContactUceCapability.java @@ -19,6 +19,7 @@ package android.telephony.ims; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; +import android.annotation.SystemApi; import android.net.Uri; import android.os.Parcel; import android.os.Parcelable; @@ -33,6 +34,7 @@ import java.util.List; * Contains the User Capability Exchange capabilities corresponding to a contact's URI. * @hide */ +@SystemApi public final class RcsContactUceCapability implements Parcelable { /** Contains presence information associated with the contact */ @@ -70,52 +72,46 @@ public final class RcsContactUceCapability implements Parcelable { public @interface SourceType {} /** + * Capability information for the requested contact has expired and can not be refreshed due to + * a temporary network error. This is a temporary error and the capabilities of the contact + * should be queried again at a later time. + */ + public static final int REQUEST_RESULT_UNKNOWN = 0; + + /** * The requested contact was found to be offline when queried. This is only applicable to * contact capabilities that were queried via OPTIONS requests and the network returned a * 408/480 response. */ - public static final int REQUEST_RESULT_NOT_ONLINE = 0; + public static final int REQUEST_RESULT_NOT_ONLINE = 1; /** * Capability information for the requested contact was not found. The contact should not be * considered an RCS user. */ - public static final int REQUEST_RESULT_NOT_FOUND = 1; + public static final int REQUEST_RESULT_NOT_FOUND = 2; /** * Capability information for the requested contact was found successfully. */ - public static final int REQUEST_RESULT_FOUND = 2; - - /** - * Capability information for the requested contact has expired and can not be refreshed due to - * a temporary network error. This is a temporary error and the capabilities of the contact - * should be queried again at a later time. - */ - public static final int REQUEST_RESULT_UNKNOWN = 3; + public static final int REQUEST_RESULT_FOUND = 3; /** @hide */ @Retention(RetentionPolicy.SOURCE) @IntDef(prefix = "REQUEST_RESULT_", value = { + REQUEST_RESULT_UNKNOWN, REQUEST_RESULT_NOT_ONLINE, REQUEST_RESULT_NOT_FOUND, - REQUEST_RESULT_FOUND, - REQUEST_RESULT_UNKNOWN + REQUEST_RESULT_FOUND }) public @interface RequestResult {} /** - * The base class of {@link OptionsBuilder} and {@link PresenceBuilder} - */ - public static abstract class RcsUcsCapabilityBuilder { - public abstract @NonNull RcsContactUceCapability build(); - } - - /** * Builder to help construct {@link RcsContactUceCapability} instances when capabilities were * queried through SIP OPTIONS. + * @hide */ - public static class OptionsBuilder extends RcsUcsCapabilityBuilder { + public static final class OptionsBuilder { private final RcsContactUceCapability mCapabilities; @@ -162,7 +158,6 @@ public final class RcsContactUceCapability implements Parcelable { /** * @return the constructed instance. */ - @Override public @NonNull RcsContactUceCapability build() { return mCapabilities; } @@ -172,7 +167,7 @@ public final class RcsContactUceCapability implements Parcelable { * Builder to help construct {@link RcsContactUceCapability} instances when capabilities were * queried through a presence server. */ - public static class PresenceBuilder extends RcsUcsCapabilityBuilder { + public static final class PresenceBuilder { private final RcsContactUceCapability mCapabilities; @@ -214,7 +209,6 @@ public final class RcsContactUceCapability implements Parcelable { /** * @return the RcsContactUceCapability instance. */ - @Override public @NonNull RcsContactUceCapability build() { return mCapabilities; } @@ -284,6 +278,7 @@ public final class RcsContactUceCapability implements Parcelable { * <p> * Note: this is only populated if {@link #getCapabilityMechanism} is * {@link RcsContactUceCapability#CAPABILITY_MECHANISM_OPTIONS} + * @hide */ public @NonNull List<String> getOptionsFeatureTags() { if (mCapabilityMechanism != CAPABILITY_MECHANISM_OPTIONS) { @@ -299,7 +294,7 @@ public final class RcsContactUceCapability implements Parcelable { * Note: this is only populated if {@link #getCapabilityMechanism} is * {@link RcsContactUceCapability#CAPABILITY_MECHANISM_PRESENCE} */ - public @NonNull List<RcsContactPresenceTuple> getPresenceTuples() { + public @NonNull List<RcsContactPresenceTuple> getCapabilityTuples() { if (mCapabilityMechanism != CAPABILITY_MECHANISM_PRESENCE) { return Collections.emptyList(); } @@ -309,13 +304,14 @@ public final class RcsContactUceCapability implements Parcelable { /** * Get the RcsContactPresenceTuple associated with the given service id. * @param serviceId The service id to get the presence tuple. - * @return The RcsContactPresenceTuple which has the given service id. + * @return The RcsContactPresenceTuple which has the given service id or {@code null} if the + * service id does not exist in the list of presence tuples returned from the network. * * <p> * Note: this is only populated if {@link #getCapabilityMechanism} is * {@link RcsContactUceCapability#CAPABILITY_MECHANISM_PRESENCE} */ - public @Nullable RcsContactPresenceTuple getPresenceTuple(@NonNull String serviceId) { + public @Nullable RcsContactPresenceTuple getCapabilityTuple(@NonNull String serviceId) { if (mCapabilityMechanism != CAPABILITY_MECHANISM_PRESENCE) { return null; } diff --git a/telephony/java/android/telephony/ims/RcsUceAdapter.java b/telephony/java/android/telephony/ims/RcsUceAdapter.java index 6c31466c2a89..070fd799d6cc 100644 --- a/telephony/java/android/telephony/ims/RcsUceAdapter.java +++ b/telephony/java/android/telephony/ims/RcsUceAdapter.java @@ -63,6 +63,7 @@ public class RcsUceAdapter { * RcsFeature should not publish capabilities or service capability requests. * @hide */ + @SystemApi public static final int CAPABILITY_TYPE_PRESENCE_UCE = 1 << 1; /**@hide*/ @@ -77,12 +78,14 @@ public class RcsUceAdapter { * An unknown error has caused the request to fail. * @hide */ + @SystemApi public static final int ERROR_GENERIC_FAILURE = 1; /** * The carrier network does not have UCE support enabled for this subscriber. * @hide */ + @SystemApi public static final int ERROR_NOT_ENABLED = 2; /** @@ -90,12 +93,14 @@ public class RcsUceAdapter { * 1x only currently). * @hide */ + @SystemApi public static final int ERROR_NOT_AVAILABLE = 3; /** * The network has responded with SIP 403 error and a reason "User not registered." * @hide */ + @SystemApi public static final int ERROR_NOT_REGISTERED = 4; /** @@ -103,12 +108,14 @@ public class RcsUceAdapter { * presence" for this subscriber. * @hide */ + @SystemApi public static final int ERROR_NOT_AUTHORIZED = 5; /** * The network has responded to this request with a SIP 403 error and no reason. * @hide */ + @SystemApi public static final int ERROR_FORBIDDEN = 6; /** @@ -116,6 +123,7 @@ public class RcsUceAdapter { * subscriber to the carrier network. * @hide */ + @SystemApi public static final int ERROR_NOT_FOUND = 7; /** @@ -123,6 +131,7 @@ public class RcsUceAdapter { * with a lower number of contact numbers. The number varies per carrier. * @hide */ + @SystemApi // TODO: Try to integrate this into the API so that the service will split based on carrier. public static final int ERROR_REQUEST_TOO_LARGE = 8; @@ -130,18 +139,21 @@ public class RcsUceAdapter { * The network did not respond to the capabilities request before the request timed out. * @hide */ + @SystemApi public static final int ERROR_REQUEST_TIMEOUT = 9; /** * The request failed due to the service having insufficient memory. * @hide */ + @SystemApi public static final int ERROR_INSUFFICIENT_MEMORY = 10; /** * The network was lost while trying to complete the request. * @hide */ + @SystemApi public static final int ERROR_LOST_NETWORK = 11; /** @@ -149,6 +161,7 @@ public class RcsUceAdapter { * time returned in {@link CapabilitiesCallback#onError} has elapsed. * @hide */ + @SystemApi public static final int ERROR_SERVER_UNAVAILABLE = 12; /**@hide*/ @@ -405,6 +418,7 @@ public class RcsUceAdapter { * @see #requestCapabilities(Executor, List, CapabilitiesCallback) * @hide */ + @SystemApi public interface CapabilitiesCallback { /** @@ -424,10 +438,10 @@ public class RcsUceAdapter { * The pending request has resulted in an error and may need to be retried, depending on the * error code. * @param errorCode The reason for the framework being unable to process the request. - * @param retryAfterMilliseconds The time in milliseconds the requesting application should + * @param retryIntervalMillis The time in milliseconds the requesting application should * wait before retrying, if non-zero. */ - void onError(@ErrorCode int errorCode, long retryAfterMilliseconds); + void onError(@ErrorCode int errorCode, long retryIntervalMillis); } private final Context mContext; @@ -458,9 +472,9 @@ public class RcsUceAdapter { * {@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}. * + * @param contactNumbers A list of numbers that the capabilities are being requested for. * @param executor The executor that will be used when the request is completed and the * {@link CapabilitiesCallback} is called. - * @param contactNumbers A list of numbers that the capabilities are being requested for. * @param c A one-time callback for when the request for capabilities completes or there is an * error processing the request. * @throws ImsException if the subscription associated with this instance of @@ -469,9 +483,10 @@ public class RcsUceAdapter { * becomes inactive. See {@link ImsException#getCode()} for more information on the error codes. * @hide */ + @SystemApi @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE) - public void requestCapabilities(@NonNull @CallbackExecutor Executor executor, - @NonNull List<Uri> contactNumbers, + public void requestCapabilities(@NonNull List<Uri> contactNumbers, + @NonNull @CallbackExecutor Executor executor, @NonNull CapabilitiesCallback c) throws ImsException { if (c == null) { throw new IllegalArgumentException("Must include a non-null CapabilitiesCallback."); @@ -495,8 +510,7 @@ public class RcsUceAdapter { public void onCapabilitiesReceived(List<RcsContactUceCapability> contactCapabilities) { final long callingIdentity = Binder.clearCallingIdentity(); try { - executor.execute(() -> - c.onCapabilitiesReceived(contactCapabilities)); + executor.execute(() -> c.onCapabilitiesReceived(contactCapabilities)); } finally { restoreCallingIdentity(callingIdentity); } @@ -550,13 +564,17 @@ public class RcsUceAdapter { * {@link #ERROR_NOT_AVAILABLE} or {@link #ERROR_NOT_ENABLED}. * * @param contactNumber The contact of the capabilities is being requested for. + * @param executor The executor that will be used when the request is completed and the + * {@link CapabilitiesCallback} is called. * @param c A one-time callback for when the request for capabilities completes or there is * an error processing the request. * @hide */ + @SystemApi @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE) - public void requestNetworkAvailability(@NonNull @CallbackExecutor Executor executor, - @NonNull Uri contactNumber, @NonNull CapabilitiesCallback c) throws ImsException { + public void requestAvailability(@NonNull Uri contactNumber, + @NonNull @CallbackExecutor Executor executor, + @NonNull CapabilitiesCallback c) throws ImsException { if (executor == null) { throw new IllegalArgumentException("Must include a non-null Executor."); } @@ -569,7 +587,7 @@ public class RcsUceAdapter { IImsRcsController imsRcsController = getIImsRcsController(); if (imsRcsController == null) { - Log.e(TAG, "requestNetworkAvailability: IImsRcsController is null"); + Log.e(TAG, "requestAvailability: IImsRcsController is null"); throw new ImsException("Cannot find remote IMS service", ImsException.CODE_ERROR_SERVICE_UNAVAILABLE); } @@ -579,8 +597,7 @@ public class RcsUceAdapter { public void onCapabilitiesReceived(List<RcsContactUceCapability> contactCapabilities) { final long callingIdentity = Binder.clearCallingIdentity(); try { - executor.execute(() -> - c.onCapabilitiesReceived(contactCapabilities)); + executor.execute(() -> c.onCapabilitiesReceived(contactCapabilities)); } finally { restoreCallingIdentity(callingIdentity); } @@ -606,12 +623,12 @@ public class RcsUceAdapter { }; try { - imsRcsController.requestNetworkAvailability(mSubId, mContext.getOpPackageName(), + imsRcsController.requestAvailability(mSubId, mContext.getOpPackageName(), mContext.getAttributionTag(), contactNumber, internalCallback); } catch (ServiceSpecificException e) { throw new ImsException(e.toString(), e.errorCode); } catch (RemoteException e) { - Log.e(TAG, "Error calling IImsRcsController#requestNetworkAvailability", e); + Log.e(TAG, "Error calling IImsRcsController#requestAvailability", e); throw new ImsException("Remote IMS Service is not available", ImsException.CODE_ERROR_SERVICE_UNAVAILABLE); } @@ -683,7 +700,7 @@ public class RcsUceAdapter { if (imsRcsController == null) { Log.e(TAG, "addOnPublishStateChangedListener : IImsRcsController is null"); throw new ImsException("Cannot find remote IMS service", - ImsException.CODE_ERROR_SERVICE_UNAVAILABLE); + ImsException.CODE_ERROR_SERVICE_UNAVAILABLE); } PublishStateCallbackAdapter stateCallback = addPublishStateCallback(executor, listener); @@ -694,7 +711,7 @@ public class RcsUceAdapter { } catch (RemoteException e) { Log.e(TAG, "Error calling IImsRcsController#registerUcePublishStateCallback", e); throw new ImsException("Remote IMS Service is not available", - ImsException.CODE_ERROR_SERVICE_UNAVAILABLE); + ImsException.CODE_ERROR_SERVICE_UNAVAILABLE); } } diff --git a/telephony/java/android/telephony/ims/SipDelegateImsConfiguration.java b/telephony/java/android/telephony/ims/SipDelegateImsConfiguration.java index eddbb1002f20..8762b6a712f2 100644 --- a/telephony/java/android/telephony/ims/SipDelegateImsConfiguration.java +++ b/telephony/java/android/telephony/ims/SipDelegateImsConfiguration.java @@ -280,6 +280,12 @@ public final class SipDelegateImsConfiguration implements Parcelable { "sip_config_path_header_string"; /** + * The SIP User-Agent header value used by the IMS stack during IMS registration. + */ + public static final String KEY_SIP_CONFIG_USER_AGENT_HEADER_STRING = + "sip_config_sip_user_agent_header_string"; + + /** * SIP User part string in contact header */ public static final String KEY_SIP_CONFIG_URI_USER_PART_STRING = @@ -292,12 +298,20 @@ public final class SipDelegateImsConfiguration implements Parcelable { "sip_config_p_access_network_info_header_string"; /** - * SIP P-last-access-network-info header string + * The SIP P-last-access-network-info header value, populated for networks that require this + * information to be provided in outgoing SIP messages. */ public static final String KEY_SIP_CONFIG_P_LAST_ACCESS_NETWORK_INFO_HEADER_STRING = "sip_config_p_last_access_network_info_header_string"; /** + * The Cellular-Network-Info header value (See 3GPP 24.229, section 7.2.15), populated for + * networks that require this information to be provided as part of outgoing SIP messages. + */ + public static final String KEY_SIP_CONFIG_CELLULAR_NETWORK_INFO_HEADER_STRING = + "sip_config_cellular_network_info_header_string"; + + /** * SIP P-associated-uri header string */ public static final String KEY_SIP_CONFIG_P_ASSOCIATED_URI_HEADER_STRING = @@ -320,9 +334,11 @@ public final class SipDelegateImsConfiguration implements Parcelable { KEY_SIP_CONFIG_SERVICE_ROUTE_HEADER_STRING, KEY_SIP_CONFIG_SECURITY_VERIFY_HEADER_STRING, KEY_SIP_CONFIG_PATH_HEADER_STRING, + KEY_SIP_CONFIG_USER_AGENT_HEADER_STRING, KEY_SIP_CONFIG_URI_USER_PART_STRING, KEY_SIP_CONFIG_P_ACCESS_NETWORK_INFO_HEADER_STRING, KEY_SIP_CONFIG_P_LAST_ACCESS_NETWORK_INFO_HEADER_STRING, + KEY_SIP_CONFIG_CELLULAR_NETWORK_INFO_HEADER_STRING, KEY_SIP_CONFIG_P_ASSOCIATED_URI_HEADER_STRING }) @Retention(RetentionPolicy.SOURCE) diff --git a/telephony/java/android/telephony/ims/aidl/IImsRcsController.aidl b/telephony/java/android/telephony/ims/aidl/IImsRcsController.aidl index 36349895c35b..7a6c28bddd09 100644 --- a/telephony/java/android/telephony/ims/aidl/IImsRcsController.aidl +++ b/telephony/java/android/telephony/ims/aidl/IImsRcsController.aidl @@ -52,7 +52,7 @@ interface IImsRcsController { // ImsUceAdapter specific void requestCapabilities(int subId, String callingPackage, String callingFeatureId, in List<Uri> contactNumbers, IRcsUceControllerCallback c); - void requestNetworkAvailability(int subId, String callingPackage, + void requestAvailability(int subId, String callingPackage, String callingFeatureId, in Uri contactNumber, IRcsUceControllerCallback c); int getUcePublishState(int subId); diff --git a/telephony/java/android/telephony/ims/stub/ImsEcbmImplBase.java b/telephony/java/android/telephony/ims/stub/ImsEcbmImplBase.java index 06c35eaec6dd..2e35d27614d1 100644 --- a/telephony/java/android/telephony/ims/stub/ImsEcbmImplBase.java +++ b/telephony/java/android/telephony/ims/stub/ImsEcbmImplBase.java @@ -23,6 +23,8 @@ import android.util.Log; import com.android.ims.internal.IImsEcbm; import com.android.ims.internal.IImsEcbmListener; +import java.util.Objects; + /** * Base implementation of ImsEcbm, which implements stub versions of the methods * in the IImsEcbm AIDL. Override the methods that your implementation of ImsEcbm supports. @@ -36,11 +38,27 @@ import com.android.ims.internal.IImsEcbmListener; public class ImsEcbmImplBase { private static final String TAG = "ImsEcbmImplBase"; + private final Object mLock = new Object(); private IImsEcbmListener mListener; - private IImsEcbm mImsEcbm = new IImsEcbm.Stub() { + private final IImsEcbm mImsEcbm = new IImsEcbm.Stub() { @Override public void setListener(IImsEcbmListener listener) { - mListener = listener; + synchronized (mLock) { + if (mImsEcbm != null && listener != null && Objects.equals( + mImsEcbm.asBinder(), listener.asBinder())) { + return; + } + if (listener == null) { + mListener = null; + } 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."); + } + } } @Override @@ -69,9 +87,13 @@ public class ImsEcbmImplBase { */ public final void enteredEcbm() { Log.d(TAG, "Entered ECBM."); - if (mListener != null) { + IImsEcbmListener listener; + synchronized (mLock) { + listener = mListener; + } + if (listener != null) { try { - mListener.enteredECBM(); + listener.enteredECBM(); } catch (RemoteException e) { throw new RuntimeException(e); } @@ -85,9 +107,13 @@ public class ImsEcbmImplBase { */ public final void exitedEcbm() { Log.d(TAG, "Exited ECBM."); - if (mListener != null) { + IImsEcbmListener listener; + synchronized (mLock) { + listener = mListener; + } + if (listener != null) { try { - mListener.exitedECBM(); + listener.exitedECBM(); } catch (RemoteException e) { throw new RuntimeException(e); } diff --git a/telephony/java/android/telephony/ims/stub/ImsMultiEndpointImplBase.java b/telephony/java/android/telephony/ims/stub/ImsMultiEndpointImplBase.java index d002903a11b6..555a47eb8200 100644 --- a/telephony/java/android/telephony/ims/stub/ImsMultiEndpointImplBase.java +++ b/telephony/java/android/telephony/ims/stub/ImsMultiEndpointImplBase.java @@ -25,6 +25,7 @@ import com.android.ims.internal.IImsExternalCallStateListener; import com.android.ims.internal.IImsMultiEndpoint; import java.util.List; +import java.util.Objects; /** * Base implementation of ImsMultiEndpoint, which implements stub versions of the methods @@ -41,10 +42,28 @@ public class ImsMultiEndpointImplBase { private static final String TAG = "MultiEndpointImplBase"; private IImsExternalCallStateListener mListener; - private IImsMultiEndpoint mImsMultiEndpoint = new IImsMultiEndpoint.Stub() { + private final Object mLock = new Object(); + private final IImsMultiEndpoint mImsMultiEndpoint = new IImsMultiEndpoint.Stub() { + @Override public void setListener(IImsExternalCallStateListener listener) throws RemoteException { - mListener = listener; + synchronized (mLock) { + if (mListener != null && listener != null && Objects.equals( + mListener.asBinder(), listener.asBinder())) { + return; + } + + if (listener == null) { + mListener = null; + } 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."); + } + } } @Override @@ -65,9 +84,13 @@ public class ImsMultiEndpointImplBase { */ public final void onImsExternalCallStateUpdate(List<ImsExternalCallState> externalCallDialogs) { Log.d(TAG, "ims external call state update triggered."); - if (mListener != null) { + IImsExternalCallStateListener listener; + synchronized (mLock) { + listener = mListener; + } + if (listener != null) { try { - mListener.onImsExternalCallStateUpdate(externalCallDialogs); + listener.onImsExternalCallStateUpdate(externalCallDialogs); } catch (RemoteException e) { throw new RuntimeException(e); } diff --git a/telephony/java/android/telephony/ims/stub/ImsUtImplBase.java b/telephony/java/android/telephony/ims/stub/ImsUtImplBase.java index f5219d5b49e8..eef4fcaceeaf 100644 --- a/telephony/java/android/telephony/ims/stub/ImsUtImplBase.java +++ b/telephony/java/android/telephony/ims/stub/ImsUtImplBase.java @@ -29,6 +29,7 @@ import com.android.ims.internal.IImsUtListener; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; +import java.util.Objects; /** * Base implementation of IMS UT interface, which implements stubs. Override these methods to @@ -116,7 +117,10 @@ public class ImsUtImplBase { */ public static final int INVALID_RESULT = -1; - private IImsUt.Stub mServiceImpl = new IImsUt.Stub() { + private final IImsUt.Stub mServiceImpl = new IImsUt.Stub() { + private final Object mLock = new Object(); + private ImsUtListener mUtListener; + @Override public void close() throws RemoteException { ImsUtImplBase.this.close(); @@ -202,7 +206,26 @@ public class ImsUtImplBase { @Override public void setListener(IImsUtListener listener) throws RemoteException { - ImsUtImplBase.this.setListener(new ImsUtListener(listener)); + synchronized (mLock) { + if (mUtListener != null && listener != null && Objects.equals( + mUtListener.getListenerInterface().asBinder(), listener.asBinder())) { + return; + } + + if (listener == null) { + mUtListener = null; + } 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!"); + } + } + + ImsUtImplBase.this.setListener(mUtListener); } @Override diff --git a/telephony/java/android/telephony/ims/stub/RcsCapabilityExchangeImplBase.java b/telephony/java/android/telephony/ims/stub/RcsCapabilityExchangeImplBase.java index c84e23c38e97..7eba709a11da 100644 --- a/telephony/java/android/telephony/ims/stub/RcsCapabilityExchangeImplBase.java +++ b/telephony/java/android/telephony/ims/stub/RcsCapabilityExchangeImplBase.java @@ -24,6 +24,7 @@ import android.annotation.SuppressLint; import android.annotation.SystemApi; import android.net.Uri; import android.telephony.ims.ImsException; +import android.telephony.ims.RcsUceAdapter; import android.telephony.ims.feature.ImsFeature; import android.telephony.ims.feature.RcsFeature; import android.util.Log; @@ -139,18 +140,19 @@ public class RcsCapabilityExchangeImplBase { * Provide the framework with a subsequent network response update to * {@link #publishCapabilities(String, PublishResponseCallback)}. * - * @param code The SIP response code sent from the network for the operation + * @param sipCode The SIP response code sent from the network for the operation * token specified. * @param reason The optional reason response from the network. If there is a reason header * included in the response, that should take precedence over the reason provided in the - * status line. If the network provided no reason with the code, the string should be empty. + * status line. If the network provided no reason with the sip code, the string should be + * empty. * @throws ImsException If this {@link RcsCapabilityExchangeImplBase} instance is * not currently connected to the framework. This can happen if the {@link RcsFeature} * is not {@link ImsFeature#STATE_READY} and the {@link RcsFeature} has not received * the {@link ImsFeature#onFeatureReady()} callback. This may also happen in rare cases * when the Telephony stack has crashed. */ - void onNetworkResponse(@IntRange(from = 100, to = 699) int code, + void onNetworkResponse(@IntRange(from = 100, to = 699) int sipCode, @NonNull String reason) throws ImsException; } @@ -173,7 +175,7 @@ public class RcsCapabilityExchangeImplBase { /** * Send the response of a SIP OPTIONS capability exchange to the framework. - * @param code The SIP response code that was sent by the network in response + * @param sipCode The SIP response code that was sent by the network in response * to the request sent by {@link #sendOptionsCapabilityRequest}. * @param reason The optional SIP response reason sent by the network. * If none was sent, this should be an empty string. @@ -186,17 +188,20 @@ public class RcsCapabilityExchangeImplBase { * {@link ImsFeature#onFeatureReady()} callback. This may also happen in rare * cases when the Telephony stack has crashed. */ - void onNetworkResponse(int code, @NonNull String reason, + void onNetworkResponse(int sipCode, @NonNull String reason, @Nullable List<String> theirCaps) throws ImsException; } /** * Interface used by the framework to receive the response of the subscribe request. - * @hide */ public interface SubscribeResponseCallback { /** * Notify the framework that the command associated with this callback has failed. + * <p> + * Must only be called when there was an error generating a SUBSCRIBE request due to an + * IMS stack error. This is a terminating event, so no other callback event will be + * expected after this callback. * * @param code The reason why the associated command has failed. * @throws ImsException If this {@link RcsCapabilityExchangeImplBase} instance is @@ -211,27 +216,38 @@ public class RcsCapabilityExchangeImplBase { /** * Notify the framework of the response to the SUBSCRIBE request from * {@link #subscribeForCapabilities(List<Uri>, SubscribeResponseCallback)}. + * <p> + * If the carrier network responds to the SUBSCRIBE request with a 2XX response, then the + * framework will expect the IMS stack to call {@link #onNotifyCapabilitiesUpdate}, + * {@link #onResourceTerminated}, and {@link #onTerminated} as required for the + * subsequent NOTIFY responses to the subscription. * - * @param code The SIP response code sent from the network for the operation + * @param sipCode The SIP response code sent from the network for the operation * token specified. * @param reason The optional reason response from the network. If the network - * provided no reason with the code, the string should be empty. + * provided no reason with the sip code, the string should be empty. * @throws ImsException If this {@link RcsCapabilityExchangeImplBase} instance is * not currently connected to the framework. This can happen if the * {@link RcsFeature} is not {@link ImsFeature#STATE_READY} and the * {@link RcsFeature} has not received the {@link ImsFeature#onFeatureReady()} callback. * This may also happen in rare cases when the Telephony stack has crashed. */ - void onNetworkResponse(@IntRange(from = 100, to = 699) int code, + void onNetworkResponse(@IntRange(from = 100, to = 699) int sipCode, @NonNull String reason) throws ImsException; /** - * Provides the framework with latest XML PIDF documents included in the - * network response for the requested contacts' capabilities requested by the - * Framework using {@link #requestCapabilities(List, int)}. This should be - * called every time a new NOTIFY event is received with new capability - * information. + * Notify the framework of the latest XML PIDF documents included in the network response + * for the requested contacts' capabilities requested by the Framework using + * {@link RcsUceAdapter#requestCapabilities(Executor, List<Uri>, CapabilitiesCallback)}. + * <p> + * The expected format for the PIDF XML is defined in RFC3861. Each XML document must be a + * "application/pidf+xml" object and start with a root <presence> element. For NOTIFY + * responses that contain RLMI information and potentially multiple PIDF XMLs, each + * PIDF XML should be separated and added as a separate item in the List. This should be + * called every time a new NOTIFY event is received with new capability information. * + * @param pidfXmls The list of the PIDF XML data for the contact URIs that it subscribed + * for. * @throws ImsException If this {@link RcsCapabilityExchangeImplBase} instance is * not currently connected to the framework. * This can happen if the {@link RcsFeature} is not {@link ImsFeature#STATE_READY} and the @@ -242,21 +258,42 @@ public class RcsCapabilityExchangeImplBase { void onNotifyCapabilitiesUpdate(@NonNull List<String> pidfXmls) throws ImsException; /** - * A resource in the resource list for the presence subscribe event has been terminated. + * Notify the framework that a resource in the RLMI XML contained in the NOTIFY response + * for the ongoing SUBSCRIBE dialog has been terminated. * <p> - * This allows the framework to know that there will not be any capability information for - * a specific contact URI that they subscribed for. + * This will be used to notify the framework that a contact URI that the IMS stack has + * subscribed to on the Resource List Server has been terminated as well as the reason why. + * Usually this means that there will not be any capability information for the contact URI + * that they subscribed for. See RFC 4662 for more information. + * + * @param uriTerminatedReason The contact URIs which have been terminated. Each pair in the + * list is the contact URI and its terminated reason. + * @throws ImsException If this {@link RcsCapabilityExchangeImplBase} instance is + * not currently connected to the framework. + * This can happen if the {@link RcsFeature} is not {@link ImsFeature#STATE_READY} and the + * {@link RcsFeature} {@link ImsFeature#STATE_READY} and the {@link RcsFeature} has not + * received the {@link ImsFeature#onFeatureReady()} callback. This may also happen in + * rare cases when the Telephony stack has crashed. */ void onResourceTerminated( @NonNull List<Pair<Uri, String>> uriTerminatedReason) throws ImsException; /** - * The subscription associated with a previous #requestCapabilities operation - * has been terminated. This will mostly be due to the subscription expiring, - * but may also happen due to an error. - * <p> - * This allows the framework to know that there will no longer be any - * capability updates for the requested operationToken. + * The subscription associated with a previous + * {@link RcsUceAdapter#requestCapabilities(Executor, List<Uri>, CapabilitiesCallback)} + * operation has been terminated. This will mostly be due to the network sending a final + * NOTIFY response due to the subscription expiring, but this may also happen due to a + * network error. + * + * @param reason The reason for the request being unable to process. + * @param retryAfterMilliseconds The time in milliseconds the requesting application should + * wait before retrying, if non-zero. + * @throws ImsException If this {@link RcsCapabilityExchangeImplBase} instance is + * not currently connected to the framework. + * This can happen if the {@link RcsFeature} is not {@link ImsFeature#STATE_READY} and the + * {@link RcsFeature} {@link ImsFeature#STATE_READY} and the {@link RcsFeature} has not + * received the {@link ImsFeature#onFeatureReady()} callback. This may also happen in + * rare cases when the Telephony stack has crashed. */ void onTerminated(@NonNull String reason, long retryAfterMilliseconds) throws ImsException; } @@ -278,18 +315,23 @@ public class RcsCapabilityExchangeImplBase { /** * The user capabilities of one or multiple contacts have been requested by the framework. * <p> + * The implementer must follow up this call with an + * {@link SubscribeResponseCallback#onCommandError} call to indicate this operation has failed. * The response from the network to the SUBSCRIBE request must be sent back to the framework - * using {@link #onSubscribeNetworkResponse(int, String, int)}. As NOTIFY requests come in from - * the network, the requested contact’s capabilities should be sent back to the framework using - * {@link #onSubscribeNotifyRequest} and {@link onSubscribeResourceTerminated} + * using {@link SubscribeResponseCallback#onNetworkResponse(int, String)}. + * As NOTIFY requests come in from the network, the requested contact’s capabilities should be + * sent back to the framework using + * {@link SubscribeResponseCallback#onNotifyCapabilitiesUpdate(List<String>}) and + * {@link SubscribeResponseCallback#onResourceTerminated(List<Pair<Uri, String>>)} * should be called with the presence information for the contacts specified. * <p> - * Once the subscription is terminated, {@link #onSubscriptionTerminated} must be called for - * the framework to finish listening for NOTIFY responses. + * Once the subscription is terminated, + * {@link SubscribeResponseCallback#onTerminated(String, long)} must be called for the + * framework to finish listening for NOTIFY responses. + * * @param uris A {@link List} of the {@link Uri}s that the framework is requesting the UCE * capabilities for. * @param cb The callback of the subscribe request. - * @hide */ // executor used is defined in the constructor. @SuppressLint("ExecutorRegistration") diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl index e556664bb323..77d46f4c39cd 100644 --- a/telephony/java/com/android/internal/telephony/ITelephony.aidl +++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl @@ -2382,6 +2382,26 @@ interface ITelephony { */ String getMobileProvisioningUrl(); + /* + * Remove the EAB contacts from the EAB database. + */ + int removeContactFromEab(int subId, String contacts); + + /** + * Get the EAB contact from the EAB database. + */ + String getContactFromEab(String contact); + + /* + * Check whether the device supports RCS User Capability Exchange or not. + */ + boolean getDeviceUceEnabled(); + + /* + * Set the device supports RCS User Capability Exchange. + */ + void setDeviceUceEnabled(boolean isEnabled); + /** * Set a SignalStrengthUpdateRequest to receive notification when Signal Strength breach the * specified thresholds. |