blob: fd206c1e803f7d521e4bd378c53cbe3a833883fc [file] [log] [blame]
/*
* Copyright (C) 2020 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.telephony.ims;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.SuppressLint;
import android.annotation.SystemApi;
import android.os.Parcel;
import android.os.Parcelable;
import android.util.ArraySet;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.Objects;
import java.util.Set;
/**
* Contains the full state of the IMS feature tags associated with a SipDelegate and managed by the
* ImsService.
* @hide
*/
@SystemApi
public final class DelegateRegistrationState implements Parcelable {
/**
* This feature tag has been deregistered for an unknown reason. Outgoing out-of-dialog SIP
* messages associated with feature tags that are not registered will fail.
*/
public static final int DEREGISTERED_REASON_UNKNOWN = 0;
/**
* This feature tag has been deregistered because it is not provisioned to be used on this radio
* access technology or PDN. Outgoing out-of-dialog SIP messages associated with feature tags
* that are not registered will fail.
* <p>
* There may be new incoming SIP dialog requests on a feature that that is not provisioned. It
* is still expected that the SipDelegateConnection responds to the request.
*/
public static final int DEREGISTERED_REASON_NOT_PROVISIONED = 1;
/**
* This feature tag has been deregistered because IMS has been deregistered. All outgoing SIP
* messages will fail until IMS registration occurs.
*/
public static final int DEREGISTERED_REASON_NOT_REGISTERED = 2;
/**
* This feature tag is being deregistered because the PDN that the IMS registration is on is
*changing.
* All open SIP dialogs need to be closed before the PDN change can proceed using
* {@link SipDelegateConnection#closeDialog(String)}.
*/
public static final int DEREGISTERING_REASON_PDN_CHANGE = 3;
/**
* This feature tag is being deregistered due to a provisioning change. This can be triggered by
* many things, such as a provisioning change triggered by the carrier network, a radio access
* technology change by the modem causing a different set of feature tags to be provisioned, or
* a user triggered hange, such as data being enabled/disabled.
* <p>
* All open SIP dialogs associated with the new deprovisioned feature tag need to be closed
* using {@link SipDelegateConnection#closeDialog(String)} before the IMS registration
* modification can proceed.
*/
public static final int DEREGISTERING_REASON_PROVISIONING_CHANGE = 4;
/**
* This feature tag is deregistering because the SipDelegate associated with this feature tag
* needs to change its supported feature set.
* <p>
* All open SIP Dialogs associated with this feature tag must be closed
* using {@link SipDelegateConnection#closeDialog(String)} before this operation can proceed.
*/
public static final int DEREGISTERING_REASON_FEATURE_TAGS_CHANGING = 5;
/**
* This feature tag is deregistering because the SipDelegate is in the process of being
* destroyed.
* <p>
* All open SIP Dialogs associated with this feature tag must be closed
* using {@link SipDelegateConnection#closeDialog(String)} before this operation can proceed.
*/
public static final int DEREGISTERING_REASON_DESTROY_PENDING = 6;
/** @hide */
@Retention(RetentionPolicy.SOURCE)
@IntDef(prefix = "DEREGISTERED_REASON_", value = {
DEREGISTERED_REASON_UNKNOWN,
DEREGISTERED_REASON_NOT_PROVISIONED,
DEREGISTERED_REASON_NOT_REGISTERED
})
public @interface DeregisteredReason {}
/** @hide */
@Retention(RetentionPolicy.SOURCE)
@IntDef(prefix = "DEREGISTERING_REASON_", value = {
DEREGISTERING_REASON_PDN_CHANGE,
DEREGISTERING_REASON_PROVISIONING_CHANGE,
DEREGISTERING_REASON_FEATURE_TAGS_CHANGING,
DEREGISTERING_REASON_DESTROY_PENDING
})
public @interface DeregisteringReason {}
private ArraySet<String> mRegisteredTags = new ArraySet<>();
private final ArraySet<FeatureTagState> mDeregisteringTags = new ArraySet<>();
private final ArraySet<FeatureTagState> mDeregisteredTags = new ArraySet<>();
/**
* Builder used to create new instances of {@link DelegateRegistrationState}.
*/
public static final class Builder {
private final DelegateRegistrationState mState;
/* Create a new instance of {@link Builder} */
public Builder() {
mState = new DelegateRegistrationState();
}
/**
* Add a feature tag that is currently included in the current network IMS Registration.
* @param featureTag The IMS media feature tag included in the current IMS registration.
* @return The in-progress Builder instance for RegistrationState.
*/
public @NonNull Builder addRegisteredFeatureTag(@NonNull String featureTag) {
mState.mRegisteredTags.add(featureTag);
return this;
}
/**
* Add a list of feature tags that are currently included in the current network IMS
* Registration.
* @param featureTags The IMS media feature tags included in the current IMS registration.
* @return The in-progress Builder instance for RegistrationState.
*/
@SuppressLint("MissingGetterMatchingBuilder")
public @NonNull Builder addRegisteredFeatureTags(@NonNull Set<String> featureTags) {
mState.mRegisteredTags.addAll(featureTags);
return this;
}
/**
* Add a feature tag that is in the current network IMS Registration, but is in the progress
* of being deregistered and requires action from the RCS application before the IMS
* registration can be modified.
*
* See {@link DeregisteringReason} for more information regarding what is required by the
* RCS application to proceed.
*
* @param featureTag The media feature tag that has limited or no availability due to its
* current deregistering state.
* @param reason The reason why the media feature tag has moved to the deregistering state.
* The availability of the feature tag depends on the {@link DeregisteringReason}.
* @return The in-progress Builder instance for RegistrationState.
*/
public @NonNull Builder addDeregisteringFeatureTag(@NonNull String featureTag,
@DeregisteringReason int reason) {
mState.mDeregisteringTags.add(new FeatureTagState(featureTag, reason));
return this;
}
/**
* Add a feature tag that is currently not included in the network RCS registration. See
* {@link DeregisteredReason} for more information regarding the reason for why the feature
* tag is not registered.
* @param featureTag The media feature tag that is not registered.
* @param reason The reason why the media feature tag has been deregistered.
* @return The in-progress Builder instance for RegistrationState.
*/
public @NonNull Builder addDeregisteredFeatureTag(@NonNull String featureTag,
@DeregisteredReason int reason) {
mState.mDeregisteredTags.add(new FeatureTagState(featureTag, reason));
return this;
}
/**
* @return the finalized instance.
*/
public @NonNull DelegateRegistrationState build() {
return mState;
}
}
/**
* The builder should be used to construct a new instance of this class.
*/
private DelegateRegistrationState() {}
/**
* Used for unparcelling only.
*/
private DelegateRegistrationState(Parcel source) {
mRegisteredTags = (ArraySet<String>) source.readArraySet(null);
readStateFromParcel(source, mDeregisteringTags);
readStateFromParcel(source, mDeregisteredTags);
}
/**
* Get the feature tags that this SipDelegate is associated with that are currently part of the
* network IMS registration. SIP Messages both in and out of a SIP Dialog may be sent and
* received using these feature tags.
* @return A Set of feature tags that the SipDelegate has associated with that are included in
* the network IMS registration.
*/
public @NonNull Set<String> getRegisteredFeatureTags() {
return new ArraySet<>(mRegisteredTags);
}
/**
* Get the feature tags that this SipDelegate is associated with that are currently part of the
* network IMS registration but are in the process of being deregistered.
* <p>
* Any incoming SIP messages associated with a feature tag included in this list will still be
* delivered. Outgoing SIP messages that are still in-dialog will be delivered to the
* SipDelegate, but outgoing out-of-dialog SIP messages with a feature tag that is included in
* this list will fail.
* <p>
* The SipDelegate will stay in this state for a limited period of time while it waits for the
* RCS application to perform a specific action. More details on the actions that can cause this
* state as well as the expected response are included in the reason codes and can be found in
* {@link DeregisteringReason}.
* @return A Set of feature tags that the SipDelegate has associated with that are included in
* the network IMS registration but are in the process of deregistering.
*/
public @NonNull Set<FeatureTagState> getDeregisteringFeatureTags() {
return new ArraySet<>(mDeregisteringTags);
}
/**
* Get the list of feature tags that are associated with this SipDelegate but are not currently
* included in the network IMS registration.
* <p>
* See {@link DeregisteredReason} codes for more information related to the reasons why this may
* occur.
* <p>
* Due to network race conditions, there may still be onditions where an incoming out-of-dialog
* SIP message is delivered for a feature tag that is considered deregistered. Due to this
* condition, in-dialog outgoing SIP messages for deregistered feature tags will still be
* allowed as long as they are in response to a dialog started by a remote party. Any outgoing
* out-of-dialog SIP messages associated with feature tags included in this list will fail to be
* sent.
* @return A list of feature tags that the SipDelegate has associated with that not included in
* the network IMS registration.
*/
public @NonNull Set<FeatureTagState> getDeregisteredFeatureTags() {
return new ArraySet<>(mDeregisteredTags);
}
public static final @NonNull Creator<DelegateRegistrationState> CREATOR =
new Creator<DelegateRegistrationState>() {
@Override
public DelegateRegistrationState createFromParcel(Parcel source) {
return new DelegateRegistrationState(source);
}
@Override
public DelegateRegistrationState[] newArray(int size) {
return new DelegateRegistrationState[size];
}
};
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(@NonNull Parcel dest, int flags) {
dest.writeArraySet(mRegisteredTags);
writeStateToParcel(dest, mDeregisteringTags);
writeStateToParcel(dest, mDeregisteredTags);
}
private void writeStateToParcel(Parcel dest, Set<FeatureTagState> state) {
dest.writeInt(state.size());
for (FeatureTagState s : state) {
dest.writeString(s.getFeatureTag());
dest.writeInt(s.getState());
}
}
private void readStateFromParcel(Parcel source, Set<FeatureTagState> emptyState) {
int len = source.readInt();
for (int i = 0; i < len; i++) {
String ft = source.readString();
int reason = source.readInt();
emptyState.add(new FeatureTagState(ft, reason));
}
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
DelegateRegistrationState that = (DelegateRegistrationState) o;
return mRegisteredTags.equals(that.mRegisteredTags)
&& mDeregisteringTags.equals(that.mDeregisteringTags)
&& mDeregisteredTags.equals(that.mDeregisteredTags);
}
@Override
public int hashCode() {
return Objects.hash(mRegisteredTags, mDeregisteringTags, mDeregisteredTags);
}
@Override
public String toString() {
return "DelegateRegistrationState{ registered={" + mRegisteredTags
+ "}, deregistering={" + mDeregisteringTags + "}, deregistered={"
+ mDeregisteredTags + "}}";
}
}