Java tutorial
/* * Copyright (C) 2006 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 static android.telephony.TelephonyManager.NETWORK_TYPE_BITMASK_UNKNOWN; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SystemApi; import android.annotation.TestApi; import android.annotation.UnsupportedAppUsage; import android.content.Intent; import android.os.Build; import android.os.Bundle; import android.os.Parcel; import android.os.Parcelable; import android.telephony.AccessNetworkConstants.AccessNetworkType; import android.telephony.AccessNetworkConstants.TransportType; import android.telephony.NetworkRegistrationInfo.Domain; import android.telephony.NetworkRegistrationInfo.NRState; import android.text.TextUtils; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Objects; import java.util.stream.Collectors; /** * Contains phone state and service related information. * * The following phone information is included in returned ServiceState: * * <ul> * <li>Service state: IN_SERVICE, OUT_OF_SERVICE, EMERGENCY_ONLY, POWER_OFF * <li>Duplex mode: UNKNOWN, FDD, TDD * <li>Roaming indicator * <li>Operator name, short name and numeric id * <li>Network selection mode * </ul> * * For historical reasons this class is not declared as final; however, * it should be treated as though it were final. */ public class ServiceState implements Parcelable { static final String LOG_TAG = "PHONE"; static final boolean DBG = false; static final boolean VDBG = false; // STOPSHIP if true /** * Normal operation condition, the phone is registered * with an operator either in home network or in roaming. */ public static final int STATE_IN_SERVICE = TelephonyProtoEnums.SERVICE_STATE_IN_SERVICE; // 0 /** * Phone is not registered with any operator, the phone * can be currently searching a new operator to register to, or not * searching to registration at all, or registration is denied, or radio * signal is not available. */ public static final int STATE_OUT_OF_SERVICE = TelephonyProtoEnums.SERVICE_STATE_OUT_OF_SERVICE; // 1 /** * The phone is registered and locked. Only emergency numbers are allowed. {@more} */ public static final int STATE_EMERGENCY_ONLY = TelephonyProtoEnums.SERVICE_STATE_EMERGENCY_ONLY; // 2 /** * Radio of telephony is explicitly powered off. */ public static final int STATE_POWER_OFF = TelephonyProtoEnums.SERVICE_STATE_POWER_OFF; // 3 /** @hide */ @Retention(RetentionPolicy.SOURCE) @IntDef(prefix = "FREQUENCY_RANGE_", value = { FREQUENCY_RANGE_UNKNOWN, FREQUENCY_RANGE_LOW, FREQUENCY_RANGE_MID, FREQUENCY_RANGE_HIGH, FREQUENCY_RANGE_MMWAVE }) public @interface FrequencyRange { } /** * Indicates frequency range is unknown. * @hide */ public static final int FREQUENCY_RANGE_UNKNOWN = -1; /** * Indicates the frequency range is below 1GHz. * @hide */ public static final int FREQUENCY_RANGE_LOW = 1; /** * Indicates the frequency range is between 1GHz to 3GHz. * @hide */ public static final int FREQUENCY_RANGE_MID = 2; /** * Indicates the frequency range is between 3GHz and 6GHz. * @hide */ public static final int FREQUENCY_RANGE_HIGH = 3; /** * Indicates the frequency range is above 6GHz (millimeter wave frequency). * @hide */ public static final int FREQUENCY_RANGE_MMWAVE = 4; private static final List<Integer> FREQUENCY_RANGE_ORDER = Arrays.asList(FREQUENCY_RANGE_UNKNOWN, FREQUENCY_RANGE_LOW, FREQUENCY_RANGE_MID, FREQUENCY_RANGE_HIGH, FREQUENCY_RANGE_MMWAVE); /** @hide */ @Retention(RetentionPolicy.SOURCE) @IntDef(prefix = "DUPLEX_MODE_", value = { DUPLEX_MODE_UNKNOWN, DUPLEX_MODE_FDD, DUPLEX_MODE_TDD }) public @interface DuplexMode { } /** * Duplex mode for the phone is unknown. */ public static final int DUPLEX_MODE_UNKNOWN = 0; /** * Duplex mode for the phone is frequency-division duplexing. */ public static final int DUPLEX_MODE_FDD = 1; /** * Duplex mode for the phone is time-division duplexing. */ public static final int DUPLEX_MODE_TDD = 2; /** @hide */ @Retention(RetentionPolicy.SOURCE) @IntDef(prefix = { "RIL_RADIO_TECHNOLOGY_" }, value = { RIL_RADIO_TECHNOLOGY_UNKNOWN, RIL_RADIO_TECHNOLOGY_GPRS, RIL_RADIO_TECHNOLOGY_EDGE, RIL_RADIO_TECHNOLOGY_UMTS, RIL_RADIO_TECHNOLOGY_IS95A, RIL_RADIO_TECHNOLOGY_IS95B, RIL_RADIO_TECHNOLOGY_1xRTT, RIL_RADIO_TECHNOLOGY_EVDO_0, RIL_RADIO_TECHNOLOGY_EVDO_A, RIL_RADIO_TECHNOLOGY_HSDPA, RIL_RADIO_TECHNOLOGY_HSUPA, RIL_RADIO_TECHNOLOGY_HSPA, RIL_RADIO_TECHNOLOGY_EVDO_B, RIL_RADIO_TECHNOLOGY_EHRPD, RIL_RADIO_TECHNOLOGY_LTE, RIL_RADIO_TECHNOLOGY_HSPAP, RIL_RADIO_TECHNOLOGY_GSM, RIL_RADIO_TECHNOLOGY_TD_SCDMA, RIL_RADIO_TECHNOLOGY_IWLAN, RIL_RADIO_TECHNOLOGY_LTE_CA, RIL_RADIO_TECHNOLOGY_NR }) public @interface RilRadioTechnology { } /** * Available radio technologies for GSM, UMTS and CDMA. * Duplicates the constants from hardware/radio/include/ril.h * This should only be used by agents working with the ril. Others * should use the equivalent TelephonyManager.NETWORK_TYPE_* */ /** @hide */ public static final int RIL_RADIO_TECHNOLOGY_UNKNOWN = 0; /** @hide */ public static final int RIL_RADIO_TECHNOLOGY_GPRS = 1; /** @hide */ public static final int RIL_RADIO_TECHNOLOGY_EDGE = 2; /** @hide */ public static final int RIL_RADIO_TECHNOLOGY_UMTS = 3; /** @hide */ public static final int RIL_RADIO_TECHNOLOGY_IS95A = 4; /** @hide */ public static final int RIL_RADIO_TECHNOLOGY_IS95B = 5; /** @hide */ public static final int RIL_RADIO_TECHNOLOGY_1xRTT = 6; /** @hide */ public static final int RIL_RADIO_TECHNOLOGY_EVDO_0 = 7; /** @hide */ public static final int RIL_RADIO_TECHNOLOGY_EVDO_A = 8; /** @hide */ public static final int RIL_RADIO_TECHNOLOGY_HSDPA = 9; /** @hide */ public static final int RIL_RADIO_TECHNOLOGY_HSUPA = 10; /** @hide */ public static final int RIL_RADIO_TECHNOLOGY_HSPA = 11; /** @hide */ public static final int RIL_RADIO_TECHNOLOGY_EVDO_B = 12; /** @hide */ public static final int RIL_RADIO_TECHNOLOGY_EHRPD = 13; /** @hide */ public static final int RIL_RADIO_TECHNOLOGY_LTE = 14; /** @hide */ public static final int RIL_RADIO_TECHNOLOGY_HSPAP = 15; /** * GSM radio technology only supports voice. It does not support data. * @hide */ public static final int RIL_RADIO_TECHNOLOGY_GSM = 16; /** @hide */ public static final int RIL_RADIO_TECHNOLOGY_TD_SCDMA = 17; /** * IWLAN * @hide */ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P) public static final int RIL_RADIO_TECHNOLOGY_IWLAN = 18; /** * LTE_CA * @hide */ public static final int RIL_RADIO_TECHNOLOGY_LTE_CA = 19; /** * NR(New Radio) 5G. * @hide */ public static final int RIL_RADIO_TECHNOLOGY_NR = 20; /** * The number of the radio technologies. */ private static final int NEXT_RIL_RADIO_TECHNOLOGY = 21; /** @hide */ public static final int RIL_RADIO_CDMA_TECHNOLOGY_BITMASK = (1 << (RIL_RADIO_TECHNOLOGY_IS95A - 1)) | (1 << (RIL_RADIO_TECHNOLOGY_IS95B - 1)) | (1 << (RIL_RADIO_TECHNOLOGY_1xRTT - 1)) | (1 << (RIL_RADIO_TECHNOLOGY_EVDO_0 - 1)) | (1 << (RIL_RADIO_TECHNOLOGY_EVDO_A - 1)) | (1 << (RIL_RADIO_TECHNOLOGY_EVDO_B - 1)) | (1 << (RIL_RADIO_TECHNOLOGY_EHRPD - 1)); private int mVoiceRegState = STATE_OUT_OF_SERVICE; private int mDataRegState = STATE_OUT_OF_SERVICE; /** @hide */ @Retention(RetentionPolicy.SOURCE) @IntDef(prefix = { "ROAMING_TYPE_" }, value = { ROAMING_TYPE_NOT_ROAMING, ROAMING_TYPE_UNKNOWN, ROAMING_TYPE_DOMESTIC, ROAMING_TYPE_INTERNATIONAL }) public @interface RoamingType { } /** * Not roaming, registered in home network. * @hide */ @SystemApi public static final int ROAMING_TYPE_NOT_ROAMING = 0; /** * registered in a roaming network, but can not tell if it's domestic or international. * @hide */ @SystemApi public static final int ROAMING_TYPE_UNKNOWN = 1; /** * registered in a domestic roaming network * @hide */ @SystemApi public static final int ROAMING_TYPE_DOMESTIC = 2; /** * registered in an international roaming network * @hide */ @SystemApi public static final int ROAMING_TYPE_INTERNATIONAL = 3; /** * Unknown ID. Could be returned by {@link #getCdmaNetworkId()} or {@link #getCdmaSystemId()} */ public static final int UNKNOWN_ID = -1; private String mVoiceOperatorAlphaLong; private String mVoiceOperatorAlphaShort; private String mVoiceOperatorNumeric; private String mDataOperatorAlphaLong; private String mDataOperatorAlphaShort; private String mDataOperatorNumeric; @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P) private boolean mIsManualNetworkSelection; private boolean mIsEmergencyOnly; @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) private boolean mCssIndicator; @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P) private int mNetworkId; @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P) private int mSystemId; @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) private int mCdmaRoamingIndicator; @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) private int mCdmaDefaultRoamingIndicator; @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) private int mCdmaEriIconIndex; @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) private int mCdmaEriIconMode; @FrequencyRange private int mNrFrequencyRange; private int mChannelNumber; private int[] mCellBandwidths = new int[0]; /* EARFCN stands for E-UTRA Absolute Radio Frequency Channel Number, * Reference: 3GPP TS 36.104 5.4.3 */ private int mLteEarfcnRsrpBoost = 0; private final List<NetworkRegistrationInfo> mNetworkRegistrationInfos = new ArrayList<>(); private String mOperatorAlphaLongRaw; private String mOperatorAlphaShortRaw; private boolean mIsIwlanPreferred; /** * get String description of roaming type * @hide */ public static final String getRoamingLogString(int roamingType) { switch (roamingType) { case ROAMING_TYPE_NOT_ROAMING: return "home"; case ROAMING_TYPE_UNKNOWN: return "roaming"; case ROAMING_TYPE_DOMESTIC: return "Domestic Roaming"; case ROAMING_TYPE_INTERNATIONAL: return "International Roaming"; default: return "UNKNOWN"; } } /** * Create a new ServiceState from a intent notifier Bundle * * This method is used by PhoneStateIntentReceiver and maybe by * external applications. * * @param m Bundle from intent notifier * @return newly created ServiceState * @hide */ @UnsupportedAppUsage public static ServiceState newFromBundle(Bundle m) { ServiceState ret; ret = new ServiceState(); ret.setFromNotifierBundle(m); return ret; } /** * Empty constructor */ public ServiceState() { } /** * Copy constructors * * @param s Source service state */ public ServiceState(ServiceState s) { copyFrom(s); } protected void copyFrom(ServiceState s) { mVoiceRegState = s.mVoiceRegState; mDataRegState = s.mDataRegState; mVoiceOperatorAlphaLong = s.mVoiceOperatorAlphaLong; mVoiceOperatorAlphaShort = s.mVoiceOperatorAlphaShort; mVoiceOperatorNumeric = s.mVoiceOperatorNumeric; mDataOperatorAlphaLong = s.mDataOperatorAlphaLong; mDataOperatorAlphaShort = s.mDataOperatorAlphaShort; mDataOperatorNumeric = s.mDataOperatorNumeric; mIsManualNetworkSelection = s.mIsManualNetworkSelection; mCssIndicator = s.mCssIndicator; mNetworkId = s.mNetworkId; mSystemId = s.mSystemId; mCdmaRoamingIndicator = s.mCdmaRoamingIndicator; mCdmaDefaultRoamingIndicator = s.mCdmaDefaultRoamingIndicator; mCdmaEriIconIndex = s.mCdmaEriIconIndex; mCdmaEriIconMode = s.mCdmaEriIconMode; mIsEmergencyOnly = s.mIsEmergencyOnly; mChannelNumber = s.mChannelNumber; mCellBandwidths = s.mCellBandwidths == null ? null : Arrays.copyOf(s.mCellBandwidths, s.mCellBandwidths.length); mLteEarfcnRsrpBoost = s.mLteEarfcnRsrpBoost; synchronized (mNetworkRegistrationInfos) { mNetworkRegistrationInfos.clear(); mNetworkRegistrationInfos.addAll(s.getNetworkRegistrationInfoList()); } mNrFrequencyRange = s.mNrFrequencyRange; mOperatorAlphaLongRaw = s.mOperatorAlphaLongRaw; mOperatorAlphaShortRaw = s.mOperatorAlphaShortRaw; mIsIwlanPreferred = s.mIsIwlanPreferred; } /** * Construct a ServiceState object from the given parcel. * * @deprecated The constructor takes parcel should not be public at the beginning. Use * {@link #ServiceState()} instead. */ @Deprecated public ServiceState(Parcel in) { mVoiceRegState = in.readInt(); mDataRegState = in.readInt(); mVoiceOperatorAlphaLong = in.readString(); mVoiceOperatorAlphaShort = in.readString(); mVoiceOperatorNumeric = in.readString(); mDataOperatorAlphaLong = in.readString(); mDataOperatorAlphaShort = in.readString(); mDataOperatorNumeric = in.readString(); mIsManualNetworkSelection = in.readInt() != 0; mCssIndicator = (in.readInt() != 0); mNetworkId = in.readInt(); mSystemId = in.readInt(); mCdmaRoamingIndicator = in.readInt(); mCdmaDefaultRoamingIndicator = in.readInt(); mCdmaEriIconIndex = in.readInt(); mCdmaEriIconMode = in.readInt(); mIsEmergencyOnly = in.readInt() != 0; mLteEarfcnRsrpBoost = in.readInt(); synchronized (mNetworkRegistrationInfos) { in.readList(mNetworkRegistrationInfos, NetworkRegistrationInfo.class.getClassLoader()); } mChannelNumber = in.readInt(); mCellBandwidths = in.createIntArray(); mNrFrequencyRange = in.readInt(); mOperatorAlphaLongRaw = in.readString(); mOperatorAlphaShortRaw = in.readString(); mIsIwlanPreferred = in.readBoolean(); } public void writeToParcel(Parcel out, int flags) { out.writeInt(mVoiceRegState); out.writeInt(mDataRegState); out.writeString(mVoiceOperatorAlphaLong); out.writeString(mVoiceOperatorAlphaShort); out.writeString(mVoiceOperatorNumeric); out.writeString(mDataOperatorAlphaLong); out.writeString(mDataOperatorAlphaShort); out.writeString(mDataOperatorNumeric); out.writeInt(mIsManualNetworkSelection ? 1 : 0); out.writeInt(mCssIndicator ? 1 : 0); out.writeInt(mNetworkId); out.writeInt(mSystemId); out.writeInt(mCdmaRoamingIndicator); out.writeInt(mCdmaDefaultRoamingIndicator); out.writeInt(mCdmaEriIconIndex); out.writeInt(mCdmaEriIconMode); out.writeInt(mIsEmergencyOnly ? 1 : 0); out.writeInt(mLteEarfcnRsrpBoost); synchronized (mNetworkRegistrationInfos) { out.writeList(mNetworkRegistrationInfos); } out.writeInt(mChannelNumber); out.writeIntArray(mCellBandwidths); out.writeInt(mNrFrequencyRange); out.writeString(mOperatorAlphaLongRaw); out.writeString(mOperatorAlphaShortRaw); out.writeBoolean(mIsIwlanPreferred); } public int describeContents() { return 0; } public static final Parcelable.Creator<ServiceState> CREATOR = new Parcelable.Creator<ServiceState>() { public ServiceState createFromParcel(Parcel in) { return new ServiceState(in); } public ServiceState[] newArray(int size) { return new ServiceState[size]; } }; /** * Get current voice service state */ public int getState() { return getVoiceRegState(); } /** * Get current voice service state * * @see #STATE_IN_SERVICE * @see #STATE_OUT_OF_SERVICE * @see #STATE_EMERGENCY_ONLY * @see #STATE_POWER_OFF * * @hide */ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P) public int getVoiceRegState() { return mVoiceRegState; } /** * Get current data service state * * @see #STATE_IN_SERVICE * @see #STATE_OUT_OF_SERVICE * @see #STATE_EMERGENCY_ONLY * @see #STATE_POWER_OFF * * @hide */ @UnsupportedAppUsage public int getDataRegState() { return mDataRegState; } /** * Get the current duplex mode * * @see #DUPLEX_MODE_UNKNOWN * @see #DUPLEX_MODE_FDD * @see #DUPLEX_MODE_TDD * * @return Current {@code DuplexMode} for the phone */ @DuplexMode public int getDuplexMode() { // only support LTE duplex mode if (!isLte(getRilDataRadioTechnology())) { return DUPLEX_MODE_UNKNOWN; } int band = AccessNetworkUtils.getOperatingBandForEarfcn(mChannelNumber); return AccessNetworkUtils.getDuplexModeForEutranBand(band); } /** * Get the channel number of the current primary serving cell, or -1 if unknown * * <p>This is EARFCN for LTE, UARFCN for UMTS, and ARFCN for GSM. * * @return Channel number of primary serving cell */ public int getChannelNumber() { return mChannelNumber; } /** * Get an array of cell bandwidths (kHz) for the current serving cells * * @return Current serving cell bandwidths */ public int[] getCellBandwidths() { return mCellBandwidths == null ? new int[0] : mCellBandwidths; } /** * Get current roaming indicator of phone * (note: not just decoding from TS 27.007 7.2) * * @return true if TS 27.007 7.2 roaming is true * and ONS is different from SPN */ public boolean getRoaming() { return getVoiceRoaming() || getDataRoaming(); } /** * Get current voice network roaming status * @return roaming status * @hide */ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P) public boolean getVoiceRoaming() { return getVoiceRoamingType() != ROAMING_TYPE_NOT_ROAMING; } /** * Get current voice network roaming type * @return roaming type * @hide */ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P) public @RoamingType int getVoiceRoamingType() { final NetworkRegistrationInfo regState = getNetworkRegistrationInfo(NetworkRegistrationInfo.DOMAIN_CS, AccessNetworkConstants.TRANSPORT_TYPE_WWAN); if (regState != null) { return regState.getRoamingType(); } return ROAMING_TYPE_NOT_ROAMING; } /** * Get current data network roaming type * @return roaming type * @hide */ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P) public boolean getDataRoaming() { return getDataRoamingType() != ROAMING_TYPE_NOT_ROAMING; } /** * Get whether data network registration state is roaming * @return true if registration indicates roaming, false otherwise * @hide */ public boolean getDataRoamingFromRegistration() { final NetworkRegistrationInfo regState = getNetworkRegistrationInfo(NetworkRegistrationInfo.DOMAIN_PS, AccessNetworkConstants.TRANSPORT_TYPE_WWAN); if (regState != null) { return regState.getRegistrationState() == NetworkRegistrationInfo.REGISTRATION_STATE_ROAMING; } return false; } /** * Get current data network roaming type * @return roaming type * @hide */ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P) public @RoamingType int getDataRoamingType() { final NetworkRegistrationInfo regState = getNetworkRegistrationInfo(NetworkRegistrationInfo.DOMAIN_PS, AccessNetworkConstants.TRANSPORT_TYPE_WWAN); if (regState != null) { return regState.getRoamingType(); } return ROAMING_TYPE_NOT_ROAMING; } /** * @hide */ @UnsupportedAppUsage public boolean isEmergencyOnly() { return mIsEmergencyOnly; } /** * @hide */ @UnsupportedAppUsage public int getCdmaRoamingIndicator() { return this.mCdmaRoamingIndicator; } /** * @hide */ @UnsupportedAppUsage public int getCdmaDefaultRoamingIndicator() { return this.mCdmaDefaultRoamingIndicator; } /** * @hide */ @UnsupportedAppUsage public int getCdmaEriIconIndex() { return this.mCdmaEriIconIndex; } /** * @hide */ @UnsupportedAppUsage public int getCdmaEriIconMode() { return this.mCdmaEriIconMode; } /** * Get current registered operator name in long alphanumeric format. * * In GSM/UMTS, long format can be up to 16 characters long. * In CDMA, returns the ERI text, if set. Otherwise, returns the ONS. * * @return long name of operator, null if unregistered or unknown */ public String getOperatorAlphaLong() { return mVoiceOperatorAlphaLong; } /** * Get current registered voice network operator name in long alphanumeric format. * @return long name of operator * @hide */ @UnsupportedAppUsage public String getVoiceOperatorAlphaLong() { return mVoiceOperatorAlphaLong; } /** * Get current registered data network operator name in long alphanumeric format. * @return long name of voice operator * @hide */ public String getDataOperatorAlphaLong() { return mDataOperatorAlphaLong; } /** * Get current registered operator name in short alphanumeric format. * * In GSM/UMTS, short format can be up to 8 characters long. * * @return short name of operator, null if unregistered or unknown */ public String getOperatorAlphaShort() { return mVoiceOperatorAlphaShort; } /** * Get current registered voice network operator name in short alphanumeric format. * @return short name of operator, null if unregistered or unknown * @hide */ @UnsupportedAppUsage public String getVoiceOperatorAlphaShort() { return mVoiceOperatorAlphaShort; } /** * Get current registered data network operator name in short alphanumeric format. * @return short name of operator, null if unregistered or unknown * @hide */ @UnsupportedAppUsage public String getDataOperatorAlphaShort() { return mDataOperatorAlphaShort; } /** * Get current registered operator name in long alphanumeric format if * available or short otherwise. * * @see #getOperatorAlphaLong * @see #getOperatorAlphaShort * * @return name of operator, null if unregistered or unknown * @hide */ public String getOperatorAlpha() { if (TextUtils.isEmpty(mVoiceOperatorAlphaLong)) { return mVoiceOperatorAlphaShort; } return mVoiceOperatorAlphaLong; } /** * Get current registered operator numeric id. * * In GSM/UMTS, numeric format is 3 digit country code plus 2 or 3 digit * network code. * * @return numeric format of operator, null if unregistered or unknown */ /* * The country code can be decoded using * {@link com.android.internal.telephony.MccTable#countryCodeForMcc(int)}. */ public String getOperatorNumeric() { return mVoiceOperatorNumeric; } /** * Get current registered voice network operator numeric id. * @return numeric format of operator, null if unregistered or unknown * @hide */ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P) public String getVoiceOperatorNumeric() { return mVoiceOperatorNumeric; } /** * Get current registered data network operator numeric id. * @return numeric format of operator, null if unregistered or unknown * @hide */ @UnsupportedAppUsage public String getDataOperatorNumeric() { return mDataOperatorNumeric; } /** * Get current network selection mode. * * @return true if manual mode, false if automatic mode */ public boolean getIsManualSelection() { return mIsManualNetworkSelection; } @Override public int hashCode() { synchronized (mNetworkRegistrationInfos) { return Objects.hash(mVoiceRegState, mDataRegState, mChannelNumber, Arrays.hashCode(mCellBandwidths), mVoiceOperatorAlphaLong, mVoiceOperatorAlphaShort, mVoiceOperatorNumeric, mDataOperatorAlphaLong, mDataOperatorAlphaShort, mDataOperatorNumeric, mIsManualNetworkSelection, mCssIndicator, mNetworkId, mSystemId, mCdmaRoamingIndicator, mCdmaDefaultRoamingIndicator, mCdmaEriIconIndex, mCdmaEriIconMode, mIsEmergencyOnly, mLteEarfcnRsrpBoost, mNetworkRegistrationInfos, mNrFrequencyRange, mOperatorAlphaLongRaw, mOperatorAlphaShortRaw, mIsIwlanPreferred); } } @Override public boolean equals(Object o) { if (!(o instanceof ServiceState)) return false; ServiceState s = (ServiceState) o; synchronized (mNetworkRegistrationInfos) { return mVoiceRegState == s.mVoiceRegState && mDataRegState == s.mDataRegState && mIsManualNetworkSelection == s.mIsManualNetworkSelection && mChannelNumber == s.mChannelNumber && Arrays.equals(mCellBandwidths, s.mCellBandwidths) && equalsHandlesNulls(mVoiceOperatorAlphaLong, s.mVoiceOperatorAlphaLong) && equalsHandlesNulls(mVoiceOperatorAlphaShort, s.mVoiceOperatorAlphaShort) && equalsHandlesNulls(mVoiceOperatorNumeric, s.mVoiceOperatorNumeric) && equalsHandlesNulls(mDataOperatorAlphaLong, s.mDataOperatorAlphaLong) && equalsHandlesNulls(mDataOperatorAlphaShort, s.mDataOperatorAlphaShort) && equalsHandlesNulls(mDataOperatorNumeric, s.mDataOperatorNumeric) && equalsHandlesNulls(mCssIndicator, s.mCssIndicator) && equalsHandlesNulls(mNetworkId, s.mNetworkId) && equalsHandlesNulls(mSystemId, s.mSystemId) && equalsHandlesNulls(mCdmaRoamingIndicator, s.mCdmaRoamingIndicator) && equalsHandlesNulls(mCdmaDefaultRoamingIndicator, s.mCdmaDefaultRoamingIndicator) && mIsEmergencyOnly == s.mIsEmergencyOnly && equalsHandlesNulls(mOperatorAlphaLongRaw, s.mOperatorAlphaLongRaw) && equalsHandlesNulls(mOperatorAlphaShortRaw, s.mOperatorAlphaShortRaw) && mNetworkRegistrationInfos.size() == s.mNetworkRegistrationInfos.size() && mNetworkRegistrationInfos.containsAll(s.mNetworkRegistrationInfos) && mNrFrequencyRange == s.mNrFrequencyRange && mIsIwlanPreferred == s.mIsIwlanPreferred; } } /** * Convert roaming type to string * * @param roamingType roaming type * @return The roaming type in string format * * @hide */ public static String roamingTypeToString(@RoamingType int roamingType) { switch (roamingType) { case ROAMING_TYPE_NOT_ROAMING: return "NOT_ROAMING"; case ROAMING_TYPE_UNKNOWN: return "UNKNOWN"; case ROAMING_TYPE_DOMESTIC: return "DOMESTIC"; case ROAMING_TYPE_INTERNATIONAL: return "INTERNATIONAL"; } return "Unknown roaming type " + roamingType; } /** * Convert radio technology to String * * @param rt radioTechnology * @return String representation of the RAT * * @hide */ @UnsupportedAppUsage public static String rilRadioTechnologyToString(int rt) { String rtString; switch (rt) { case RIL_RADIO_TECHNOLOGY_UNKNOWN: rtString = "Unknown"; break; case RIL_RADIO_TECHNOLOGY_GPRS: rtString = "GPRS"; break; case RIL_RADIO_TECHNOLOGY_EDGE: rtString = "EDGE"; break; case RIL_RADIO_TECHNOLOGY_UMTS: rtString = "UMTS"; break; case RIL_RADIO_TECHNOLOGY_IS95A: rtString = "CDMA-IS95A"; break; case RIL_RADIO_TECHNOLOGY_IS95B: rtString = "CDMA-IS95B"; break; case RIL_RADIO_TECHNOLOGY_1xRTT: rtString = "1xRTT"; break; case RIL_RADIO_TECHNOLOGY_EVDO_0: rtString = "EvDo-rev.0"; break; case RIL_RADIO_TECHNOLOGY_EVDO_A: rtString = "EvDo-rev.A"; break; case RIL_RADIO_TECHNOLOGY_HSDPA: rtString = "HSDPA"; break; case RIL_RADIO_TECHNOLOGY_HSUPA: rtString = "HSUPA"; break; case RIL_RADIO_TECHNOLOGY_HSPA: rtString = "HSPA"; break; case RIL_RADIO_TECHNOLOGY_EVDO_B: rtString = "EvDo-rev.B"; break; case RIL_RADIO_TECHNOLOGY_EHRPD: rtString = "eHRPD"; break; case RIL_RADIO_TECHNOLOGY_LTE: rtString = "LTE"; break; case RIL_RADIO_TECHNOLOGY_HSPAP: rtString = "HSPAP"; break; case RIL_RADIO_TECHNOLOGY_GSM: rtString = "GSM"; break; case RIL_RADIO_TECHNOLOGY_IWLAN: rtString = "IWLAN"; break; case RIL_RADIO_TECHNOLOGY_TD_SCDMA: rtString = "TD-SCDMA"; break; case RIL_RADIO_TECHNOLOGY_LTE_CA: rtString = "LTE_CA"; break; default: rtString = "Unexpected"; Rlog.w(LOG_TAG, "Unexpected radioTechnology=" + rt); break; } return rtString; } /** * Convert RIL Service State to String * * @param serviceState * @return String representation of the ServiceState * * @hide */ public static String rilServiceStateToString(int serviceState) { switch (serviceState) { case STATE_IN_SERVICE: return "IN_SERVICE"; case STATE_OUT_OF_SERVICE: return "OUT_OF_SERVICE"; case STATE_EMERGENCY_ONLY: return "EMERGENCY_ONLY"; case STATE_POWER_OFF: return "POWER_OFF"; default: return "UNKNOWN"; } } @Override public String toString() { synchronized (mNetworkRegistrationInfos) { return new StringBuilder().append("{mVoiceRegState=").append(mVoiceRegState) .append("(" + rilServiceStateToString(mVoiceRegState) + ")").append(", mDataRegState=") .append(mDataRegState).append("(" + rilServiceStateToString(mDataRegState) + ")") .append(", mChannelNumber=").append(mChannelNumber).append(", duplexMode()=") .append(getDuplexMode()).append(", mCellBandwidths=").append(Arrays.toString(mCellBandwidths)) .append(", mVoiceOperatorAlphaLong=").append(mVoiceOperatorAlphaLong) .append(", mVoiceOperatorAlphaShort=").append(mVoiceOperatorAlphaShort) .append(", mDataOperatorAlphaLong=").append(mDataOperatorAlphaLong) .append(", mDataOperatorAlphaShort=").append(mDataOperatorAlphaShort) .append(", isManualNetworkSelection=").append(mIsManualNetworkSelection) .append(mIsManualNetworkSelection ? "(manual)" : "(automatic)") .append(", getRilVoiceRadioTechnology=").append(getRilVoiceRadioTechnology()) .append("(" + rilRadioTechnologyToString(getRilVoiceRadioTechnology()) + ")") .append(", getRilDataRadioTechnology=").append(getRilDataRadioTechnology()) .append("(" + rilRadioTechnologyToString(getRilDataRadioTechnology()) + ")") .append(", mCssIndicator=").append(mCssIndicator ? "supported" : "unsupported") .append(", mNetworkId=").append(mNetworkId).append(", mSystemId=").append(mSystemId) .append(", mCdmaRoamingIndicator=").append(mCdmaRoamingIndicator) .append(", mCdmaDefaultRoamingIndicator=").append(mCdmaDefaultRoamingIndicator) .append(", mIsEmergencyOnly=").append(mIsEmergencyOnly).append(", isUsingCarrierAggregation=") .append(isUsingCarrierAggregation()).append(", mLteEarfcnRsrpBoost=") .append(mLteEarfcnRsrpBoost).append(", mNetworkRegistrationInfos=") .append(mNetworkRegistrationInfos).append(", mNrFrequencyRange=").append(mNrFrequencyRange) .append(", mOperatorAlphaLongRaw=").append(mOperatorAlphaLongRaw) .append(", mOperatorAlphaShortRaw=").append(mOperatorAlphaShortRaw) .append(", mIsIwlanPreferred=").append(mIsIwlanPreferred).append("}").toString(); } } private void init() { if (DBG) Rlog.d(LOG_TAG, "init"); mVoiceRegState = STATE_OUT_OF_SERVICE; mDataRegState = STATE_OUT_OF_SERVICE; mChannelNumber = -1; mCellBandwidths = new int[0]; mVoiceOperatorAlphaLong = null; mVoiceOperatorAlphaShort = null; mVoiceOperatorNumeric = null; mDataOperatorAlphaLong = null; mDataOperatorAlphaShort = null; mDataOperatorNumeric = null; mIsManualNetworkSelection = false; mCssIndicator = false; mNetworkId = -1; mSystemId = -1; mCdmaRoamingIndicator = -1; mCdmaDefaultRoamingIndicator = -1; mCdmaEriIconIndex = -1; mCdmaEriIconMode = -1; mIsEmergencyOnly = false; mLteEarfcnRsrpBoost = 0; mNrFrequencyRange = FREQUENCY_RANGE_UNKNOWN; synchronized (mNetworkRegistrationInfos) { mNetworkRegistrationInfos.clear(); addNetworkRegistrationInfo( new NetworkRegistrationInfo.Builder().setDomain(NetworkRegistrationInfo.DOMAIN_CS) .setTransportType(AccessNetworkConstants.TRANSPORT_TYPE_WWAN) .setRegistrationState(NetworkRegistrationInfo.REGISTRATION_STATE_UNKNOWN).build()); addNetworkRegistrationInfo( new NetworkRegistrationInfo.Builder().setDomain(NetworkRegistrationInfo.DOMAIN_PS) .setTransportType(AccessNetworkConstants.TRANSPORT_TYPE_WWAN) .setRegistrationState(NetworkRegistrationInfo.REGISTRATION_STATE_UNKNOWN).build()); } mOperatorAlphaLongRaw = null; mOperatorAlphaShortRaw = null; mIsIwlanPreferred = false; } public void setStateOutOfService() { init(); } public void setStateOff() { init(); mVoiceRegState = STATE_POWER_OFF; mDataRegState = STATE_POWER_OFF; } public void setState(int state) { setVoiceRegState(state); if (DBG) Rlog.e(LOG_TAG, "[ServiceState] setState deprecated use setVoiceRegState()"); } /** @hide */ @UnsupportedAppUsage public void setVoiceRegState(int state) { mVoiceRegState = state; if (DBG) Rlog.d(LOG_TAG, "[ServiceState] setVoiceRegState=" + mVoiceRegState); } /** @hide */ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) public void setDataRegState(int state) { mDataRegState = state; if (VDBG) Rlog.d(LOG_TAG, "[ServiceState] setDataRegState=" + mDataRegState); } /** @hide */ @TestApi public void setCellBandwidths(int[] bandwidths) { mCellBandwidths = bandwidths; } /** @hide */ @TestApi public void setChannelNumber(int channelNumber) { mChannelNumber = channelNumber; } public void setRoaming(boolean roaming) { setVoiceRoaming(roaming); setDataRoaming(roaming); } /** @hide */ @UnsupportedAppUsage public void setVoiceRoaming(boolean roaming) { setVoiceRoamingType(roaming ? ROAMING_TYPE_UNKNOWN : ROAMING_TYPE_NOT_ROAMING); } /** @hide */ @TestApi public void setVoiceRoamingType(@RoamingType int type) { NetworkRegistrationInfo regInfo = getNetworkRegistrationInfo(NetworkRegistrationInfo.DOMAIN_CS, AccessNetworkConstants.TRANSPORT_TYPE_WWAN); if (regInfo == null) { regInfo = new NetworkRegistrationInfo.Builder().setDomain(NetworkRegistrationInfo.DOMAIN_CS) .setTransportType(AccessNetworkConstants.TRANSPORT_TYPE_WWAN).build(); } regInfo.setRoamingType(type); addNetworkRegistrationInfo(regInfo); } /** @hide */ @UnsupportedAppUsage public void setDataRoaming(boolean dataRoaming) { setDataRoamingType(dataRoaming ? ROAMING_TYPE_UNKNOWN : ROAMING_TYPE_NOT_ROAMING); } /** @hide */ @TestApi public void setDataRoamingType(@RoamingType int type) { NetworkRegistrationInfo regInfo = getNetworkRegistrationInfo(NetworkRegistrationInfo.DOMAIN_PS, AccessNetworkConstants.TRANSPORT_TYPE_WWAN); if (regInfo == null) { regInfo = new NetworkRegistrationInfo.Builder().setDomain(NetworkRegistrationInfo.DOMAIN_PS) .setTransportType(AccessNetworkConstants.TRANSPORT_TYPE_WWAN).build(); } regInfo.setRoamingType(type); addNetworkRegistrationInfo(regInfo); } /** * @hide */ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) public void setEmergencyOnly(boolean emergencyOnly) { mIsEmergencyOnly = emergencyOnly; } /** * @hide */ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) public void setCdmaRoamingIndicator(int roaming) { this.mCdmaRoamingIndicator = roaming; } /** * @hide */ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) public void setCdmaDefaultRoamingIndicator(int roaming) { this.mCdmaDefaultRoamingIndicator = roaming; } /** * @hide */ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) public void setCdmaEriIconIndex(int index) { this.mCdmaEriIconIndex = index; } /** * @hide */ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) public void setCdmaEriIconMode(int mode) { this.mCdmaEriIconMode = mode; } public void setOperatorName(String longName, String shortName, String numeric) { mVoiceOperatorAlphaLong = longName; mVoiceOperatorAlphaShort = shortName; mVoiceOperatorNumeric = numeric; mDataOperatorAlphaLong = longName; mDataOperatorAlphaShort = shortName; mDataOperatorNumeric = numeric; } /** @hide */ public void setVoiceOperatorName(String longName, String shortName, String numeric) { mVoiceOperatorAlphaLong = longName; mVoiceOperatorAlphaShort = shortName; mVoiceOperatorNumeric = numeric; } /** @hide */ public void setDataOperatorName(String longName, String shortName, String numeric) { mDataOperatorAlphaLong = longName; mDataOperatorAlphaShort = shortName; mDataOperatorNumeric = numeric; } /** * In CDMA, mOperatorAlphaLong can be set from the ERI text. * This is done from the GsmCdmaPhone and not from the ServiceStateTracker. * * @hide */ @UnsupportedAppUsage public void setOperatorAlphaLong(String longName) { mVoiceOperatorAlphaLong = longName; mDataOperatorAlphaLong = longName; } /** @hide */ public void setVoiceOperatorAlphaLong(String longName) { mVoiceOperatorAlphaLong = longName; } /** @hide */ public void setDataOperatorAlphaLong(String longName) { mDataOperatorAlphaLong = longName; } public void setIsManualSelection(boolean isManual) { mIsManualNetworkSelection = isManual; } /** * Test whether two objects hold the same data values or both are null. * * @param a first obj * @param b second obj * @return true if two objects equal or both are null */ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) private static boolean equalsHandlesNulls(Object a, Object b) { return (a == null) ? (b == null) : a.equals(b); } /** * Set ServiceState based on intent notifier map. * * @param m intent notifier map * @hide */ @UnsupportedAppUsage private void setFromNotifierBundle(Bundle m) { ServiceState ssFromBundle = m.getParcelable(Intent.EXTRA_SERVICE_STATE); if (ssFromBundle != null) { copyFrom(ssFromBundle); } } /** * Set intent notifier Bundle based on service state. * * @param m intent notifier Bundle * @hide */ @UnsupportedAppUsage public void fillInNotifierBundle(Bundle m) { m.putParcelable(Intent.EXTRA_SERVICE_STATE, this); // serviceState already consists of below entries. // for backward compatibility, we continue fill in below entries. m.putInt("voiceRegState", mVoiceRegState); m.putInt("dataRegState", mDataRegState); m.putInt("dataRoamingType", getDataRoamingType()); m.putInt("voiceRoamingType", getVoiceRoamingType()); m.putString("operator-alpha-long", mVoiceOperatorAlphaLong); m.putString("operator-alpha-short", mVoiceOperatorAlphaShort); m.putString("operator-numeric", mVoiceOperatorNumeric); m.putString("data-operator-alpha-long", mDataOperatorAlphaLong); m.putString("data-operator-alpha-short", mDataOperatorAlphaShort); m.putString("data-operator-numeric", mDataOperatorNumeric); m.putBoolean("manual", mIsManualNetworkSelection); m.putInt("radioTechnology", getRilVoiceRadioTechnology()); m.putInt("dataRadioTechnology", getRadioTechnology()); m.putBoolean("cssIndicator", mCssIndicator); m.putInt("networkId", mNetworkId); m.putInt("systemId", mSystemId); m.putInt("cdmaRoamingIndicator", mCdmaRoamingIndicator); m.putInt("cdmaDefaultRoamingIndicator", mCdmaDefaultRoamingIndicator); m.putBoolean("emergencyOnly", mIsEmergencyOnly); m.putBoolean("isDataRoamingFromRegistration", getDataRoamingFromRegistration()); m.putBoolean("isUsingCarrierAggregation", isUsingCarrierAggregation()); m.putInt("LteEarfcnRsrpBoost", mLteEarfcnRsrpBoost); m.putInt("ChannelNumber", mChannelNumber); m.putIntArray("CellBandwidths", mCellBandwidths); m.putInt("mNrFrequencyRange", mNrFrequencyRange); m.putString("operator-alpha-long-raw", mOperatorAlphaLongRaw); m.putString("operator-alpha-short-raw", mOperatorAlphaShortRaw); } /** @hide */ @TestApi public void setRilVoiceRadioTechnology(@RilRadioTechnology int rt) { Rlog.e(LOG_TAG, "ServiceState.setRilVoiceRadioTechnology() called. It's encouraged to " + "use addNetworkRegistrationInfo() instead *******"); // Sync to network registration state NetworkRegistrationInfo regInfo = getNetworkRegistrationInfo(NetworkRegistrationInfo.DOMAIN_CS, AccessNetworkConstants.TRANSPORT_TYPE_WWAN); if (regInfo == null) { regInfo = new NetworkRegistrationInfo.Builder().setDomain(NetworkRegistrationInfo.DOMAIN_CS) .setTransportType(AccessNetworkConstants.TRANSPORT_TYPE_WWAN).build(); } regInfo.setAccessNetworkTechnology(rilRadioTechnologyToNetworkType(rt)); addNetworkRegistrationInfo(regInfo); } /** @hide */ @TestApi public void setRilDataRadioTechnology(@RilRadioTechnology int rt) { Rlog.e(LOG_TAG, "ServiceState.setRilDataRadioTechnology() called. It's encouraged to " + "use addNetworkRegistrationInfo() instead *******"); // Sync to network registration state. Always write down the WWAN transport. For AP-assisted // mode device, use addNetworkRegistrationInfo() to set the correct transport if RAT // is IWLAN. NetworkRegistrationInfo regInfo = getNetworkRegistrationInfo(NetworkRegistrationInfo.DOMAIN_PS, AccessNetworkConstants.TRANSPORT_TYPE_WWAN); if (regInfo == null) { regInfo = new NetworkRegistrationInfo.Builder().setDomain(NetworkRegistrationInfo.DOMAIN_PS) .setTransportType(AccessNetworkConstants.TRANSPORT_TYPE_WWAN).build(); } regInfo.setAccessNetworkTechnology(rilRadioTechnologyToNetworkType(rt)); addNetworkRegistrationInfo(regInfo); } /** @hide */ public boolean isUsingCarrierAggregation() { NetworkRegistrationInfo nri = getNetworkRegistrationInfo(NetworkRegistrationInfo.DOMAIN_PS, AccessNetworkConstants.TRANSPORT_TYPE_WWAN); if (nri != null) { DataSpecificRegistrationInfo dsri = nri.getDataSpecificInfo(); if (dsri != null) { return dsri.isUsingCarrierAggregation(); } } return false; } /** @hide */ public void setIsUsingCarrierAggregation(boolean ca) { NetworkRegistrationInfo nri = getNetworkRegistrationInfo(NetworkRegistrationInfo.DOMAIN_PS, AccessNetworkConstants.TRANSPORT_TYPE_WWAN); if (nri != null) { DataSpecificRegistrationInfo dsri = nri.getDataSpecificInfo(); if (dsri != null) { dsri.setIsUsingCarrierAggregation(ca); } } } /** * @return the frequency range of 5G NR. * @hide */ public @FrequencyRange int getNrFrequencyRange() { return mNrFrequencyRange; } /** * Get the NR 5G state of the mobile data network. * @return the NR 5G state. * @hide */ public @NRState int getNrState() { final NetworkRegistrationInfo regInfo = getNetworkRegistrationInfo(NetworkRegistrationInfo.DOMAIN_PS, AccessNetworkConstants.TRANSPORT_TYPE_WWAN); if (regInfo == null) return NetworkRegistrationInfo.NR_STATE_NONE; return regInfo.getNrState(); } /** * @param nrFrequencyRange the frequency range of 5G NR. * @hide */ public void setNrFrequencyRange(@FrequencyRange int nrFrequencyRange) { mNrFrequencyRange = nrFrequencyRange; } /** @hide */ public int getLteEarfcnRsrpBoost() { return mLteEarfcnRsrpBoost; } /** @hide */ public void setLteEarfcnRsrpBoost(int LteEarfcnRsrpBoost) { mLteEarfcnRsrpBoost = LteEarfcnRsrpBoost; } /** @hide */ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) public void setCssIndicator(int css) { this.mCssIndicator = (css != 0); } /** @hide */ @TestApi public void setCdmaSystemAndNetworkId(int systemId, int networkId) { this.mSystemId = systemId; this.mNetworkId = networkId; } /** @hide */ @UnsupportedAppUsage public int getRilVoiceRadioTechnology() { NetworkRegistrationInfo wwanRegInfo = getNetworkRegistrationInfo(NetworkRegistrationInfo.DOMAIN_CS, AccessNetworkConstants.TRANSPORT_TYPE_WWAN); if (wwanRegInfo != null) { return networkTypeToRilRadioTechnology(wwanRegInfo.getAccessNetworkTechnology()); } return RIL_RADIO_TECHNOLOGY_UNKNOWN; } /** @hide */ @UnsupportedAppUsage public int getRilDataRadioTechnology() { return networkTypeToRilRadioTechnology(getDataNetworkType()); } /** * @hide * @Deprecated to be removed Q3 2013 use {@link #getRilDataRadioTechnology} or * {@link #getRilVoiceRadioTechnology} */ @UnsupportedAppUsage public int getRadioTechnology() { Rlog.e(LOG_TAG, "ServiceState.getRadioTechnology() DEPRECATED will be removed *******"); return getRilDataRadioTechnology(); } /** @hide */ public static int rilRadioTechnologyToNetworkType(@RilRadioTechnology int rat) { switch (rat) { case ServiceState.RIL_RADIO_TECHNOLOGY_GPRS: return TelephonyManager.NETWORK_TYPE_GPRS; case ServiceState.RIL_RADIO_TECHNOLOGY_EDGE: return TelephonyManager.NETWORK_TYPE_EDGE; case ServiceState.RIL_RADIO_TECHNOLOGY_UMTS: return TelephonyManager.NETWORK_TYPE_UMTS; case ServiceState.RIL_RADIO_TECHNOLOGY_HSDPA: return TelephonyManager.NETWORK_TYPE_HSDPA; case ServiceState.RIL_RADIO_TECHNOLOGY_HSUPA: return TelephonyManager.NETWORK_TYPE_HSUPA; case ServiceState.RIL_RADIO_TECHNOLOGY_HSPA: return TelephonyManager.NETWORK_TYPE_HSPA; case ServiceState.RIL_RADIO_TECHNOLOGY_IS95A: case ServiceState.RIL_RADIO_TECHNOLOGY_IS95B: return TelephonyManager.NETWORK_TYPE_CDMA; case ServiceState.RIL_RADIO_TECHNOLOGY_1xRTT: return TelephonyManager.NETWORK_TYPE_1xRTT; case ServiceState.RIL_RADIO_TECHNOLOGY_EVDO_0: return TelephonyManager.NETWORK_TYPE_EVDO_0; case ServiceState.RIL_RADIO_TECHNOLOGY_EVDO_A: return TelephonyManager.NETWORK_TYPE_EVDO_A; case ServiceState.RIL_RADIO_TECHNOLOGY_EVDO_B: return TelephonyManager.NETWORK_TYPE_EVDO_B; case ServiceState.RIL_RADIO_TECHNOLOGY_EHRPD: return TelephonyManager.NETWORK_TYPE_EHRPD; case ServiceState.RIL_RADIO_TECHNOLOGY_LTE: return TelephonyManager.NETWORK_TYPE_LTE; case ServiceState.RIL_RADIO_TECHNOLOGY_HSPAP: return TelephonyManager.NETWORK_TYPE_HSPAP; case ServiceState.RIL_RADIO_TECHNOLOGY_GSM: return TelephonyManager.NETWORK_TYPE_GSM; case ServiceState.RIL_RADIO_TECHNOLOGY_TD_SCDMA: return TelephonyManager.NETWORK_TYPE_TD_SCDMA; case ServiceState.RIL_RADIO_TECHNOLOGY_IWLAN: return TelephonyManager.NETWORK_TYPE_IWLAN; case ServiceState.RIL_RADIO_TECHNOLOGY_LTE_CA: return TelephonyManager.NETWORK_TYPE_LTE_CA; case ServiceState.RIL_RADIO_TECHNOLOGY_NR: return TelephonyManager.NETWORK_TYPE_NR; default: return TelephonyManager.NETWORK_TYPE_UNKNOWN; } } /** @hide */ public static int rilRadioTechnologyToAccessNetworkType(@RilRadioTechnology int rt) { switch (rt) { case RIL_RADIO_TECHNOLOGY_GPRS: case RIL_RADIO_TECHNOLOGY_EDGE: case RIL_RADIO_TECHNOLOGY_GSM: return AccessNetworkType.GERAN; case RIL_RADIO_TECHNOLOGY_UMTS: case RIL_RADIO_TECHNOLOGY_HSDPA: case RIL_RADIO_TECHNOLOGY_HSPAP: case RIL_RADIO_TECHNOLOGY_HSUPA: case RIL_RADIO_TECHNOLOGY_HSPA: case RIL_RADIO_TECHNOLOGY_TD_SCDMA: return AccessNetworkType.UTRAN; case RIL_RADIO_TECHNOLOGY_IS95A: case RIL_RADIO_TECHNOLOGY_IS95B: case RIL_RADIO_TECHNOLOGY_1xRTT: case RIL_RADIO_TECHNOLOGY_EVDO_0: case RIL_RADIO_TECHNOLOGY_EVDO_A: case RIL_RADIO_TECHNOLOGY_EVDO_B: case RIL_RADIO_TECHNOLOGY_EHRPD: return AccessNetworkType.CDMA2000; case RIL_RADIO_TECHNOLOGY_LTE: case RIL_RADIO_TECHNOLOGY_LTE_CA: return AccessNetworkType.EUTRAN; case RIL_RADIO_TECHNOLOGY_IWLAN: return AccessNetworkType.IWLAN; case RIL_RADIO_TECHNOLOGY_UNKNOWN: default: return AccessNetworkType.UNKNOWN; } } /** @hide */ public static int networkTypeToRilRadioTechnology(int networkType) { switch (networkType) { case TelephonyManager.NETWORK_TYPE_GPRS: return ServiceState.RIL_RADIO_TECHNOLOGY_GPRS; case TelephonyManager.NETWORK_TYPE_EDGE: return ServiceState.RIL_RADIO_TECHNOLOGY_EDGE; case TelephonyManager.NETWORK_TYPE_UMTS: return ServiceState.RIL_RADIO_TECHNOLOGY_UMTS; case TelephonyManager.NETWORK_TYPE_HSDPA: return ServiceState.RIL_RADIO_TECHNOLOGY_HSDPA; case TelephonyManager.NETWORK_TYPE_HSUPA: return ServiceState.RIL_RADIO_TECHNOLOGY_HSUPA; case TelephonyManager.NETWORK_TYPE_HSPA: return ServiceState.RIL_RADIO_TECHNOLOGY_HSPA; case TelephonyManager.NETWORK_TYPE_CDMA: return ServiceState.RIL_RADIO_TECHNOLOGY_IS95A; case TelephonyManager.NETWORK_TYPE_1xRTT: return ServiceState.RIL_RADIO_TECHNOLOGY_1xRTT; case TelephonyManager.NETWORK_TYPE_EVDO_0: return ServiceState.RIL_RADIO_TECHNOLOGY_EVDO_0; case TelephonyManager.NETWORK_TYPE_EVDO_A: return ServiceState.RIL_RADIO_TECHNOLOGY_EVDO_A; case TelephonyManager.NETWORK_TYPE_EVDO_B: return ServiceState.RIL_RADIO_TECHNOLOGY_EVDO_B; case TelephonyManager.NETWORK_TYPE_EHRPD: return ServiceState.RIL_RADIO_TECHNOLOGY_EHRPD; case TelephonyManager.NETWORK_TYPE_LTE: return ServiceState.RIL_RADIO_TECHNOLOGY_LTE; case TelephonyManager.NETWORK_TYPE_HSPAP: return ServiceState.RIL_RADIO_TECHNOLOGY_HSPAP; case TelephonyManager.NETWORK_TYPE_GSM: return ServiceState.RIL_RADIO_TECHNOLOGY_GSM; case TelephonyManager.NETWORK_TYPE_TD_SCDMA: return ServiceState.RIL_RADIO_TECHNOLOGY_TD_SCDMA; case TelephonyManager.NETWORK_TYPE_IWLAN: return ServiceState.RIL_RADIO_TECHNOLOGY_IWLAN; case TelephonyManager.NETWORK_TYPE_LTE_CA: return ServiceState.RIL_RADIO_TECHNOLOGY_LTE_CA; default: return ServiceState.RIL_RADIO_TECHNOLOGY_UNKNOWN; } } /** @hide */ public static int networkTypeToAccessNetworkType(@TelephonyManager.NetworkType int networkType) { return rilRadioTechnologyToAccessNetworkType(networkTypeToRilRadioTechnology(networkType)); } /** * Get current data network type. * * Note that for IWLAN AP-assisted mode device, which is reporting both camped access networks * (cellular RAT and IWLAN)at the same time, this API is simulating the old legacy mode device * behavior, * * @return Current data network type * @hide */ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P) public @TelephonyManager.NetworkType int getDataNetworkType() { final NetworkRegistrationInfo iwlanRegInfo = getNetworkRegistrationInfo(NetworkRegistrationInfo.DOMAIN_PS, AccessNetworkConstants.TRANSPORT_TYPE_WLAN); final NetworkRegistrationInfo wwanRegInfo = getNetworkRegistrationInfo(NetworkRegistrationInfo.DOMAIN_PS, AccessNetworkConstants.TRANSPORT_TYPE_WWAN); // For legacy mode device, or AP-assisted mode device but IWLAN is out of service, use // the RAT from cellular. if (iwlanRegInfo == null || !iwlanRegInfo.isInService()) { return (wwanRegInfo != null) ? wwanRegInfo.getAccessNetworkTechnology() : TelephonyManager.NETWORK_TYPE_UNKNOWN; } // At this point, it must be an AP-assisted mode device and IWLAN is in service. We should // use the RAT from IWLAN service is cellular is out of service, or when both are in service // and any APN type of data is preferred on IWLAN. if (!wwanRegInfo.isInService() || mIsIwlanPreferred) { return iwlanRegInfo.getAccessNetworkTechnology(); } // If both cellular and IWLAN are in service, but no APN is preferred on IWLAN, still use // the RAT from cellular. return wwanRegInfo.getAccessNetworkTechnology(); } /** @hide */ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P) public @TelephonyManager.NetworkType int getVoiceNetworkType() { final NetworkRegistrationInfo regState = getNetworkRegistrationInfo(NetworkRegistrationInfo.DOMAIN_CS, AccessNetworkConstants.TRANSPORT_TYPE_WWAN); if (regState != null) { return regState.getAccessNetworkTechnology(); } return TelephonyManager.NETWORK_TYPE_UNKNOWN; } /** @hide */ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) public int getCssIndicator() { return this.mCssIndicator ? 1 : 0; } /** * Get the CDMA NID (Network Identification Number), a number uniquely identifying a network * within a wireless system. (Defined in 3GPP2 C.S0023 3.4.8) * @return The CDMA NID or {@link #UNKNOWN_ID} if not available. */ public int getCdmaNetworkId() { return this.mNetworkId; } /** * Get the CDMA SID (System Identification Number), a number uniquely identifying a wireless * system. (Defined in 3GPP2 C.S0023 3.4.8) * @return The CDMA SID or {@link #UNKNOWN_ID} if not available. */ public int getCdmaSystemId() { return this.mSystemId; } /** @hide */ @UnsupportedAppUsage public static boolean isGsm(int radioTechnology) { return radioTechnology == RIL_RADIO_TECHNOLOGY_GPRS || radioTechnology == RIL_RADIO_TECHNOLOGY_EDGE || radioTechnology == RIL_RADIO_TECHNOLOGY_UMTS || radioTechnology == RIL_RADIO_TECHNOLOGY_HSDPA || radioTechnology == RIL_RADIO_TECHNOLOGY_HSUPA || radioTechnology == RIL_RADIO_TECHNOLOGY_HSPA || radioTechnology == RIL_RADIO_TECHNOLOGY_LTE || radioTechnology == RIL_RADIO_TECHNOLOGY_HSPAP || radioTechnology == RIL_RADIO_TECHNOLOGY_GSM || radioTechnology == RIL_RADIO_TECHNOLOGY_TD_SCDMA || radioTechnology == RIL_RADIO_TECHNOLOGY_IWLAN || radioTechnology == RIL_RADIO_TECHNOLOGY_LTE_CA; } /** @hide */ @UnsupportedAppUsage public static boolean isCdma(int radioTechnology) { return radioTechnology == RIL_RADIO_TECHNOLOGY_IS95A || radioTechnology == RIL_RADIO_TECHNOLOGY_IS95B || radioTechnology == RIL_RADIO_TECHNOLOGY_1xRTT || radioTechnology == RIL_RADIO_TECHNOLOGY_EVDO_0 || radioTechnology == RIL_RADIO_TECHNOLOGY_EVDO_A || radioTechnology == RIL_RADIO_TECHNOLOGY_EVDO_B || radioTechnology == RIL_RADIO_TECHNOLOGY_EHRPD; } /** @hide */ public static boolean isLte(int radioTechnology) { return radioTechnology == RIL_RADIO_TECHNOLOGY_LTE || radioTechnology == RIL_RADIO_TECHNOLOGY_LTE_CA; } /** @hide */ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) public static boolean bearerBitmapHasCdma(int networkTypeBitmask) { return (RIL_RADIO_CDMA_TECHNOLOGY_BITMASK & convertNetworkTypeBitmaskToBearerBitmask(networkTypeBitmask)) != 0; } /** @hide */ @UnsupportedAppUsage public static boolean bitmaskHasTech(int bearerBitmask, int radioTech) { if (bearerBitmask == 0) { return true; } else if (radioTech >= 1) { return ((bearerBitmask & (1 << (radioTech - 1))) != 0); } return false; } /** * * Returns whether the bearerBitmask includes a networkType that matches the accessNetworkType. * * The NetworkType refers to NetworkType in TelephonyManager. For example * {@link TelephonyManager#NETWORK_TYPE_GPRS}. * * The accessNetworkType refers to {@link AccessNetworkType}. * * @hide * */ public static boolean networkBitmaskHasAccessNetworkType( @TelephonyManager.NetworkTypeBitMask int networkBitmask, int accessNetworkType) { if (networkBitmask == NETWORK_TYPE_BITMASK_UNKNOWN) return true; if (accessNetworkType == AccessNetworkType.UNKNOWN) return false; int networkType = 1; while (networkBitmask != 0) { if ((networkBitmask & 1) != 0) { if (networkTypeToAccessNetworkType(networkType) == accessNetworkType) { return true; } } networkBitmask = networkBitmask >> 1; networkType++; } return false; } /** @hide */ public static int getBitmaskForTech(int radioTech) { if (radioTech >= 1) { return (1 << (radioTech - 1)); } return 0; } /** @hide */ public static int getBitmaskFromString(String bearerList) { String[] bearers = bearerList.split("\\|"); int bearerBitmask = 0; for (String bearer : bearers) { int bearerInt = 0; try { bearerInt = Integer.parseInt(bearer.trim()); } catch (NumberFormatException nfe) { return 0; } if (bearerInt == 0) { return 0; } bearerBitmask |= getBitmaskForTech(bearerInt); } return bearerBitmask; } /** @hide */ public static int convertNetworkTypeBitmaskToBearerBitmask(int networkTypeBitmask) { if (networkTypeBitmask == 0) { return 0; } int bearerBitmask = 0; for (int bearerInt = 0; bearerInt < NEXT_RIL_RADIO_TECHNOLOGY; bearerInt++) { if (bitmaskHasTech(networkTypeBitmask, rilRadioTechnologyToNetworkType(bearerInt))) { bearerBitmask |= getBitmaskForTech(bearerInt); } } return bearerBitmask; } /** @hide */ public static int convertBearerBitmaskToNetworkTypeBitmask(int bearerBitmask) { if (bearerBitmask == 0) { return 0; } int networkTypeBitmask = 0; for (int bearerInt = 0; bearerInt < NEXT_RIL_RADIO_TECHNOLOGY; bearerInt++) { if (bitmaskHasTech(bearerBitmask, bearerInt)) { networkTypeBitmask |= getBitmaskForTech(rilRadioTechnologyToNetworkType(bearerInt)); } } return networkTypeBitmask; } /** * Returns a merged ServiceState consisting of the base SS with voice settings from the * voice SS. The voice SS is only used if it is IN_SERVICE (otherwise the base SS is returned). * @hide * */ @UnsupportedAppUsage public static ServiceState mergeServiceStates(ServiceState baseSs, ServiceState voiceSs) { if (voiceSs.mVoiceRegState != STATE_IN_SERVICE) { return baseSs; } ServiceState newSs = new ServiceState(baseSs); // voice overrides newSs.mVoiceRegState = voiceSs.mVoiceRegState; newSs.mIsEmergencyOnly = false; // only get here if voice is IN_SERVICE return newSs; } /** * Get all of the available network registration info. * * @return List of {@link NetworkRegistrationInfo} * @hide */ @NonNull @SystemApi public List<NetworkRegistrationInfo> getNetworkRegistrationInfoList() { synchronized (mNetworkRegistrationInfos) { List<NetworkRegistrationInfo> newList = new ArrayList<>(); for (NetworkRegistrationInfo nri : mNetworkRegistrationInfos) { newList.add(new NetworkRegistrationInfo(nri)); } return newList; } } /** * Get the network registration info list for the transport type. * * @param transportType The transport type * @return List of {@link NetworkRegistrationInfo} * @hide */ @NonNull @SystemApi public List<NetworkRegistrationInfo> getNetworkRegistrationInfoListForTransportType( @TransportType int transportType) { List<NetworkRegistrationInfo> list = new ArrayList<>(); synchronized (mNetworkRegistrationInfos) { for (NetworkRegistrationInfo networkRegistrationInfo : mNetworkRegistrationInfos) { if (networkRegistrationInfo.getTransportType() == transportType) { list.add(new NetworkRegistrationInfo(networkRegistrationInfo)); } } } return list; } /** * Get the network registration info list for the network domain. * * @param domain The network {@link NetworkRegistrationInfo.Domain domain} * @return List of {@link NetworkRegistrationInfo} * @hide */ @NonNull @SystemApi public List<NetworkRegistrationInfo> getNetworkRegistrationInfoListForDomain(@Domain int domain) { List<NetworkRegistrationInfo> list = new ArrayList<>(); synchronized (mNetworkRegistrationInfos) { for (NetworkRegistrationInfo networkRegistrationInfo : mNetworkRegistrationInfos) { if (networkRegistrationInfo.getDomain() == domain) { list.add(new NetworkRegistrationInfo(networkRegistrationInfo)); } } } return list; } /** * Get the network registration state for the transport type and network domain. * * @param domain The network {@link NetworkRegistrationInfo.Domain domain} * @param transportType The transport type * @return The matching {@link NetworkRegistrationInfo} * @hide * */ @Nullable @SystemApi public NetworkRegistrationInfo getNetworkRegistrationInfo(@Domain int domain, @TransportType int transportType) { synchronized (mNetworkRegistrationInfos) { for (NetworkRegistrationInfo networkRegistrationInfo : mNetworkRegistrationInfos) { if (networkRegistrationInfo.getTransportType() == transportType && networkRegistrationInfo.getDomain() == domain) { return new NetworkRegistrationInfo(networkRegistrationInfo); } } } return null; } /** * @hide */ @TestApi public void addNetworkRegistrationInfo(NetworkRegistrationInfo nri) { if (nri == null) return; synchronized (mNetworkRegistrationInfos) { for (int i = 0; i < mNetworkRegistrationInfos.size(); i++) { NetworkRegistrationInfo curRegState = mNetworkRegistrationInfos.get(i); if (curRegState.getTransportType() == nri.getTransportType() && curRegState.getDomain() == nri.getDomain()) { mNetworkRegistrationInfos.remove(i); break; } } mNetworkRegistrationInfos.add(new NetworkRegistrationInfo(nri)); } } /** * @hide */ public static final int getBetterNRFrequencyRange(int range1, int range2) { return FREQUENCY_RANGE_ORDER.indexOf(range1) > FREQUENCY_RANGE_ORDER.indexOf(range2) ? range1 : range2; } /** * Returns a copy of self with location-identifying information removed. * Always clears the NetworkRegistrationInfo's CellIdentity fields, but if removeCoarseLocation * is true, clears other info as well. * @hide */ public ServiceState sanitizeLocationInfo(boolean removeCoarseLocation) { ServiceState state = new ServiceState(this); synchronized (state.mNetworkRegistrationInfos) { List<NetworkRegistrationInfo> networkRegistrationInfos = state.mNetworkRegistrationInfos.stream() .map(NetworkRegistrationInfo::sanitizeLocationInfo).collect(Collectors.toList()); state.mNetworkRegistrationInfos.clear(); state.mNetworkRegistrationInfos.addAll(networkRegistrationInfos); } if (!removeCoarseLocation) return state; state.mDataOperatorAlphaLong = null; state.mDataOperatorAlphaShort = null; state.mDataOperatorNumeric = null; state.mVoiceOperatorAlphaLong = null; state.mVoiceOperatorAlphaShort = null; state.mVoiceOperatorNumeric = null; return state; } /** * @hide */ public void setOperatorAlphaLongRaw(String operatorAlphaLong) { mOperatorAlphaLongRaw = operatorAlphaLong; } /** * The current registered raw data network operator name in long alphanumeric format. * * @hide */ public String getOperatorAlphaLongRaw() { return mOperatorAlphaLongRaw; } /** * @hide */ public void setOperatorAlphaShortRaw(String operatorAlphaShort) { mOperatorAlphaShortRaw = operatorAlphaShort; } /** * The current registered raw data network operator name in short alphanumeric format. * * @hide */ public String getOperatorAlphaShortRaw() { return mOperatorAlphaShortRaw; } /** * Set to {@code true} if any data network is preferred on IWLAN. * * @param isIwlanPreferred {@code true} if IWLAN is preferred. * @hide */ public void setIwlanPreferred(boolean isIwlanPreferred) { mIsIwlanPreferred = isIwlanPreferred; } /** * @return {@code true} if any data network is preferred on IWLAN. * * Note only when this value is true, {@link #getDataNetworkType()} will return * {@link TelephonyManager#NETWORK_TYPE_IWLAN} when AP-assisted mode device camps on both * cellular and IWLAN. This value does not affect legacy mode devices as the data network * type is directly reported by the modem. * * @hide */ public boolean isIwlanPreferred() { return mIsIwlanPreferred; } }