From de188ac200fa23b8dd6db4eb5659fc3c814d24b6 Mon Sep 17 00:00:00 2001 From: sqian Date: Wed, 29 Jan 2020 14:59:27 -0800 Subject: Support Call Forwarding and Call Waiting APIs for voice call. Allows system apps to get/set call forwarding configuration including reason, status, number and timeout. Allows system apps to get/set the status for call waiting function; Call waiting function enables the waiting for the incoming call when it reaches the user who is busy to make another call and allows users to decide whether to switch to the incoming call. Test: Cts; Treehugger; https://paste.googleplex.com/5810435984982016 Bug: 147920077 Change-Id: Iadeea607749c67209df8cb1313f8b134df0a5c4a Merged-In: Iadeea607749c67209df8cb1313f8b134df0a5c4a (cherry picked from commit ce96e26c277a746aa95774851ad8daf5c8b3c0d1) --- api/system-current.txt | 29 ++ telephony/java/android/telephony/Annotation.java | 42 +++ .../java/android/telephony/CallForwardingInfo.aidl | 19 ++ .../java/android/telephony/CallForwardingInfo.java | 307 +++++++++++++++++++++ .../java/android/telephony/TelephonyManager.java | 187 +++++++++++++ .../com/android/internal/telephony/ITelephony.aidl | 74 +++++ 6 files changed, 658 insertions(+) create mode 100644 telephony/java/android/telephony/CallForwardingInfo.aidl create mode 100644 telephony/java/android/telephony/CallForwardingInfo.java diff --git a/api/system-current.txt b/api/system-current.txt index fe904109580e..65b9b1fed9de 100755 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -8411,6 +8411,27 @@ package android.telephony { field @NonNull public static final android.os.Parcelable.Creator CREATOR; } + public final class CallForwardingInfo implements android.os.Parcelable { + ctor public CallForwardingInfo(int, int, @Nullable String, int); + method public int describeContents(); + method @Nullable public String getNumber(); + method public int getReason(); + method public int getStatus(); + method public int getTimeoutSeconds(); + field @NonNull public static final android.os.Parcelable.Creator CREATOR; + field public static final int REASON_ALL = 4; // 0x4 + field public static final int REASON_ALL_CONDITIONAL = 5; // 0x5 + field public static final int REASON_BUSY = 1; // 0x1 + field public static final int REASON_NOT_REACHABLE = 3; // 0x3 + field public static final int REASON_NO_REPLY = 2; // 0x2 + field public static final int REASON_UNCONDITIONAL = 0; // 0x0 + field public static final int STATUS_ACTIVE = 1; // 0x1 + field public static final int STATUS_FDN_CHECK_FAILURE = 2; // 0x2 + field public static final int STATUS_INACTIVE = 0; // 0x0 + field public static final int STATUS_NOT_SUPPORTED = 4; // 0x4 + field public static final int STATUS_UNKNOWN_ERROR = 3; // 0x3 + } + public final class CallQuality implements android.os.Parcelable { ctor public CallQuality(int, int, int, int, int, int, int, int, int, int, int); method public int describeContents(); @@ -9487,6 +9508,8 @@ package android.telephony { method @Nullable @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public String getAidForAppType(int); method @Deprecated @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public java.util.List getAllowedCarriers(int); method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public long getAllowedNetworkTypes(); + method @NonNull @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public android.telephony.CallForwardingInfo getCallForwarding(int); + method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public int getCallWaitingStatus(); method @Nullable @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public android.telephony.ImsiEncryptionInfo getCarrierInfoForImsiEncryption(int); method public java.util.List getCarrierPackageNamesForIntent(android.content.Intent); method public java.util.List getCarrierPackageNamesForIntentAndPhone(android.content.Intent, int); @@ -9567,6 +9590,8 @@ package android.telephony { method @Deprecated @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public int setAllowedCarriers(int, java.util.List); method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean setAllowedNetworkTypes(long); method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setAlwaysReportSignalStrength(boolean); + method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean setCallForwarding(@NonNull android.telephony.CallForwardingInfo); + method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean setCallWaitingStatus(boolean); method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setCarrierDataEnabled(boolean); method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public int setCarrierRestrictionRules(@NonNull android.telephony.CarrierRestrictionRules); method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setDataActivationState(int); @@ -9598,6 +9623,10 @@ package android.telephony { field public static final String ACTION_SIM_APPLICATION_STATE_CHANGED = "android.telephony.action.SIM_APPLICATION_STATE_CHANGED"; field public static final String ACTION_SIM_CARD_STATE_CHANGED = "android.telephony.action.SIM_CARD_STATE_CHANGED"; field public static final String ACTION_SIM_SLOT_STATUS_CHANGED = "android.telephony.action.SIM_SLOT_STATUS_CHANGED"; + field public static final int CALL_WAITING_STATUS_ACTIVE = 1; // 0x1 + field public static final int CALL_WAITING_STATUS_INACTIVE = 2; // 0x2 + field public static final int CALL_WAITING_STATUS_NOT_SUPPORTED = 4; // 0x4 + field public static final int CALL_WAITING_STATUS_UNKNOWN_ERROR = 3; // 0x3 field public static final int CARD_POWER_DOWN = 0; // 0x0 field public static final int CARD_POWER_UP = 1; // 0x1 field public static final int CARD_POWER_UP_PASS_THROUGH = 2; // 0x2 diff --git a/telephony/java/android/telephony/Annotation.java b/telephony/java/android/telephony/Annotation.java index 9e6dfef0608b..db17a9505a27 100644 --- a/telephony/java/android/telephony/Annotation.java +++ b/telephony/java/android/telephony/Annotation.java @@ -597,6 +597,48 @@ public class Annotation { public @interface ImsAudioCodec { } + /** + * Call forwarding function status + */ + @IntDef(prefix = { "STATUS_" }, value = { + CallForwardingInfo.STATUS_ACTIVE, + CallForwardingInfo.STATUS_INACTIVE, + CallForwardingInfo.STATUS_UNKNOWN_ERROR, + CallForwardingInfo.STATUS_NOT_SUPPORTED, + CallForwardingInfo.STATUS_FDN_CHECK_FAILURE + }) + @Retention(RetentionPolicy.SOURCE) + public @interface CallForwardingStatus { + } + + /** + * Call forwarding reason types + */ + @IntDef(flag = true, prefix = { "REASON_" }, value = { + CallForwardingInfo.REASON_UNCONDITIONAL, + CallForwardingInfo.REASON_BUSY, + CallForwardingInfo.REASON_NO_REPLY, + CallForwardingInfo.REASON_NOT_REACHABLE, + CallForwardingInfo.REASON_ALL, + CallForwardingInfo.REASON_ALL_CONDITIONAL + }) + @Retention(RetentionPolicy.SOURCE) + public @interface CallForwardingReason { + } + + /** + * Call waiting function status + */ + @IntDef(prefix = { "CALL_WAITING_STATUS_" }, value = { + TelephonyManager.CALL_WAITING_STATUS_ACTIVE, + TelephonyManager.CALL_WAITING_STATUS_INACTIVE, + TelephonyManager.CALL_WAITING_STATUS_NOT_SUPPORTED, + TelephonyManager.CALL_WAITING_STATUS_UNKNOWN_ERROR + }) + @Retention(RetentionPolicy.SOURCE) + public @interface CallWaitingStatus { + } + /** * UICC SIM Application Types */ diff --git a/telephony/java/android/telephony/CallForwardingInfo.aidl b/telephony/java/android/telephony/CallForwardingInfo.aidl new file mode 100644 index 000000000000..2019e07d4bda --- /dev/null +++ b/telephony/java/android/telephony/CallForwardingInfo.aidl @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2020, 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; + +parcelable CallForwardingInfo; \ No newline at end of file diff --git a/telephony/java/android/telephony/CallForwardingInfo.java b/telephony/java/android/telephony/CallForwardingInfo.java new file mode 100644 index 000000000000..33ad5e8beea3 --- /dev/null +++ b/telephony/java/android/telephony/CallForwardingInfo.java @@ -0,0 +1,307 @@ +/* + * Copyright (C) 2020 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; + +import android.annotation.NonNull; +import android.annotation.Nullable; +import android.annotation.SuppressLint; +import android.annotation.SystemApi; +import android.os.Parcel; +import android.os.Parcelable; +import android.telephony.Annotation.CallForwardingReason; +import android.telephony.Annotation.CallForwardingStatus; + +import java.util.Objects; + +/** + * Defines the call forwarding information. + * @hide + */ +@SystemApi +public final class CallForwardingInfo implements Parcelable { + private static final String TAG = "CallForwardingInfo"; + + /** + * Indicates the call forwarding status is inactive. + * + * @hide + */ + @SystemApi + public static final int STATUS_INACTIVE = 0; + + /** + * Indicates the call forwarding status is active. + * + * @hide + */ + @SystemApi + public static final int STATUS_ACTIVE = 1; + + /** + * Indicates the call forwarding could not be enabled because the recipient is not on + * Fixed Dialing Number (FDN) list. + * + * @hide + */ + @SystemApi + public static final int STATUS_FDN_CHECK_FAILURE = 2; + + /** + * Indicates the call forwarding status is with an unknown error. + * + * @hide + */ + @SystemApi + public static final int STATUS_UNKNOWN_ERROR = 3; + + /** + * Indicates the call forwarding is not supported (e.g. called via CDMA). + * + * @hide + */ + @SystemApi + public static final int STATUS_NOT_SUPPORTED = 4; + + /** + * Indicates the call forwarding reason is "unconditional". + * Reference: 3GPP TS 27.007 version 10.3.0 Release 10 - 7.11 Call forwarding number + * and conditions +CCFC + * @hide + */ + @SystemApi + public static final int REASON_UNCONDITIONAL = 0; + + /** + * Indicates the call forwarding status is "busy". + * Reference: 3GPP TS 27.007 version 10.3.0 Release 10 - 7.11 Call forwarding number + * and conditions +CCFC + * @hide + */ + @SystemApi + public static final int REASON_BUSY = 1; + + /** + * Indicates the call forwarding reason is "no reply". + * Reference: 3GPP TS 27.007 version 10.3.0 Release 10 - 7.11 Call forwarding number + * and conditions +CCFC + * @hide + */ + @SystemApi + public static final int REASON_NO_REPLY = 2; + + /** + * Indicates the call forwarding reason is "not reachable". + * Reference: 3GPP TS 27.007 version 10.3.0 Release 10 - 7.11 Call forwarding number + * and conditions +CCFC + * @hide + */ + @SystemApi + public static final int REASON_NOT_REACHABLE = 3; + + /** + * Indicates the call forwarding reason is "all", for setting all call forwarding reasons + * simultaneously (unconditional, busy, no reply, and not reachable). + * Reference: 3GPP TS 27.007 version 10.3.0 Release 10 - 7.11 Call forwarding number + * and conditions +CCFC + * @hide + */ + @SystemApi + public static final int REASON_ALL = 4; + + /** + * Indicates the call forwarding reason is "all_conditional", for setting all conditional call + * forwarding reasons simultaneously (busy, no reply, and not reachable). + * Reference: 3GPP TS 27.007 version 10.3.0 Release 10 - 7.11 Call forwarding number + * and conditions +CCFC + * @hide + */ + @SystemApi + public static final int REASON_ALL_CONDITIONAL = 5; + + /** + * The call forwarding status. + */ + private @CallForwardingStatus int mStatus; + + /** + * The call forwarding reason indicates the condition under which calls will be forwarded. + * Reference: 3GPP TS 27.007 version 10.3.0 Release 10 - 7.11 Call forwarding number + * and conditions +CCFC + */ + private @CallForwardingReason int mReason; + + /** + * The phone number to which calls will be forwarded. + * Reference: 3GPP TS 27.007 version 10.3.0 Release 10 - 7.11 Call forwarding number + * and conditions +CCFC + */ + private String mNumber; + + /** + * Gets the timeout (in seconds) before the forwarding is attempted. + */ + private int mTimeSeconds; + + /** + * Construct a CallForwardingInfo. + * + * @param status the call forwarding status + * @param reason the call forwarding reason + * @param number the phone number to which calls will be forwarded + * @param timeSeconds the timeout (in seconds) before the forwarding is attempted + * @hide + */ + @SystemApi + public CallForwardingInfo(@CallForwardingStatus int status, @CallForwardingReason int reason, + @Nullable String number, int timeSeconds) { + mStatus = status; + mReason = reason; + mNumber = number; + mTimeSeconds = timeSeconds; + } + + /** + * Returns the call forwarding status. + * + * @return the call forwarding status. + * + * @hide + */ + @SystemApi + public @CallForwardingStatus int getStatus() { + return mStatus; + } + + /** + * Returns the call forwarding reason. The call forwarding reason indicates the condition + * under which calls will be forwarded. For example, {@link #REASON_NO_REPLY} indicates + * that calls will be forward to {@link #getNumber()} when the user fails to answer the call. + * + * @return the call forwarding reason. + * + * @hide + */ + @SystemApi + public @CallForwardingReason int getReason() { + return mReason; + } + + /** + * Returns the phone number to which calls will be forwarded. + * + * @return the number calls will be forwarded to, or {@code null} if call forwarding + * is being disabled. + * + * @hide + */ + @SystemApi + @Nullable + public String getNumber() { + return mNumber; + } + + /** + * Gets the timeout (in seconds) before the forwarding is attempted. For example, + * if {@link #REASON_NO_REPLY} is the call forwarding reason, the device will wait this + * duration of time before forwarding the call to {@link #getNumber()}. + * + * Reference: 3GPP TS 27.007 version 10.3.0 Release 10 + * 7.11 Call forwarding number and conditions +CCFC + * + * @return the timeout (in seconds) before the forwarding is attempted. + * + * @hide + */ + @SystemApi + @SuppressLint("MethodNameUnits") + public int getTimeoutSeconds() { + return mTimeSeconds; + } + + @Override + public int describeContents() { + return 0; + } + + /** + * @hide + */ + @Override + public void writeToParcel(Parcel out, int flags) { + out.writeString(mNumber); + out.writeInt(mStatus); + out.writeInt(mReason); + out.writeInt(mTimeSeconds); + } + + private CallForwardingInfo(Parcel in) { + mNumber = in.readString(); + mStatus = in.readInt(); + mReason = in.readInt(); + mTimeSeconds = in.readInt(); + } + + /** + * @hide + */ + @Override + public boolean equals(Object o) { + if (this == o) return true; + + if (!(o instanceof CallForwardingInfo)) { + return false; + } + + CallForwardingInfo other = (CallForwardingInfo) o; + return mStatus == other.mStatus + && mNumber == other.mNumber + && mReason == other.mReason + && mTimeSeconds == other.mTimeSeconds; + } + + /** + * @hide + */ + @Override + public int hashCode() { + return Objects.hash(mStatus, mNumber, mReason, mTimeSeconds); + } + + public static final @NonNull Parcelable.Creator CREATOR = + new Parcelable.Creator() { + @Override + public CallForwardingInfo createFromParcel(Parcel in) { + return new CallForwardingInfo(in); + } + + @Override + public CallForwardingInfo[] newArray(int size) { + return new CallForwardingInfo[size]; + } + }; + + /** + * @hide + */ + @Override + public String toString() { + return "[CallForwardingInfo: status=" + mStatus + + ", reason= " + mReason + + ", timeSec= " + mTimeSeconds + " seconds" + + ", number=" + Rlog.pii(TAG, mNumber) + "]"; + } +} diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java index 58b82bfab485..67e036de151c 100644 --- a/telephony/java/android/telephony/TelephonyManager.java +++ b/telephony/java/android/telephony/TelephonyManager.java @@ -71,7 +71,9 @@ import android.telecom.PhoneAccount; import android.telecom.PhoneAccountHandle; import android.telecom.TelecomManager; import android.telephony.Annotation.ApnType; +import android.telephony.Annotation.CallForwardingReason; import android.telephony.Annotation.CallState; +import android.telephony.Annotation.CallWaitingStatus; import android.telephony.Annotation.NetworkType; import android.telephony.Annotation.RadioPowerState; import android.telephony.Annotation.SimActivationState; @@ -12201,6 +12203,191 @@ public class TelephonyManager { return false; } + /** + * Gets the voice call forwarding info {@link CallForwardingInfo}, given the call forward + * reason. + * + * @param callForwardingReason the call forwarding reasons + * + * @throws IllegalArgumentException if callForwardingReason is not any of + * {@link CallForwardingInfo.REASON_UNCONDITIONAL}, {@link CallForwardingInfo.REASON_BUSY}, + * {@link CallForwardingInfo.REASON_NO_REPLY}, {@link CallForwardingInfo.REASON_NOT_REACHABLE}, + * {@link CallForwardingInfo.REASON_ALL}, {@link CallForwardingInfo.REASON_ALL_CONDITIONAL} + * + * @return {@link CallForwardingInfo} with the status {@link CallForwardingInfo#STATUS_ACTIVE} + * or {@link CallForwardingInfo#STATUS_INACTIVE} and the target phone number to forward calls + * to, if it's available. Otherwise, it will return a {@link CallForwardingInfo} with status + * {@link CallForwardingInfo#STATUS_UNKNOWN_ERROR}, + * {@link CallForwardingInfo#STATUS_NOT_SUPPORTED}, + * or {@link CallForwardingInfo#STATUS_FDN_CHECK_FAILURE} depending on the situation. + * + * @hide + */ + @SystemApi + @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) + @NonNull + public CallForwardingInfo getCallForwarding(@CallForwardingReason int callForwardingReason) { + if (callForwardingReason < CallForwardingInfo.REASON_UNCONDITIONAL + || callForwardingReason > CallForwardingInfo.REASON_ALL_CONDITIONAL) { + throw new IllegalArgumentException("callForwardingReason is out of range"); + } + try { + ITelephony telephony = getITelephony(); + if (telephony != null) { + return telephony.getCallForwarding(getSubId(), callForwardingReason); + } + } catch (RemoteException ex) { + Rlog.e(TAG, "getCallForwarding RemoteException", ex); + } catch (NullPointerException ex) { + Rlog.e(TAG, "getCallForwarding NPE", ex); + } + return new CallForwardingInfo( + CallForwardingInfo.STATUS_UNKNOWN_ERROR, 0 /* reason */, null /* number */, + 0 /* timeout */); + } + + /** + * Sets the voice call forwarding info including status (enable/disable), call forwarding + * reason, the number to forward, and the timeout before the forwarding is attempted. + * + * @param callForwardingInfo {@link CallForwardingInfo} to setup the call forwarding. + * Enabling if {@link CallForwardingInfo#getStatus()} returns + * {@link CallForwardingInfo#STATUS_ACTIVE}; Disabling if + * {@link CallForwardingInfo#getStatus()} returns {@link CallForwardingInfo#STATUS_INACTIVE}. + * + * @throws IllegalArgumentException if any of the following for parameter callForwardingInfo: + * 0) it is {@code null}. + * 1) {@link CallForwardingInfo#getStatus()} returns neither + * {@link CallForwardingInfo#STATUS_ACTIVE} nor {@link CallForwardingInfo#STATUS_INACTIVE}. + * 2) {@link CallForwardingInfo#getReason()} is not any of + * {@link CallForwardingInfo.REASON_UNCONDITIONAL}, {@link CallForwardingInfo.REASON_BUSY}, + * {@link CallForwardingInfo.REASON_NO_REPLY}, {@link CallForwardingInfo.REASON_NOT_REACHABLE}, + * {@link CallForwardingInfo.REASON_ALL}, {@link CallForwardingInfo.REASON_ALL_CONDITIONAL} + * 3) {@link CallForwardingInfo#getNumber()} returns {@code null}. + * 4) {@link CallForwardingInfo#getTimeoutSeconds()} doesn't return a positive value. + * + * @return {@code true} to indicate it was set successfully; {@code false} otherwise. + * + * @hide + */ + @SystemApi + @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) + public boolean setCallForwarding(@NonNull CallForwardingInfo callForwardingInfo) { + if (callForwardingInfo == null) { + throw new IllegalArgumentException("callForwardingInfo is null"); + } + int callForwardingStatus = callForwardingInfo.getStatus(); + if (callForwardingStatus != CallForwardingInfo.STATUS_ACTIVE + && callForwardingStatus != CallForwardingInfo.STATUS_INACTIVE) { + throw new IllegalArgumentException( + "callForwardingStatus is neither active nor inactive"); + } + int callForwardingReason = callForwardingInfo.getReason(); + if (callForwardingReason < CallForwardingInfo.REASON_UNCONDITIONAL + || callForwardingReason > CallForwardingInfo.REASON_ALL_CONDITIONAL) { + throw new IllegalArgumentException("callForwardingReason is out of range"); + } + if (callForwardingInfo.getNumber() == null) { + throw new IllegalArgumentException("callForwarding number is null"); + } + if (callForwardingInfo.getTimeoutSeconds() <= 0) { + throw new IllegalArgumentException("callForwarding timeout isn't positive"); + } + try { + ITelephony telephony = getITelephony(); + if (telephony != null) { + return telephony.setCallForwarding(getSubId(), callForwardingInfo); + } + } catch (RemoteException ex) { + Rlog.e(TAG, "setCallForwarding RemoteException", ex); + } catch (NullPointerException ex) { + Rlog.e(TAG, "setCallForwarding NPE", ex); + } + return false; + } + + /** + * Indicates the call waiting status is active. + * + * @hide + */ + @SystemApi + public static final int CALL_WAITING_STATUS_ACTIVE = 1; + + /** + * Indicates the call waiting status is inactive. + * + * @hide + */ + @SystemApi + public static final int CALL_WAITING_STATUS_INACTIVE = 2; + + /** + * Indicates the call waiting status is with an unknown error. + * + * @hide + */ + @SystemApi + public static final int CALL_WAITING_STATUS_UNKNOWN_ERROR = 3; + + /** + * Indicates the call waiting is not supported (e.g. called via CDMA). + * + * @hide + */ + @SystemApi + public static final int CALL_WAITING_STATUS_NOT_SUPPORTED = 4; + + /** + * Gets the status of voice call waiting function. Call waiting function enables the waiting + * for the incoming call when it reaches the user who is busy to make another call and allows + * users to decide whether to switch to the incoming call. + * + * @return the status of call waiting function. + * @hide + */ + @SystemApi + @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) + public @CallWaitingStatus int getCallWaitingStatus() { + try { + ITelephony telephony = getITelephony(); + if (telephony != null) { + return telephony.getCallWaitingStatus(getSubId()); + } + } catch (RemoteException ex) { + Rlog.e(TAG, "getCallWaitingStatus RemoteException", ex); + } catch (NullPointerException ex) { + Rlog.e(TAG, "getCallWaitingStatus NPE", ex); + } + return CALL_WAITING_STATUS_UNKNOWN_ERROR; + } + + /** + * Sets the status for voice call waiting function. Call waiting function enables the waiting + * for the incoming call when it reaches the user who is busy to make another call and allows + * users to decide whether to switch to the incoming call. + * + * @param isEnable {@code true} to enable; {@code false} to disable. + * @return {@code true} to indicate it was set successfully; {@code false} otherwise. + * + * @hide + */ + @SystemApi + @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) + public boolean setCallWaitingStatus(boolean isEnable) { + try { + ITelephony telephony = getITelephony(); + if (telephony != null) { + return telephony.setCallWaitingStatus(getSubId(), isEnable); + } + } catch (RemoteException ex) { + Rlog.e(TAG, "setCallWaitingStatus RemoteException", ex); + } catch (NullPointerException ex) { + Rlog.e(TAG, "setCallWaitingStatus NPE", ex); + } + return false; + } + /** * Set allowing mobile data during voice call. * diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl index 1d794cde7d9c..d7fbafbcf5c7 100644 --- a/telephony/java/com/android/internal/telephony/ITelephony.aidl +++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl @@ -29,6 +29,7 @@ import android.net.Uri; import android.service.carrier.CarrierIdentifier; import android.telecom.PhoneAccount; import android.telecom.PhoneAccountHandle; +import android.telephony.CallForwardingInfo; import android.telephony.CarrierRestrictionRules; import android.telephony.CellIdentity; import android.telephony.CellInfo; @@ -1630,6 +1631,79 @@ interface ITelephony { */ NetworkStats getVtDataUsage(int subId, boolean perUidStats); + /** + * Gets the voice call forwarding info {@link CallForwardingInfo}, given the call forward + * reason. + * + * @param callForwardingReason the call forwarding reasons which are the bitwise-OR combination + * of the following constants: + *
    + *
  1. {@link CallForwardingInfo#REASON_BUSY}
  2. + *
  3. {@link CallForwardingInfo#REASON_NO_REPLY}
  4. + *
  5. {@link CallForwardingInfo#REASON_NOT_REACHABLE}
  6. + *
+ * + * @throws IllegalArgumentException if callForwardingReason is not a bitwise-OR combination + * of {@link CallForwardingInfo.REASON_BUSY}, {@link CallForwardingInfo.REASON_BUSY}, + * {@link CallForwardingInfo.REASON_NOT_REACHABLE} + * + * @return {@link CallForwardingInfo} with the status {@link CallForwardingInfo#STATUS_ACTIVE} + * or {@link CallForwardingInfo#STATUS_INACTIVE} and the target phone number to forward calls + * to, if it's available. Otherwise, it will return a {@link CallForwardingInfo} with status + * {@link CallForwardingInfo#STATUS_NOT_SUPPORTED} or + * {@link CallForwardingInfo#STATUS_FDN_CHECK_FAILURE} depending on the situation. + * + * @hide + */ + CallForwardingInfo getCallForwarding(int subId, int callForwardingReason); + + /** + * Sets the voice call forwarding info including status (enable/disable), call forwarding + * reason, the number to forward, and the timeout before the forwarding is attempted. + * + * @param callForwardingInfo {@link CallForwardingInfo} to setup the call forwarding. + * Enabling if {@link CallForwardingInfo#getStatus()} returns + * {@link CallForwardingInfo#STATUS_ACTIVE}; Disabling if + * {@link CallForwardingInfo#getStatus()} returns {@link CallForwardingInfo#STATUS_INACTIVE}. + * + * @throws IllegalArgumentException if any of the following: + * 0) callForwardingInfo is null. + * 1) {@link CallForwardingInfo#getStatus()} for callForwardingInfo returns neither + * {@link CallForwardingInfo#STATUS_ACTIVE} nor {@link CallForwardingInfo#STATUS_INACTIVE}. + * 2) {@link CallForwardingInfo#getReason()} for callForwardingInfo doesn't return the + * bitwise-OR combination of {@link CallForwardingInfo.REASON_BUSY}, + * {@link CallForwardingInfo.REASON_BUSY}, {@link CallForwardingInfo.REASON_NOT_REACHABLE} + * 3) {@link CallForwardingInfo#getNumber()} for callForwardingInfo returns null. + * 4) {@link CallForwardingInfo#getTimeout()} for callForwardingInfo returns nagetive value. + * + * @return {@code true} to indicate it was set successfully; {@code false} otherwise. + * + * @hide + */ + boolean setCallForwarding(int subId, in CallForwardingInfo callForwardingInfo); + + /** + * Gets the status of voice call waiting function. Call waiting function enables the waiting + * for the incoming call when it reaches the user who is busy to make another call and allows + * users to decide whether to switch to the incoming call. + * + * @return the status of call waiting function. + * @hide + */ + int getCallWaitingStatus(int subId); + + /** + * Sets the status for voice call waiting function. Call waiting function enables the waiting + * for the incoming call when it reaches the user who is busy to make another call and allows + * users to decide whether to switch to the incoming call. + * + * @param isEnable {@code true} to enable; {@code false} to disable. + * @return {@code true} to indicate it was set successfully; {@code false} otherwise. + * + * @hide + */ + boolean setCallWaitingStatus(int subId, boolean isEnable); + /** * Policy control of data connection. Usually used when data limit is passed. * @param enabled True if enabling the data, otherwise disabling. -- cgit v1.2.3-59-g8ed1b