480 lines
16 KiB
Java
480 lines
16 KiB
Java
/*
|
|
* 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.IntRange;
|
|
import android.os.Parcel;
|
|
import android.os.Parcelable;
|
|
import android.os.PersistableBundle;
|
|
|
|
import com.android.telephony.Rlog;
|
|
|
|
import java.util.Objects;
|
|
|
|
/**
|
|
* Signal strength related information.
|
|
*/
|
|
public final class CellSignalStrengthCdma extends CellSignalStrength implements Parcelable {
|
|
|
|
private static final String LOG_TAG = "CellSignalStrengthCdma";
|
|
private static final boolean DBG = false;
|
|
|
|
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 mLevel;
|
|
|
|
/** @hide */
|
|
public CellSignalStrengthCdma() {
|
|
setDefaultValues();
|
|
}
|
|
|
|
/**
|
|
* SignalStrength constructor for input from the HAL.
|
|
*
|
|
* Note that values received from the HAL require coersion to be compatible here. All values
|
|
* reported through IRadio are the negative of the actual values (which results in a positive
|
|
* input to this method.
|
|
*
|
|
* <p>Note that this HAL is inconsistent with UMTS-based radio techs as the value indicating
|
|
* that a field is unreported is negative, rather than a large(r) positive number.
|
|
* <p>Also note that to keep the public-facing methods of this class consistent with others,
|
|
* unreported values are coerced to {@link android.telephony.CellInfo#UNAVAILABLE UNAVAILABLE}
|
|
* rather than left as -1, which is a departure from SignalStrength, which is stuck with the
|
|
* values it currently reports.
|
|
*
|
|
* @param cdmaDbm CDMA signal strength value or CellInfo.UNAVAILABLE if invalid.
|
|
* @param cdmaEcio CDMA pilot/noise ratio or CellInfo.UNAVAILABLE if invalid.
|
|
* @param evdoDbm negative of the EvDO signal strength value or CellInfo.UNAVAILABLE if invalid.
|
|
* @param evdoEcio negative of the EvDO pilot/noise ratio or CellInfo.UNAVAILABLE if invalid.
|
|
* @param evdoSnr an SNR value 0..8 or CellInfo.UNVAILABLE if invalid.
|
|
* @hide
|
|
*/
|
|
public CellSignalStrengthCdma(int cdmaDbm, int cdmaEcio, int evdoDbm, int evdoEcio,
|
|
int evdoSnr) {
|
|
mCdmaDbm = inRangeOrUnavailable(cdmaDbm, -120, 0);
|
|
mCdmaEcio = inRangeOrUnavailable(cdmaEcio, -160, 0);
|
|
mEvdoDbm = inRangeOrUnavailable(evdoDbm, -120, 0);
|
|
mEvdoEcio = inRangeOrUnavailable(evdoEcio, -160, 0);
|
|
mEvdoSnr = inRangeOrUnavailable(evdoSnr, 0, 8);
|
|
|
|
updateLevel(null, null);
|
|
}
|
|
|
|
/** @hide */
|
|
public CellSignalStrengthCdma(CellSignalStrengthCdma s) {
|
|
copyFrom(s);
|
|
}
|
|
|
|
/** @hide */
|
|
protected void copyFrom(CellSignalStrengthCdma s) {
|
|
mCdmaDbm = s.mCdmaDbm;
|
|
mCdmaEcio = s.mCdmaEcio;
|
|
mEvdoDbm = s.mEvdoDbm;
|
|
mEvdoEcio = s.mEvdoEcio;
|
|
mEvdoSnr = s.mEvdoSnr;
|
|
mLevel = s.mLevel;
|
|
}
|
|
|
|
/** @hide */
|
|
@Override
|
|
public CellSignalStrengthCdma copy() {
|
|
return new CellSignalStrengthCdma(this);
|
|
}
|
|
|
|
/** @hide */
|
|
@Override
|
|
public void setDefaultValues() {
|
|
mCdmaDbm = CellInfo.UNAVAILABLE;
|
|
mCdmaEcio = CellInfo.UNAVAILABLE;
|
|
mEvdoDbm = CellInfo.UNAVAILABLE;
|
|
mEvdoEcio = CellInfo.UNAVAILABLE;
|
|
mEvdoSnr = CellInfo.UNAVAILABLE;
|
|
mLevel = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
|
|
}
|
|
|
|
/** {@inheritDoc} */
|
|
@Override
|
|
@IntRange(from = SIGNAL_STRENGTH_NONE_OR_UNKNOWN, to = SIGNAL_STRENGTH_GREAT)
|
|
public int getLevel() {
|
|
return mLevel;
|
|
}
|
|
|
|
/** @hide */
|
|
@Override
|
|
public void updateLevel(PersistableBundle cc, ServiceState ss) {
|
|
int cdmaLevel = getCdmaLevel();
|
|
int evdoLevel = getEvdoLevel();
|
|
if (evdoLevel == SIGNAL_STRENGTH_NONE_OR_UNKNOWN) {
|
|
/* We don't know evdo, use cdma */
|
|
mLevel = getCdmaLevel();
|
|
} else if (cdmaLevel == SIGNAL_STRENGTH_NONE_OR_UNKNOWN) {
|
|
/* We don't know cdma, use evdo */
|
|
mLevel = getEvdoLevel();
|
|
} else {
|
|
/* We know both, use the lowest level */
|
|
mLevel = cdmaLevel < evdoLevel ? cdmaLevel : evdoLevel;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Get the 1xRTT Level in (Android) ASU.
|
|
*
|
|
* There is no standard definition of ASU for CDMA; however, Android defines it as the
|
|
* the lesser of the following two results (for 1xRTT):
|
|
* <table>
|
|
* <thead><tr><th>RSSI Range (dBm)</th><th>ASU Value</th></tr><thead>
|
|
* <tbody>
|
|
* <tr><td>-75..</td><td>16</td></tr>
|
|
* <tr><td>-82..-76</td><td>8</td></tr>
|
|
* <tr><td>-90..-83</td><td>4</td></tr>
|
|
* <tr><td>-95..-91</td><td>2</td></tr>
|
|
* <tr><td>-100..-96</td><td>1</td></tr>
|
|
* <tr><td>..-101</td><td>99</td></tr>
|
|
* </tbody>
|
|
* </table>
|
|
* <table>
|
|
* <thead><tr><th>Ec/Io Range (dB)</th><th>ASU Value</th></tr><thead>
|
|
* <tbody>
|
|
* <tr><td>-90..</td><td>16</td></tr>
|
|
* <tr><td>-100..-91</td><td>8</td></tr>
|
|
* <tr><td>-115..-101</td><td>4</td></tr>
|
|
* <tr><td>-130..-116</td><td>2</td></tr>
|
|
* <tr><td>--150..-131</td><td>1</td></tr>
|
|
* <tr><td>..-151</td><td>99</td></tr>
|
|
* </tbody>
|
|
* </table>
|
|
* @return 1xRTT Level in Android ASU {1,2,4,8,16,99}
|
|
*/
|
|
@Override
|
|
public int getAsuLevel() {
|
|
final int cdmaDbm = getCdmaDbm();
|
|
final int cdmaEcio = getCdmaEcio();
|
|
int cdmaAsuLevel;
|
|
int ecioAsuLevel;
|
|
|
|
if (cdmaDbm == CellInfo.UNAVAILABLE) cdmaAsuLevel = 99;
|
|
else 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 == CellInfo.UNAVAILABLE) ecioAsuLevel = 99;
|
|
else 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("getAsuLevel=" + level);
|
|
return level;
|
|
}
|
|
|
|
/**
|
|
* Get cdma as level 0..4
|
|
*/
|
|
public int getCdmaLevel() {
|
|
final int cdmaDbm = getCdmaDbm();
|
|
final int cdmaEcio = getCdmaEcio();
|
|
int levelDbm;
|
|
int levelEcio;
|
|
|
|
if (cdmaDbm == CellInfo.UNAVAILABLE) levelDbm = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
|
|
else 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 == CellInfo.UNAVAILABLE) levelEcio = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
|
|
else 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 Evdo as level 0..4
|
|
*/
|
|
public int getEvdoLevel() {
|
|
int evdoDbm = getEvdoDbm();
|
|
int evdoSnr = getEvdoSnr();
|
|
int levelEvdoDbm;
|
|
int levelEvdoSnr;
|
|
|
|
if (evdoDbm == CellInfo.UNAVAILABLE) levelEvdoDbm = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
|
|
else 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 == CellInfo.UNAVAILABLE) levelEvdoSnr = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
|
|
else 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 Level in (Android) ASU.
|
|
*
|
|
* There is no standard definition of ASU for CDMA; however, Android defines it as the
|
|
* the lesser of the following two results (for EVDO):
|
|
* <table>
|
|
* <thead><tr><th>RSSI Range (dBm)</th><th>ASU Value</th></tr><thead>
|
|
* <tbody>
|
|
* <tr><td>-65..</td><td>16</td></tr>
|
|
* <tr><td>-75..-66</td><td>8</td></tr>
|
|
* <tr><td>-85..-76</td><td>4</td></tr>
|
|
* <tr><td>-95..-86</td><td>2</td></tr>
|
|
* <tr><td>-105..-96</td><td>1</td></tr>
|
|
* <tr><td>..-106</td><td>99</td></tr>
|
|
* </tbody>
|
|
* </table>
|
|
* <table>
|
|
* <thead><tr><th>SNR Range (unitless)</th><th>ASU Value</th></tr><thead>
|
|
* <tbody>
|
|
* <tr><td>7..</td><td>16</td></tr>
|
|
* <tr><td>6</td><td>8</td></tr>
|
|
* <tr><td>5</td><td>4</td></tr>
|
|
* <tr><td>3..4</td><td>2</td></tr>
|
|
* <tr><td>1..2</td><td>1</td></tr>
|
|
* <tr><td>0</td><td>99</td></tr>
|
|
* </tbody>
|
|
* </table>
|
|
*
|
|
* @return EVDO Level in Android ASU {1,2,4,8,16,99}
|
|
*
|
|
* @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 the signal strength as dBm
|
|
*
|
|
* @return min(CDMA RSSI, EVDO RSSI) of the measured cell.
|
|
*/
|
|
@Override
|
|
public int getDbm() {
|
|
int cdmaDbm = getCdmaDbm();
|
|
int evdoDbm = getEvdoDbm();
|
|
|
|
// Use the lower value to be conservative
|
|
return (cdmaDbm < evdoDbm) ? cdmaDbm : evdoDbm;
|
|
}
|
|
|
|
/**
|
|
* Get the CDMA RSSI value in dBm
|
|
*/
|
|
public int getCdmaDbm() {
|
|
return mCdmaDbm;
|
|
}
|
|
|
|
/** @hide */
|
|
public void setCdmaDbm(int cdmaDbm) {
|
|
mCdmaDbm = cdmaDbm;
|
|
}
|
|
|
|
/**
|
|
* Get the CDMA Ec/Io value in dB*10
|
|
*/
|
|
public int getCdmaEcio() {
|
|
return mCdmaEcio;
|
|
}
|
|
|
|
/** @hide */
|
|
public void setCdmaEcio(int cdmaEcio) {
|
|
mCdmaEcio = cdmaEcio;
|
|
}
|
|
|
|
/**
|
|
* Get the EVDO RSSI value in dBm
|
|
*/
|
|
public int getEvdoDbm() {
|
|
return mEvdoDbm;
|
|
}
|
|
|
|
/** @hide */
|
|
public void setEvdoDbm(int evdoDbm) {
|
|
mEvdoDbm = evdoDbm;
|
|
}
|
|
|
|
/**
|
|
* Get the EVDO Ec/Io value in dB*10
|
|
*/
|
|
public int getEvdoEcio() {
|
|
return mEvdoEcio;
|
|
}
|
|
|
|
/** @hide */
|
|
public void setEvdoEcio(int evdoEcio) {
|
|
mEvdoEcio = evdoEcio;
|
|
}
|
|
|
|
/**
|
|
* Get the signal to noise ratio. Valid values are 0-8. 8 is the highest.
|
|
*/
|
|
public int getEvdoSnr() {
|
|
return mEvdoSnr;
|
|
}
|
|
|
|
/** @hide */
|
|
public void setEvdoSnr(int evdoSnr) {
|
|
mEvdoSnr = evdoSnr;
|
|
}
|
|
|
|
@Override
|
|
public int hashCode() {
|
|
return Objects.hash(mCdmaDbm, mCdmaEcio, mEvdoDbm, mEvdoEcio, mEvdoSnr, mLevel);
|
|
}
|
|
|
|
private static final CellSignalStrengthCdma sInvalid = new CellSignalStrengthCdma();
|
|
|
|
/** @hide */
|
|
@Override
|
|
public boolean isValid() {
|
|
return !this.equals(sInvalid);
|
|
}
|
|
|
|
@Override
|
|
public boolean equals (Object o) {
|
|
CellSignalStrengthCdma s;
|
|
if (!(o instanceof CellSignalStrengthCdma)) return false;
|
|
s = (CellSignalStrengthCdma) o;
|
|
|
|
return mCdmaDbm == s.mCdmaDbm
|
|
&& mCdmaEcio == s.mCdmaEcio
|
|
&& mEvdoDbm == s.mEvdoDbm
|
|
&& mEvdoEcio == s.mEvdoEcio
|
|
&& mEvdoSnr == s.mEvdoSnr
|
|
&& mLevel == s.mLevel;
|
|
}
|
|
|
|
/**
|
|
* @return string representation.
|
|
*/
|
|
@Override
|
|
public String toString() {
|
|
return "CellSignalStrengthCdma:"
|
|
+ " cdmaDbm=" + mCdmaDbm
|
|
+ " cdmaEcio=" + mCdmaEcio
|
|
+ " evdoDbm=" + mEvdoDbm
|
|
+ " evdoEcio=" + mEvdoEcio
|
|
+ " evdoSnr=" + mEvdoSnr
|
|
+ " level=" + mLevel;
|
|
}
|
|
|
|
/** Implement the Parcelable interface */
|
|
@Override
|
|
public void writeToParcel(Parcel dest, int flags) {
|
|
if (DBG) log("writeToParcel(Parcel, int): " + toString());
|
|
dest.writeInt(mCdmaDbm);
|
|
dest.writeInt(mCdmaEcio);
|
|
dest.writeInt(mEvdoDbm);
|
|
dest.writeInt(mEvdoEcio);
|
|
dest.writeInt(mEvdoSnr);
|
|
dest.writeInt(mLevel);
|
|
}
|
|
|
|
/**
|
|
* Construct a SignalStrength object from the given parcel
|
|
* where the TYPE_CDMA token is already been processed.
|
|
*/
|
|
private CellSignalStrengthCdma(Parcel in) {
|
|
// CdmaDbm, CdmaEcio, EvdoDbm and EvdoEcio are written into
|
|
// the parcel as positive values.
|
|
// Need to convert into negative values unless the value is invalid
|
|
mCdmaDbm = in.readInt();
|
|
mCdmaEcio = in.readInt();
|
|
mEvdoDbm = in.readInt();
|
|
mEvdoEcio = in.readInt();
|
|
mEvdoSnr = in.readInt();
|
|
mLevel = in.readInt();
|
|
if (DBG) log("CellSignalStrengthCdma(Parcel): " + toString());
|
|
}
|
|
|
|
/** Implement the Parcelable interface */
|
|
@Override
|
|
public int describeContents() {
|
|
return 0;
|
|
}
|
|
|
|
/** Implement the Parcelable interface */
|
|
@SuppressWarnings("hiding")
|
|
public static final @android.annotation.NonNull Parcelable.Creator<CellSignalStrengthCdma> CREATOR =
|
|
new Parcelable.Creator<CellSignalStrengthCdma>() {
|
|
@Override
|
|
public CellSignalStrengthCdma createFromParcel(Parcel in) {
|
|
return new CellSignalStrengthCdma(in);
|
|
}
|
|
|
|
@Override
|
|
public CellSignalStrengthCdma[] newArray(int size) {
|
|
return new CellSignalStrengthCdma[size];
|
|
}
|
|
};
|
|
|
|
/**
|
|
* log
|
|
*/
|
|
private static void log(String s) {
|
|
Rlog.w(LOG_TAG, s);
|
|
}
|
|
}
|