/*
 * Copyright (C) 2012 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package android.telephony;

import android.annotation.NonNull;
import android.annotation.UnsupportedAppUsage;
import android.os.Build;
import android.os.Bundle;
import android.os.Parcel;
import android.os.Parcelable;
import android.os.PersistableBundle;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

/**
 * Contains phone signal strength related information.
 */
public class SignalStrength implements Parcelable {

    private static final String LOG_TAG = "SignalStrength";
    private static final boolean DBG = false;

    /** @hide */
    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
    public static final int SIGNAL_STRENGTH_NONE_OR_UNKNOWN =
            CellSignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN; // = 0
    /** @hide */
    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
    public static final int SIGNAL_STRENGTH_POOR =
            CellSignalStrength.SIGNAL_STRENGTH_POOR; // = 1
    /** @hide */
    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
    public static final int SIGNAL_STRENGTH_MODERATE =
            CellSignalStrength.SIGNAL_STRENGTH_MODERATE; // = 2
    /** @hide */
    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
    public static final int SIGNAL_STRENGTH_GOOD =
            CellSignalStrength.SIGNAL_STRENGTH_GOOD; // = 3
    /** @hide */
    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
    public static final int SIGNAL_STRENGTH_GREAT =
            CellSignalStrength.SIGNAL_STRENGTH_GREAT; // = 4
    /** @hide */
    @UnsupportedAppUsage
    public static final int NUM_SIGNAL_STRENGTH_BINS = 5;

    /** SIGNAL_STRENGTH_NAMES is currently used by BatteryStats, but to-be-removed soon. */
    /** @hide */
    public static final String[] SIGNAL_STRENGTH_NAMES = {
        "none", "poor", "moderate", "good", "great"
    };

    /**
     * Indicates the invalid measures of signal strength.
     *
     * For example, this can be returned by {@link #getEvdoDbm()} or {@link #getCdmaDbm()}
     */
    public static final int INVALID = Integer.MAX_VALUE;

    private static final int LTE_RSRP_THRESHOLDS_NUM = 4;

    private static final int WCDMA_RSCP_THRESHOLDS_NUM = 4;

    /* The type of signal measurement */
    private static final String MEASUREMENT_TYPE_RSCP = "rscp";

    CellSignalStrengthCdma mCdma;
    CellSignalStrengthGsm mGsm;
    CellSignalStrengthWcdma mWcdma;
    CellSignalStrengthTdscdma mTdscdma;
    CellSignalStrengthLte mLte;
    CellSignalStrengthNr mNr;

    /**
     * Create a new SignalStrength 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 SignalStrength
     *
     * @hide
     */
    @UnsupportedAppUsage
    public static SignalStrength newFromBundle(Bundle m) {
        SignalStrength ret;
        ret = new SignalStrength();
        ret.setFromNotifierBundle(m);
        return ret;
    }

    /**
     * This constructor is used to create SignalStrength with default
     * values.
     *
     * @return newly created SignalStrength
     * @hide
     */
    @UnsupportedAppUsage
    public SignalStrength() {
        this(new CellSignalStrengthCdma(), new CellSignalStrengthGsm(),
                new CellSignalStrengthWcdma(), new CellSignalStrengthTdscdma(),
                new CellSignalStrengthLte(), new CellSignalStrengthNr());
    }

    /**
     * Constructor with all fields present
     *
     * @hide
     */
    public SignalStrength(
            @NonNull CellSignalStrengthCdma cdma,
            @NonNull CellSignalStrengthGsm gsm,
            @NonNull CellSignalStrengthWcdma wcdma,
            @NonNull CellSignalStrengthTdscdma tdscdma,
            @NonNull CellSignalStrengthLte lte,
            @NonNull CellSignalStrengthNr nr) {
        mCdma = cdma;
        mGsm = gsm;
        mWcdma = wcdma;
        mTdscdma = tdscdma;
        mLte = lte;
        mNr = nr;
    }

