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