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