    /**
     * Constructor for Radio HAL V1.0
     *
     * @hide
     */
    public SignalStrength(android.hardware.radio.V1_0.SignalStrength signalStrength) {
        this(new CellSignalStrengthCdma(signalStrength.cdma, signalStrength.evdo),
                new CellSignalStrengthGsm(signalStrength.gw),
                new CellSignalStrengthWcdma(),
                new CellSignalStrengthTdscdma(signalStrength.tdScdma),
                new CellSignalStrengthLte(signalStrength.lte),
                new CellSignalStrengthNr());
    }

    /**
     * Constructor for Radio HAL V1.2
     *
     * @hide
     */
    public SignalStrength(android.hardware.radio.V1_2.SignalStrength signalStrength) {
        this(new CellSignalStrengthCdma(signalStrength.cdma, signalStrength.evdo),
                new CellSignalStrengthGsm(signalStrength.gsm),
                new CellSignalStrengthWcdma(signalStrength.wcdma),
                new CellSignalStrengthTdscdma(signalStrength.tdScdma),
                new CellSignalStrengthLte(signalStrength.lte),
                new CellSignalStrengthNr());
    }

    /**
     * Constructor for Radio HAL V1.4.
     *
     * @param signalStrength signal strength reported from modem.
     * @hide
     */
    public SignalStrength(android.hardware.radio.V1_4.SignalStrength signalStrength) {
        this(new CellSignalStrengthCdma(signalStrength.cdma, signalStrength.evdo),
                new CellSignalStrengthGsm(signalStrength.gsm),
                new CellSignalStrengthWcdma(signalStrength.wcdma),
                new CellSignalStrengthTdscdma(signalStrength.tdscdma),
                new CellSignalStrengthLte(signalStrength.lte),
                new CellSignalStrengthNr(signalStrength.nr));
    }

    private CellSignalStrength getPrimary() {
        // This behavior is intended to replicate the legacy behavior of getLevel() by prioritizing
        // newer faster RATs for default/for display purposes.
        if (mLte.isValid()) return mLte;
        if (mCdma.isValid()) return mCdma;
        if (mTdscdma.isValid()) return mTdscdma;
        if (mWcdma.isValid()) return mWcdma;
        if (mGsm.isValid()) return mGsm;
        if (mNr.isValid()) return mNr;
        return mLte;
    }

    /**
     * Returns a List of CellSignalStrength Components of this SignalStrength Report.
     *
     * Use this API to access underlying
     * {@link android.telephony#CellSignalStrength CellSignalStrength} objects that provide more
     * granular information about the SignalStrength report. Only valid (non-empty)
     * CellSignalStrengths will be returned. The order of any returned elements is not guaranteed,
     * and the list may contain more than one instance of a CellSignalStrength type.
     *
     * @return a List of CellSignalStrength or an empty List if there are no valid measurements.
     *
     * @see android.telephony#CellSignalStrength
     * @see android.telephony#CellSignalStrengthNr
     * @see android.telephony#CellSignalStrengthLte
     * @see android.telephony#CellSignalStrengthTdscdma
     * @see android.telephony#CellSignalStrengthWcdma
     * @see android.telephony#CellSignalStrengthCdma
     * @see android.telephony#CellSignalStrengthGsm
     */
    @NonNull public List<CellSignalStrength> getCellSignalStrengths() {
        return getCellSignalStrengths(CellSignalStrength.class);
    }

