diff options
Diffstat (limited to 'telephony')
5 files changed, 360 insertions, 6 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 72ad23b8edb1..68ef7543c33f 100644 --- a/telephony/java/android/telephony/CarrierConfigManager.java +++ b/telephony/java/android/telephony/CarrierConfigManager.java @@ -3751,6 +3751,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 @@ -5058,6 +5161,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 @@ -5581,7 +5694,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[] { @@ -5653,6 +5784,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_VONR_SETTING_VISIBILITY_BOOL, false); } /** diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java index 255a61266ebf..abab426b3252 100644 --- a/telephony/java/android/telephony/TelephonyManager.java +++ b/telephony/java/android/telephony/TelephonyManager.java @@ -3483,7 +3483,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(); } @@ -12143,6 +12144,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 diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl index 018dabfdb552..89e39256bf09 100644 --- a/telephony/java/com/android/internal/telephony/ITelephony.aidl +++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl @@ -2228,6 +2228,20 @@ interface ITelephony { List<String> getEquivalentHomePlmns(int subId, String callingPackage, String callingFeatureId); /** + * Enable or disable Voice over NR (VoNR) + * @param subId the subscription ID that this action applies to. + * @param enabled enable or disable VoNR. + * @return operation result. + */ + int setVoNrEnabled(int subId, boolean enabled); + + /** + * Is voice over NR enabled + * @return true if VoNR is enabled else false + */ + boolean isVoNrEnabled(int subId); + + /** * Enable/Disable E-UTRA-NR Dual Connectivity * @return operation result. See TelephonyManager.EnableNrDualConnectivityResult for * details diff --git a/telephony/java/com/android/internal/telephony/RILConstants.java b/telephony/java/com/android/internal/telephony/RILConstants.java index fe8e6715fe35..fadc23b315d6 100644 --- a/telephony/java/com/android/internal/telephony/RILConstants.java +++ b/telephony/java/com/android/internal/telephony/RILConstants.java @@ -528,6 +528,8 @@ public interface RILConstants { int RIL_REQUEST_SET_ALLOWED_NETWORK_TYPES_BITMAP = 222; int RIL_REQUEST_GET_ALLOWED_NETWORK_TYPES_BITMAP = 223; int RIL_REQUEST_GET_SLICING_CONFIG = 224; + int RIL_REQUEST_ENABLE_VONR = 225; + int RIL_REQUEST_IS_VONR_ENABLED = 225; /* Responses begin */ int RIL_RESPONSE_ACKNOWLEDGEMENT = 800; |