1 /*
2  * Copyright (C) 2018 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 package android.telephony.ims;
17 
18 import android.annotation.IntDef;
19 import android.annotation.NonNull;
20 import android.annotation.Nullable;
21 import android.annotation.SystemApi;
22 import android.os.Parcel;
23 import android.os.Parcelable;
24 import android.telephony.Rlog;
25 
26 import java.lang.annotation.Retention;
27 import java.lang.annotation.RetentionPolicy;
28 import java.util.ArrayList;
29 import java.util.Arrays;
30 import java.util.List;
31 
32 /**
33  * Provides STK Call Control Supplementary Service information.
34  *
35  * {@hide}
36  */
37 @SystemApi
38 public final class ImsSsData implements Parcelable {
39 
40     private static final String TAG = ImsSsData.class.getCanonicalName();
41 
42     // Supplementary Service Type
43     // Call Forwarding
44     public static final int SS_CFU = 0;
45     public static final int SS_CF_BUSY = 1;
46     public static final int SS_CF_NO_REPLY = 2;
47     public static final int SS_CF_NOT_REACHABLE = 3;
48     public static final int SS_CF_ALL = 4;
49     public static final int SS_CF_ALL_CONDITIONAL = 5;
50     public static final int SS_CFUT = 6;
51     // Called Line Presentation
52     public static final int SS_CLIP = 7;
53     public static final int SS_CLIR = 8;
54     public static final int SS_COLP = 9;
55     public static final int SS_COLR = 10;
56     // Calling Name Presentation
57     public static final int SS_CNAP = 11;
58     // Call Waiting
59     public static final int SS_WAIT = 12;
60     // Call Barring
61     public static final int SS_BAOC = 13;
62     public static final int SS_BAOIC = 14;
63     public static final int SS_BAOIC_EXC_HOME = 15;
64     public static final int SS_BAIC = 16;
65     public static final int SS_BAIC_ROAMING = 17;
66     public static final int SS_ALL_BARRING = 18;
67     public static final int SS_OUTGOING_BARRING = 19;
68     public static final int SS_INCOMING_BARRING = 20;
69     public static final int SS_INCOMING_BARRING_DN = 21;
70     public static final int SS_INCOMING_BARRING_ANONYMOUS = 22;
71 
72 
73     /**@hide*/
74     @IntDef(flag = true, prefix = {"SS_"}, value = {
75             SS_ACTIVATION,
76             SS_DEACTIVATION,
77             SS_INTERROGATION,
78             SS_REGISTRATION,
79             SS_ERASURE})
80     @Retention(RetentionPolicy.SOURCE)
81     public @interface RequestType{}
82 
83     //Supplementary Service Request Types
84     public static final int SS_ACTIVATION = 0;
85     public static final int SS_DEACTIVATION = 1;
86     public static final int SS_INTERROGATION = 2;
87     public static final int SS_REGISTRATION = 3;
88     public static final int SS_ERASURE = 4;
89 
90     /**@hide*/
91     @IntDef(flag = true, prefix = {"SS_"}, value = {
92             SS_ALL_TELE_AND_BEARER_SERVICES,
93             SS_ALL_TELESEVICES,
94             SS_TELEPHONY,
95             SS_ALL_DATA_TELESERVICES,
96             SS_SMS_SERVICES,
97             SS_ALL_TELESERVICES_EXCEPT_SMS})
98     @Retention(RetentionPolicy.SOURCE)
99     public @interface TeleserviceType{}
100 
101     // Supplementary Service Teleservice Type
102     public static final int SS_ALL_TELE_AND_BEARER_SERVICES = 0;
103     public static final int SS_ALL_TELESEVICES = 1;
104     public static final int SS_TELEPHONY = 2;
105     public static final int SS_ALL_DATA_TELESERVICES = 3;
106     public static final int SS_SMS_SERVICES = 4;
107     public static final int SS_ALL_TELESERVICES_EXCEPT_SMS = 5;
108 
109     /**
110      * No call forwarding service class defined.
111      *
112      * See TS 27.007 7.11 (+CCFC) and 7.4 (CLCK)
113      */
114     public static final int SERVICE_CLASS_NONE = 0;
115 
116     /**
117      * Service class flag for voice telephony.
118      *
119      * See TS 27.007 7.11 (+CCFC) and 7.4 (CLCK)
120      */
121     public static final int SERVICE_CLASS_VOICE = 1;
122 
123     /**
124      * Service class flag for all data bearers (including
125      * {@link #SERVICE_CLASS_DATA_CIRCUIT_SYNC,
126      * {@link #SERVICE_CLASS_DATA_CIRCUIT_ASYNC}, {@link #SERVICE_CLASS_PACKET_ACCESS},
127      * {@link #SERVICE_CLASS_PAD}}) if supported by the carrier.
128      *
129      * See TS 27.007 7.11 (+CCFC) and 7.4 (CLCK)
130      */
131     public static final int SERVICE_CLASS_DATA = (1 << 1);
132     /**
133      * Service class flag for fax services.
134      *
135      * See TS 27.007 7.11 (+CCFC) and 7.4 (CLCK)
136      */
137     public static final int SERVICE_CLASS_FAX = (1 << 2);
138     /**
139      * Service class flag for SMS services.
140      *
141      * See TS 27.007 7.11 (+CCFC) and 7.4 (CLCK)
142      */
143     public static final int SERVICE_CLASS_SMS = (1 << 3);
144     /**
145      * Service class flag for the synchronous bearer service.
146      *
147      * See TS 27.007 7.11 (+CCFC) and 7.4 (CLCK)
148      */
149     public static final int SERVICE_CLASS_DATA_CIRCUIT_SYNC = (1 << 4);
150 
151     /**
152      * Service class flag for the asynchronous bearer service.
153      *
154      * See TS 27.007 7.11 (+CCFC) and 7.4 (CLCK)
155      */
156     public static final int SERVICE_CLASS_DATA_CIRCUIT_ASYNC = (1 << 5);
157 
158     /**
159      * Service class flag for the packet access bearer service.
160      *
161      * See TS 27.007 7.11 (+CCFC) and 7.4 (CLCK)
162      */
163     public static final int SERVICE_CLASS_DATA_PACKET_ACCESS = (1 << 6);
164 
165     /**
166      * Service class flag for the Packet Assembly/Disassembly bearer service.
167      *
168      * See TS 27.007 7.11 (+CCFC) and 7.4 (CLCK)
169      */
170     public static final int SERVICE_CLASS_DATA_PAD = (1 << 7);
171 
172     /**@hide*/
173     @IntDef(flag = true, prefix = {"SERVICE_CLASS_"}, value = {
174             SERVICE_CLASS_NONE,
175             SERVICE_CLASS_VOICE,
176             SERVICE_CLASS_DATA,
177             SERVICE_CLASS_FAX,
178             SERVICE_CLASS_SMS,
179             SERVICE_CLASS_DATA_CIRCUIT_SYNC,
180             SERVICE_CLASS_DATA_CIRCUIT_ASYNC,
181             SERVICE_CLASS_DATA_PACKET_ACCESS,
182             SERVICE_CLASS_DATA_PAD})
183     @Retention(RetentionPolicy.SOURCE)
184     public @interface ServiceClassFlags{}
185 
186     /**
187      * Result code used if the operation was successful. See {@link #getResult()}.
188      */
189     public static final int RESULT_SUCCESS = 0;
190 
191     /** @hide */
192     @IntDef(flag = true, prefix = { "SS_" }, value = {
193             SS_CFU,
194             SS_CF_BUSY,
195             SS_CF_NO_REPLY,
196             SS_CF_NOT_REACHABLE,
197             SS_CF_ALL,
198             SS_CF_ALL_CONDITIONAL,
199             SS_CFUT,
200             SS_CLIP,
201             SS_CLIR,
202             SS_COLP,
203             SS_COLR,
204             SS_CNAP,
205             SS_WAIT,
206             SS_BAOC,
207             SS_BAOIC,
208             SS_BAOIC_EXC_HOME,
209             SS_BAIC,
210             SS_BAIC_ROAMING,
211             SS_ALL_BARRING,
212             SS_OUTGOING_BARRING,
213             SS_INCOMING_BARRING,
214             SS_INCOMING_BARRING_DN,
215             SS_INCOMING_BARRING_ANONYMOUS
216     })
217     @Retention(RetentionPolicy.SOURCE)
218     public @interface ServiceType{}
219 
220     /**
221      * The Service type of this Supplementary service.
222      * @hide
223      */
224     public final @ServiceType int serviceType;
225 
226     /**
227      * Supplementary Service request Type:
228      *     {@link #SS_ACTIVATION),
229      *     {@link #SS_DEACTIVATION},
230      *     {@link #SS_INTERROGATION},
231      *     {@link #SS_REGISTRATION},
232      *     {@link #SS_ERASURE}
233      * @hide
234      */
235     public final @RequestType int requestType;
236 
237     /**
238      * Supplementary Service teleservice type:
239      *     {@link #SS_ALL_TELE_AND_BEARER_SERVICES},
240      *     {@link #SS_ALL_TELESEVICES},
241      *     {@link #SS_TELEPHONY},
242      *     {@link #SS_ALL_DATA_TELESERVICES},
243      *     {@link #SS_SMS_SERVICES},
244      *     {@link #SS_ALL_TELESERVICES_EXCEPT_SMS}
245      *
246      * @hide
247      */
248     public final @TeleserviceType int teleserviceType;
249 
250     /**
251      * Supplementary Service service class.
252      *
253      * @hide
254      */
255     public final @ServiceClassFlags int serviceClass;
256 
257     /**
258      * Result of Supplementary Service operation. Valid values are:
259      *     {@link #RESULT_SUCCESS} if the result is success, or
260      *     ImsReasonInfo code if the result is a failure.
261      *
262      * @hide
263      */
264     public final int result;
265 
266     private int[] mSsInfo;
267     private List<ImsCallForwardInfo> mCfInfo;
268     private List<ImsSsInfo> mImsSsInfo;
269 
270     /**
271      * Builder for optional ImsSsData parameters.
272      */
273     public static final class Builder {
274         private ImsSsData mImsSsData;
275 
276         /**
277          * Generate IMS Supplementary Service information.
278          * @param serviceType The Supplementary Service type.
279          * @param requestType Supplementary Service request Type:
280          *     {@link #SS_ACTIVATION},
281          *     {@link #SS_DEACTIVATION},
282          *     {@link #SS_INTERROGATION},
283          *     {@link #SS_REGISTRATION},
284          *     {@link #SS_ERASURE}
285          * @param teleserviceType Supplementary Service teleservice type:
286          *     {@link #SS_ALL_TELE_AND_BEARER_SERVICES},
287          *     {@link #SS_ALL_TELESEVICES},
288          *     {@link #SS_TELEPHONY},
289          *     {@link #SS_ALL_DATA_TELESERVICES},
290          *     {@link #SS_SMS_SERVICES},
291          *     {@link #SS_ALL_TELESERVICES_EXCEPT_SMS}
292          * @param serviceClass Supplementary Service service class. See See 27.007 +CCFC or +CLCK.
293          * @param result Result of Supplementary Service operation. Valid values are 0 if the result
294          *               is success, or {@link ImsReasonInfo} code if the result is a failure.
295          * @return this Builder instance for further constructing.
296          * @see #build()
297          */
Builder(@erviceType int serviceType, int requestType, int teleserviceType, @ServiceClassFlags int serviceClass, int result)298         public Builder(@ServiceType int serviceType, int requestType, int teleserviceType,
299                 @ServiceClassFlags int serviceClass, int result) {
300             mImsSsData = new ImsSsData(serviceType, requestType, teleserviceType, serviceClass,
301                     result);
302         }
303 
304         /**
305          * Set the array of {@link ImsSsInfo}s that are associated with this supplementary service
306          * data.
307          */
setSuppServiceInfo(@onNull List<ImsSsInfo> imsSsInfos)308         public @NonNull Builder setSuppServiceInfo(@NonNull List<ImsSsInfo> imsSsInfos) {
309             mImsSsData.mImsSsInfo = imsSsInfos;
310             return this;
311         }
312 
313         /**
314          * Set the array of {@link ImsCallForwardInfo}s that are associated with this supplementary
315          * service data.
316          */
setCallForwardingInfo( @onNull List<ImsCallForwardInfo> imsCallForwardInfos)317         public @NonNull Builder setCallForwardingInfo(
318                 @NonNull List<ImsCallForwardInfo> imsCallForwardInfos) {
319             mImsSsData.mCfInfo = imsCallForwardInfos;
320             return this;
321         }
322 
323         /**
324          * @return an {@link ImsSsData} containing optional parameters.
325          */
build()326         public @NonNull ImsSsData build() {
327             return mImsSsData;
328         }
329     }
330 
331     /**
332      * Generate IMS Supplementary Service information.
333      * @param serviceType The Supplementary Service type.
334      * @param requestType Supplementary Service request Type. Valid values are:
335      *     {@link #SS_ACTIVATION},
336      *     {@link #SS_DEACTIVATION},
337      *     {@link #SS_INTERROGATION},
338      *     {@link #SS_REGISTRATION},
339      *     {@link #SS_ERASURE}
340      * @param teleserviceType Supplementary Service teleservice type:
341      *     {@link #SS_ALL_TELE_AND_BEARER_SERVICES},
342      *     {@link #SS_ALL_TELESEVICES},
343      *     {@link #SS_TELEPHONY},
344      *     {@link #SS_ALL_DATA_TELESERVICES},
345      *     {@link #SS_SMS_SERVICES},
346      *     {@link #SS_ALL_TELESERVICES_EXCEPT_SMS}
347      * @param serviceClass Supplementary Service service class. See See 27.007 +CCFC or +CLCK.
348      * @param result Result of Supplementary Service operation. Valid values are 0 if the result is
349      *               success, or ImsReasonInfo code if the result is a failure.
350      */
ImsSsData(@erviceType int serviceType, int requestType, int teleserviceType, @ServiceClassFlags int serviceClass, int result)351     public ImsSsData(@ServiceType int serviceType, int requestType, int teleserviceType,
352             @ServiceClassFlags int serviceClass, int result) {
353         this.serviceType = serviceType;
354         this.requestType = requestType;
355         this.teleserviceType = teleserviceType;
356         this.serviceClass = serviceClass;
357         this.result = result;
358     }
359 
ImsSsData(Parcel in)360     private ImsSsData(Parcel in) {
361         serviceType = in.readInt();
362         requestType = in.readInt();
363         teleserviceType = in.readInt();
364         serviceClass = in.readInt();
365         result = in.readInt();
366         mSsInfo = in.createIntArray();
367         mCfInfo = in.readParcelableList(new ArrayList<>(), this.getClass().getClassLoader());
368         mImsSsInfo = in.readParcelableList(new ArrayList<>(), this.getClass().getClassLoader());
369     }
370 
371     public static final @android.annotation.NonNull Creator<ImsSsData> CREATOR = new Creator<ImsSsData>() {
372         @Override
373         public ImsSsData createFromParcel(Parcel in) {
374             return new ImsSsData(in);
375         }
376 
377         @Override
378         public ImsSsData[] newArray(int size) {
379             return new ImsSsData[size];
380         }
381     };
382 
383     @Override
writeToParcel(Parcel out, int flags)384     public void writeToParcel(Parcel out, int flags) {
385         out.writeInt(getServiceType());
386         out.writeInt(getRequestType());
387         out.writeInt(getTeleserviceType());
388         out.writeInt(getServiceClass());
389         out.writeInt(getResult());
390         out.writeIntArray(mSsInfo);
391         out.writeParcelableList(mCfInfo, 0);
392         out.writeParcelableList(mImsSsInfo, 0);
393     }
394 
395     @Override
describeContents()396     public int describeContents() {
397         return 0;
398     }
399 
400     /**
401      * Old method, kept for compatibility. See {@link #isTypeCf()}
402      * @hide
403      */
isTypeCF()404     public boolean isTypeCF() {
405         return (getServiceType() == SS_CFU || getServiceType() == SS_CF_BUSY
406                 || getServiceType() == SS_CF_NO_REPLY || getServiceType() == SS_CF_NOT_REACHABLE
407                 || getServiceType() == SS_CF_ALL || getServiceType() == SS_CF_ALL_CONDITIONAL);
408     }
409 
isTypeCf()410     public boolean isTypeCf() {
411         return isTypeCF();
412     }
413 
isTypeUnConditional()414     public boolean isTypeUnConditional() {
415         return (getServiceType() == SS_CFU || getServiceType() == SS_CF_ALL);
416     }
417 
418     /**
419      * Old method, kept for compatibility. See {@link #isTypeCf()}
420      * @hide
421      */
isTypeCW()422     public boolean isTypeCW() {
423         return (getServiceType() == SS_WAIT);
424     }
425 
isTypeCw()426     public boolean isTypeCw() {
427         return isTypeCW();
428     }
429 
isTypeClip()430     public boolean isTypeClip() {
431         return (getServiceType() == SS_CLIP);
432     }
433 
isTypeColr()434     public boolean isTypeColr() {
435         return (getServiceType() == SS_COLR);
436     }
437 
isTypeColp()438     public boolean isTypeColp() {
439         return (getServiceType() == SS_COLP);
440     }
441 
isTypeClir()442     public boolean isTypeClir() {
443         return (getServiceType() == SS_CLIR);
444     }
445 
isTypeIcb()446     public boolean isTypeIcb() {
447         return (getServiceType() == SS_INCOMING_BARRING_DN
448                 || getServiceType() == SS_INCOMING_BARRING_ANONYMOUS);
449     }
450 
isTypeBarring()451     public boolean isTypeBarring() {
452         return (getServiceType() == SS_BAOC || getServiceType() == SS_BAOIC
453                 || getServiceType() == SS_BAOIC_EXC_HOME || getServiceType() == SS_BAIC
454                 || getServiceType() == SS_BAIC_ROAMING || getServiceType() == SS_ALL_BARRING
455                 || getServiceType() == SS_OUTGOING_BARRING
456                 || getServiceType() == SS_INCOMING_BARRING);
457     }
458 
isTypeInterrogation()459     public boolean isTypeInterrogation() {
460         return (getRequestType() == SS_INTERROGATION);
461     }
462 
463     /**
464      * Supplementary Service request Type.
465      */
getRequestType()466     public @RequestType int getRequestType() {
467         return requestType;
468     }
469 
470     /**
471      * The Service type of this Supplementary service.
472      */
getServiceType()473     public @ServiceType int getServiceType() {
474         return serviceType;
475     }
476 
477     /**
478      * Supplementary Service teleservice type.
479      */
getTeleserviceType()480     public @TeleserviceType int getTeleserviceType() {
481         return teleserviceType;
482     }
483 
484     /**
485      * Supplementary Service service class.
486      */
getServiceClass()487     public @ServiceClassFlags int getServiceClass() {
488         return serviceClass;
489     }
490 
491     /**
492      * Result of Supplementary Service operation. Valid values are:
493      *     {@link #RESULT_SUCCESS} if the result is success, or
494      *     {@link ImsReasonInfo.UtReason} code if the result is a failure.
495      */
getResult()496     public @ImsReasonInfo.UtReason int getResult() {
497         return result;
498     }
499 
500     /** @hide */
setSuppServiceInfo(int[] ssInfo)501     public void setSuppServiceInfo(int[] ssInfo) {
502         mSsInfo = ssInfo;
503     }
504 
505     /** @hide */
setImsSpecificSuppServiceInfo(ImsSsInfo[] imsSsInfo)506     public void setImsSpecificSuppServiceInfo(ImsSsInfo[] imsSsInfo) {
507         mImsSsInfo = Arrays.asList(imsSsInfo);
508     }
509 
510     /** @hide */
setCallForwardingInfo(ImsCallForwardInfo[] cfInfo)511     public void setCallForwardingInfo(ImsCallForwardInfo[] cfInfo) {
512         mCfInfo = Arrays.asList(cfInfo);
513     }
514 
515     /**
516      * This is a compatibility function to transform the public API to a form that can be processed
517      * by telephony.
518      *
519      * @hide
520      */
521     //TODO: Refactor Telephony to use well defined classes instead of an int[] to process SS.
getSuppServiceInfoCompat()522     public int[] getSuppServiceInfoCompat() {
523         if (mSsInfo != null) {
524             // Something has set the ssInfo using hidden APIs, so for compatibility just return that
525             // structure directly.
526             return mSsInfo;
527         }
528 
529 
530         int[] result = new int[2];
531         if (mImsSsInfo == null || mImsSsInfo.size() == 0) {
532             Rlog.e(TAG, "getSuppServiceInfoCompat: Could not parse mImsSsInfo, returning empty "
533                     + "int[]");
534             return result;
535         }
536 
537         // Convert ImsSsInfo into a form that telephony can read (as per 3GPP 27.007)
538         // CLIR (section 7.7)
539         if (isTypeClir()) {
540             // Assume there will only be one ImsSsInfo.
541             // contains {"n","m"} parameters
542             result[0] = mImsSsInfo.get(0).getClirOutgoingState();
543             result[1] = mImsSsInfo.get(0).getClirInterrogationStatus();
544             return result;
545         }
546         // COLR 7.31
547         if (isTypeColr()) {
548             result[0] = mImsSsInfo.get(0).getProvisionStatus();
549         }
550         // Facility Lock CLCK 7.4 (for call barring), CLIP 7.6, COLP 7.8, as well as any
551         // other result, just return the status for the "n" parameter and provisioning status for
552         // "m" as the default.
553         result[0] = mImsSsInfo.get(0).getStatus();
554         result[1] = mImsSsInfo.get(0).getProvisionStatus();
555         return result;
556     }
557 
558     /**
559      * @return an array of {@link ImsSsInfo}s associated with this supplementary service data.
560      */
getSuppServiceInfo()561     public @NonNull List<ImsSsInfo> getSuppServiceInfo() {
562         return mImsSsInfo;
563     }
564 
565     /**
566      * @return an array of {@link ImsCallForwardInfo}s associated with this supplementary service
567      * data.
568      **/
getCallForwardInfo()569     public @Nullable List<ImsCallForwardInfo> getCallForwardInfo() {
570         return mCfInfo;
571     }
572 
toString()573     public String toString() {
574         return "[ImsSsData] " + "ServiceType: " + getServiceType()
575             + " RequestType: " + getRequestType()
576             + " TeleserviceType: " + getTeleserviceType()
577             + " ServiceClass: " + getServiceClass()
578             + " Result: " + getResult();
579     }
580 }
581