    /**
     * Returns a List of CellSignalStrength Components of this SignalStrength Report.
     *
     * Use this API to access underlying
     * {@link android.telephony#CellSignalStrength CellSignalStrength} objects that provide more
     * granular information about the SignalStrength report. Only valid (non-empty)
     * CellSignalStrengths will be returned. The order of any returned elements is not guaranteed,
     * and the list may contain more than one instance of a CellSignalStrength type.
     *
     * @param clazz a class type that extends
     *        {@link android.telephony.CellSignalStrength CellSignalStrength} to filter possible
     *        return values.
     * @return a List of CellSignalStrength or an empty List if there are no valid measurements.
     *
     * @see android.telephony#CellSignalStrength
     * @see android.telephony#CellSignalStrengthNr
     * @see android.telephony#CellSignalStrengthLte
     * @see android.telephony#CellSignalStrengthTdscdma
     * @see android.telephony#CellSignalStrengthWcdma
     * @see android.telephony#CellSignalStrengthCdma
     * @see android.telephony#CellSignalStrengthGsm
     */
    @NonNull public <T extends CellSignalStrength> List<T> getCellSignalStrengths(
            @NonNull Class<T> clazz) {
        List<T> cssList = new ArrayList<>(2); // Usually have 2 or fewer elems
        if (mLte.isValid() && clazz.isAssignableFrom(CellSignalStrengthLte.class)) {
            cssList.add((T) mLte);
        }
        if (mCdma.isValid() && clazz.isAssignableFrom(CellSignalStrengthCdma.class)) {
            cssList.add((T) mCdma);
        }
        if (mTdscdma.isValid() && clazz.isAssignableFrom(CellSignalStrengthTdscdma.class)) {
            cssList.add((T) mTdscdma);
        }
        if (mWcdma.isValid() && clazz.isAssignableFrom(CellSignalStrengthWcdma.class)) {
            cssList.add((T) mWcdma);
        }
        if (mGsm.isValid() && clazz.isAssignableFrom(CellSignalStrengthGsm.class)) {
            cssList.add((T) mGsm);
        }
        if (mNr.isValid() && clazz.isAssignableFrom(CellSignalStrengthNr.class)) {
            cssList.add((T) mNr);
        }
        return cssList;
    }

    /** @hide */
    public void updateLevel(PersistableBundle cc, ServiceState ss) {
        mCdma.updateLevel(cc, ss);
        mGsm.updateLevel(cc, ss);
        mWcdma.updateLevel(cc, ss);
        mTdscdma.updateLevel(cc, ss);
        mLte.updateLevel(cc, ss);
        mNr.updateLevel(cc, ss);
    }

    /**
     * Copy constructors
     *
     * @param s Source SignalStrength
     *
     * @hide
     */
    @UnsupportedAppUsage
    public SignalStrength(SignalStrength s) {
        copyFrom(s);
    }

    /**
     * @hide
     */
    @UnsupportedAppUsage
    protected void copyFrom(SignalStrength s) {
        mCdma = new CellSignalStrengthCdma(s.mCdma);
        mGsm = new CellSignalStrengthGsm(s.mGsm);
        mWcdma = new CellSignalStrengthWcdma(s.mWcdma);
        mTdscdma = new CellSignalStrengthTdscdma(s.mTdscdma);
        mLte = new CellSignalStrengthLte(s.mLte);
        mNr = new CellSignalStrengthNr(s.mNr);
    }

    /**
     * Construct a SignalStrength object from the given parcel.
     *
     * @hide
     */
    @UnsupportedAppUsage
    public SignalStrength(Parcel in) {
        if (DBG) log("Size of signalstrength parcel:" + in.dataSize());

        mCdma = in.readParcelable(CellSignalStrengthCdma.class.getClassLoader());
        mGsm = in.readParcelable(CellSignalStrengthGsm.class.getClassLoader());
        mWcdma = in.readParcelable(CellSignalStrengthWcdma.class.getClassLoader());
        mTdscdma = in.readParcelable(CellSignalStrengthTdscdma.class.getClassLoader());
        mLte = in.readParcelable(CellSignalStrengthLte.class.getClassLoader());
        mNr = in.readParcelable(CellSignalStrengthLte.class.getClassLoader());
    }

    /**
     * {@link Parcelable#writeToParcel}
     */
    public void writeToParcel(Parcel out, int flags) {
        out.writeParcelable(mCdma, flags);
        out.writeParcelable(mGsm, flags);
        out.writeParcelable(mWcdma, flags);
        out.writeParcelable(mTdscdma, flags);
        out.writeParcelable(mLte, flags);
        out.writeParcelable(mNr, flags);
    }

