| /* |
| * 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.annotation.TestApi; |
| import android.os.Parcel; |
| import android.os.Parcelable; |
| import com.android.telephony.Rlog; |
| |
| import java.lang.annotation.Retention; |
| import java.lang.annotation.RetentionPolicy; |
| import java.util.ArrayList; |
| import java.util.Arrays; |
| import java.util.List; |
| |
| /** |
| * Provides STK Call Control Supplementary Service information. |
| * |
| * {@hide} |
| */ |
| @SystemApi |
| @TestApi |
| public final class ImsSsData implements Parcelable { |
| |
| private static final String TAG = ImsSsData.class.getCanonicalName(); |
| |
| // Supplementary Service Type |
| // Call Forwarding |
| public static final int SS_CFU = 0; |
| public static final int SS_CF_BUSY = 1; |
| public static final int SS_CF_NO_REPLY = 2; |
| public static final int SS_CF_NOT_REACHABLE = 3; |
| public static final int SS_CF_ALL = 4; |
| public static final int SS_CF_ALL_CONDITIONAL = 5; |
| public static final int SS_CFUT = 6; |
| // Called Line Presentation |
| public static final int SS_CLIP = 7; |
| public static final int SS_CLIR = 8; |
| public static final int SS_COLP = 9; |
| public static final int SS_COLR = 10; |
| // Calling Name Presentation |
| public static final int SS_CNAP = 11; |
| // Call Waiting |
| public static final int SS_WAIT = 12; |
| // Call Barring |
| public static final int SS_BAOC = 13; |
| public static final int SS_BAOIC = 14; |
| public static final int SS_BAOIC_EXC_HOME = 15; |
| public static final int SS_BAIC = 16; |
| public static final int SS_BAIC_ROAMING = 17; |
| public static final int SS_ALL_BARRING = 18; |
| public static final int SS_OUTGOING_BARRING = 19; |
| public static final int SS_INCOMING_BARRING = 20; |
| public static final int SS_INCOMING_BARRING_DN = 21; |
| public static final int SS_INCOMING_BARRING_ANONYMOUS = 22; |
| |
| |
| /**@hide*/ |
| @IntDef(flag = true, prefix = {"SS_"}, value = { |
| SS_ACTIVATION, |
| SS_DEACTIVATION, |
| SS_INTERROGATION, |
| SS_REGISTRATION, |
| SS_ERASURE}) |
| @Retention(RetentionPolicy.SOURCE) |
| public @interface RequestType{} |
| |
| //Supplementary Service Request Types |
| public static final int SS_ACTIVATION = 0; |
| public static final int SS_DEACTIVATION = 1; |
| public static final int SS_INTERROGATION = 2; |
| public static final int SS_REGISTRATION = 3; |
| public static final int SS_ERASURE = 4; |
| |
| /**@hide*/ |
| @IntDef(flag = true, prefix = {"SS_"}, value = { |
| SS_ALL_TELE_AND_BEARER_SERVICES, |
| SS_ALL_TELESEVICES, |
| SS_TELEPHONY, |
| SS_ALL_DATA_TELESERVICES, |
| SS_SMS_SERVICES, |
| SS_ALL_TELESERVICES_EXCEPT_SMS}) |
| @Retention(RetentionPolicy.SOURCE) |
| public @interface TeleserviceType{} |
| |
| // Supplementary Service Teleservice Type |
| public static final int SS_ALL_TELE_AND_BEARER_SERVICES = 0; |
| public static final int SS_ALL_TELESEVICES = 1; |
| public static final int SS_TELEPHONY = 2; |
| public static final int SS_ALL_DATA_TELESERVICES = 3; |
| public static final int SS_SMS_SERVICES = 4; |
| public static final int SS_ALL_TELESERVICES_EXCEPT_SMS = 5; |
| |
| /** |
| * No call forwarding service class defined. |
| * |
| * See TS 27.007 7.11 (+CCFC) and 7.4 (CLCK) |
| */ |
| public static final int SERVICE_CLASS_NONE = 0; |
| |
| /** |
| * Service class flag for voice telephony. |
| * |
| * See TS 27.007 7.11 (+CCFC) and 7.4 (CLCK) |
| */ |
| public static final int SERVICE_CLASS_VOICE = 1; |
| |
| /** |
| * Service class flag for all data bearers (including |
| * {@link #SERVICE_CLASS_DATA_CIRCUIT_SYNC, |
| * {@link #SERVICE_CLASS_DATA_CIRCUIT_ASYNC}, {@link #SERVICE_CLASS_PACKET_ACCESS}, |
| * {@link #SERVICE_CLASS_PAD}}) if supported by the carrier. |
| * |
| * See TS 27.007 7.11 (+CCFC) and 7.4 (CLCK) |
| */ |
| public static final int SERVICE_CLASS_DATA = (1 << 1); |
| /** |
| * Service class flag for fax services. |
| * |
| * See TS 27.007 7.11 (+CCFC) and 7.4 (CLCK) |
| */ |
| public static final int SERVICE_CLASS_FAX = (1 << 2); |
| /** |
| * Service class flag for SMS services. |
| * |
| * See TS 27.007 7.11 (+CCFC) and 7.4 (CLCK) |
| */ |
| public static final int SERVICE_CLASS_SMS = (1 << 3); |
| /** |
| * Service class flag for the synchronous bearer service. |
| * |
| * See TS 27.007 7.11 (+CCFC) and 7.4 (CLCK) |
| */ |
| public static final int SERVICE_CLASS_DATA_CIRCUIT_SYNC = (1 << 4); |
| |
| /** |
| * Service class flag for the asynchronous bearer service. |
| * |
| * See TS 27.007 7.11 (+CCFC) and 7.4 (CLCK) |
| */ |
| public static final int SERVICE_CLASS_DATA_CIRCUIT_ASYNC = (1 << 5); |
| |
| /** |
| * Service class flag for the packet access bearer service. |
| * |
| * See TS 27.007 7.11 (+CCFC) and 7.4 (CLCK) |
| */ |
| public static final int SERVICE_CLASS_DATA_PACKET_ACCESS = (1 << 6); |
| |
| /** |
| * Service class flag for the Packet Assembly/Disassembly bearer service. |
| * |
| * See TS 27.007 7.11 (+CCFC) and 7.4 (CLCK) |
| */ |
| public static final int SERVICE_CLASS_DATA_PAD = (1 << 7); |
| |
| /**@hide*/ |
| @IntDef(flag = true, prefix = {"SERVICE_CLASS_"}, value = { |
| SERVICE_CLASS_NONE, |
| SERVICE_CLASS_VOICE, |
| SERVICE_CLASS_DATA, |
| SERVICE_CLASS_FAX, |
| SERVICE_CLASS_SMS, |
| SERVICE_CLASS_DATA_CIRCUIT_SYNC, |
| SERVICE_CLASS_DATA_CIRCUIT_ASYNC, |
| SERVICE_CLASS_DATA_PACKET_ACCESS, |
| SERVICE_CLASS_DATA_PAD}) |
| @Retention(RetentionPolicy.SOURCE) |
| public @interface ServiceClassFlags{} |
| |
| /** |
| * Result code used if the operation was successful. See {@link #getResult()}. |
| */ |
| public static final int RESULT_SUCCESS = 0; |
| |
| /** @hide */ |
| @IntDef(flag = true, prefix = { "SS_" }, value = { |
| SS_CFU, |
| SS_CF_BUSY, |
| SS_CF_NO_REPLY, |
| SS_CF_NOT_REACHABLE, |
| SS_CF_ALL, |
| SS_CF_ALL_CONDITIONAL, |
| SS_CFUT, |
| SS_CLIP, |
| SS_CLIR, |
| SS_COLP, |
| SS_COLR, |
| SS_CNAP, |
| SS_WAIT, |
| SS_BAOC, |
| SS_BAOIC, |
| SS_BAOIC_EXC_HOME, |
| SS_BAIC, |
| SS_BAIC_ROAMING, |
| SS_ALL_BARRING, |
| SS_OUTGOING_BARRING, |
| SS_INCOMING_BARRING, |
| SS_INCOMING_BARRING_DN, |
| SS_INCOMING_BARRING_ANONYMOUS |
| }) |
| @Retention(RetentionPolicy.SOURCE) |
| public @interface ServiceType{} |
| |
| /** |
| * The Service type of this Supplementary service. |
| * @hide |
| */ |
| public final @ServiceType int serviceType; |
| |
| /** |
| * Supplementary Service request Type: |
| * {@link #SS_ACTIVATION), |
| * {@link #SS_DEACTIVATION}, |
| * {@link #SS_INTERROGATION}, |
| * {@link #SS_REGISTRATION}, |
| * {@link #SS_ERASURE} |
| * @hide |
| */ |
| public final @RequestType int requestType; |
| |
| /** |
| * Supplementary Service teleservice type: |
| * {@link #SS_ALL_TELE_AND_BEARER_SERVICES}, |
| * {@link #SS_ALL_TELESEVICES}, |
| * {@link #SS_TELEPHONY}, |
| * {@link #SS_ALL_DATA_TELESERVICES}, |
| * {@link #SS_SMS_SERVICES}, |
| * {@link #SS_ALL_TELESERVICES_EXCEPT_SMS} |
| * |
| * @hide |
| */ |
| public final @TeleserviceType int teleserviceType; |
| |
| /** |
| * Supplementary Service service class. |
| * |
| * @hide |
| */ |
| public final @ServiceClassFlags int serviceClass; |
| |
| /** |
| * Result of Supplementary Service operation. Valid values are: |
| * {@link #RESULT_SUCCESS} if the result is success, or |
| * ImsReasonInfo code if the result is a failure. |
| * |
| * @hide |
| */ |
| public final int result; |
| |
| private int[] mSsInfo; |
| private List<ImsCallForwardInfo> mCfInfo; |
| private List<ImsSsInfo> mImsSsInfo; |
| |
| /** |
| * Builder for optional ImsSsData parameters. |
| */ |
| public static final class Builder { |
| private ImsSsData mImsSsData; |
| |
| /** |
| * Generate IMS Supplementary Service information. |
| * @param serviceType The Supplementary Service type. |
| * @param requestType Supplementary Service request Type: |
| * {@link #SS_ACTIVATION}, |
| * {@link #SS_DEACTIVATION}, |
| * {@link #SS_INTERROGATION}, |
| * {@link #SS_REGISTRATION}, |
| * {@link #SS_ERASURE} |
| * @param teleserviceType Supplementary Service teleservice type: |
| * {@link #SS_ALL_TELE_AND_BEARER_SERVICES}, |
| * {@link #SS_ALL_TELESEVICES}, |
| * {@link #SS_TELEPHONY}, |
| * {@link #SS_ALL_DATA_TELESERVICES}, |
| * {@link #SS_SMS_SERVICES}, |
| * {@link #SS_ALL_TELESERVICES_EXCEPT_SMS} |
| * @param serviceClass Supplementary Service service class. See See 27.007 +CCFC or +CLCK. |
| * @param result Result of Supplementary Service operation. Valid values are 0 if the result |
| * is success, or {@link ImsReasonInfo} code if the result is a failure. |
| * @return this Builder instance for further constructing. |
| * @see #build() |
| */ |
| public Builder(@ServiceType int serviceType, int requestType, int teleserviceType, |
| @ServiceClassFlags int serviceClass, int result) { |
| mImsSsData = new ImsSsData(serviceType, requestType, teleserviceType, serviceClass, |
| result); |
| } |
| |
| /** |
| * Set the array of {@link ImsSsInfo}s that are associated with this supplementary service |
| * data. |
| */ |
| public @NonNull Builder setSuppServiceInfo(@NonNull List<ImsSsInfo> imsSsInfos) { |
| mImsSsData.mImsSsInfo = imsSsInfos; |
| return this; |
| } |
| |
| /** |
| * Set the array of {@link ImsCallForwardInfo}s that are associated with this supplementary |
| * service data. |
| */ |
| public @NonNull Builder setCallForwardingInfo( |
| @NonNull List<ImsCallForwardInfo> imsCallForwardInfos) { |
| mImsSsData.mCfInfo = imsCallForwardInfos; |
| return this; |
| } |
| |
| /** |
| * @return an {@link ImsSsData} containing optional parameters. |
| */ |
| public @NonNull ImsSsData build() { |
| return mImsSsData; |
| } |
| } |
| |
| /** |
| * Generate IMS Supplementary Service information. |
| * @param serviceType The Supplementary Service type. |
| * @param requestType Supplementary Service request Type. Valid values are: |
| * {@link #SS_ACTIVATION}, |
| * {@link #SS_DEACTIVATION}, |
| * {@link #SS_INTERROGATION}, |
| * {@link #SS_REGISTRATION}, |
| * {@link #SS_ERASURE} |
| * @param teleserviceType Supplementary Service teleservice type: |
| * {@link #SS_ALL_TELE_AND_BEARER_SERVICES}, |
| * {@link #SS_ALL_TELESEVICES}, |
| * {@link #SS_TELEPHONY}, |
| * {@link #SS_ALL_DATA_TELESERVICES}, |
| * {@link #SS_SMS_SERVICES}, |
| * {@link #SS_ALL_TELESERVICES_EXCEPT_SMS} |
| * @param serviceClass Supplementary Service service class. See See 27.007 +CCFC or +CLCK. |
| * @param result Result of Supplementary Service operation. Valid values are 0 if the result is |
| * success, or ImsReasonInfo code if the result is a failure. |
| */ |
| public ImsSsData(@ServiceType int serviceType, int requestType, int teleserviceType, |
| @ServiceClassFlags int serviceClass, int result) { |
| this.serviceType = serviceType; |
| this.requestType = requestType; |
| this.teleserviceType = teleserviceType; |
| this.serviceClass = serviceClass; |
| this.result = result; |
| } |
| |
| private ImsSsData(Parcel in) { |
| serviceType = in.readInt(); |
| requestType = in.readInt(); |
| teleserviceType = in.readInt(); |
| serviceClass = in.readInt(); |
| result = in.readInt(); |
| mSsInfo = in.createIntArray(); |
| mCfInfo = in.readParcelableList(new ArrayList<>(), this.getClass().getClassLoader()); |
| mImsSsInfo = in.readParcelableList(new ArrayList<>(), this.getClass().getClassLoader()); |
| } |
| |
| public static final @android.annotation.NonNull Creator<ImsSsData> CREATOR = new Creator<ImsSsData>() { |
| @Override |
| public ImsSsData createFromParcel(Parcel in) { |
| return new ImsSsData(in); |
| } |
| |
| @Override |
| public ImsSsData[] newArray(int size) { |
| return new ImsSsData[size]; |
| } |
| }; |
| |
| @Override |
| public void writeToParcel(Parcel out, int flags) { |
| out.writeInt(getServiceType()); |
| out.writeInt(getRequestType()); |
| out.writeInt(getTeleserviceType()); |
| out.writeInt(getServiceClass()); |
| out.writeInt(getResult()); |
| out.writeIntArray(mSsInfo); |
| out.writeParcelableList(mCfInfo, 0); |
| out.writeParcelableList(mImsSsInfo, 0); |
| } |
| |
| @Override |
| public int describeContents() { |
| return 0; |
| } |
| |
| /** |
| * Old method, kept for compatibility. See {@link #isTypeCf()} |
| * @hide |
| */ |
| public boolean isTypeCF() { |
| return (getServiceType() == SS_CFU || getServiceType() == SS_CF_BUSY |
| || getServiceType() == SS_CF_NO_REPLY || getServiceType() == SS_CF_NOT_REACHABLE |
| || getServiceType() == SS_CF_ALL || getServiceType() == SS_CF_ALL_CONDITIONAL); |
| } |
| |
| public boolean isTypeCf() { |
| return isTypeCF(); |
| } |
| |
| public boolean isTypeUnConditional() { |
| return (getServiceType() == SS_CFU || getServiceType() == SS_CF_ALL); |
| } |
| |
| /** |
| * Old method, kept for compatibility. See {@link #isTypeCf()} |
| * @hide |
| */ |
| public boolean isTypeCW() { |
| return (getServiceType() == SS_WAIT); |
| } |
| |
| public boolean isTypeCw() { |
| return isTypeCW(); |
| } |
| |
| public boolean isTypeClip() { |
| return (getServiceType() == SS_CLIP); |
| } |
| |
| public boolean isTypeColr() { |
| return (getServiceType() == SS_COLR); |
| } |
| |
| public boolean isTypeColp() { |
| return (getServiceType() == SS_COLP); |
| } |
| |
| public boolean isTypeClir() { |
| return (getServiceType() == SS_CLIR); |
| } |
| |
| public boolean isTypeIcb() { |
| return (getServiceType() == SS_INCOMING_BARRING_DN |
| || getServiceType() == SS_INCOMING_BARRING_ANONYMOUS); |
| } |
| |
| public boolean isTypeBarring() { |
| return (getServiceType() == SS_BAOC || getServiceType() == SS_BAOIC |
| || getServiceType() == SS_BAOIC_EXC_HOME || getServiceType() == SS_BAIC |
| || getServiceType() == SS_BAIC_ROAMING || getServiceType() == SS_ALL_BARRING |
| || getServiceType() == SS_OUTGOING_BARRING |
| || getServiceType() == SS_INCOMING_BARRING); |
| } |
| |
| public boolean isTypeInterrogation() { |
| return (getRequestType() == SS_INTERROGATION); |
| } |
| |
| /** |
| * Supplementary Service request Type. |
| */ |
| public @RequestType int getRequestType() { |
| return requestType; |
| } |
| |
| /** |
| * The Service type of this Supplementary service. |
| */ |
| public @ServiceType int getServiceType() { |
| return serviceType; |
| } |
| |
| /** |
| * Supplementary Service teleservice type. |
| */ |
| public @TeleserviceType int getTeleserviceType() { |
| return teleserviceType; |
| } |
| |
| /** |
| * Supplementary Service service class. |
| */ |
| public @ServiceClassFlags int getServiceClass() { |
| return serviceClass; |
| } |
| |
| /** |
| * Result of Supplementary Service operation. Valid values are: |
| * {@link #RESULT_SUCCESS} if the result is success, or |
| * {@link ImsReasonInfo.UtReason} code if the result is a failure. |
| */ |
| public @ImsReasonInfo.UtReason int getResult() { |
| return result; |
| } |
| |
| /** @hide */ |
| public void setSuppServiceInfo(int[] ssInfo) { |
| mSsInfo = ssInfo; |
| } |
| |
| /** @hide */ |
| public void setImsSpecificSuppServiceInfo(ImsSsInfo[] imsSsInfo) { |
| mImsSsInfo = Arrays.asList(imsSsInfo); |
| } |
| |
| /** @hide */ |
| public void setCallForwardingInfo(ImsCallForwardInfo[] cfInfo) { |
| mCfInfo = Arrays.asList(cfInfo); |
| } |
| |
| /** |
| * This is a compatibility function to transform the public API to a form that can be processed |
| * by telephony. |
| * |
| * @hide |
| */ |
| //TODO: Refactor Telephony to use well defined classes instead of an int[] to process SS. |
| public int[] getSuppServiceInfoCompat() { |
| if (mSsInfo != null) { |
| // Something has set the ssInfo using hidden APIs, so for compatibility just return that |
| // structure directly. |
| return mSsInfo; |
| } |
| |
| |
| int[] result = new int[2]; |
| if (mImsSsInfo == null || mImsSsInfo.size() == 0) { |
| Rlog.e(TAG, "getSuppServiceInfoCompat: Could not parse mImsSsInfo, returning empty " |
| + "int[]"); |
| return result; |
| } |
| |
| // Convert ImsSsInfo into a form that telephony can read (as per 3GPP 27.007) |
| // CLIR (section 7.7) |
| if (isTypeClir()) { |
| // Assume there will only be one ImsSsInfo. |
| // contains {"n","m"} parameters |
| result[0] = mImsSsInfo.get(0).getClirOutgoingState(); |
| result[1] = mImsSsInfo.get(0).getClirInterrogationStatus(); |
| return result; |
| } |
| // COLR 7.31 |
| if (isTypeColr()) { |
| result[0] = mImsSsInfo.get(0).getProvisionStatus(); |
| } |
| // Facility Lock CLCK 7.4 (for call barring), CLIP 7.6, COLP 7.8, as well as any |
| // other result, just return the status for the "n" parameter and provisioning status for |
| // "m" as the default. |
| result[0] = mImsSsInfo.get(0).getStatus(); |
| result[1] = mImsSsInfo.get(0).getProvisionStatus(); |
| return result; |
| } |
| |
| /** |
| * @return an array of {@link ImsSsInfo}s associated with this supplementary service data. |
| */ |
| public @NonNull List<ImsSsInfo> getSuppServiceInfo() { |
| return mImsSsInfo; |
| } |
| |
| /** |
| * @return an array of {@link ImsCallForwardInfo}s associated with this supplementary service |
| * data. |
| **/ |
| public @Nullable List<ImsCallForwardInfo> getCallForwardInfo() { |
| return mCfInfo; |
| } |
| |
| @NonNull |
| @Override |
| public String toString() { |
| return "[ImsSsData] " + "ServiceType: " + getServiceType() |
| + " RequestType: " + getRequestType() |
| + " TeleserviceType: " + getTeleserviceType() |
| + " ServiceClass: " + getServiceClass() |
| + " Result: " + getResult(); |
| } |
| } |