blob: 7b58755d2c2f44fdcd3168dceb37b76c7c00ad22 [file] [log] [blame]
/*
* 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.os.Bundle;
import android.os.Parcel;
import android.os.Parcelable;
import android.telephony.Rlog;
import android.content.res.Resources;
/**
* 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 */
public static final int SIGNAL_STRENGTH_NONE_OR_UNKNOWN = 0;
/** @hide */
public static final int SIGNAL_STRENGTH_POOR = 1;
/** @hide */
public static final int SIGNAL_STRENGTH_MODERATE = 2;
/** @hide */
public static final int SIGNAL_STRENGTH_GOOD = 3;
/** @hide */
public static final int SIGNAL_STRENGTH_GREAT = 4;
/** @hide */
public static final int NUM_SIGNAL_STRENGTH_BINS = 5;
/** @hide */
public static final String[] SIGNAL_STRENGTH_NAMES = {
"none", "poor", "moderate", "good", "great"
};
/** @hide */
//Use int max, as -1 is a valid value in signal strength
public static final int INVALID = 0x7FFFFFFF;
private static final int RSRP_THRESH_TYPE_STRICT = 0;
private static final int[] RSRP_THRESH_STRICT = new int[] {-140, -115, -105, -95, -85, -44};
private static final int[] RSRP_THRESH_LENIENT = new int[] {-140, -128, -118, -108, -98, -44};
private int mGsmSignalStrength; // Valid values are (0-31, 99) as defined in TS 27.007 8.5
private int mGsmBitErrorRate; // bit error rate (0-7, 99) as defined in TS 27.007 8.5
private int mCdmaDbm; // This value is the RSSI value
private int mCdmaEcio; // This value is the Ec/Io
private int mEvdoDbm; // This value is the EVDO RSSI value
private int mEvdoEcio; // This value is the EVDO Ec/Io
private int mEvdoSnr; // Valid values are 0-8. 8 is the highest signal to noise ratio
private int mLteSignalStrength;
private int mLteRsrp;
private int mLteRsrq;
private int mLteRssnr;
private int mLteCqi;
private boolean isGsm; // This value is set by the ServiceStateTracker onSignalStrengthResult
/**
* 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
*/
public static SignalStrength newFromBundle(Bundle m) {
SignalStrength ret;
ret = new SignalStrength();
ret.setFromNotifierBundle(m);
return ret;
}
/**
* Empty constructor
*
* @hide
*/
public SignalStrength() {
mGsmSignalStrength = 99;
mGsmBitErrorRate = -1;
mCdmaDbm = -1;
mCdmaEcio = -1;
mEvdoDbm = -1;
mEvdoEcio = -1;
mEvdoSnr = -1;
mLteSignalStrength = 99;
mLteRsrp = INVALID;
mLteRsrq = INVALID;
mLteRssnr = INVALID;
mLteCqi = INVALID;
isGsm = true;
}
/**
* This constructor is used to create SignalStrength with default
* values and set the isGsmFlag with the value passed in the input
*
* @param gsmFlag true if Gsm Phone,false if Cdma phone
* @return newly created SignalStrength
* @hide
*/
public SignalStrength(boolean gsmFlag) {
mGsmSignalStrength = 99;
mGsmBitErrorRate = -1;
mCdmaDbm = -1;
mCdmaEcio = -1;
mEvdoDbm = -1;
mEvdoEcio = -1;
mEvdoSnr = -1;
mLteSignalStrength = 99;
mLteRsrp = INVALID;
mLteRsrq = INVALID;
mLteRssnr = INVALID;
mLteCqi = INVALID;
isGsm = gsmFlag;
}
/**
* Constructor
*
* @hide
*/
public SignalStrength(int gsmSignalStrength, int gsmBitErrorRate,
int cdmaDbm, int cdmaEcio,
int evdoDbm, int evdoEcio, int evdoSnr,
int lteSignalStrength, int lteRsrp, int lteRsrq, int lteRssnr, int lteCqi,
boolean gsmFlag) {
initialize(gsmSignalStrength, gsmBitErrorRate, cdmaDbm, cdmaEcio,
evdoDbm, evdoEcio, evdoSnr, lteSignalStrength, lteRsrp,
lteRsrq, lteRssnr, lteCqi, gsmFlag);
}
/**
* Constructor
*
* @hide
*/
public SignalStrength(int gsmSignalStrength, int gsmBitErrorRate,
int cdmaDbm, int cdmaEcio,
int evdoDbm, int evdoEcio, int evdoSnr,
boolean gsmFlag) {
initialize(gsmSignalStrength, gsmBitErrorRate, cdmaDbm, cdmaEcio,
evdoDbm, evdoEcio, evdoSnr, 99, INVALID,
INVALID, INVALID, INVALID, gsmFlag);
}
/**
* Copy constructors
*
* @param s Source SignalStrength
*
* @hide
*/
public SignalStrength(SignalStrength s) {
copyFrom(s);
}
/**
* Initialize gsm/cdma values, sets lte values to defaults.
*
* @param gsmSignalStrength
* @param gsmBitErrorRate
* @param cdmaDbm
* @param cdmaEcio
* @param evdoDbm
* @param evdoEcio
* @param evdoSnr
* @param gsm
*
* @hide
*/
public void initialize(int gsmSignalStrength, int gsmBitErrorRate,
int cdmaDbm, int cdmaEcio,
int evdoDbm, int evdoEcio, int evdoSnr,
boolean gsm) {
initialize(gsmSignalStrength, gsmBitErrorRate, cdmaDbm, cdmaEcio,
evdoDbm, evdoEcio, evdoSnr, 99, INVALID,
INVALID, INVALID, INVALID, gsm);
}
/**
* Initialize all the values
*
* @param gsmSignalStrength
* @param gsmBitErrorRate
* @param cdmaDbm
* @param cdmaEcio
* @param evdoDbm
* @param evdoEcio
* @param evdoSnr
* @param lteSignalStrength
* @param lteRsrp
* @param lteRsrq
* @param lteRssnr
* @param lteCqi
* @param gsm
*
* @hide
*/
public void initialize(int gsmSignalStrength, int gsmBitErrorRate,
int cdmaDbm, int cdmaEcio,
int evdoDbm, int evdoEcio, int evdoSnr,
int lteSignalStrength, int lteRsrp, int lteRsrq, int lteRssnr, int lteCqi,
boolean gsm) {
mGsmSignalStrength = gsmSignalStrength;
mGsmBitErrorRate = gsmBitErrorRate;
mCdmaDbm = cdmaDbm;
mCdmaEcio = cdmaEcio;
mEvdoDbm = evdoDbm;
mEvdoEcio = evdoEcio;
mEvdoSnr = evdoSnr;
mLteSignalStrength = lteSignalStrength;
mLteRsrp = lteRsrp;
mLteRsrq = lteRsrq;
mLteRssnr = lteRssnr;
mLteCqi = lteCqi;
isGsm = gsm;
if (DBG) log("initialize: " + toString());
}
/**
* @hide
*/
protected void copyFrom(SignalStrength s) {
mGsmSignalStrength = s.mGsmSignalStrength;
mGsmBitErrorRate = s.mGsmBitErrorRate;
mCdmaDbm = s.mCdmaDbm;
mCdmaEcio = s.mCdmaEcio;
mEvdoDbm = s.mEvdoDbm;
mEvdoEcio = s.mEvdoEcio;
mEvdoSnr = s.mEvdoSnr;
mLteSignalStrength = s.mLteSignalStrength;
mLteRsrp = s.mLteRsrp;
mLteRsrq = s.mLteRsrq;
mLteRssnr = s.mLteRssnr;
mLteCqi = s.mLteCqi;
isGsm = s.isGsm;
}
/**
* Construct a SignalStrength object from the given parcel.
*
* @hide
*/
public SignalStrength(Parcel in) {
if (DBG) log("Size of signalstrength parcel:" + in.dataSize());
mGsmSignalStrength = in.readInt();
mGsmBitErrorRate = in.readInt();
mCdmaDbm = in.readInt();
mCdmaEcio = in.readInt();
mEvdoDbm = in.readInt();
mEvdoEcio = in.readInt();
mEvdoSnr = in.readInt();
mLteSignalStrength = in.readInt();
mLteRsrp = in.readInt();
mLteRsrq = in.readInt();
mLteRssnr = in.readInt();
mLteCqi = in.readInt();
isGsm = (in.readInt() != 0);
}
/**
* Make a SignalStrength object from the given parcel as passed up by
* the ril which does not have isGsm. isGsm will be changed by ServiceStateTracker
* so the default is a don't care.
*
* @hide
*/
public static SignalStrength makeSignalStrengthFromRilParcel(Parcel in) {
if (DBG) log("Size of signalstrength parcel:" + in.dataSize());
SignalStrength ss = new SignalStrength();
ss.mGsmSignalStrength = in.readInt();
ss.mGsmBitErrorRate = in.readInt();
ss.mCdmaDbm = in.readInt();
ss.mCdmaEcio = in.readInt();
ss.mEvdoDbm = in.readInt();
ss.mEvdoEcio = in.readInt();
ss.mEvdoSnr = in.readInt();
ss.mLteSignalStrength = in.readInt();
ss.mLteRsrp = in.readInt();
ss.mLteRsrq = in.readInt();
ss.mLteRssnr = in.readInt();
ss.mLteCqi = in.readInt();
return ss;
}
/**
* {@link Parcelable#writeToParcel}
*/
public void writeToParcel(Parcel out, int flags) {
out.writeInt(mGsmSignalStrength);
out.writeInt(mGsmBitErrorRate);
out.writeInt(mCdmaDbm);
out.writeInt(mCdmaEcio);
out.writeInt(mEvdoDbm);
out.writeInt(mEvdoEcio);
out.writeInt(mEvdoSnr);
out.writeInt(mLteSignalStrength);
out.writeInt(mLteRsrp);
out.writeInt(mLteRsrq);
out.writeInt(mLteRssnr);
out.writeInt(mLteCqi);
out.writeInt(isGsm ? 1 : 0);
}
/**
* {@link Parcelable#describeContents}
*/
public int describeContents() {
return 0;
}
/**
* {@link Parcelable.Creator}
*
* @hide
*/
public static final 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];
}
};
/**
* Validate the individual signal strength fields as per the range
* specified in ril.h
* Set to invalid any field that is not in the valid range
* Cdma, evdo, lte rsrp & rsrq values are sign converted
* when received from ril interface
*
* @return
* Valid values for all signalstrength fields
* @hide
*/
public void validateInput() {
if (DBG) log("Signal before validate=" + this);
// TS 27.007 8.5
mGsmSignalStrength = mGsmSignalStrength >= 0 ? mGsmSignalStrength : 99;
// BER no change;
mCdmaDbm = mCdmaDbm > 0 ? -mCdmaDbm : -120;
mCdmaEcio = (mCdmaEcio > 0) ? -mCdmaEcio : -160;
mEvdoDbm = (mEvdoDbm > 0) ? -mEvdoDbm : -120;
mEvdoEcio = (mEvdoEcio >= 0) ? -mEvdoEcio : -1;
mEvdoSnr = ((mEvdoSnr > 0) && (mEvdoSnr <= 8)) ? mEvdoSnr : -1;
// TS 36.214 Physical Layer Section 5.1.3, TS 36.331 RRC
mLteSignalStrength = (mLteSignalStrength >= 0) ? mLteSignalStrength : 99;
mLteRsrp = ((mLteRsrp >= 44) && (mLteRsrp <= 140)) ? -mLteRsrp : SignalStrength.INVALID;
mLteRsrq = ((mLteRsrq >= 3) && (mLteRsrq <= 20)) ? -mLteRsrq : SignalStrength.INVALID;
mLteRssnr = ((mLteRssnr >= -200) && (mLteRssnr <= 300)) ? mLteRssnr
: SignalStrength.INVALID;
// Cqi no change
if (DBG) log("Signal after validate=" + this);
}
/**
* @param true - Gsm, Lte phones
* false - Cdma phones
*
* Used by voice phone to set the isGsm
* flag
* @hide
*/
public void setGsm(boolean gsmFlag) {
isGsm = gsmFlag;
}
/**
* Get the GSM Signal Strength, valid values are (0-31, 99) as defined in TS
* 27.007 8.5
*/
public int getGsmSignalStrength() {
return this.mGsmSignalStrength;
}
/**
* Get the GSM bit error rate (0-7, 99) as defined in TS 27.007 8.5
*/
public int getGsmBitErrorRate() {
return this.mGsmBitErrorRate;
}
/**
* Get the CDMA RSSI value in dBm
*/
public int getCdmaDbm() {
return this.mCdmaDbm;
}
/**
* Get the CDMA Ec/Io value in dB*10
*/
public int getCdmaEcio() {
return this.mCdmaEcio;
}
/**
* Get the EVDO RSSI value in dBm
*/
public int getEvdoDbm() {
return this.mEvdoDbm;
}
/**
* Get the EVDO Ec/Io value in dB*10
*/
public int getEvdoEcio() {
return this.mEvdoEcio;
}
/**
* Get the signal to noise ratio. Valid values are 0-8. 8 is the highest.
*/
public int getEvdoSnr() {
return this.mEvdoSnr;
}
/** @hide */
public int getLteSignalStrength() {
return mLteSignalStrength;
}
/** @hide */
public int getLteRsrp() {
return mLteRsrp;
}
/** @hide */
public int getLteRsrq() {
return mLteRsrq;
}
/** @hide */
public int getLteRssnr() {
return mLteRssnr;
}
/** @hide */
public int getLteCqi() {
return mLteCqi;
}
/**
* Get signal level as an int from 0..4
*/
public int getLevel() {
int level;
if (isGsm) {
level = getLteLevel();
if (level == SIGNAL_STRENGTH_NONE_OR_UNKNOWN) {
level = getGsmLevel();
}
} else {
int cdmaLevel = getCdmaLevel();
int evdoLevel = getEvdoLevel();
if (evdoLevel == SIGNAL_STRENGTH_NONE_OR_UNKNOWN) {
/* We don't know evdo, use cdma */
level = cdmaLevel;
} else if (cdmaLevel == SIGNAL_STRENGTH_NONE_OR_UNKNOWN) {
/* We don't know cdma, use evdo */
level = evdoLevel;
} else {
/* We know both, use the lowest level */
level = cdmaLevel < evdoLevel ? cdmaLevel : evdoLevel;
}
}
if (DBG) log("getLevel=" + level);
return level;
}
/**
* Get the signal level as an asu value between 0..31, 99 is unknown
*
* @hide
*/
public int getAsuLevel() {
int asuLevel;
if (isGsm) {
if (getLteLevel() == SIGNAL_STRENGTH_NONE_OR_UNKNOWN) {
asuLevel = getGsmAsuLevel();
} else {
asuLevel = getLteAsuLevel();
}
} else {
int cdmaAsuLevel = getCdmaAsuLevel();
int evdoAsuLevel = getEvdoAsuLevel();
if (evdoAsuLevel == 0) {
/* We don't know evdo use, cdma */
asuLevel = cdmaAsuLevel;
} else if (cdmaAsuLevel == 0) {
/* We don't know cdma use, evdo */
asuLevel = evdoAsuLevel;
} else {
/* We know both, use the lowest level */
asuLevel = cdmaAsuLevel < evdoAsuLevel ? cdmaAsuLevel : evdoAsuLevel;
}
}
if (DBG) log("getAsuLevel=" + asuLevel);
return asuLevel;
}
/**
* Get the signal strength as dBm
*
* @hide
*/
public int getDbm() {
int dBm;
if(isGsm()) {
dBm = getLteDbm();
if (dBm == INVALID) {
dBm = getGsmDbm();
}
} else {
int cdmaDbm = getCdmaDbm();
int evdoDbm = getEvdoDbm();
return (evdoDbm == -120) ? cdmaDbm : ((cdmaDbm == -120) ? evdoDbm
: (cdmaDbm < evdoDbm ? cdmaDbm : evdoDbm));
}
if (DBG) log("getDbm=" + dBm);
return dBm;
}
/**
* Get Gsm signal strength as dBm
*
* @hide
*/
public int getGsmDbm() {
int dBm;
int gsmSignalStrength = getGsmSignalStrength();
int asu = (gsmSignalStrength == 99 ? -1 : gsmSignalStrength);
if (asu != -1) {
dBm = -113 + (2 * asu);
} else {
dBm = -1;
}
if (DBG) log("getGsmDbm=" + dBm);
return dBm;
}
/**
* Get gsm as level 0..4
*
* @hide
*/
public int getGsmLevel() {
int level;
// ASU ranges from 0 to 31 - TS 27.007 Sec 8.5
// asu = 0 (-113dB or less) is very weak
// signal, its better to show 0 bars to the user in such cases.
// asu = 99 is a special case, where the signal strength is unknown.
int asu = getGsmSignalStrength();
if (asu <= 2 || asu == 99) level = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
else if (asu >= 12) level = SIGNAL_STRENGTH_GREAT;
else if (asu >= 8) level = SIGNAL_STRENGTH_GOOD;
else if (asu >= 5) level = SIGNAL_STRENGTH_MODERATE;
else level = SIGNAL_STRENGTH_POOR;
if (DBG) log("getGsmLevel=" + level);
return level;
}
/**
* Get the gsm signal level as an asu value between 0..31, 99 is unknown
*
* @hide
*/
public int getGsmAsuLevel() {
// ASU ranges from 0 to 31 - TS 27.007 Sec 8.5
// asu = 0 (-113dB or less) is very weak
// signal, its better to show 0 bars to the user in such cases.
// asu = 99 is a special case, where the signal strength is unknown.
int level = getGsmSignalStrength();
if (DBG) log("getGsmAsuLevel=" + level);
return level;
}
/**
* Get cdma as level 0..4
*
* @hide
*/
public int getCdmaLevel() {
final int cdmaDbm = getCdmaDbm();
final int cdmaEcio = getCdmaEcio();
int levelDbm;
int levelEcio;
if (cdmaDbm >= -75) levelDbm = SIGNAL_STRENGTH_GREAT;
else if (cdmaDbm >= -85) levelDbm = SIGNAL_STRENGTH_GOOD;
else if (cdmaDbm >= -95) levelDbm = SIGNAL_STRENGTH_MODERATE;
else if (cdmaDbm >= -100) levelDbm = SIGNAL_STRENGTH_POOR;
else levelDbm = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
// Ec/Io are in dB*10
if (cdmaEcio >= -90) levelEcio = SIGNAL_STRENGTH_GREAT;
else if (cdmaEcio >= -110) levelEcio = SIGNAL_STRENGTH_GOOD;
else if (cdmaEcio >= -130) levelEcio = SIGNAL_STRENGTH_MODERATE;
else if (cdmaEcio >= -150) levelEcio = SIGNAL_STRENGTH_POOR;
else levelEcio = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
int level = (levelDbm < levelEcio) ? levelDbm : levelEcio;
if (DBG) log("getCdmaLevel=" + level);
return level;
}
/**
* Get the cdma signal level as an asu value between 0..31, 99 is unknown
*
* @hide
*/
public int getCdmaAsuLevel() {
final int cdmaDbm = getCdmaDbm();
final int cdmaEcio = getCdmaEcio();
int cdmaAsuLevel;
int ecioAsuLevel;
if (cdmaDbm >= -75) cdmaAsuLevel = 16;
else if (cdmaDbm >= -82) cdmaAsuLevel = 8;
else if (cdmaDbm >= -90) cdmaAsuLevel = 4;
else if (cdmaDbm >= -95) cdmaAsuLevel = 2;
else if (cdmaDbm >= -100) cdmaAsuLevel = 1;
else cdmaAsuLevel = 99;
// Ec/Io are in dB*10
if (cdmaEcio >= -90) ecioAsuLevel = 16;
else if (cdmaEcio >= -100) ecioAsuLevel = 8;
else if (cdmaEcio >= -115) ecioAsuLevel = 4;
else if (cdmaEcio >= -130) ecioAsuLevel = 2;
else if (cdmaEcio >= -150) ecioAsuLevel = 1;
else ecioAsuLevel = 99;
int level = (cdmaAsuLevel < ecioAsuLevel) ? cdmaAsuLevel : ecioAsuLevel;
if (DBG) log("getCdmaAsuLevel=" + level);
return level;
}
/**
* Get Evdo as level 0..4
*
* @hide
*/
public int getEvdoLevel() {
int evdoDbm = getEvdoDbm();
int evdoSnr = getEvdoSnr();
int levelEvdoDbm;
int levelEvdoSnr;
if (evdoDbm >= -65) levelEvdoDbm = SIGNAL_STRENGTH_GREAT;
else if (evdoDbm >= -75) levelEvdoDbm = SIGNAL_STRENGTH_GOOD;
else if (evdoDbm >= -90) levelEvdoDbm = SIGNAL_STRENGTH_MODERATE;
else if (evdoDbm >= -105) levelEvdoDbm = SIGNAL_STRENGTH_POOR;
else levelEvdoDbm = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
if (evdoSnr >= 7) levelEvdoSnr = SIGNAL_STRENGTH_GREAT;
else if (evdoSnr >= 5) levelEvdoSnr = SIGNAL_STRENGTH_GOOD;
else if (evdoSnr >= 3) levelEvdoSnr = SIGNAL_STRENGTH_MODERATE;
else if (evdoSnr >= 1) levelEvdoSnr = SIGNAL_STRENGTH_POOR;
else levelEvdoSnr = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
int level = (levelEvdoDbm < levelEvdoSnr) ? levelEvdoDbm : levelEvdoSnr;
if (DBG) log("getEvdoLevel=" + level);
return level;
}
/**
* Get the evdo signal level as an asu value between 0..31, 99 is unknown
*
* @hide
*/
public int getEvdoAsuLevel() {
int evdoDbm = getEvdoDbm();
int evdoSnr = getEvdoSnr();
int levelEvdoDbm;
int levelEvdoSnr;
if (evdoDbm >= -65) levelEvdoDbm = 16;
else if (evdoDbm >= -75) levelEvdoDbm = 8;
else if (evdoDbm >= -85) levelEvdoDbm = 4;
else if (evdoDbm >= -95) levelEvdoDbm = 2;
else if (evdoDbm >= -105) levelEvdoDbm = 1;
else levelEvdoDbm = 99;
if (evdoSnr >= 7) levelEvdoSnr = 16;
else if (evdoSnr >= 6) levelEvdoSnr = 8;
else if (evdoSnr >= 5) levelEvdoSnr = 4;
else if (evdoSnr >= 3) levelEvdoSnr = 2;
else if (evdoSnr >= 1) levelEvdoSnr = 1;
else levelEvdoSnr = 99;
int level = (levelEvdoDbm < levelEvdoSnr) ? levelEvdoDbm : levelEvdoSnr;
if (DBG) log("getEvdoAsuLevel=" + level);
return level;
}
/**
* Get LTE as dBm
*
* @hide
*/
public int getLteDbm() {
return mLteRsrp;
}
/**
* Get LTE as level 0..4
*
* @hide
*/
public int getLteLevel() {
/*
* TS 36.214 Physical Layer Section 5.1.3 TS 36.331 RRC RSSI = received
* signal + noise RSRP = reference signal dBm RSRQ = quality of signal
* dB= Number of Resource blocksxRSRP/RSSI SNR = gain=signal/noise ratio
* = -10log P1/P2 dB
*/
int rssiIconLevel = SIGNAL_STRENGTH_NONE_OR_UNKNOWN, rsrpIconLevel = -1, snrIconLevel = -1;
int rsrpThreshType = Resources.getSystem().getInteger(com.android.internal.R.integer.
config_LTE_RSRP_threshold_type);
int[] threshRsrp;
if (rsrpThreshType == RSRP_THRESH_TYPE_STRICT) {
threshRsrp = RSRP_THRESH_STRICT;
} else {
threshRsrp = RSRP_THRESH_LENIENT;
}
if (mLteRsrp > threshRsrp[5]) rsrpIconLevel = -1;
else if (mLteRsrp >= threshRsrp[4]) rsrpIconLevel = SIGNAL_STRENGTH_GREAT;
else if (mLteRsrp >= threshRsrp[3]) rsrpIconLevel = SIGNAL_STRENGTH_GOOD;
else if (mLteRsrp >= threshRsrp[2]) rsrpIconLevel = SIGNAL_STRENGTH_MODERATE;
else if (mLteRsrp >= threshRsrp[1]) rsrpIconLevel = SIGNAL_STRENGTH_POOR;
else if (mLteRsrp >= threshRsrp[0]) rsrpIconLevel = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
/*
* Values are -200 dB to +300 (SNR*10dB) RS_SNR >= 13.0 dB =>4 bars 4.5
* dB <= RS_SNR < 13.0 dB => 3 bars 1.0 dB <= RS_SNR < 4.5 dB => 2 bars
* -3.0 dB <= RS_SNR < 1.0 dB 1 bar RS_SNR < -3.0 dB/No Service Antenna
* Icon Only
*/
if (mLteRssnr > 300) snrIconLevel = -1;
else if (mLteRssnr >= 130) snrIconLevel = SIGNAL_STRENGTH_GREAT;
else if (mLteRssnr >= 45) snrIconLevel = SIGNAL_STRENGTH_GOOD;
else if (mLteRssnr >= 10) snrIconLevel = SIGNAL_STRENGTH_MODERATE;
else if (mLteRssnr >= -30) snrIconLevel = SIGNAL_STRENGTH_POOR;
else if (mLteRssnr >= -200)
snrIconLevel = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
if (DBG) log("getLTELevel - rsrp:" + mLteRsrp + " snr:" + mLteRssnr + " rsrpIconLevel:"
+ rsrpIconLevel + " snrIconLevel:" + snrIconLevel);
/* Choose a measurement type to use for notification */
if (snrIconLevel != -1 && rsrpIconLevel != -1) {
/*
* The number of bars displayed shall be the smaller of the bars
* associated with LTE RSRP and the bars associated with the LTE
* RS_SNR
*/
return (rsrpIconLevel < snrIconLevel ? rsrpIconLevel : snrIconLevel);
}
if (snrIconLevel != -1) return snrIconLevel;
if (rsrpIconLevel != -1) return rsrpIconLevel;
/* Valid values are (0-63, 99) as defined in TS 36.331 */
if (mLteSignalStrength > 63) rssiIconLevel = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
else if (mLteSignalStrength >= 12) rssiIconLevel = SIGNAL_STRENGTH_GREAT;
else if (mLteSignalStrength >= 8) rssiIconLevel = SIGNAL_STRENGTH_GOOD;
else if (mLteSignalStrength >= 5) rssiIconLevel = SIGNAL_STRENGTH_MODERATE;
else if (mLteSignalStrength >= 0) rssiIconLevel = SIGNAL_STRENGTH_POOR;
if (DBG) log("getLTELevel - rssi:" + mLteSignalStrength + " rssiIconLevel:"
+ rssiIconLevel);
return rssiIconLevel;
}
/**
* 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
*
* @hide
*/
public int getLteAsuLevel() {
int lteAsuLevel = 99;
int lteDbm = getLteDbm();
/*
* 3GPP 27.007 (Ver 10.3.0) Sec 8.69
* 0 -140 dBm or less
* 1 -139 dBm
* 2...96 -138... -44 dBm
* 97 -43 dBm or greater
* 255 not known or not detectable
*/
/*
* validateInput will always give a valid range between -140 t0 -44 as
* per ril.h. so RSRP >= -43 & <-140 will fall under asu level 255
* and not 97 or 0
*/
if (lteDbm == SignalStrength.INVALID) lteAsuLevel = 255;
else lteAsuLevel = lteDbm + 140;
if (DBG) log("Lte Asu level: "+lteAsuLevel);
return lteAsuLevel;
}
/**
* @return true if this is for GSM
*/
public boolean isGsm() {
return this.isGsm;
}
/**
* @return hash code
*/
@Override
public int hashCode() {
int primeNum = 31;
return ((mGsmSignalStrength * primeNum)
+ (mGsmBitErrorRate * primeNum)
+ (mCdmaDbm * primeNum) + (mCdmaEcio * primeNum)
+ (mEvdoDbm * primeNum) + (mEvdoEcio * primeNum) + (mEvdoSnr * primeNum)
+ (mLteSignalStrength * primeNum) + (mLteRsrp * primeNum)
+ (mLteRsrq * primeNum) + (mLteRssnr * primeNum) + (mLteCqi * primeNum)
+ (isGsm ? 1 : 0));
}
/**
* @return true if the signal strengths are the same
*/
@Override
public boolean equals (Object o) {
SignalStrength s;
try {
s = (SignalStrength) o;
} catch (ClassCastException ex) {
return false;
}
if (o == null) {
return false;
}
return (mGsmSignalStrength == s.mGsmSignalStrength
&& mGsmBitErrorRate == s.mGsmBitErrorRate
&& mCdmaDbm == s.mCdmaDbm
&& mCdmaEcio == s.mCdmaEcio
&& mEvdoDbm == s.mEvdoDbm
&& mEvdoEcio == s.mEvdoEcio
&& mEvdoSnr == s.mEvdoSnr
&& mLteSignalStrength == s.mLteSignalStrength
&& mLteRsrp == s.mLteRsrp
&& mLteRsrq == s.mLteRsrq
&& mLteRssnr == s.mLteRssnr
&& mLteCqi == s.mLteCqi
&& isGsm == s.isGsm);
}
/**
* @return string representation.
*/
@Override
public String toString() {
return ("SignalStrength:"
+ " " + mGsmSignalStrength
+ " " + mGsmBitErrorRate
+ " " + mCdmaDbm
+ " " + mCdmaEcio
+ " " + mEvdoDbm
+ " " + mEvdoEcio
+ " " + mEvdoSnr
+ " " + mLteSignalStrength
+ " " + mLteRsrp
+ " " + mLteRsrq
+ " " + mLteRssnr
+ " " + mLteCqi
+ " " + (isGsm ? "gsm|lte" : "cdma"));
}
/**
* Set SignalStrength based on intent notifier map
*
* @param m intent notifier map
* @hide
*/
private void setFromNotifierBundle(Bundle m) {
mGsmSignalStrength = m.getInt("GsmSignalStrength");
mGsmBitErrorRate = m.getInt("GsmBitErrorRate");
mCdmaDbm = m.getInt("CdmaDbm");
mCdmaEcio = m.getInt("CdmaEcio");
mEvdoDbm = m.getInt("EvdoDbm");
mEvdoEcio = m.getInt("EvdoEcio");
mEvdoSnr = m.getInt("EvdoSnr");
mLteSignalStrength = m.getInt("LteSignalStrength");
mLteRsrp = m.getInt("LteRsrp");
mLteRsrq = m.getInt("LteRsrq");
mLteRssnr = m.getInt("LteRssnr");
mLteCqi = m.getInt("LteCqi");
isGsm = m.getBoolean("isGsm");
}
/**
* Set intent notifier Bundle based on SignalStrength
*
* @param m intent notifier Bundle
* @hide
*/
public void fillInNotifierBundle(Bundle m) {
m.putInt("GsmSignalStrength", mGsmSignalStrength);
m.putInt("GsmBitErrorRate", mGsmBitErrorRate);
m.putInt("CdmaDbm", mCdmaDbm);
m.putInt("CdmaEcio", mCdmaEcio);
m.putInt("EvdoDbm", mEvdoDbm);
m.putInt("EvdoEcio", mEvdoEcio);
m.putInt("EvdoSnr", mEvdoSnr);
m.putInt("LteSignalStrength", mLteSignalStrength);
m.putInt("LteRsrp", mLteRsrp);
m.putInt("LteRsrq", mLteRsrq);
m.putInt("LteRssnr", mLteRssnr);
m.putInt("LteCqi", mLteCqi);
m.putBoolean("isGsm", Boolean.valueOf(isGsm));
}
/**
* log
*/
private static void log(String s) {
Rlog.w(LOG_TAG, s);
}
}