    /**
     * {@link Parcelable#describeContents}
     */
    public int describeContents() {
        return 0;
    }

    /**
     * {@link Parcelable.Creator}
     *
     * @hide
     */
    @UnsupportedAppUsage
    public static final @android.annotation.NonNull Parcelable.Creator<SignalStrength> CREATOR = new Parcelable.Creator() {
        public SignalStrength createFromParcel(Parcel in) {
            return new SignalStrength(in);
        }

        public SignalStrength[] newArray(int size) {
            return new SignalStrength[size];
        }
    };

    /**
     * Get the GSM RSSI in ASU.
     *
     * Asu is calculated based on 3GPP RSRP. Refer to 3GPP 27.007 (Ver 10.3.0) Sec 8.69
     *
     * @return RSSI in ASU 0..31, 99, or UNAVAILABLE
     *
     * @deprecated this information should be retrieved from
     *             {@link CellSignalStrengthGsm#getAsuLevel}.
     * @see android.telephony#CellSignalStrengthGsm
     * @see android.telephony.SignalStrength#getCellSignalStrengths
     */
    @Deprecated
    public int getGsmSignalStrength() {
        return mGsm.getAsuLevel();
    }

    /**
     * Get the GSM bit error rate (0-7, 99) as defined in TS 27.007 8.5
     *
     * @deprecated this information should be retrieved from
     *             {@link CellSignalStrengthGsm#getBitErrorRate}.
     *
     * @see android.telephony#CellSignalStrengthGsm
     * @see android.telephony.SignalStrength#getCellSignalStrengths()
     */
    @Deprecated
    public int getGsmBitErrorRate() {
        return mGsm.getBitErrorRate();
    }

    /**
     * Get the CDMA RSSI value in dBm
     *
     * @return the CDMA RSSI value or {@link #INVALID} if invalid
     *
     * @deprecated this information should be retrieved from
     *             {@link CellSignalStrengthCdma#getCdmaDbm}.
     *
     * @see android.telephony#CellSignalStrengthCdma
     * @see android.telephony.SignalStrength#getCellSignalStrengths()
     */
    @Deprecated
    public int getCdmaDbm() {
        return mCdma.getCdmaDbm();
    }

    /**
     * Get the CDMA Ec/Io value in dB*10
     *
     * @deprecated this information should be retrieved from
     *             {@link CellSignalStrengthCdma#getCdmaEcio}.
     *
     * @see android.telephony#CellSignalStrengthCdma
     * @see android.telephony.SignalStrength#getCellSignalStrengths()
     */
    @Deprecated
    public int getCdmaEcio() {
        return mCdma.getCdmaEcio();
    }

    /**
     * Get the EVDO RSSI value in dBm
     *
     * @return the EVDO RSSI value or {@link #INVALID} if invalid
     *
     * @deprecated this information should be retrieved from
     *             {@link CellSignalStrengthCdma#getEvdoDbm}.
     *
     * @see android.telephony#CellSignalStrengthCdma
     * @see android.telephony.SignalStrength#getCellSignalStrengths()
     */
    @Deprecated
    public int getEvdoDbm() {
        return mCdma.getEvdoDbm();
    }

    /**
     * Get the EVDO Ec/Io value in dB*10
     *
     * @deprecated this information should be retrieved from
     *             {@link CellSignalStrengthCdma#getEvdoEcio}.
     *
     * @see android.telephony#CellSignalStrengthCdma
     * @see android.telephony.SignalStrength#getCellSignalStrengths()
     */
    @Deprecated
    public int getEvdoEcio() {
        return mCdma.getEvdoEcio();
    }

