Java tutorial
/* * 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.annotation.StringDef; import android.os.Parcel; import android.os.Parcelable; import android.os.PersistableBundle; import android.telephony.Rlog; import android.text.TextUtils; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.Objects; /** * Wcdma signal strength related information. */ public final class CellSignalStrengthWcdma extends CellSignalStrength implements Parcelable { private static final String LOG_TAG = "CellSignalStrengthWcdma"; private static final boolean DBG = false; private static final int WCDMA_RSSI_MAX = -51; private static final int WCDMA_RSSI_GREAT = -77; private static final int WCDMA_RSSI_GOOD = -87; private static final int WCDMA_RSSI_MODERATE = -97; private static final int WCDMA_RSSI_POOR = -107; private static final int WCDMA_RSSI_MIN = -113; private static final int[] sRssiThresholds = new int[] { WCDMA_RSSI_POOR, WCDMA_RSSI_MODERATE, WCDMA_RSSI_GOOD, WCDMA_RSSI_GREAT }; private static final int WCDMA_RSCP_MAX = -24; private static final int WCDMA_RSCP_GREAT = -85; private static final int WCDMA_RSCP_GOOD = -95; private static final int WCDMA_RSCP_MODERATE = -105; private static final int WCDMA_RSCP_POOR = -115; private static final int WCDMA_RSCP_MIN = -120; private static final int[] sRscpThresholds = new int[] { WCDMA_RSCP_POOR, WCDMA_RSCP_MODERATE, WCDMA_RSCP_GOOD, WCDMA_RSCP_GREAT }; // TODO: Because these are used as values in CarrierConfig, they should be exposed somehow. /** @hide */ @Retention(RetentionPolicy.SOURCE) @StringDef({ LEVEL_CALCULATION_METHOD_RSSI, LEVEL_CALCULATION_METHOD_RSCP }) public @interface LevelCalculationMethod { } /** @hide */ public static final String LEVEL_CALCULATION_METHOD_RSSI = "rssi"; /** @hide */ public static final String LEVEL_CALCULATION_METHOD_RSCP = "rscp"; // Default to RSSI for backwards compatibility with older devices private static final String DEFAULT_LEVEL_CALCULATION_METHOD = LEVEL_CALCULATION_METHOD_RSSI; private int mRssi; // in dBm [-113, 51] or CellInfo.UNAVAILABLE if unknown private int mBitErrorRate; // bit error rate (0-7, 99) as defined in TS 27.007 8.5 or // CellInfo.UNAVAILABLE if unknown private int mRscp; // in dBm [-120, -24] private int mEcNo; // range -24, 1, CellInfo.UNAVAILABLE if unknown private int mLevel; /** @hide */ public CellSignalStrengthWcdma() { setDefaultValues(); } /** @hide */ public CellSignalStrengthWcdma(int rssi, int ber, int rscp, int ecno) { mRssi = inRangeOrUnavailable(rssi, WCDMA_RSSI_MIN, WCDMA_RSSI_MAX); mBitErrorRate = inRangeOrUnavailable(ber, 0, 7, 99); mRscp = inRangeOrUnavailable(rscp, -120, -24); mEcNo = inRangeOrUnavailable(ecno, -24, 1); updateLevel(null, null); } /** @hide */ public CellSignalStrengthWcdma(android.hardware.radio.V1_0.WcdmaSignalStrength wcdma) { // Convert from HAL values as part of construction. this(getRssiDbmFromAsu(wcdma.signalStrength), wcdma.bitErrorRate, CellInfo.UNAVAILABLE, CellInfo.UNAVAILABLE); if (mRssi == CellInfo.UNAVAILABLE && mRscp == CellInfo.UNAVAILABLE) { setDefaultValues(); } } /** @hide */ public CellSignalStrengthWcdma(android.hardware.radio.V1_2.WcdmaSignalStrength wcdma) { // Convert from HAL values as part of construction. this(getRssiDbmFromAsu(wcdma.base.signalStrength), wcdma.base.bitErrorRate, getRscpDbmFromAsu(wcdma.rscp), getEcNoDbFromAsu(wcdma.ecno)); if (mRssi == CellInfo.UNAVAILABLE && mRscp == CellInfo.UNAVAILABLE) { setDefaultValues(); } } /** @hide */ public CellSignalStrengthWcdma(CellSignalStrengthWcdma s) { copyFrom(s); } /** @hide */ protected void copyFrom(CellSignalStrengthWcdma s) { mRssi = s.mRssi; mBitErrorRate = s.mBitErrorRate; mRscp = s.mRscp; mEcNo = s.mEcNo; mLevel = s.mLevel; } /** @hide */ @Override public CellSignalStrengthWcdma copy() { return new CellSignalStrengthWcdma(this); } /** @hide */ @Override public void setDefaultValues() { mRssi = CellInfo.UNAVAILABLE; mBitErrorRate = CellInfo.UNAVAILABLE; mRscp = CellInfo.UNAVAILABLE; mEcNo = 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) { String calcMethod; int[] rscpThresholds; if (cc == null) { calcMethod = DEFAULT_LEVEL_CALCULATION_METHOD; rscpThresholds = sRscpThresholds; } else { // TODO: abstract this entire thing into a series of functions calcMethod = cc.getString(CarrierConfigManager.KEY_WCDMA_DEFAULT_SIGNAL_STRENGTH_MEASUREMENT_STRING, DEFAULT_LEVEL_CALCULATION_METHOD); if (TextUtils.isEmpty(calcMethod)) calcMethod = DEFAULT_LEVEL_CALCULATION_METHOD; rscpThresholds = cc.getIntArray(CarrierConfigManager.KEY_WCDMA_RSCP_THRESHOLDS_INT_ARRAY); if (rscpThresholds == null || rscpThresholds.length != NUM_SIGNAL_STRENGTH_THRESHOLDS) { rscpThresholds = sRscpThresholds; } } int level = NUM_SIGNAL_STRENGTH_THRESHOLDS; switch (calcMethod) { case LEVEL_CALCULATION_METHOD_RSCP: if (mRscp < WCDMA_RSCP_MIN || mRscp > WCDMA_RSCP_MAX) { mLevel = SIGNAL_STRENGTH_NONE_OR_UNKNOWN; return; } while (level > 0 && mRscp < rscpThresholds[level - 1]) level--; mLevel = level; return; default: loge("Invalid Level Calculation Method for CellSignalStrengthWcdma = " + calcMethod); /** fall through */ case LEVEL_CALCULATION_METHOD_RSSI: if (mRssi < WCDMA_RSSI_MIN || mRssi > WCDMA_RSSI_MAX) { mLevel = SIGNAL_STRENGTH_NONE_OR_UNKNOWN; return; } while (level > 0 && mRssi < sRssiThresholds[level - 1]) level--; mLevel = level; return; } } /** * Get the RSCP as dBm value -120..-24dBm or {@link CellInfo#UNAVAILABLE UNAVAILABLE}. */ @Override public int getDbm() { if (mRscp != CellInfo.UNAVAILABLE) return mRscp; return mRssi; } /** * Get the RSCP in ASU. * * Asu is calculated based on 3GPP RSCP. Refer to 3GPP 27.007 (Ver 10.3.0) Sec 8.69 * * @return RSCP in ASU 0..96, 255, or UNAVAILABLE */ @Override public int getAsuLevel() { if (mRscp != CellInfo.UNAVAILABLE) return getAsuFromRscpDbm(mRscp); // For historical reasons, if RSCP is unavailable, this API will very incorrectly return // RSSI. This hackery will be removed when most devices are using Radio HAL 1.2+ if (mRssi != CellInfo.UNAVAILABLE) return getAsuFromRssiDbm(mRssi); return getAsuFromRscpDbm(CellInfo.UNAVAILABLE); } /** * Get the RSSI as dBm * * @hide */ public int getRssi() { return mRssi; } /** * Get the RSCP as dBm * * @hide */ public int getRscp() { return mRscp; } /** * Get the Ec/No as dB * * @hide */ public int getEcNo() { return mEcNo; } /** * Return the Bit Error Rate * * @returns the bit error rate (0-7, 99) as defined in TS 27.007 8.5 or UNAVAILABLE. * @hide */ public int getBitErrorRate() { return mBitErrorRate; } @Override public int hashCode() { return Objects.hash(mRssi, mBitErrorRate, mRscp, mEcNo, mLevel); } private static final CellSignalStrengthWcdma sInvalid = new CellSignalStrengthWcdma(); /** @hide */ @Override public boolean isValid() { return !this.equals(sInvalid); } @Override public boolean equals(Object o) { if (!(o instanceof CellSignalStrengthWcdma)) return false; CellSignalStrengthWcdma s = (CellSignalStrengthWcdma) o; return mRssi == s.mRssi && mBitErrorRate == s.mBitErrorRate && mRscp == s.mRscp && mEcNo == s.mEcNo && mLevel == s.mLevel; } /** * @return string representation. */ @Override public String toString() { return "CellSignalStrengthWcdma:" + " ss=" + mRssi + " ber=" + mBitErrorRate + " rscp=" + mRscp + " ecno=" + mEcNo + " level=" + mLevel; } /** Implement the Parcelable interface */ @Override public void writeToParcel(Parcel dest, int flags) { if (DBG) log("writeToParcel(Parcel, int): " + toString()); dest.writeInt(mRssi); dest.writeInt(mBitErrorRate); dest.writeInt(mRscp); dest.writeInt(mEcNo); dest.writeInt(mLevel); } /** * Construct a SignalStrength object from the given parcel * where the token is already been processed. */ private CellSignalStrengthWcdma(Parcel in) { mRssi = in.readInt(); mBitErrorRate = in.readInt(); mRscp = in.readInt(); mEcNo = in.readInt(); mLevel = in.readInt(); if (DBG) log("CellSignalStrengthWcdma(Parcel): " + toString()); } /** Implement the Parcelable interface */ @Override public int describeContents() { return 0; } /** Implement the Parcelable interface */ @SuppressWarnings("hiding") public static final Parcelable.Creator<CellSignalStrengthWcdma> CREATOR = new Parcelable.Creator<CellSignalStrengthWcdma>() { @Override public CellSignalStrengthWcdma createFromParcel(Parcel in) { return new CellSignalStrengthWcdma(in); } @Override public CellSignalStrengthWcdma[] newArray(int size) { return new CellSignalStrengthWcdma[size]; } }; /** * 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); } }