1 /* 2 * Copyright (C) 2021 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package android.telephony.ims; 18 19 import android.annotation.IntDef; 20 import android.annotation.NonNull; 21 import android.annotation.Nullable; 22 import android.annotation.SystemApi; 23 import android.os.Parcel; 24 import android.os.Parcelable; 25 import android.telephony.AccessNetworkConstants; 26 import android.telephony.ims.stub.ImsRegistrationImplBase; 27 import android.util.ArraySet; 28 29 import java.lang.annotation.Retention; 30 import java.lang.annotation.RetentionPolicy; 31 import java.util.ArrayList; 32 import java.util.Collections; 33 import java.util.Objects; 34 import java.util.Set; 35 36 /** 37 * Contains the attributes associated with the current IMS registration. 38 */ 39 public final class ImsRegistrationAttributes implements Parcelable { 40 41 /** 42 * Attribute to specify if an EPDG tunnel is setup over the cellular internet APN. 43 * <p> 44 * If IMS is registered through an EPDG tunnel is setup over the cellular internet APN then this 45 * bit will be set. If IMS is registered through the IMS APN, then this bit will not be set. 46 * 47 */ 48 public static final int ATTR_EPDG_OVER_CELL_INTERNET = 1 << 0; 49 50 /** @hide */ 51 // Defines the underlying radio technology type that we have registered for IMS over. 52 @IntDef(prefix = "ATTR_", 53 value = { 54 ATTR_EPDG_OVER_CELL_INTERNET, 55 }, 56 flag = true) 57 @Retention(RetentionPolicy.SOURCE) 58 public @interface ImsAttributeFlag {} 59 60 /** 61 * Builder for creating {@link ImsRegistrationAttributes} instances. 62 * @hide 63 */ 64 @SystemApi 65 public static final class Builder { 66 private final int mRegistrationTech; 67 private Set<String> mFeatureTags = Collections.emptySet(); 68 69 /** 70 * Build a new instance of {@link ImsRegistrationAttributes}. 71 * 72 * @param registrationTech The Radio Access Technology that IMS is registered on. 73 */ Builder(@msRegistrationImplBase.ImsRegistrationTech int registrationTech)74 public Builder(@ImsRegistrationImplBase.ImsRegistrationTech int registrationTech) { 75 mRegistrationTech = registrationTech; 76 } 77 78 /** 79 * Optional IMS feature tags included in this IMS registration. 80 * @param tags A set of Strings containing the MMTEL and RCS feature tags associated with 81 * the IMS registration. This information is used for services such as the UCE 82 * service to ascertain the complete IMS registration state to ensure the SIP 83 * PUBLISH is accurate. The format of the set of feature tags must be one feature 84 * tag key and value per entry. Each feature tag will contain the feature tag name 85 * and string value (if applicable), even if they have the same feature tag name. 86 * For example, 87 * {@code +g.3gpp.icsi-ref="urn%3Aurn-7%3A3gpp-service.ims.icsi.oma.cpm.msg, 88 * urn%3Aurn-7%3A3gpp-service.ims.icsi.oma.cpm.session", +g.gsma.callcomposer} must 89 * be split into three feature tag entries: 90 * {@code {+g.3gpp.icsi-ref="urn%3Aurn-7%3A3gpp-service.ims.icsi.oma.cpm.msg", 91 * +g.3gpp.icsi-ref="urn%3Aurn-7%3A3gpp-service.ims.icsi.oma.cpm.session", 92 * +g.gsma.callcomposer}}. 93 */ setFeatureTags(@onNull Set<String> tags)94 public @NonNull Builder setFeatureTags(@NonNull Set<String> tags) { 95 if (tags == null) { 96 throw new IllegalArgumentException("feature tag set must not be null"); 97 } 98 mFeatureTags = new ArraySet<>(tags); 99 return this; 100 } 101 102 /** 103 * @return A new instance created from this builder. 104 */ build()105 public @NonNull ImsRegistrationAttributes build() { 106 return new ImsRegistrationAttributes(mRegistrationTech, 107 RegistrationManager.getAccessType(mRegistrationTech), 108 getAttributeFlags(mRegistrationTech), 109 mFeatureTags); 110 } 111 112 /** 113 * @return attribute flags from the registration technology. 114 */ getAttributeFlags(int imsRadioTech)115 private static int getAttributeFlags(int imsRadioTech) { 116 int attributes = 0; 117 if (imsRadioTech == ImsRegistrationImplBase.REGISTRATION_TECH_CROSS_SIM) { 118 attributes |= ATTR_EPDG_OVER_CELL_INTERNET; 119 } 120 return attributes; 121 } 122 } 123 124 private final int mRegistrationTech; 125 private final int mTransportType; 126 private final int mImsAttributeFlags; 127 private final ArrayList<String> mFeatureTags; 128 129 /** 130 * Create a new {@link ImsRegistrationAttributes} instance. 131 * 132 * @param registrationTech The technology that IMS has been registered on. 133 * @param transportType The transport type that IMS has been registered on. 134 * @param imsAttributeFlags The attributes associated with the IMS registration. 135 * @param featureTags The feature tags included in the IMS registration. 136 * @see Builder 137 * @hide 138 */ ImsRegistrationAttributes( @msRegistrationImplBase.ImsRegistrationTech int registrationTech, @AccessNetworkConstants.TransportType int transportType, @ImsAttributeFlag int imsAttributeFlags, @Nullable Set<String> featureTags)139 public ImsRegistrationAttributes( 140 @ImsRegistrationImplBase.ImsRegistrationTech int registrationTech, 141 @AccessNetworkConstants.TransportType int transportType, 142 @ImsAttributeFlag int imsAttributeFlags, 143 @Nullable Set<String> featureTags) { 144 mRegistrationTech = registrationTech; 145 mTransportType = transportType; 146 mImsAttributeFlags = imsAttributeFlags; 147 mFeatureTags = new ArrayList<>(featureTags); 148 } 149 150 /**@hide*/ ImsRegistrationAttributes(Parcel source)151 public ImsRegistrationAttributes(Parcel source) { 152 mRegistrationTech = source.readInt(); 153 mTransportType = source.readInt(); 154 mImsAttributeFlags = source.readInt(); 155 mFeatureTags = new ArrayList<>(); 156 source.readList(mFeatureTags, null /*classloader*/); 157 } 158 159 /** 160 * @return The Radio Access Technology that the IMS registration has been registered over. 161 * @hide 162 */ 163 @SystemApi getRegistrationTechnology()164 public @ImsRegistrationImplBase.ImsRegistrationTech int getRegistrationTechnology() { 165 return mRegistrationTech; 166 } 167 168 /** 169 * @return The access network transport type that IMS has been registered over. 170 */ getTransportType()171 public @AccessNetworkConstants.TransportType int getTransportType() { 172 return mTransportType; 173 } 174 175 /** 176 * @return A bit-mask containing attributes associated with the IMS registration. 177 */ getAttributeFlags()178 public @ImsAttributeFlag int getAttributeFlags() { 179 return mImsAttributeFlags; 180 } 181 182 /** 183 * Gets the Set of feature tags associated with the current IMS registration, if the IMS 184 * service supports supplying this information. 185 * <p> 186 * The format of the set of feature tags will be one feature tag key and value per entry and 187 * will potentially contain MMTEL and RCS feature tags, depending the configuration of the IMS 188 * service associated with the registration indications. Each feature tag will contain the 189 * feature tag name and string value (if applicable), even if they have the same feature tag 190 * name. For example, {@code +g.3gpp.icsi-ref="urn%3Aurn-7%3A3gpp-service.ims.icsi.oma.cpm.msg, 191 * urn%3Aurn-7%3A3gpp-service.ims.icsi.oma.cpm.session", +g.gsma.callcomposer} will be split 192 * into three feature tag entries: 193 * {@code {+g.3gpp.icsi-ref="urn%3Aurn-7%3A3gpp-service.ims.icsi.oma.cpm.msg", 194 * +g.3gpp.icsi-ref="urn%3Aurn-7%3A3gpp-service.ims.icsi.oma.cpm.session", 195 * +g.gsma.callcomposer}}. 196 * @return The Set of feature tags associated with the current IMS registration. 197 */ getFeatureTags()198 public @NonNull Set<String> getFeatureTags() { 199 if (mFeatureTags == null) { 200 return Collections.emptySet(); 201 } 202 return new ArraySet<>(mFeatureTags); 203 } 204 205 @Override describeContents()206 public int describeContents() { 207 return 0; 208 } 209 210 @Override writeToParcel(@onNull Parcel dest, int flags)211 public void writeToParcel(@NonNull Parcel dest, int flags) { 212 dest.writeInt(mRegistrationTech); 213 dest.writeInt(mTransportType); 214 dest.writeInt(mImsAttributeFlags); 215 dest.writeList(mFeatureTags); 216 } 217 218 public static final @NonNull Creator<ImsRegistrationAttributes> CREATOR = 219 new Creator<ImsRegistrationAttributes>() { 220 @Override 221 public ImsRegistrationAttributes createFromParcel(Parcel source) { 222 return new ImsRegistrationAttributes(source); 223 } 224 225 @Override 226 public ImsRegistrationAttributes[] newArray(int size) { 227 return new ImsRegistrationAttributes[size]; 228 } 229 }; 230 231 @Override equals(Object o)232 public boolean equals(Object o) { 233 if (this == o) return true; 234 if (o == null || getClass() != o.getClass()) return false; 235 ImsRegistrationAttributes that = (ImsRegistrationAttributes) o; 236 return mRegistrationTech == that.mRegistrationTech 237 && mTransportType == that.mTransportType 238 && mImsAttributeFlags == that.mImsAttributeFlags 239 && Objects.equals(mFeatureTags, that.mFeatureTags); 240 } 241 242 @Override hashCode()243 public int hashCode() { 244 return Objects.hash(mRegistrationTech, mTransportType, mImsAttributeFlags, mFeatureTags); 245 } 246 247 @Override toString()248 public String toString() { 249 return "ImsRegistrationAttributes { transportType= " + mTransportType + ", attributeFlags=" 250 + mImsAttributeFlags + ", featureTags=[" + mFeatureTags + "]}"; 251 } 252 } 253