    /**
     * Get the signal to noise ratio. Valid values are 0-8. 8 is the highest.
     *
     * @deprecated this information should be retrieved from
     *             {@link CellSignalStrengthCdma#getEvdoSnr}.
     *
     * @see android.telephony#CellSignalStrengthCdma
     * @see android.telephony.SignalStrength#getCellSignalStrengths()
     */
    @Deprecated
    public int getEvdoSnr() {
        return mCdma.getEvdoSnr();
    }

    /**
     * @deprecated this information should be retrieved from
     *             {@link CellSignalStrengthLte#getRssi}.
     *
     * @see android.telephony#CellSignalStrengthLte
     * @see android.telephony.SignalStrength#getCellSignalStrengths()
     * @hide
     */
    @Deprecated
    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
    public int getLteSignalStrength() {
        return mLte.getRssi();
    }

    /**
     * @deprecated this information should be retrieved from
     *             {@link CellSignalStrengthLte#getRsrp}.
     *
     * @see android.telephony#CellSignalStrengthLte
     * @see android.telephony.SignalStrength#getCellSignalStrengths()
     * @hide
     */
    @Deprecated
    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
    public int getLteRsrp() {
        return mLte.getRsrp();
    }

    /**
     * @deprecated this information should be retrieved from
     *             {@link CellSignalStrengthLte#getRsrq}.
     *
     * @see android.telephony#CellSignalStrengthLte
     * @see android.telephony.SignalStrength#getCellSignalStrengths()
     * @hide
     */
    @Deprecated
    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
    public int getLteRsrq() {
        return mLte.getRsrq();
    }

    /**
     * @deprecated this information should be retrieved from
     *             {@link CellSignalStrengthLte#getRssnr}.
     *
     * @see android.telephony#CellSignalStrengthLte
     * @see android.telephony.SignalStrength#getCellSignalStrengths()
     * @hide
     */
    @Deprecated
    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
    public int getLteRssnr() {
        return mLte.getRssnr();
    }

    /**
     * @deprecated this information should be retrieved from
     *             {@link CellSignalStrengthLte#getCqi}.
     *
     * @see android.telephony#CellSignalStrengthLte
     * @see android.telephony.SignalStrength#getCellSignalStrengths()
     * @hide
     */
    @Deprecated
    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
    public int getLteCqi() {
        return mLte.getCqi();
    }

    /**
     * Retrieve an abstract level value for the overall signal strength.
     *
     * @return a single integer from 0 to 4 representing the general signal quality.
     *     This may take into account many different radio technology inputs.
     *     0 represents very poor signal strength
     *     while 4 represents a very strong signal strength.
     */
    public int getLevel() {
        int level = getPrimary().getLevel();
        if (level < SIGNAL_STRENGTH_NONE_OR_UNKNOWN || level > SIGNAL_STRENGTH_GREAT) {
            loge("Invalid Level " + level + ", this=" + this);
            return SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
        }
        return getPrimary().getLevel();
    }

    /**
     * Get the signal level as an asu value with a range dependent on the underlying technology.
     *
     * @deprecated this information should be retrieved from
     *             {@link CellSignalStrength#getAsuLevel}. Because the levels vary by technology,
     *             this method is misleading and should not be used.
     * @see android.telephony#CellSignalStrength
     * @see android.telephony.SignalStrength#getCellSignalStrengths
     * @hide
     */
    @Deprecated
    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
    public int getAsuLevel() {
        return getPrimary().getAsuLevel();
    }

    /**
     * Get the signal strength as dBm
     *
     * @deprecated this information should be retrieved from
     *             {@link CellSignalStrength#getDbm()}. Because the levels vary by technology,
     *             this method is misleading and should not be used.
     * @see android.telephony#CellSignalStrength
     * @see android.telephony.SignalStrength#getCellSignalStrengths
     * @hide
     */
    @Deprecated
    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
    public int getDbm() {
        return getPrimary().getDbm();
    }

