summaryrefslogtreecommitdiff
path: root/telephony/java/android
diff options
context:
space:
mode:
authorEric Arseneau <earseneau@google.com>2021-12-19 22:49:43 -0800
committerEric Arseneau <earseneau@google.com>2021-12-22 12:52:50 -0800
commit3e8cb98421761bb7dfafe59a22a15fe2e176f272 (patch)
tree754d2b985bde4574c8789e254b120866cf23002a /telephony/java/android
parent48cbb14e1815430efd7ff5086e7a4c70e75d475f (diff)
parent6c2cb6876a30dee0b94d946ca529e06cd96b9642 (diff)
Merge s-mpr-2021-12-05
Change-Id: Ic2889f5eb531008340529eadc36ec8efc62b1984
Diffstat (limited to 'telephony/java/android')
-rw-r--r--telephony/java/android/telephony/AvailableNetworkInfo.java119
-rw-r--r--telephony/java/android/telephony/CarrierConfigManager.java151
-rw-r--r--telephony/java/android/telephony/SignalStrengthUpdateRequest.java27
-rw-r--r--telephony/java/android/telephony/TelephonyManager.java108
4 files changed, 387 insertions, 18 deletions
diff --git a/telephony/java/android/telephony/AvailableNetworkInfo.java b/telephony/java/android/telephony/AvailableNetworkInfo.java
index a1c5bbefbbe1..ae597e02f33c 100644
--- a/telephony/java/android/telephony/AvailableNetworkInfo.java
+++ b/telephony/java/android/telephony/AvailableNetworkInfo.java
@@ -19,6 +19,7 @@ package android.telephony;
import android.annotation.NonNull;
import android.os.Parcel;
import android.os.Parcelable;
+import android.telephony.RadioAccessSpecifier;
import java.util.ArrayList;
import java.util.Arrays;
@@ -76,13 +77,28 @@ public final class AvailableNetworkInfo implements Parcelable {
* Opportunistic network service will use these bands to scan.
*
* When no specific bands are specified (empty array or null) CBRS band
- * {@link AccessNetworkConstants.EutranBand.BAND_48} will be used for network scan.
+ * {@link AccessNetworkConstants.EutranBand.BAND_48
+ * } will be used for network scan.
*
* See {@link AccessNetworkConstants} for details.
+ *
+ * @deprecated use {@link #mRadioAccessSpecifiers} instead
*/
+ @Deprecated
private ArrayList<Integer> mBands;
/**
+ * Returns a list of {@link RadioAccessSpecifier} associated with the available network.
+ * Opportunistic network service will use this to determine which bands to scan for.
+ *
+ * If this entry is left empty, {@link RadioAcccessSpecifier}s with {@link AccessNetworkType}s
+ * of {@link AccessNetworkConstants.AccessNetworkType.EUTRAN} and {@link
+ * AccessNetworkConstants.AccessNetworkType.NGRAN} with bands 48 and 71 on each will be assumed
+ * by Opportunistic network service.
+ */
+ private ArrayList<RadioAccessSpecifier> mRadioAccessSpecifiers;
+
+ /**
* Return subscription Id of the available network.
* This value must be one of the entry retrieved from
* {@link SubscriptionManager#getOpportunisticSubscriptions}
@@ -129,6 +145,22 @@ public final class AvailableNetworkInfo implements Parcelable {
return (List<Integer>) mBands.clone();
}
+ /**
+ * Returns a list of {@link RadioAccessSpecifier} associated with the available network.
+ * Opportunistic network service will use this to determine which bands to scan for.
+ *
+ * the returned value is one of {@link AccessNetworkConstants.AccessNetworkType}. When no
+ * specific access network type is specified, {@link RadioAccessSpecifier}s with {@link
+ * AccessNetworkType}s of {@link AccessNetworkConstants.AccessNetworkType.EUTRAN} and {@link
+ * AccessNetworkConstants.AccessNetworkType.NGRAN} with bands 48 and 71 on each will be assumed
+ * by Opportunistic network service.
+ * @return the access network type associated with the available network.
+ * @hide
+ */
+ public List<RadioAccessSpecifier> getRadioAccessSpecifiers() {
+ return (List<RadioAccessSpecifier>) mRadioAccessSpecifiers.clone();
+ }
+
@Override
public int describeContents() {
return 0;
@@ -140,6 +172,7 @@ public final class AvailableNetworkInfo implements Parcelable {
dest.writeInt(mPriority);
dest.writeStringList(mMccMncs);
dest.writeList(mBands);
+ dest.writeList(mRadioAccessSpecifiers);
}
private AvailableNetworkInfo(Parcel in) {
@@ -149,14 +182,25 @@ public final class AvailableNetworkInfo implements Parcelable {
in.readStringList(mMccMncs);
mBands = new ArrayList<>();
in.readList(mBands, Integer.class.getClassLoader());
+ mRadioAccessSpecifiers = new ArrayList<>();
+ in.readList(mRadioAccessSpecifiers, RadioAccessSpecifier.class.getClassLoader());
}
public AvailableNetworkInfo(int subId, int priority, @NonNull List<String> mccMncs,
@NonNull List<Integer> bands) {
+ this(subId, priority, mccMncs, bands,
+ new ArrayList<RadioAccessSpecifier>());
+ }
+
+ /** @hide */
+ private AvailableNetworkInfo(int subId, int priority, @NonNull List<String> mccMncs,
+ @NonNull List<Integer> bands, @NonNull List<RadioAccessSpecifier>
+ radioAccessSpecifiers) {
mSubId = subId;
mPriority = priority;
mMccMncs = new ArrayList<String>(mccMncs);
mBands = new ArrayList<Integer>(bands);
+ mRadioAccessSpecifiers = new ArrayList<RadioAccessSpecifier>(radioAccessSpecifiers);
}
@Override
@@ -177,12 +221,13 @@ public final class AvailableNetworkInfo implements Parcelable {
&& mPriority == ani.mPriority
&& (((mMccMncs != null)
&& mMccMncs.equals(ani.mMccMncs)))
- && mBands.equals(ani.mBands));
+ && mBands.equals(ani.mBands))
+ && mRadioAccessSpecifiers.equals(ani.getRadioAccessSpecifiers());
}
@Override
public int hashCode() {
- return Objects.hash(mSubId, mPriority, mMccMncs, mBands);
+ return Objects.hash(mSubId, mPriority, mMccMncs, mBands, mRadioAccessSpecifiers);
}
public static final @android.annotation.NonNull Parcelable.Creator<AvailableNetworkInfo> CREATOR =
@@ -204,6 +249,72 @@ public final class AvailableNetworkInfo implements Parcelable {
+ " mSubId: " + mSubId
+ " mPriority: " + mPriority
+ " mMccMncs: " + Arrays.toString(mMccMncs.toArray())
- + " mBands: " + Arrays.toString(mBands.toArray()));
+ + " mBands: " + Arrays.toString(mBands.toArray())
+ + " mRadioAccessSpecifiers: " + Arrays.toString(mRadioAccessSpecifiers.toArray()));
+ }
+
+ /**
+ * Provides a convenient way to set the fields of a {@link AvailableNetworkInfo} when
+ * creating a new instance.
+ *
+ * <p>The example below shows how you might create a new {@code AvailableNetworkInfo}:
+ *
+ * <pre><code>
+ *
+ * AvailableNetworkInfo aNI = new AvailableNetworkInfo.Builder()
+ * .setSubId(1)
+ * .setPriority(AvailableNetworkInfo.PRIORITY_MED)
+ * .build();
+ * </code></pre>
+ *
+ * @hide
+ */
+ public static final class Builder {
+ private int mSubId = Integer.MIN_VALUE;
+ private int mPriority = AvailableNetworkInfo.PRIORITY_LOW;
+ private ArrayList<String> mMccMncs = new ArrayList<>();
+ private ArrayList<Integer> mBands = new ArrayList<>();
+ private ArrayList<RadioAccessSpecifier> mRadioAccessSpecifiers = new ArrayList<>();
+
+ public @NonNull Builder setSubId(int subId) {
+ mSubId = subId;
+ return this;
+ }
+
+ public @NonNull Builder setPriority(int priority) {
+ if (priority > AvailableNetworkInfo.PRIORITY_LOW
+ || priority < AvailableNetworkInfo.PRIORITY_HIGH) {
+ throw new IllegalArgumentException("A valid priority must be set");
+ }
+ mPriority = priority;
+ return this;
+ }
+
+ public @NonNull Builder setMccMncs(@NonNull ArrayList<String> mccMncs) {
+ Objects.requireNonNull(mccMncs, "A non-null ArrayList of mccmncs must be set. An empty "
+ + "list is still accepted. Please read documentation in "
+ + "AvailableNetworkService to see consequences of an empty Arraylist.");
+ mMccMncs = mccMncs;
+ return this;
+ }
+
+ public @NonNull Builder setRadioAccessSpecifiers(
+ @NonNull ArrayList<RadioAccessSpecifier> radioAccessSpecifiers) {
+ Objects.requireNonNull(radioAccessSpecifiers, "A non-null ArrayList of "
+ + "RadioAccessSpecifiers must be set. An empty list is still accepted. Please "
+ + "read documentation in AvailableNetworkService to see consequences of an "
+ + "empty Arraylist.");
+ mRadioAccessSpecifiers = radioAccessSpecifiers;
+ return this;
+ }
+
+ public @NonNull AvailableNetworkInfo build() {
+ if (mSubId == Integer.MIN_VALUE) {
+ throw new IllegalArgumentException("A valid subId must be set");
+ }
+
+ return new AvailableNetworkInfo(mSubId, mPriority, mMccMncs, mBands,
+ mRadioAccessSpecifiers);
+ }
}
}
diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java
index 0dfbc22df71f..548efb82bee7 100644
--- a/telephony/java/android/telephony/CarrierConfigManager.java
+++ b/telephony/java/android/telephony/CarrierConfigManager.java
@@ -1003,6 +1003,21 @@ public class CarrierConfigManager {
= "carrier_use_ims_first_for_emergency_bool";
/**
+ * When {@code true}, the determination of whether to place a call as an emergency call will be
+ * based on the known {@link android.telephony.emergency.EmergencyNumber}s for the SIM on which
+ * the call is being placed. In a dual SIM scenario, if Sim A has the emergency numbers
+ * 123, 456 and Sim B has the emergency numbers 789, and the user places a call on SIM A to 789,
+ * it will not be treated as an emergency call in this case.
+ * When {@code false}, the determination is based on the emergency numbers from all device SIMs,
+ * regardless of which SIM the call is being placed on. If Sim A has the emergency numbers
+ * 123, 456 and Sim B has the emergency numbers 789, and the user places a call on SIM A to 789,
+ * the call will be dialed as an emergency number, but with an unspecified routing.
+ * @hide
+ */
+ public static final String KEY_USE_ONLY_DIALED_SIM_ECC_LIST_BOOL =
+ "use_only_dialed_sim_ecc_list_bool";
+
+ /**
* When IMS instant lettering is available for a carrier (see
* {@link #KEY_CARRIER_INSTANT_LETTERING_AVAILABLE_BOOL}), determines the list of characters
* which may not be contained in messages. Should be specified as a regular expression suitable
@@ -3814,6 +3829,109 @@ public class CarrierConfigManager {
"opportunistic_network_max_backoff_time_long";
/**
+ * Controls SS-RSRP threshold in dBm at which 5G opportunistic network will be considered good
+ * enough for internet data.
+ *
+ * @hide
+ */
+ public static final String KEY_OPPORTUNISTIC_NETWORK_ENTRY_THRESHOLD_SS_RSRP_INT =
+ "opportunistic_network_entry_threshold_ss_rsrp_int";
+
+ /**
+ * Controls SS-RSRQ threshold in dB at which 5G opportunistic network will be considered good
+ * enough for internet data.
+ *
+ * @hide
+ */
+ public static final String KEY_OPPORTUNISTIC_NETWORK_ENTRY_THRESHOLD_SS_RSRQ_DOUBLE =
+ "opportunistic_network_entry_threshold_ss_rsrq_double";
+
+ /**
+ * Controls SS-RSRP threshold in dBm below which 5G opportunistic network available will not
+ * be considered good enough for internet data.
+ *
+ * @hide
+ */
+ public static final String KEY_OPPORTUNISTIC_NETWORK_EXIT_THRESHOLD_SS_RSRP_INT =
+ "opportunistic_network_exit_threshold_ss_rsrp_int";
+
+ /**
+ * Controls SS-RSRQ threshold in dB below which 5G opportunistic network available will not
+ * be considered good enough for internet data.
+ *
+ * @hide
+ */
+ public static final String KEY_OPPORTUNISTIC_NETWORK_EXIT_THRESHOLD_SS_RSRQ_DOUBLE =
+ "opportunistic_network_exit_threshold_ss_rsrq_double";
+
+ /**
+ * Controls back off time in milliseconds for switching back to
+ * 5G opportunistic subscription. This time will be added to
+ * {@link CarrierConfigManager#KEY_OPPORTUNISTIC_NETWORK_5G_DATA_SWITCH_HYSTERESIS_TIME_LONG} to
+ * determine hysteresis time if there is ping pong situation
+ * (determined by system app or 1st party app) between primary and 5G opportunistic
+ * subscription. Ping ping situation is defined in
+ * #KEY_OPPORTUNISTIC_NETWORK_5G_PING_PONG_TIME_LONG.
+ * If ping pong situation continuous #KEY_OPPORTUNISTIC_5G_NETWORK_BACKOFF_TIME_LONG
+ * will be added to previously determined hysteresis time.
+ *
+ * @hide
+ */
+ public static final String KEY_OPPORTUNISTIC_NETWORK_5G_BACKOFF_TIME_LONG =
+ "opportunistic_network_5g_backoff_time_long";
+
+ /**
+ * Controls the max back off time in milliseconds for switching back to
+ * 5G opportunistic subscription.
+ * This time will be the max hysteresis that can be determined irrespective of there is
+ * continuous ping pong situation or not as described in
+ * #KEY_OPPORTUNISTIC_NETWORK_5G_PING_PONG_TIME_LONG and
+ * #KEY_OPPORTUNISTIC_NETWORK_5G_BACKOFF_TIME_LONG.
+ *
+ * @hide
+ */
+ public static final String KEY_OPPORTUNISTIC_NETWORK_5G_MAX_BACKOFF_TIME_LONG =
+ "opportunistic_network_5g_max_backoff_time_long";
+
+ /**
+ * Controls the ping pong determination of 5G opportunistic network.
+ * If opportunistic network is determined as out of service or below
+ * #KEY_OPPORTUNISTIC_NETWORK_EXIT_THRESHOLD_SS_RSRP_INT or
+ * #KEY_OPPORTUNISTIC_NETWORK_EXIT_THRESHOLD_SS_RSRQ_INT within
+ * #KEY_OPPORTUNISTIC_NETWORK_5G_PING_PONG_TIME_LONG of switching to opportunistic network,
+ * it will be determined as ping pong situation by system app or 1st party app.
+ *
+ * @hide
+ */
+ public static final String KEY_OPPORTUNISTIC_NETWORK_5G_PING_PONG_TIME_LONG =
+ "opportunistic_network_5g_ping_pong_time_long";
+
+ /**
+ * Controls hysteresis time in milliseconds for which will be waited before switching
+ * data to a 5G opportunistic network.
+ *
+ * @hide
+ */
+ public static final String KEY_OPPORTUNISTIC_NETWORK_5G_DATA_SWITCH_HYSTERESIS_TIME_LONG =
+ "opportunistic_network_5g_data_switch_hysteresis_time_long";
+
+ /**
+ * Controls hysteresis time in milliseconds for which will be waited before switching from
+ * 5G opportunistic network to primary network.
+ *
+ * @hide
+ */
+ public static final String KEY_OPPORTUNISTIC_NETWORK_5G_DATA_SWITCH_EXIT_HYSTERESIS_TIME_LONG =
+ "opportunistic_network_5g_data_switch_exit_hysteresis_time_long";
+ /**
+ * Controls whether 4G opportunistic networks should be scanned for possible data switch.
+ *
+ * @hide
+ */
+ public static final String KEY_ENABLE_4G_OPPORTUNISTIC_NETWORK_SCAN_BOOL =
+ "enabled_4g_opportunistic_network_scan_bool";
+
+ /**
* Indicates zero or more emergency number prefix(es), because some carrier requires
* if users dial an emergency number address with a specific prefix, the combination of the
* prefix and the address is also a valid emergency number to dial. For example, an emergency
@@ -5121,6 +5239,16 @@ public class CarrierConfigManager {
"display_no_data_notification_on_permanent_failure_bool";
/**
+ * Boolean indicating if the VoNR setting is visible in the Call Settings menu.
+ * If true, the VoNR setting menu will be visible. If false, the menu will be gone.
+ *
+ * Disabled by default.
+ *
+ * @hide
+ */
+ public static final String KEY_VONR_SETTING_VISIBILITY_BOOL = "vonr_setting_visibility_bool";
+
+ /**
* Determine whether unthrottle data retry when tracking area code (TAC/LAC) from cell changes
*
* @hide
@@ -5222,6 +5350,7 @@ public class CarrierConfigManager {
sDefaults.putBoolean(KEY_CARRIER_IMS_GBA_REQUIRED_BOOL, false);
sDefaults.putBoolean(KEY_CARRIER_INSTANT_LETTERING_AVAILABLE_BOOL, false);
sDefaults.putBoolean(KEY_CARRIER_USE_IMS_FIRST_FOR_EMERGENCY_BOOL, true);
+ sDefaults.putBoolean(KEY_USE_ONLY_DIALED_SIM_ECC_LIST_BOOL, false);
sDefaults.putString(KEY_CARRIER_NETWORK_SERVICE_WWAN_PACKAGE_OVERRIDE_STRING, "");
sDefaults.putString(KEY_CARRIER_NETWORK_SERVICE_WLAN_PACKAGE_OVERRIDE_STRING, "");
sDefaults.putString(KEY_CARRIER_QUALIFIED_NETWORKS_SERVICE_PACKAGE_OVERRIDE_STRING, "");
@@ -5690,7 +5819,25 @@ public class CarrierConfigManager {
sDefaults.putLong(KEY_OPPORTUNISTIC_NETWORK_BACKOFF_TIME_LONG, 10000);
/* Default value is 60 seconds. */
sDefaults.putLong(KEY_OPPORTUNISTIC_NETWORK_MAX_BACKOFF_TIME_LONG, 60000);
- sDefaults.putAll(ImsServiceEntitlement.getDefaults());
+ /* Default value is -111 dBm. */
+ sDefaults.putInt(KEY_OPPORTUNISTIC_NETWORK_ENTRY_THRESHOLD_SS_RSRP_INT, -111);
+ /* Default value is -18.5 dB. */
+ sDefaults.putDouble(KEY_OPPORTUNISTIC_NETWORK_ENTRY_THRESHOLD_SS_RSRQ_DOUBLE, -18.5);
+ /* Default value is -120 dBm. */
+ sDefaults.putInt(KEY_OPPORTUNISTIC_NETWORK_EXIT_THRESHOLD_SS_RSRP_INT, -120);
+ /* Default value is -18.5 dB. */
+ sDefaults.putDouble(KEY_OPPORTUNISTIC_NETWORK_EXIT_THRESHOLD_SS_RSRQ_DOUBLE, -18.5);
+ /* Default value is 10 seconds. */
+ sDefaults.putLong(KEY_OPPORTUNISTIC_NETWORK_5G_BACKOFF_TIME_LONG, 10000);
+ /* Default value is 60 seconds. */
+ sDefaults.putLong(KEY_OPPORTUNISTIC_NETWORK_5G_MAX_BACKOFF_TIME_LONG, 60000);
+ /* Default value is 60 seconds. */
+ sDefaults.putLong(KEY_OPPORTUNISTIC_NETWORK_5G_PING_PONG_TIME_LONG, 60000);
+ /* Default value is 2 seconds. */
+ sDefaults.putLong(KEY_OPPORTUNISTIC_NETWORK_5G_DATA_SWITCH_HYSTERESIS_TIME_LONG, 2000);
+ /* Default value is 2 seconds. */
+ sDefaults.putLong(KEY_OPPORTUNISTIC_NETWORK_5G_DATA_SWITCH_EXIT_HYSTERESIS_TIME_LONG, 2000);
+ sDefaults.putBoolean(KEY_ENABLE_4G_OPPORTUNISTIC_NETWORK_SCAN_BOOL, true);
sDefaults.putAll(Gps.getDefaults());
sDefaults.putIntArray(KEY_CDMA_ENHANCED_ROAMING_INDICATOR_FOR_HOME_NETWORK_INT_ARRAY,
new int[] {
@@ -5762,7 +5909,7 @@ public class CarrierConfigManager {
sDefaults.putString(KEY_CARRIER_PROVISIONING_APP_STRING, "");
sDefaults.putBoolean(KEY_DISPLAY_NO_DATA_NOTIFICATION_ON_PERMANENT_FAILURE_BOOL, false);
sDefaults.putBoolean(KEY_UNTHROTTLE_DATA_RETRY_WHEN_TAC_CHANGES_BOOL, false);
- sDefaults.putBoolean(KEY_CARRIER_SUPPORTS_MULTIANCHOR_CONFERENCE, false);
+ sDefaults.putBoolean(KEY_VONR_SETTING_VISIBILITY_BOOL, false);
sDefaults.putStringArray(KEY_MULTI_APN_ARRAY_FOR_SAME_GID, new String[] {
"52FF:mms,supl,hipri,default,fota:SA:nrphone",
"52FF:mms,supl,hipri,default,fota:NSA:nxtgenphone",
diff --git a/telephony/java/android/telephony/SignalStrengthUpdateRequest.java b/telephony/java/android/telephony/SignalStrengthUpdateRequest.java
index fe7e5976b132..41e24ddb3fa6 100644
--- a/telephony/java/android/telephony/SignalStrengthUpdateRequest.java
+++ b/telephony/java/android/telephony/SignalStrengthUpdateRequest.java
@@ -26,8 +26,10 @@ import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
+import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
+import java.util.Map;
import java.util.Objects;
import java.util.Set;
@@ -101,9 +103,11 @@ public final class SignalStrengthUpdateRequest implements Parcelable {
}
mSignalThresholdInfos = new ArrayList<>(signalThresholdInfos);
- // Sort the collection with RAN ascending order, make the ordering not matter for equals
+ // Sort the collection with RAN and then SignalMeasurementType ascending order, make the
+ // ordering not matter for equals
mSignalThresholdInfos.sort(
- Comparator.comparingInt(SignalThresholdInfo::getRadioAccessNetworkType));
+ Comparator.comparingInt(SignalThresholdInfo::getRadioAccessNetworkType)
+ .thenComparing(SignalThresholdInfo::getSignalMeasurementType));
return this;
}
@@ -144,7 +148,7 @@ public final class SignalStrengthUpdateRequest implements Parcelable {
* @return the SignalStrengthUpdateRequest object
*
* @throws IllegalArgumentException if the SignalThresholdInfo collection is empty size, the
- * radio access network type in the collection is not unique
+ * signal measurement type for the same RAN in the collection is not unique
*/
public @NonNull SignalStrengthUpdateRequest build() {
return new SignalStrengthUpdateRequest(mSignalThresholdInfos,
@@ -258,14 +262,23 @@ public final class SignalStrengthUpdateRequest implements Parcelable {
}
/**
- * Throw IAE when the RAN in the collection is not unique.
+ * Throw IAE if SignalThresholdInfo collection is null or empty,
+ * or the SignalMeasurementType for the same RAN in the collection is not unique.
*/
private static void validate(Collection<SignalThresholdInfo> infos) {
- Set<Integer> uniqueRan = new HashSet<>(infos.size());
+ if (infos == null || infos.isEmpty()) {
+ throw new IllegalArgumentException("SignalThresholdInfo collection is null or empty");
+ }
+
+ // Map from RAN to set of SignalMeasurementTypes
+ Map<Integer, Set<Integer>> ranToTypes = new HashMap<>(infos.size());
for (SignalThresholdInfo info : infos) {
final int ran = info.getRadioAccessNetworkType();
- if (!uniqueRan.add(ran)) {
- throw new IllegalArgumentException("RAN: " + ran + " is not unique");
+ final int type = info.getSignalMeasurementType();
+ ranToTypes.putIfAbsent(ran, new HashSet<>());
+ if (!ranToTypes.get(ran).add(type)) {
+ throw new IllegalArgumentException(
+ "SignalMeasurementType " + type + " for RAN " + ran + " is not unique");
}
}
}
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index 799930c53669..ba0d6afe25a4 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -3515,7 +3515,8 @@ public class TelephonyManager {
*/
private int getLogicalSlotIndex(int physicalSlotIndex) {
UiccSlotInfo[] slotInfos = getUiccSlotsInfo();
- if (slotInfos != null && physicalSlotIndex >= 0 && physicalSlotIndex < slotInfos.length) {
+ if (slotInfos != null && physicalSlotIndex >= 0 && physicalSlotIndex < slotInfos.length
+ && slotInfos[physicalSlotIndex] != null) {
return slotInfos[physicalSlotIndex].getLogicalSlotIdx();
}
@@ -8888,7 +8889,8 @@ public class TelephonyManager {
}
/**
- * Set the preferred network type to global mode which includes LTE, CDMA, EvDo and GSM/WCDMA.
+ * Set the preferred network type to global mode which includes NR, LTE, CDMA, EvDo
+ * and GSM/WCDMA.
*
* <p>Requires that the calling app has carrier privileges (see {@link #hasCarrierPrivileges}).
*
@@ -8899,7 +8901,8 @@ public class TelephonyManager {
}
/**
- * Set the preferred network type to global mode which includes LTE, CDMA, EvDo and GSM/WCDMA.
+ * Set the preferred network type to global mode which includes NR, LTE, CDMA, EvDo
+ * and GSM/WCDMA.
*
* <p>Requires that the calling app has carrier privileges (see {@link #hasCarrierPrivileges}).
*
@@ -8907,7 +8910,7 @@ public class TelephonyManager {
* @hide
*/
public boolean setPreferredNetworkTypeToGlobal(int subId) {
- return setPreferredNetworkType(subId, RILConstants.NETWORK_MODE_LTE_CDMA_EVDO_GSM_WCDMA);
+ return setPreferredNetworkType(subId, RILConstants.NETWORK_MODE_NR_LTE_CDMA_EVDO_GSM_WCDMA);
}
/**
@@ -12178,6 +12181,100 @@ public class TelephonyManager {
}
/**
+ * No error. Operation succeeded.
+ * @hide
+ */
+ public static final int ENABLE_VONR_SUCCESS = 0;
+
+ /**
+ * Radio is not available.
+ * @hide
+ */
+ public static final int ENABLE_VONR_RADIO_NOT_AVAILABLE = 2;
+
+ /**
+ * Internal Radio error.
+ * @hide
+ */
+ public static final int ENABLE_VONR_RADIO_ERROR = 3;
+
+ /**
+ * Voice over NR enable/disable request is received when system is in invalid state.
+ * @hide
+ */
+ public static final int ENABLE_VONR_RADIO_INVALID_STATE = 4;
+
+ /**
+ * Voice over NR enable/disable request is not supported.
+ * @hide
+ */
+ public static final int ENABLE_VONR_REQUEST_NOT_SUPPORTED = 5;
+
+ /** @hide */
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef(prefix = {"EnableVoNrResult"}, value = {
+ ENABLE_VONR_SUCCESS,
+ ENABLE_VONR_RADIO_NOT_AVAILABLE,
+ ENABLE_VONR_RADIO_ERROR,
+ ENABLE_VONR_RADIO_INVALID_STATE,
+ ENABLE_VONR_REQUEST_NOT_SUPPORTED})
+ public @interface EnableVoNrResult {}
+
+ /**
+ * Enable or disable Voice over NR (VoNR)
+ *
+ * <p>If this object has been created with {@link #createForSubscriptionId}, applies to the
+ * given subId. Otherwise, applies to {@link SubscriptionManager#getDefaultDataSubscriptionId()}
+ *
+ * <p>Requires Permission:
+ * {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE}.
+ *
+ * @param enabled enable or disable VoNR.
+ * @throws IllegalStateException if the Telephony process is not currently available.
+ * @hide
+ */
+ @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
+ public @EnableVoNrResult int setVoNrEnabled(boolean enabled) {
+ try {
+ ITelephony service = getITelephony();
+ if (service != null) {
+ return service.setVoNrEnabled(
+ getSubId(SubscriptionManager.getDefaultDataSubscriptionId()), enabled);
+ } else {
+ throw new IllegalStateException("telephony service is null.");
+ }
+ } catch (RemoteException e) {
+ Log.e(TAG, "Error calling ITelephony#setVoNrEnabled", e);
+ }
+
+ return ENABLE_VONR_RADIO_INVALID_STATE;
+ }
+
+ /**
+ * Is Voice over NR (VoNR) enabled.
+ * @return true if Voice over NR (VoNR) is enabled else false. Enabled state does not mean
+ * voice call over NR is active or voice ove NR is available. It means the device is allowed to
+ * register IMS over NR.
+ * @throws IllegalStateException if the Telephony process is not currently available.
+ * @hide
+ */
+ @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
+ public boolean isVoNrEnabled() {
+ try {
+ ITelephony telephony = getITelephony();
+ if (telephony != null) {
+ return telephony.isVoNrEnabled(getSubId());
+ } else {
+ throw new IllegalStateException("telephony service is null.");
+ }
+ } catch (RemoteException ex) {
+ Rlog.e(TAG, "isVoNrEnabled RemoteException", ex);
+ ex.rethrowFromSystemServer();
+ }
+ return false;
+ }
+
+ /**
* Carrier action to start or stop reporting default network available events.
*
* <p>If this object has been created with {@link #createForSubscriptionId}, applies to the
@@ -14242,7 +14339,8 @@ public class TelephonyManager {
if (callForwardingInfo.getNumber() == null) {
throw new IllegalArgumentException("callForwarding number is null");
}
- if (callForwardingInfo.getTimeoutSeconds() <= 0) {
+ if (callForwardingReason == CallForwardingInfo.REASON_NO_REPLY
+ && callForwardingInfo.getTimeoutSeconds() <= 0) {
throw new IllegalArgumentException("callForwarding timeout isn't positive");
}
}