/* * Copyright (C) 2014 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package android.telephony; import android.compat.annotation.UnsupportedAppUsage; import android.os.Build; import android.os.Parcel; import android.os.Parcelable; import android.telephony.TelephonyManager.PrefNetworkMode; import com.android.internal.telephony.RILConstants; import java.util.Locale; /** * Object to indicate the phone radio type and access technology. * * @hide */ public class RadioAccessFamily implements Parcelable { /** * TODO: get rid of RAF definition in RadioAccessFamily and * use {@link TelephonyManager.NetworkTypeBitMask} * TODO: public definition {@link TelephonyManager.NetworkTypeBitMask} is long. * TODO: Convert from int to long everywhere including HAL definitions. */ // 2G public static final int RAF_UNKNOWN = (int) TelephonyManager.NETWORK_TYPE_BITMASK_UNKNOWN; public static final int RAF_GSM = (int) TelephonyManager.NETWORK_TYPE_BITMASK_GSM; public static final int RAF_GPRS = (int) TelephonyManager.NETWORK_TYPE_BITMASK_GPRS; public static final int RAF_EDGE = (int) TelephonyManager.NETWORK_TYPE_BITMASK_EDGE; public static final int RAF_IS95A = (int) TelephonyManager.NETWORK_TYPE_BITMASK_CDMA; public static final int RAF_IS95B = (int) TelephonyManager.NETWORK_TYPE_BITMASK_CDMA; public static final int RAF_1xRTT = (int) TelephonyManager.NETWORK_TYPE_BITMASK_1xRTT; // 3G public static final int RAF_EVDO_0 = (int) TelephonyManager.NETWORK_TYPE_BITMASK_EVDO_0; public static final int RAF_EVDO_A = (int) TelephonyManager.NETWORK_TYPE_BITMASK_EVDO_A; public static final int RAF_EVDO_B = (int) TelephonyManager.NETWORK_TYPE_BITMASK_EVDO_B; public static final int RAF_EHRPD = (int) TelephonyManager.NETWORK_TYPE_BITMASK_EHRPD; public static final int RAF_HSUPA = (int) TelephonyManager.NETWORK_TYPE_BITMASK_HSUPA; public static final int RAF_HSDPA = (int) TelephonyManager.NETWORK_TYPE_BITMASK_HSDPA; public static final int RAF_HSPA = (int) TelephonyManager.NETWORK_TYPE_BITMASK_HSPA; public static final int RAF_HSPAP = (int) TelephonyManager.NETWORK_TYPE_BITMASK_HSPAP; public static final int RAF_UMTS = (int) TelephonyManager.NETWORK_TYPE_BITMASK_UMTS; public static final int RAF_TD_SCDMA = (int) TelephonyManager.NETWORK_TYPE_BITMASK_TD_SCDMA; // 4G public static final int RAF_LTE = (int) TelephonyManager.NETWORK_TYPE_BITMASK_LTE; public static final int RAF_LTE_CA = (int) TelephonyManager.NETWORK_TYPE_BITMASK_LTE_CA; // 5G public static final int RAF_NR = (int) TelephonyManager.NETWORK_TYPE_BITMASK_NR; // Grouping of RAFs // 2G private static final int GSM = RAF_GSM | RAF_GPRS | RAF_EDGE; private static final int CDMA = RAF_IS95A | RAF_IS95B | RAF_1xRTT; // 3G private static final int EVDO = RAF_EVDO_0 | RAF_EVDO_A | RAF_EVDO_B | RAF_EHRPD; private static final int HS = RAF_HSUPA | RAF_HSDPA | RAF_HSPA | RAF_HSPAP; private static final int WCDMA = HS | RAF_UMTS; // 4G private static final int LTE = RAF_LTE | RAF_LTE_CA; // 5G private static final int NR = RAF_NR; /* Phone ID of phone */ private int mPhoneId; /* Radio Access Family */ private int mRadioAccessFamily; /** * Constructor. * * @param phoneId the phone ID * @param radioAccessFamily the phone radio access family bitmask based on * {@link TelephonyManager.NetworkTypeBitMask}. It's a bit mask value to represent the support * type. */ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public RadioAccessFamily(int phoneId, int radioAccessFamily) { mPhoneId = phoneId; mRadioAccessFamily = radioAccessFamily; } /** * Get phone ID. * * @return phone ID */ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public int getPhoneId() { return mPhoneId; } /** * get radio access family. * * @return radio access family */ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public @TelephonyManager.NetworkTypeBitMask int getRadioAccessFamily() { return mRadioAccessFamily; } @Override public String toString() { String ret = "{ mPhoneId = " + mPhoneId + ", mRadioAccessFamily = " + mRadioAccessFamily + "}"; return ret; } /** * Implement the Parcelable interface. * * @return describe content */ @Override public int describeContents() { return 0; } /** * Implement the Parcelable interface. * * @param outParcel The Parcel in which the object should be written. * @param flags Additional flags about how the object should be written. */ @Override public void writeToParcel(Parcel outParcel, int flags) { outParcel.writeInt(mPhoneId); outParcel.writeInt(mRadioAccessFamily); } /** * Implement the Parcelable interface. */ public static final @android.annotation.NonNull Creator CREATOR = new Creator() { @Override public android.telephony.RadioAccessFamily createFromParcel(Parcel in) { int phoneId = in.readInt(); int radioAccessFamily = in.readInt(); return new android.telephony.RadioAccessFamily(phoneId, radioAccessFamily); } @Override public android.telephony.RadioAccessFamily[] newArray(int size) { return new android.telephony.RadioAccessFamily[size]; } }; @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) @TelephonyManager.NetworkTypeBitMask public static int getRafFromNetworkType(@PrefNetworkMode int type) { switch (type) { case RILConstants.NETWORK_MODE_WCDMA_PREF: return GSM | WCDMA; case RILConstants.NETWORK_MODE_GSM_ONLY: return GSM; case RILConstants.NETWORK_MODE_WCDMA_ONLY: return WCDMA; case RILConstants.NETWORK_MODE_GSM_UMTS: return GSM | WCDMA; case RILConstants.NETWORK_MODE_CDMA: return CDMA | EVDO; case RILConstants.NETWORK_MODE_LTE_CDMA_EVDO: return LTE | CDMA | EVDO; case RILConstants.NETWORK_MODE_LTE_GSM_WCDMA: return LTE | GSM | WCDMA; case RILConstants.NETWORK_MODE_LTE_CDMA_EVDO_GSM_WCDMA: return LTE | CDMA | EVDO | GSM | WCDMA; case RILConstants.NETWORK_MODE_LTE_ONLY: return LTE; case RILConstants.NETWORK_MODE_LTE_WCDMA: return LTE | WCDMA; case RILConstants.NETWORK_MODE_CDMA_NO_EVDO: return CDMA; case RILConstants.NETWORK_MODE_EVDO_NO_CDMA: return EVDO; case RILConstants.NETWORK_MODE_GLOBAL: return GSM | WCDMA | CDMA | EVDO; case RILConstants.NETWORK_MODE_TDSCDMA_ONLY: return RAF_TD_SCDMA; case RILConstants.NETWORK_MODE_TDSCDMA_WCDMA: return RAF_TD_SCDMA | WCDMA; case RILConstants.NETWORK_MODE_LTE_TDSCDMA: return LTE | RAF_TD_SCDMA; case RILConstants.NETWORK_MODE_TDSCDMA_GSM: return RAF_TD_SCDMA | GSM; case RILConstants.NETWORK_MODE_LTE_TDSCDMA_GSM: return LTE | RAF_TD_SCDMA | GSM; case RILConstants.NETWORK_MODE_TDSCDMA_GSM_WCDMA: return RAF_TD_SCDMA | GSM | WCDMA; case RILConstants.NETWORK_MODE_LTE_TDSCDMA_WCDMA: return LTE | RAF_TD_SCDMA | WCDMA; case RILConstants.NETWORK_MODE_LTE_TDSCDMA_GSM_WCDMA: return LTE | RAF_TD_SCDMA | GSM | WCDMA; case RILConstants.NETWORK_MODE_TDSCDMA_CDMA_EVDO_GSM_WCDMA: return RAF_TD_SCDMA | CDMA | EVDO | GSM | WCDMA; case RILConstants.NETWORK_MODE_LTE_TDSCDMA_CDMA_EVDO_GSM_WCDMA: return LTE | RAF_TD_SCDMA | CDMA | EVDO | GSM | WCDMA; case (RILConstants.NETWORK_MODE_NR_ONLY): return NR; case (RILConstants.NETWORK_MODE_NR_LTE): return NR | LTE; case (RILConstants.NETWORK_MODE_NR_LTE_CDMA_EVDO): return NR | LTE | CDMA | EVDO; case (RILConstants.NETWORK_MODE_NR_LTE_GSM_WCDMA): return NR | LTE | GSM | WCDMA; case (RILConstants.NETWORK_MODE_NR_LTE_CDMA_EVDO_GSM_WCDMA): return NR | LTE | CDMA | EVDO | GSM | WCDMA; case (RILConstants.NETWORK_MODE_NR_LTE_WCDMA): return NR | LTE | WCDMA; case (RILConstants.NETWORK_MODE_NR_LTE_TDSCDMA): return NR | LTE | RAF_TD_SCDMA; case (RILConstants.NETWORK_MODE_NR_LTE_TDSCDMA_GSM): return NR | LTE | RAF_TD_SCDMA | GSM; case (RILConstants.NETWORK_MODE_NR_LTE_TDSCDMA_WCDMA): return NR | LTE | RAF_TD_SCDMA | WCDMA; case (RILConstants.NETWORK_MODE_NR_LTE_TDSCDMA_GSM_WCDMA): return NR | LTE | RAF_TD_SCDMA | GSM | WCDMA; case (RILConstants.NETWORK_MODE_NR_LTE_TDSCDMA_CDMA_EVDO_GSM_WCDMA): return NR | LTE | RAF_TD_SCDMA | CDMA | EVDO | GSM | WCDMA; default: return RAF_UNKNOWN; } } /** * if the raf includes ANY bit set for a group * adjust it to contain ALL the bits for that group */ private static int getAdjustedRaf(int raf) { raf = ((GSM & raf) > 0) ? (GSM | raf) : raf; raf = ((WCDMA & raf) > 0) ? (WCDMA | raf) : raf; raf = ((CDMA & raf) > 0) ? (CDMA | raf) : raf; raf = ((EVDO & raf) > 0) ? (EVDO | raf) : raf; raf = ((LTE & raf) > 0) ? (LTE | raf) : raf; raf = ((NR & raf) > 0) ? (NR | raf) : raf; return raf; } @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) @PrefNetworkMode public static int getNetworkTypeFromRaf(int raf) { raf = getAdjustedRaf(raf); switch (raf) { case (GSM | WCDMA): return RILConstants.NETWORK_MODE_WCDMA_PREF; case GSM: return RILConstants.NETWORK_MODE_GSM_ONLY; case WCDMA: return RILConstants.NETWORK_MODE_WCDMA_ONLY; case (CDMA | EVDO): return RILConstants.NETWORK_MODE_CDMA; case (LTE | CDMA | EVDO): return RILConstants.NETWORK_MODE_LTE_CDMA_EVDO; case (LTE | GSM | WCDMA): return RILConstants.NETWORK_MODE_LTE_GSM_WCDMA; case (LTE | CDMA | EVDO | GSM | WCDMA): return RILConstants.NETWORK_MODE_LTE_CDMA_EVDO_GSM_WCDMA; case LTE: return RILConstants.NETWORK_MODE_LTE_ONLY; case (LTE | WCDMA): return RILConstants.NETWORK_MODE_LTE_WCDMA; case CDMA: return RILConstants.NETWORK_MODE_CDMA_NO_EVDO; case EVDO: return RILConstants.NETWORK_MODE_EVDO_NO_CDMA; case (GSM | WCDMA | CDMA | EVDO): return RILConstants.NETWORK_MODE_GLOBAL; case RAF_TD_SCDMA: return RILConstants.NETWORK_MODE_TDSCDMA_ONLY; case (RAF_TD_SCDMA | WCDMA): return RILConstants.NETWORK_MODE_TDSCDMA_WCDMA; case (LTE | RAF_TD_SCDMA): return RILConstants.NETWORK_MODE_LTE_TDSCDMA; case (RAF_TD_SCDMA | GSM): return RILConstants.NETWORK_MODE_TDSCDMA_GSM; case (LTE | RAF_TD_SCDMA | GSM): return RILConstants.NETWORK_MODE_LTE_TDSCDMA_GSM; case (RAF_TD_SCDMA | GSM | WCDMA): return RILConstants.NETWORK_MODE_TDSCDMA_GSM_WCDMA; case (LTE | RAF_TD_SCDMA | WCDMA): return RILConstants.NETWORK_MODE_LTE_TDSCDMA_WCDMA; case (LTE | RAF_TD_SCDMA | GSM | WCDMA): return RILConstants.NETWORK_MODE_LTE_TDSCDMA_GSM_WCDMA; case (RAF_TD_SCDMA | CDMA | EVDO | GSM | WCDMA): return RILConstants.NETWORK_MODE_TDSCDMA_CDMA_EVDO_GSM_WCDMA; case (LTE | RAF_TD_SCDMA | CDMA | EVDO | GSM | WCDMA): return RILConstants.NETWORK_MODE_LTE_TDSCDMA_CDMA_EVDO_GSM_WCDMA; case (NR): return RILConstants.NETWORK_MODE_NR_ONLY; case (NR | LTE): return RILConstants.NETWORK_MODE_NR_LTE; case (NR | LTE | CDMA | EVDO): return RILConstants.NETWORK_MODE_NR_LTE_CDMA_EVDO; case (NR | LTE | GSM | WCDMA): return RILConstants.NETWORK_MODE_NR_LTE_GSM_WCDMA; case (NR | LTE | CDMA | EVDO | GSM | WCDMA): return RILConstants.NETWORK_MODE_NR_LTE_CDMA_EVDO_GSM_WCDMA; case (NR | LTE | WCDMA): return RILConstants.NETWORK_MODE_NR_LTE_WCDMA; case (NR | LTE | RAF_TD_SCDMA): return RILConstants.NETWORK_MODE_NR_LTE_TDSCDMA; case (NR | LTE | RAF_TD_SCDMA | GSM): return RILConstants.NETWORK_MODE_NR_LTE_TDSCDMA_GSM; case (NR | LTE | RAF_TD_SCDMA | WCDMA): return RILConstants.NETWORK_MODE_NR_LTE_TDSCDMA_WCDMA; case (NR | LTE | RAF_TD_SCDMA | GSM | WCDMA): return RILConstants.NETWORK_MODE_NR_LTE_TDSCDMA_GSM_WCDMA; case (NR | LTE | RAF_TD_SCDMA | CDMA | EVDO | GSM | WCDMA): return RILConstants.NETWORK_MODE_NR_LTE_TDSCDMA_CDMA_EVDO_GSM_WCDMA; default: return RILConstants.PREFERRED_NETWORK_MODE; } } public static int singleRafTypeFromString(String rafString) { switch (rafString) { case "GPRS": return RAF_GPRS; case "EDGE": return RAF_EDGE; case "UMTS": return RAF_UMTS; case "IS95A": return RAF_IS95A; case "IS95B": return RAF_IS95B; case "1XRTT": return RAF_1xRTT; case "EVDO_0": return RAF_EVDO_0; case "EVDO_A": return RAF_EVDO_A; case "HSDPA": return RAF_HSDPA; case "HSUPA": return RAF_HSUPA; case "HSPA": return RAF_HSPA; case "EVDO_B": return RAF_EVDO_B; case "EHRPD": return RAF_EHRPD; case "LTE": return RAF_LTE; case "HSPAP": return RAF_HSPAP; case "GSM": return RAF_GSM; case "TD_SCDMA":return RAF_TD_SCDMA; case "HS": return HS; case "CDMA": return CDMA; case "EVDO": return EVDO; case "WCDMA": return WCDMA; case "LTE_CA": return RAF_LTE_CA; case "NR": return RAF_NR; default: return RAF_UNKNOWN; } } public static int rafTypeFromString(String rafList) { rafList = rafList.toUpperCase(Locale.ROOT); String[] rafs = rafList.split("\\|"); int result = 0; for(String raf : rafs) { int rafType = singleRafTypeFromString(raf.trim()); if (rafType == RAF_UNKNOWN) return rafType; result |= rafType; } return result; } /** * Compare two sets of network types to see which is more capable. * * This algorithm first tries to see see if a set has a strict superset of RAT support for * each generation, from newest to oldest; if that results in a tie, then it returns the set * that supports the most RAT types. */ public static int compare(long networkTypeBitmaskL, long networkTypeBitmaskR) { final long[] prioritizedNetworkClassBitmasks = new long[] { TelephonyManager.NETWORK_CLASS_BITMASK_5G, TelephonyManager.NETWORK_CLASS_BITMASK_4G, TelephonyManager.NETWORK_CLASS_BITMASK_3G, TelephonyManager.NETWORK_CLASS_BITMASK_2G, }; long lhsUnique = networkTypeBitmaskL & ~networkTypeBitmaskR; long rhsUnique = networkTypeBitmaskR & ~networkTypeBitmaskL; // See if one has a strict super-set of capabilities, generation by generation. for (long classBitmask : prioritizedNetworkClassBitmasks) { int result = 0; if ((lhsUnique & classBitmask) != 0) ++result; if ((rhsUnique & classBitmask) != 0) --result; if (result != 0) return result; } // Without a clear winner, return the one that supports the most types. return Long.bitCount(networkTypeBitmaskL) - Long.bitCount(networkTypeBitmaskR); } }