    /**
     * Get Gsm signal strength as dBm
     *
     * @deprecated this information should be retrieved from
     *             {@link CellSignalStrengthGsm#getDbm}.
     *
     * @see android.telephony#CellSignalStrengthGsm
     * @see android.telephony.SignalStrength#getCellSignalStrengths()
     * @hide
     */
    @Deprecated
    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
    public int getGsmDbm() {
        return mGsm.getDbm();
    }

    /**
     * Get gsm as level 0..4
     *
     * @deprecated this information should be retrieved from
     *             {@link CellSignalStrengthGsm#getLevel}.
     *
     * @see android.telephony#CellSignalStrengthGsm
     * @see android.telephony.SignalStrength#getCellSignalStrengths()
     * @hide
     */
    @Deprecated
    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
    public int getGsmLevel() {
        return mGsm.getLevel();
    }

    /**
     * Get the gsm signal level as an asu value between 0..31, 99 is unknown
     *
     * @deprecated this information should be retrieved from
     *             {@link CellSignalStrengthGsm#getAsuLevel}.
     *
     * @see android.telephony#CellSignalStrengthGsm
     * @see android.telephony.SignalStrength#getCellSignalStrengths()
     * @hide
     */
    @Deprecated
    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
    public int getGsmAsuLevel() {
        return mGsm.getAsuLevel();
    }

    /**
     * Get cdma as level 0..4
     *
     * @deprecated this information should be retrieved from
     *             {@link CellSignalStrengthCdma#getLevel}.
     *
     * @see android.telephony#CellSignalStrengthCdma
     * @see android.telephony.SignalStrength#getCellSignalStrengths()
     * @hide
     */
    @Deprecated
    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
    public int getCdmaLevel() {
        return mCdma.getLevel();
    }

    /**
     * Get the cdma signal level as an asu value between 0..31, 99 is unknown
     *
     * @deprecated this information should be retrieved from
     *             {@link CellSignalStrengthCdma#getAsuLevel}. Since there is no definition of
     *             ASU for CDMA, the resultant value is Android-specific and is not recommended
     *             for use.
     *
     * @see android.telephony#CellSignalStrengthCdma
     * @see android.telephony.SignalStrength#getCellSignalStrengths()
     * @hide
     */
    @Deprecated
    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
    public int getCdmaAsuLevel() {
        return mCdma.getAsuLevel();
    }

    /**
     * Get Evdo as level 0..4
     *
     * @deprecated this information should be retrieved from
     *             {@link CellSignalStrengthCdma#getEvdoLevel}.
     *
     * @see android.telephony#CellSignalStrengthCdma
     * @see android.telephony.SignalStrength#getCellSignalStrengths()
     * @hide
     */
    @Deprecated
    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
    public int getEvdoLevel() {
        return mCdma.getEvdoLevel();
    }

    /**
     * Get the evdo signal level as an asu value between 0..31, 99 is unknown
     *
     * @deprecated this information should be retrieved from
     *             {@link CellSignalStrengthCdma#getEvdoAsuLevel}. Since there is no definition of
     *             ASU for EvDO, the resultant value is Android-specific and is not recommended
     *             for use.
     *
     * @see android.telephony#CellSignalStrengthCdma
     * @see android.telephony.SignalStrength#getCellSignalStrengths()
     * @hide
     */
    @Deprecated
    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
    public int getEvdoAsuLevel() {
        return mCdma.getEvdoAsuLevel();
    }

    /**
     * Get LTE as dBm
     *
     * @deprecated this information should be retrieved from
     *             {@link CellSignalStrengthLte#getDbm}.
     *
     * @see android.telephony#CellSignalStrengthLte
     * @see android.telephony.SignalStrength#getCellSignalStrengths()
     * @hide
     */
    @Deprecated
    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
    public int getLteDbm() {
        return mLte.getRsrp();
    }

    /**
     * Get LTE as level 0..4
     *
     * @deprecated this information should be retrieved from
     *             {@link CellSignalStrengthLte#getLevel}.
     *
     * @see android.telephony#CellSignalStrengthLte
     * @see android.telephony.SignalStrength#getCellSignalStrengths()
     * @hide
     */
    @Deprecated
    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
    public int getLteLevel() {
        return mLte.getLevel();
    }

