| /* |
| * Copyright (C) 2018 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package android.telephony.ims; |
| |
| import android.annotation.IntDef; |
| import android.annotation.NonNull; |
| import android.annotation.Nullable; |
| import android.annotation.SystemApi; |
| import android.net.Uri; |
| import android.os.Build; |
| import android.os.Parcel; |
| import android.os.Parcelable; |
| |
| import java.lang.annotation.Retention; |
| import java.lang.annotation.RetentionPolicy; |
| import java.util.ArrayList; |
| import java.util.Collections; |
| import java.util.HashSet; |
| import java.util.List; |
| import java.util.Set; |
| |
| /** |
| * 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 */ |
| public static final int CAPABILITY_MECHANISM_PRESENCE = 1; |
| |
| /** Contains OPTIONS information associated with the contact */ |
| public static final int CAPABILITY_MECHANISM_OPTIONS = 2; |
| |
| /** @hide */ |
| @Retention(RetentionPolicy.SOURCE) |
| @IntDef(prefix = "CAPABILITY_MECHANISM_", value = { |
| CAPABILITY_MECHANISM_PRESENCE, |
| CAPABILITY_MECHANISM_OPTIONS |
| }) |
| public @interface CapabilityMechanism {} |
| |
| /** |
| * The capabilities of this contact were requested recently enough to still be considered in |
| * the availability window. |
| */ |
| public static final int SOURCE_TYPE_NETWORK = 0; |
| |
| /** |
| * The capabilities of this contact were retrieved from the cached information in the Enhanced |
| * Address Book. |
| */ |
| public static final int SOURCE_TYPE_CACHED = 1; |
| |
| /** @hide */ |
| @Retention(RetentionPolicy.SOURCE) |
| @IntDef(prefix = "SOURCE_TYPE_", value = { |
| SOURCE_TYPE_NETWORK, |
| SOURCE_TYPE_CACHED |
| }) |
| 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 = 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 = 2; |
| |
| /** |
| * Capability information for the requested contact was found successfully. |
| */ |
| 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 |
| }) |
| public @interface RequestResult {} |
| |
| /** |
| * Builder to help construct {@link RcsContactUceCapability} instances when capabilities were |
| * queried through SIP OPTIONS. |
| */ |
| public static final class OptionsBuilder { |
| |
| private final RcsContactUceCapability mCapabilities; |
| |
| /** |
| * Create the Builder, which can be used to set UCE capabilities as well as custom |
| * capability extensions. |
| * @param contact The contact URI that the capabilities are attached to. |
| */ |
| public OptionsBuilder(@NonNull Uri contact) { |
| mCapabilities = new RcsContactUceCapability(contact, CAPABILITY_MECHANISM_OPTIONS, |
| SOURCE_TYPE_NETWORK); |
| } |
| |
| /** |
| * Create the Builder, which can be used to set UCE capabilities as well as custom |
| * capability extensions. |
| * @param contact The contact URI that the capabilities are attached to. |
| * @param sourceType The type where the capabilities of this contact were retrieved from. |
| * @hide |
| */ |
| public OptionsBuilder(@NonNull Uri contact, @SourceType int sourceType) { |
| mCapabilities = new RcsContactUceCapability(contact, CAPABILITY_MECHANISM_OPTIONS, |
| sourceType); |
| } |
| |
| /** |
| * Set the result of the capabilities request. |
| * @param requestResult the request result |
| * @return this OptionBuilder |
| */ |
| public @NonNull OptionsBuilder setRequestResult(@RequestResult int requestResult) { |
| mCapabilities.mRequestResult = requestResult; |
| return this; |
| } |
| |
| /** |
| * Add the feature tag into the capabilities instance. |
| * @param tag the supported feature tag |
| * @return this OptionBuilder |
| */ |
| public @NonNull OptionsBuilder addFeatureTag(@NonNull String tag) { |
| mCapabilities.mFeatureTags.add(tag); |
| return this; |
| } |
| |
| /** |
| * Add the list of feature tag into the capabilities instance. |
| * @param tags the list of the supported feature tags |
| * @return this OptionBuilder |
| */ |
| public @NonNull OptionsBuilder addFeatureTags(@NonNull Set<String> tags) { |
| mCapabilities.mFeatureTags.addAll(tags); |
| return this; |
| } |
| |
| /** |
| * @return the constructed instance. |
| */ |
| public @NonNull RcsContactUceCapability build() { |
| return mCapabilities; |
| } |
| } |
| |
| /** |
| * Builder to help construct {@link RcsContactUceCapability} instances when capabilities were |
| * queried through a presence server. |
| */ |
| public static final class PresenceBuilder { |
| |
| private final RcsContactUceCapability mCapabilities; |
| |
| /** |
| * Create the builder, which can be used to set UCE capabilities as well as custom |
| * capability extensions. |
| * @param contact The contact URI that the capabilities are attached to. |
| * @param sourceType The type where the capabilities of this contact were retrieved from. |
| * @param requestResult the request result |
| */ |
| public PresenceBuilder(@NonNull Uri contact, @SourceType int sourceType, |
| @RequestResult int requestResult) { |
| mCapabilities = new RcsContactUceCapability(contact, CAPABILITY_MECHANISM_PRESENCE, |
| sourceType); |
| mCapabilities.mRequestResult = requestResult; |
| } |
| |
| /** |
| * Add the {@link RcsContactPresenceTuple} into the capabilities instance. |
| * @param tuple The {@link RcsContactPresenceTuple} to be added into. |
| * @return this PresenceBuilder |
| */ |
| public @NonNull PresenceBuilder addCapabilityTuple(@NonNull RcsContactPresenceTuple tuple) { |
| mCapabilities.mPresenceTuples.add(tuple); |
| return this; |
| } |
| |
| /** |
| * Add the list of {@link RcsContactPresenceTuple} into the capabilities instance. |
| * @param tuples The list of the {@link RcsContactPresenceTuple} to be added into. |
| * @return this PresenceBuilder |
| */ |
| public @NonNull PresenceBuilder addCapabilityTuples( |
| @NonNull List<RcsContactPresenceTuple> tuples) { |
| mCapabilities.mPresenceTuples.addAll(tuples); |
| return this; |
| } |
| |
| /** |
| * Set the entity URI related to the contact whose capabilities were requested. |
| * @param entityUri the 'pres' URL of the PRESENTITY publishing presence document. |
| */ |
| public @NonNull PresenceBuilder setEntityUri(@NonNull Uri entityUri) { |
| mCapabilities.mEntityUri = entityUri; |
| return this; |
| } |
| |
| /** |
| * @return the RcsContactUceCapability instance. |
| */ |
| public @NonNull RcsContactUceCapability build() { |
| return mCapabilities; |
| } |
| } |
| |
| private final Uri mContactUri; |
| private @SourceType int mSourceType; |
| private @CapabilityMechanism int mCapabilityMechanism; |
| private @RequestResult int mRequestResult; |
| private Uri mEntityUri; |
| |
| private final Set<String> mFeatureTags = new HashSet<>(); |
| private final List<RcsContactPresenceTuple> mPresenceTuples = new ArrayList<>(); |
| |
| private RcsContactUceCapability(@NonNull Uri contactUri, @CapabilityMechanism int mechanism, |
| @SourceType int sourceType) { |
| mContactUri = contactUri; |
| mCapabilityMechanism = mechanism; |
| mSourceType = sourceType; |
| } |
| |
| private RcsContactUceCapability(Parcel in) { |
| mContactUri = in.readParcelable(Uri.class.getClassLoader(), android.net.Uri.class); |
| mCapabilityMechanism = in.readInt(); |
| mSourceType = in.readInt(); |
| mRequestResult = in.readInt(); |
| mEntityUri = in.readParcelable(Uri.class.getClassLoader(), android.net.Uri.class); |
| List<String> featureTagList = new ArrayList<>(); |
| in.readStringList(featureTagList); |
| mFeatureTags.addAll(featureTagList); |
| in.readParcelableList(mPresenceTuples, RcsContactPresenceTuple.class.getClassLoader(), android.telephony.ims.RcsContactPresenceTuple.class); |
| } |
| |
| @Override |
| public void writeToParcel(@NonNull Parcel out, int flags) { |
| out.writeParcelable(mContactUri, flags); |
| out.writeInt(mCapabilityMechanism); |
| out.writeInt(mSourceType); |
| out.writeInt(mRequestResult); |
| out.writeParcelable(mEntityUri, flags); |
| out.writeStringList(new ArrayList<>(mFeatureTags)); |
| out.writeParcelableList(mPresenceTuples, flags); |
| } |
| |
| @Override |
| public int describeContents() { |
| return 0; |
| } |
| |
| public static final @NonNull Creator<RcsContactUceCapability> CREATOR = |
| new Creator<RcsContactUceCapability>() { |
| @Override |
| public RcsContactUceCapability createFromParcel(Parcel in) { |
| return new RcsContactUceCapability(in); |
| } |
| |
| @Override |
| public RcsContactUceCapability[] newArray(int size) { |
| return new RcsContactUceCapability[size]; |
| } |
| }; |
| |
| /** |
| * @return The mechanism used to get the capabilities. |
| */ |
| public @CapabilityMechanism int getCapabilityMechanism() { |
| return mCapabilityMechanism; |
| } |
| |
| /** |
| * @return The feature tags present in the OPTIONS response from the network. |
| * <p> |
| * Note: this is only populated if {@link #getCapabilityMechanism} is |
| * {@link RcsContactUceCapability#CAPABILITY_MECHANISM_OPTIONS} |
| */ |
| public @NonNull Set<String> getFeatureTags() { |
| if (mCapabilityMechanism != CAPABILITY_MECHANISM_OPTIONS) { |
| return Collections.emptySet(); |
| } |
| return Collections.unmodifiableSet(mFeatureTags); |
| } |
| |
| /** |
| * @return The tuple elements associated with the presence element portion of the PIDF document |
| * contained in the NOTIFY response from the network. |
| * <p> |
| * Note: this is only populated if {@link #getCapabilityMechanism} is |
| * {@link RcsContactUceCapability#CAPABILITY_MECHANISM_PRESENCE} |
| */ |
| public @NonNull List<RcsContactPresenceTuple> getCapabilityTuples() { |
| if (mCapabilityMechanism != CAPABILITY_MECHANISM_PRESENCE) { |
| return Collections.emptyList(); |
| } |
| return Collections.unmodifiableList(mPresenceTuples); |
| } |
| |
| /** |
| * 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 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 getCapabilityTuple(@NonNull String serviceId) { |
| if (mCapabilityMechanism != CAPABILITY_MECHANISM_PRESENCE) { |
| return null; |
| } |
| for (RcsContactPresenceTuple tuple : mPresenceTuples) { |
| if (tuple.getServiceId() != null && tuple.getServiceId().equals(serviceId)) { |
| return tuple; |
| } |
| } |
| return null; |
| } |
| |
| /** |
| * @return the source of the data that was used to populate the capabilities of the requested |
| * contact. |
| */ |
| public @SourceType int getSourceType() { |
| return mSourceType; |
| } |
| |
| /** |
| * @return the result of querying the capabilities of the requested contact. |
| */ |
| public @RequestResult int getRequestResult() { |
| return mRequestResult; |
| } |
| |
| /** |
| * Retrieve the contact URI requested by the applications. |
| * @return the URI representing the contact associated with the capabilities. |
| */ |
| public @NonNull Uri getContactUri() { |
| return mContactUri; |
| } |
| |
| /** |
| * Retrieve the entity URI of the contact whose presence information is being requested for. |
| * @return the URI representing the 'pres' URL of the PRESENTITY publishing presence document |
| * or {@code null} if the entity uri does not exist in the presence document. |
| */ |
| public @Nullable Uri getEntityUri() { |
| return mEntityUri; |
| } |
| |
| @Override |
| public String toString() { |
| StringBuilder builder = new StringBuilder("RcsContactUceCapability"); |
| if (mCapabilityMechanism == CAPABILITY_MECHANISM_PRESENCE) { |
| builder.append("(presence) {"); |
| } else if (mCapabilityMechanism == CAPABILITY_MECHANISM_OPTIONS) { |
| builder.append("(options) {"); |
| } else { |
| builder.append("(?) {"); |
| } |
| if (Build.IS_ENG) { |
| builder.append("uri="); |
| builder.append(mContactUri); |
| } else { |
| builder.append("uri (isNull)="); |
| builder.append(mContactUri != null ? "XXX" : "null"); |
| } |
| builder.append(", sourceType="); |
| builder.append(mSourceType); |
| builder.append(", requestResult="); |
| builder.append(mRequestResult); |
| if (Build.IS_ENG) { |
| builder.append("entity uri="); |
| builder.append(mEntityUri != null ? mEntityUri : "null"); |
| } else { |
| builder.append("entity uri (isNull)="); |
| builder.append(mEntityUri != null ? "XXX" : "null"); |
| } |
| |
| if (mCapabilityMechanism == CAPABILITY_MECHANISM_PRESENCE) { |
| builder.append(", presenceTuples={"); |
| builder.append(mPresenceTuples); |
| builder.append("}"); |
| } else if (mCapabilityMechanism == CAPABILITY_MECHANISM_OPTIONS) { |
| builder.append(", featureTags={"); |
| builder.append(mFeatureTags); |
| builder.append("}"); |
| } |
| |
| return builder.toString(); |
| } |
| } |