    /**
     * Get the LTE signal level as an asu value between 0..97, 99 is unknown
     * Asu is calculated based on 3GPP RSRP. Refer to 3GPP 27.007 (Ver 10.3.0) Sec 8.69
     *
     * @deprecated this information should be retrieved from
     *             {@link CellSignalStrengthLte#getAsuLevel}.
     *
     * @see android.telephony#CellSignalStrengthLte
     * @see android.telephony.SignalStrength#getCellSignalStrengths()
     * @hide
     */
    @Deprecated
    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
    public int getLteAsuLevel() {
        return mLte.getAsuLevel();
    }

    /**
     * @return true if this is for GSM
     *
     * @deprecated This method returns true if there are any 3gpp type SignalStrength elements in
     *             this SignalStrength report or if the report contains no valid SignalStrength
     *             information. Instead callers should use
     *             {@link android.telephony.SignalStrength#getCellSignalStrengths
     *             getCellSignalStrengths()} to determine which types of information are contained
     *             in the SignalStrength report.
     */
    @Deprecated
    public boolean isGsm() {
        return !(getPrimary() instanceof CellSignalStrengthCdma);
    }

    /**
     * @return get TD-SCDMA dBm
     *
     * @deprecated this information should be retrieved from
     *             {@link CellSignalStrengthTdscdma#getDbm}.
     *
     * @see android.telephony#CellSignalStrengthTdscdma
     * @see android.telephony.SignalStrength#getCellSignalStrengths()
     * @hide
     */
    @Deprecated
    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
    public int getTdScdmaDbm() {
        return mTdscdma.getRscp();
    }

    /**
     * Get TD-SCDMA as level 0..4
     * Range : 25 to 120
     * INT_MAX: 0x7FFFFFFF denotes invalid value
     * Reference: 3GPP TS 25.123, section 9.1.1.1
     *
     * @deprecated this information should be retrieved from
     *             {@link CellSignalStrengthTdscdma#getLevel}.
     *
     * @see android.telephony#CellSignalStrengthTdscdma
     * @see android.telephony.SignalStrength#getCellSignalStrengths()
     * @hide
     */
    @Deprecated
    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
    public int getTdScdmaLevel() {
        return mTdscdma.getLevel();
     }

    /**
     * Get the TD-SCDMA signal level as an asu value.
     *
     * @deprecated this information should be retrieved from
     *             {@link CellSignalStrengthTdscdma#getAsuLevel}.
     *
     * @see android.telephony#CellSignalStrengthTdscdma
     * @see android.telephony.SignalStrength#getCellSignalStrengths()
     * @hide
     */
    @Deprecated
    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
    public int getTdScdmaAsuLevel() {
        return mTdscdma.getAsuLevel();
    }

    /**
     * Gets WCDMA RSCP as a dBm value between -120 and -24, as defined in TS 27.007 8.69.
     *
     * @deprecated this information should be retrieved from
     *             {@link CellSignalStrengthWcdma#getRscp}.
     *
     * @see android.telephony#CellSignalStrengthWcdma
     * @see android.telephony.SignalStrength#getCellSignalStrengths()
     * @hide
     */
    @Deprecated
    public int getWcdmaRscp() {
        return mWcdma.getRscp();
    }

    /**
     * Get the WCDMA signal level as an ASU value between 0-96, 255 is unknown
     *
     * @deprecated this information should be retrieved from
     *             {@link CellSignalStrengthWcdma#getAsuLevel}.
     *
     * @see android.telephony#CellSignalStrengthWcdma
     * @see android.telephony.SignalStrength#getCellSignalStrengths()
     * @hide
     */
    @Deprecated
    public int getWcdmaAsuLevel() {
        /*
         * 3GPP 27.007 (Ver 10.3.0) Sec 8.69
         * 0      -120 dBm or less
         * 1      -119 dBm
         * 2...95 -118... -25 dBm
         * 96     -24 dBm or greater
         * 255    not known or not detectable
         */
        return mWcdma.getAsuLevel();
    }

    /**
     * Gets WCDMA signal strength as a dBm value between -120 and -24, as defined in TS 27.007 8.69.
     *
     * @deprecated this information should be retrieved from
     *             {@link CellSignalStrengthWcdma#getDbm}.
     *
     * @see android.telephony#CellSignalStrengthWcdma
     * @see android.telephony.SignalStrength#getCellSignalStrengths()
     * @hide
     */
    @Deprecated
    public int getWcdmaDbm() {
        return mWcdma.getDbm();
    }

    /**
     * Get WCDMA as level 0..4
     *
     * @deprecated this information should be retrieved from
     *             {@link CellSignalStrengthWcdma#getDbm}.
     *
     * @see android.telephony#CellSignalStrengthWcdma
     * @see android.telephony.SignalStrength#getCellSignalStrengths()
     * @hide
     */
    @Deprecated
    public int getWcdmaLevel() {
        return mWcdma.getLevel();
    }

    /**
     * @return hash code
     */
    @Override
    public int hashCode() {
        return Objects.hash(mCdma, mGsm, mWcdma, mTdscdma, mLte, mNr);
    }

    /**
     * @return true if the signal strengths are the same
     */
    @Override
    public boolean equals (Object o) {
        if (!(o instanceof SignalStrength)) return false;

        SignalStrength s = (SignalStrength) o;

        return mCdma.equals(s.mCdma)
            && mGsm.equals(s.mGsm)
            && mWcdma.equals(s.mWcdma)
            && mTdscdma.equals(s.mTdscdma)
            && mLte.equals(s.mLte)
            && mNr.equals(s.mNr);
    }

    /**
     * @return string representation.
     */
    @Override
    public String toString() {
        return new StringBuilder().append("SignalStrength:{")
            .append("mCdma=").append(mCdma)
            .append(",mGsm=").append(mGsm)
            .append(",mWcdma=").append(mWcdma)
            .append(",mTdscdma=").append(mTdscdma)
            .append(",mLte=").append(mLte)
            .append(",mNr=").append(mNr)
            .append(",primary=").append(getPrimary().getClass().getSimpleName())
            .append("}")
            .toString();
    }

    /**
     * Set SignalStrength based on intent notifier map
     *
     * @param m intent notifier map
     *
     * @deprecated this method relies on non-stable implementation details, and full access to
     *             internal storage is available via {@link getCellSignalStrengths()}.
     * @hide
     */
    @Deprecated
    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
    private void setFromNotifierBundle(Bundle m) {
        mCdma = m.getParcelable("Cdma");
        mGsm = m.getParcelable("Gsm");
        mWcdma = m.getParcelable("Wcdma");
        mTdscdma = m.getParcelable("Tdscdma");
        mLte = m.getParcelable("Lte");
        mNr = m.getParcelable("Nr");
    }

    /**
     * Set intent notifier Bundle based on SignalStrength
     *
     * @param m intent notifier Bundle
     *
     * @deprecated this method relies on non-stable implementation details, and full access to
     *             internal storage is available via {@link getCellSignalStrengths()}.
     * @hide
     */
    @Deprecated
    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
    public void fillInNotifierBundle(Bundle m) {
        m.putParcelable("Cdma", mCdma);
        m.putParcelable("Gsm", mGsm);
        m.putParcelable("Wcdma", mWcdma);
        m.putParcelable("Tdscdma", mTdscdma);
        m.putParcelable("Lte", mLte);
        m.putParcelable("Nr", mNr);
    }

    /**
     * log warning
     */
    private static void log(String s) {
        Rlog.w(LOG_TAG, s);
    }

    /**
     * log error
     */
    private static void loge(String s) {
        Rlog.e(LOG_TAG, s);
    }
}
