Merge "Always call unbindService no matter what bindService returns"
diff --git a/src/java/com/android/internal/telephony/NetworkIndication.java b/src/java/com/android/internal/telephony/NetworkIndication.java
index 3800563..b8c8f53 100644
--- a/src/java/com/android/internal/telephony/NetworkIndication.java
+++ b/src/java/com/android/internal/telephony/NetworkIndication.java
@@ -29,6 +29,7 @@
import static com.android.internal.telephony.RILConstants.RIL_UNSOL_SUPP_SVC_NOTIFICATION;
import static com.android.internal.telephony.RILConstants.RIL_UNSOL_VOICE_RADIO_TECH_CHANGED;
+import android.annotation.ElapsedRealtimeLong;
import android.hardware.radio.network.IRadioNetworkIndication;
import android.os.AsyncResult;
import android.sysprop.TelephonyProperties;
@@ -237,17 +238,35 @@
* Indicates when radio has received a NITZ time message.
* @param indicationType Type of radio indication
* @param nitzTime NITZ time string in the form "yy/mm/dd,hh:mm:ss(+/-)tz,dt"
- * @param receivedTime milliseconds since boot that the NITZ time was received
+ * @param receivedTimeMs time according to {@link android.os.SystemClock#elapsedRealtime()} when
+ * the RIL sent the NITZ time to the framework
+ * @param ageMs time in milliseconds indicating how long NITZ was cached in RIL and modem.
+ * This must track true age and therefore must be calculated using clocks that
+ * include the time spend in sleep / low power states. If it can not be guaranteed,
+ * there must not be any caching done at the modem and should fill in 0 for ageMs
*/
- public void nitzTimeReceived(int indicationType, String nitzTime, long receivedTime) {
+ public void nitzTimeReceived(int indicationType, String nitzTime,
+ @ElapsedRealtimeLong long receivedTimeMs, long ageMs) {
mRil.processIndication(indicationType);
if (RIL.RILJ_LOGD) mRil.unsljLogRet(RIL_UNSOL_NITZ_TIME_RECEIVED, nitzTime);
+ // Ignore the NITZ if ageMs is not a valid time, e.g. negative or greater than
+ // receivedTimeMs.
+ if ((ageMs < 0) || (ageMs >= receivedTimeMs)) {
+ AnomalyReporter.reportAnomaly(UUID.fromString("fc7c56d4-485d-475a-aaff-394203c6cdfc"),
+ "NITZ indication with invalid age");
+
+ mRil.riljLoge("age time is invalid, ignoring nitzTimeReceived indication. "
+ + "receivedTimeMs = " + receivedTimeMs + ", ageMs = " + ageMs);
+ return;
+ }
+
// TODO: Clean this up with a parcelable class for better self-documentation
- Object[] result = new Object[2];
+ Object[] result = new Object[3];
result[0] = nitzTime;
- result[1] = receivedTime;
+ result[1] = receivedTimeMs;
+ result[2] = ageMs;
boolean ignoreNitz = TelephonyProperties.ignore_nitz().orElse(false);
diff --git a/src/java/com/android/internal/telephony/NetworkTypeController.java b/src/java/com/android/internal/telephony/NetworkTypeController.java
index a1724a6..d4a2a50 100644
--- a/src/java/com/android/internal/telephony/NetworkTypeController.java
+++ b/src/java/com/android/internal/telephony/NetworkTypeController.java
@@ -98,6 +98,7 @@
private static final int EVENT_INITIALIZE = 12;
private static final int EVENT_PHYSICAL_CHANNEL_CONFIG_CHANGED = 13;
private static final int EVENT_PCO_DATA_CHANGED = 14;
+ private static final int EVENT_BANDWIDTH_CHANGED = 15;
private static final String[] sEvents = new String[EVENT_PCO_DATA_CHANGED + 1];
static {
@@ -142,6 +143,7 @@
private boolean mIsSecondaryTimerActive;
private boolean mIsTimerResetEnabledForLegacyStateRRCIdle;
private int mLtePlusThresholdBandwidth;
+ private int mNrAdvancedThresholdBandwidth;
private int[] mAdditionalNrAdvancedBandsList;
private String mPrimaryTimerState;
private String mSecondaryTimerState;
@@ -151,6 +153,7 @@
private Boolean mIsNrAdvancedAllowedByPco = false;
private int mNrAdvancedCapablePcoId = 0;
private boolean mIsUsingUserDataForRrcDetection = false;
+ private boolean mEnableNrAdvancedWhileRoaming = true;
/**
* NetworkTypeController constructor.
@@ -200,6 +203,8 @@
mPhone.getServiceStateTracker().registerForDataRegStateOrRatChanged(
AccessNetworkConstants.TRANSPORT_TYPE_WWAN, getHandler(),
EVENT_DATA_RAT_CHANGED, null);
+ mPhone.getServiceStateTracker().registerForBandwidthChanged(
+ getHandler(), EVENT_BANDWIDTH_CHANGED, null);
mIsPhysicalChannelConfig16Supported = mPhone.getContext().getSystemService(
TelephonyManager.class).isRadioInterfaceCapabilitySupported(
TelephonyManager.CAPABILITY_PHYSICAL_CHANNEL_CONFIG_1_6_SUPPORTED);
@@ -246,6 +251,10 @@
CarrierConfigManager.KEY_NR_TIMERS_RESET_IF_NON_ENDC_AND_RRC_IDLE_BOOL);
mLtePlusThresholdBandwidth = CarrierConfigManager.getDefaultConfig().getInt(
CarrierConfigManager.KEY_LTE_PLUS_THRESHOLD_BANDWIDTH_KHZ_INT);
+ mNrAdvancedThresholdBandwidth = CarrierConfigManager.getDefaultConfig().getInt(
+ CarrierConfigManager.KEY_NR_ADVANCED_THRESHOLD_BANDWIDTH_KHZ_INT);
+ mEnableNrAdvancedWhileRoaming = CarrierConfigManager.getDefaultConfig().getBoolean(
+ CarrierConfigManager.KEY_ENABLE_NR_ADVANCED_WHILE_ROAMING_BOOL);
CarrierConfigManager configManager = (CarrierConfigManager) mPhone.getContext()
.getSystemService(Context.CARRIER_CONFIG_SERVICE);
@@ -276,10 +285,15 @@
mLtePlusThresholdBandwidth = b.getInt(
CarrierConfigManager.KEY_LTE_PLUS_THRESHOLD_BANDWIDTH_KHZ_INT,
mLtePlusThresholdBandwidth);
+ mNrAdvancedThresholdBandwidth = b.getInt(
+ CarrierConfigManager.KEY_NR_ADVANCED_THRESHOLD_BANDWIDTH_KHZ_INT,
+ mNrAdvancedThresholdBandwidth);
mAdditionalNrAdvancedBandsList = b.getIntArray(
CarrierConfigManager.KEY_ADDITIONAL_NR_ADVANCED_BANDS_INT_ARRAY);
mNrAdvancedCapablePcoId = b.getInt(
CarrierConfigManager.KEY_NR_ADVANCED_CAPABLE_PCO_ID_INT);
+ mEnableNrAdvancedWhileRoaming = b.getBoolean(
+ CarrierConfigManager.KEY_ENABLE_NR_ADVANCED_WHILE_ROAMING_BOOL);
mIsUsingUserDataForRrcDetection = b.getBoolean(
CarrierConfigManager.KEY_LTE_ENDC_USING_USER_DATA_FOR_RRC_DETECTION_BOOL);
if (mIsPhysicalChannelConfig16Supported && mIsUsingUserDataForRrcDetection) {
@@ -508,6 +522,7 @@
case EVENT_NR_STATE_CHANGED:
case EVENT_NR_FREQUENCY_CHANGED:
case EVENT_PCO_DATA_CHANGED:
+ case EVENT_BANDWIDTH_CHANGED:
// ignored
break;
case EVENT_PHYSICAL_CHANNEL_CONFIG_CHANGED:
@@ -877,6 +892,9 @@
sendMessage(EVENT_NR_STATE_CHANGED);
}
break;
+ case EVENT_BANDWIDTH_CHANGED:
+ updateNrAdvancedState();
+ break;
default:
return NOT_HANDLED;
}
@@ -1133,8 +1151,32 @@
== NetworkRegistrationInfo.NR_STATE_RESTRICTED;
}
+ /**
+ * @return {@code true} if the device is in NR advanced mode (i.e. 5G+).
+ */
private boolean isNrAdvanced() {
- return isNrAdvancedCapable() && (isNrMmwave() || isAdditionalNrAdvancedBand());
+ // Check PCO requirement. For carriers using PCO to indicate whether the data connection is
+ // NR advanced capable, mNrAdvancedCapablePcoId should be configured to non-zero.
+ if (mNrAdvancedCapablePcoId > 0 && !mIsNrAdvancedAllowedByPco) {
+ return false;
+ }
+
+ // Check if NR advanced is enabled when the device is roaming. Some carriers disable it
+ // while the device is roaming.
+ if (mPhone.getServiceState().getDataRoaming() && !mEnableNrAdvancedWhileRoaming) {
+ return false;
+ }
+
+ // Check if meeting minimum bandwidth requirement. For most carriers, there is no minimum
+ // bandwidth requirement and mNrAdvancedThresholdBandwidth is 0.
+ if (IntStream.of(mPhone.getServiceState().getCellBandwidths()).sum()
+ < mNrAdvancedThresholdBandwidth) {
+ return false;
+ }
+
+ // If all above tests passed, then check if the device is using millimeter wave bands or
+ // carrier designated bands.
+ return isNrMmwave() || isAdditionalNrAdvancedBand();
}
private boolean isNrMmwave() {
@@ -1158,13 +1200,6 @@
return false;
}
- private boolean isNrAdvancedCapable() {
- if (mNrAdvancedCapablePcoId > 0) {
- return mIsNrAdvancedAllowedByPco;
- }
- return true;
- }
-
private boolean isLte(int rat) {
return rat == TelephonyManager.NETWORK_TYPE_LTE
|| rat == TelephonyManager.NETWORK_TYPE_LTE_CA;
diff --git a/src/java/com/android/internal/telephony/NitzSignal.java b/src/java/com/android/internal/telephony/NitzSignal.java
new file mode 100644
index 0000000..889fe95
--- /dev/null
+++ b/src/java/com/android/internal/telephony/NitzSignal.java
@@ -0,0 +1,129 @@
+/*
+ * Copyright 2021 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 com.android.internal.telephony;
+
+import android.annotation.DurationMillisLong;
+import android.annotation.ElapsedRealtimeLong;
+import android.annotation.NonNull;
+import android.os.TimestampedValue;
+
+import java.time.Duration;
+import java.util.Objects;
+
+/** NITZ information and associated metadata. */
+public final class NitzSignal {
+
+ @ElapsedRealtimeLong private final long mReceiptElapsedMillis;
+ @NonNull private final NitzData mNitzData;
+ @DurationMillisLong private final long mAgeMillis;
+
+ /**
+ * @param receiptElapsedMillis the time according to {@link
+ * android.os.SystemClock#elapsedRealtime()} when the NITZ signal was first received by
+ * the platform code
+ * @param nitzData the NITZ data
+ * @param ageMillis the age of the NITZ when it was passed to the platform, e.g. if it was
+ * cached by the modem for a period of time. Must not be negative.
+ */
+ public NitzSignal(
+ @ElapsedRealtimeLong long receiptElapsedMillis,
+ @NonNull NitzData nitzData,
+ long ageMillis) {
+ mReceiptElapsedMillis = receiptElapsedMillis;
+ mNitzData = Objects.requireNonNull(nitzData);
+ if (ageMillis < 0) {
+ throw new IllegalArgumentException("ageMillis < 0");
+ }
+ mAgeMillis = ageMillis;
+ }
+
+ /**
+ * Returns the time according to {@link android.os.SystemClock#elapsedRealtime()} when the NITZ
+ * signal was first received by the platform code.
+ */
+ @ElapsedRealtimeLong
+ public long getReceiptElapsedRealtimeMillis() {
+ return mReceiptElapsedMillis;
+ }
+
+ /**
+ * Returns the NITZ data.
+ */
+ @NonNull
+ public NitzData getNitzData() {
+ return mNitzData;
+ }
+
+ /**
+ * Returns the age of the NITZ when it was passed to the platform, e.g. if it was cached by the
+ * modem for a period of time. Must not be negative.
+ */
+ @DurationMillisLong
+ public long getAgeMillis() {
+ return mAgeMillis;
+ }
+
+ /**
+ * Returns a derived property of {@code receiptElapsedMillis - ageMillis}, i.e. the time
+ * according to the elapsed realtime clock when the NITZ signal was actually received by this
+ * device taking into time it was cached by layers before the RIL.
+ */
+ @ElapsedRealtimeLong
+ public long getAgeAdjustedElapsedRealtimeMillis() {
+ return mReceiptElapsedMillis - mAgeMillis;
+ }
+
+ /**
+ * Creates a {@link android.os.TimestampedValue} containing the UTC time as the number of
+ * milliseconds since the start of the Unix epoch. The reference time is the time according to
+ * the elapsed realtime clock when that would have been the time, accounting for receipt time
+ * and age.
+ */
+ public TimestampedValue<Long> createTimeSignal() {
+ return new TimestampedValue<>(
+ getAgeAdjustedElapsedRealtimeMillis(),
+ getNitzData().getCurrentTimeInMillis());
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+ NitzSignal that = (NitzSignal) o;
+ return mReceiptElapsedMillis == that.mReceiptElapsedMillis
+ && mAgeMillis == that.mAgeMillis
+ && mNitzData.equals(that.mNitzData);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(mReceiptElapsedMillis, mNitzData, mAgeMillis);
+ }
+
+ @Override
+ public String toString() {
+ return "NitzSignal{"
+ + "mReceiptElapsedMillis=" + Duration.ofMillis(mReceiptElapsedMillis)
+ + ", mNitzData=" + mNitzData
+ + ", mAgeMillis=" + mAgeMillis
+ + '}';
+ }
+}
diff --git a/src/java/com/android/internal/telephony/NitzStateMachine.java b/src/java/com/android/internal/telephony/NitzStateMachine.java
index e1f854c..f4f4deb 100644
--- a/src/java/com/android/internal/telephony/NitzStateMachine.java
+++ b/src/java/com/android/internal/telephony/NitzStateMachine.java
@@ -21,7 +21,6 @@
import android.content.Context;
import android.os.SystemClock;
import android.os.SystemProperties;
-import android.os.TimestampedValue;
import android.provider.Settings;
import com.android.internal.util.IndentingPrintWriter;
@@ -65,7 +64,7 @@
/**
* Handle a new NITZ signal being received.
*/
- void handleNitzReceived(@NonNull TimestampedValue<NitzData> nitzSignal);
+ void handleNitzReceived(@NonNull NitzSignal nitzSignal);
/**
* Handle the user putting the device into or out of airplane mode
@@ -90,14 +89,14 @@
interface DeviceState {
/**
- * If time between NITZ updates is less than {@link #getNitzUpdateSpacingMillis()} the
- * update may be ignored.
+ * If elapsed time between two NITZ signals is less than this value then the second signal
+ * can be ignored.
*/
int getNitzUpdateSpacingMillis();
/**
- * If {@link #getNitzUpdateSpacingMillis()} hasn't been exceeded but update is >
- * {@link #getNitzUpdateDiffMillis()} do the update
+ * If UTC time between two NITZ signals is less than this value then the second signal can
+ * be ignored.
*/
int getNitzUpdateDiffMillis();
@@ -109,7 +108,7 @@
/**
* Returns the same value as {@link SystemClock#elapsedRealtime()}.
*/
- long elapsedRealtime();
+ long elapsedRealtimeMillis();
/**
* Returns the same value as {@link System#currentTimeMillis()}.
@@ -158,7 +157,7 @@
}
@Override
- public long elapsedRealtime() {
+ public long elapsedRealtimeMillis() {
return SystemClock.elapsedRealtime();
}
diff --git a/src/java/com/android/internal/telephony/Phone.java b/src/java/com/android/internal/telephony/Phone.java
index 86b9786..9d16f1f 100644
--- a/src/java/com/android/internal/telephony/Phone.java
+++ b/src/java/com/android/internal/telephony/Phone.java
@@ -2198,11 +2198,11 @@
* @return Current signal strength as SignalStrength
*/
public SignalStrength getSignalStrength() {
- ServiceStateTracker sst = getServiceStateTracker();
- if (sst == null) {
+ SignalStrengthController ssc = getSignalStrengthController();
+ if (ssc == null) {
return new SignalStrength();
} else {
- return sst.getSignalStrength();
+ return ssc.getSignalStrength();
}
}
diff --git a/src/java/com/android/internal/telephony/ServiceStateTracker.java b/src/java/com/android/internal/telephony/ServiceStateTracker.java
index 7c47293..62ec70e 100755
--- a/src/java/com/android/internal/telephony/ServiceStateTracker.java
+++ b/src/java/com/android/internal/telephony/ServiceStateTracker.java
@@ -49,7 +49,6 @@
import android.os.RegistrantList;
import android.os.SystemClock;
import android.os.SystemProperties;
-import android.os.TimestampedValue;
import android.os.UserHandle;
import android.os.WorkSource;
import android.preference.PreferenceManager;
@@ -73,7 +72,6 @@
import android.telephony.RadioAccessFamily;
import android.telephony.ServiceState;
import android.telephony.ServiceState.RilRadioTechnology;
-import android.telephony.SignalStrength;
import android.telephony.SubscriptionInfo;
import android.telephony.SubscriptionManager;
import android.telephony.SubscriptionManager.OnSubscriptionsChangedListener;
@@ -118,7 +116,6 @@
import java.io.PrintWriter;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
-import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
@@ -126,10 +123,8 @@
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
-import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
-import java.util.regex.PatternSyntaxException;
import java.util.stream.Collectors;
/**
@@ -142,9 +137,6 @@
private static final String PROP_FORCE_ROAMING = "telephony.test.forceRoaming";
- private static final long SIGNAL_STRENGTH_REFRESH_THRESHOLD_IN_MS =
- TimeUnit.SECONDS.toMillis(10);
-
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
private CommandsInterface mCi;
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
@@ -186,10 +178,6 @@
private final Set<Integer> mRadioPowerOffReasons = new HashSet();
- @UnsupportedAppUsage
- private SignalStrength mSignalStrength;
- private long mSignalStrengthUpdatedTime;
-
// TODO - this should not be public, right now used externally GsmConnetion.
public RestrictedState mRestrictedState;
@@ -203,13 +191,6 @@
@UnsupportedAppUsage
private boolean mDesiredPowerState;
- /**
- * By default, strength polling is enabled. However, if we're
- * getting unsolicited signal strength updates from the radio, set
- * value to true and don't bother polling any more.
- */
- private boolean mDontPollSignalStrength = false;
-
@UnsupportedAppUsage
private RegistrantList mVoiceRoamingOnRegistrants = new RegistrantList();
@UnsupportedAppUsage
@@ -231,6 +212,7 @@
private RegistrantList mNrStateChangedRegistrants = new RegistrantList();
private RegistrantList mNrFrequencyChangedRegistrants = new RegistrantList();
private RegistrantList mCssIndicatorChangedRegistrants = new RegistrantList();
+ private final RegistrantList mBandwidthChangedRegistrants = new RegistrantList();
private final RegistrantList mAirplaneModeChangedRegistrants = new RegistrantList();
private final RegistrantList mAreaCodeChangedRegistrants = new RegistrantList();
@@ -238,23 +220,17 @@
private boolean mPendingRadioPowerOffAfterDataOff = false;
private int mPendingRadioPowerOffAfterDataOffTag = 0;
- /** Signal strength poll rate. */
- private static final int POLL_PERIOD_MILLIS = 20 * 1000;
-
/** Waiting period before recheck gprs and voice registration. */
public static final int DEFAULT_GPRS_CHECK_PERIOD_MILLIS = 60 * 1000;
/** GSM events */
protected static final int EVENT_RADIO_STATE_CHANGED = 1;
protected static final int EVENT_NETWORK_STATE_CHANGED = 2;
- protected static final int EVENT_GET_SIGNAL_STRENGTH = 3;
protected static final int EVENT_POLL_STATE_CS_CELLULAR_REGISTRATION = 4;
protected static final int EVENT_POLL_STATE_PS_CELLULAR_REGISTRATION = 5;
protected static final int EVENT_POLL_STATE_PS_IWLAN_REGISTRATION = 6;
protected static final int EVENT_POLL_STATE_OPERATOR = 7;
- protected static final int EVENT_POLL_SIGNAL_STRENGTH = 10;
protected static final int EVENT_NITZ_TIME = 11;
- protected static final int EVENT_SIGNAL_STRENGTH_UPDATE = 12;
protected static final int EVENT_POLL_STATE_NETWORK_SELECTION_MODE = 14;
protected static final int EVENT_GET_LOC_DONE = 15;
protected static final int EVENT_SIM_RECORDS_LOADED = 16;
@@ -623,22 +599,6 @@
private final TransportManager mTransportManager;
private final SparseArray<NetworkRegistrationManager> mRegStateManagers = new SparseArray<>();
- /* list of LTE EARFCNs (E-UTRA Absolute Radio Frequency Channel Number,
- * Reference: 3GPP TS 36.104 5.4.3)
- * inclusive ranges for which the lte rsrp boost is applied */
- private ArrayList<Pair<Integer, Integer>> mEarfcnPairListForRsrpBoost = null;
- private int mLteRsrpBoost = 0; // offset which is reduced from the rsrp threshold
- // while calculating signal strength level.
-
- /* Ranges of NR ARFCNs (5G Absolute Radio Frequency Channel Number,
- * Reference: 3GPP TS 38.104)
- * inclusive ranges for which the corresponding nr rsrp boost is applied */
- private ArrayList<Pair<Integer, Integer>> mNrarfcnRangeListForRsrpBoost = null;
- private int[] mNrRsrpBoost;
-
- private final Object mRsrpBoostLock = new Object();
- private static final int INVALID_ARFCN = -1;
-
/* Last known TAC/LAC */
private int mLastKnownAreaCode = CellInfo.UNAVAILABLE;
@@ -671,7 +631,6 @@
mOutOfServiceSS.setStateOutOfService();
mUiccController.registerForIccChanged(this, EVENT_ICC_CHANGED, null);
- mCi.setOnSignalStrengthUpdate(this, EVENT_SIGNAL_STRENGTH_UPDATE, null);
mCi.registerForCellInfoList(this, EVENT_UNSOL_CELL_INFO_LIST, null);
mCi.registerForPhysicalChannelConfiguration(this, EVENT_PHYSICAL_CHANNEL_CONFIG, null);
@@ -710,7 +669,6 @@
enableCellularOnBoot);
- setSignalStrengthDefaultValues();
mPhone.getCarrierActionAgent().registerForCarrierAction(CARRIER_ACTION_SET_RADIO_ENABLED,
this, EVENT_RADIO_POWER_FROM_CARRIER, null, false);
@@ -779,7 +737,6 @@
mNewSS.setStateOutOfService();
mLastCellInfoReqTime = 0;
mLastCellInfoList = null;
- mSignalStrength = new SignalStrength();
mStartedGprsRegCheck = false;
mReportedGprsNoReg = false;
mMdn = null;
@@ -789,7 +746,7 @@
mLastNitzData = null;
mNitzState.handleNetworkUnavailable();
mCellIdentity = null;
- mSignalStrengthUpdatedTime = System.currentTimeMillis();
+ mPhone.getSignalStrengthController().setSignalStrengthDefaultValues();
//cancel any pending pollstate request on voice tech switching
cancelPollState();
@@ -828,7 +785,7 @@
// switching between GSM and CDMA phone), because the unsolicited signal strength
// information might come late or even never come. This will get the accurate signal
// strength information displayed on the UI.
- mCi.getSignalStrength(obtainMessage(EVENT_GET_SIGNAL_STRENGTH));
+ mPhone.getSignalStrengthController().getSignalStrengthFromCi();
sendMessage(obtainMessage(EVENT_PHONE_TYPE_SWITCHED));
logPhoneTypeChange();
@@ -859,7 +816,7 @@
}
public void dispose() {
- mCi.unSetOnSignalStrengthUpdate(this);
+ mPhone.getSignalStrengthController().dispose();
mUiccController.unregisterForIccChanged(this);
mCi.unregisterForCellInfoList(this);
mCi.unregisterForPhysicalChannelConfiguration(this);
@@ -885,23 +842,6 @@
return mLastPhysicalChannelConfigList;
}
- private SignalStrength mLastSignalStrength = null;
- @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
- protected boolean notifySignalStrength() {
- boolean notified = false;
- if (!mSignalStrength.equals(mLastSignalStrength)) {
- try {
- mPhone.notifySignalStrength();
- notified = true;
- mLastSignalStrength = mSignalStrength;
- } catch (NullPointerException ex) {
- loge("updateSignalStrength() Phone already destroyed: " + ex
- + "SignalStrength not notified");
- }
- }
- return notified;
- }
-
/**
* Notify all mVoiceRegStateOrRatChangedRegistrants using an
* AsyncResult in msg.obj where AsyncResult#result contains the
@@ -1367,20 +1307,6 @@
pollStateInternal(true);
break;
- case EVENT_GET_SIGNAL_STRENGTH:
- // This callback is called when signal strength is polled
- // all by itself
-
- if (!(mCi.getRadioState() == TelephonyManager.RADIO_POWER_ON)) {
- // Polling will continue when radio turns back on
- return;
- }
- ar = (AsyncResult) msg.obj;
- onSignalStrengthResult(ar);
- queueNextSignalStrengthPoll();
-
- break;
-
case EVENT_GET_LOC_DONE:
ar = (AsyncResult) msg.obj;
if (ar.exception == null) {
@@ -1421,32 +1347,20 @@
}
break;
- case EVENT_POLL_SIGNAL_STRENGTH:
- // Just poll signal strength...not part of pollState()
-
- mCi.getSignalStrength(obtainMessage(EVENT_GET_SIGNAL_STRENGTH));
- break;
-
- case EVENT_NITZ_TIME:
+ case EVENT_NITZ_TIME: {
ar = (AsyncResult) msg.obj;
- String nitzString = (String)((Object[])ar.result)[0];
- long nitzReceiveTime = ((Long)((Object[])ar.result)[1]).longValue();
+ Object[] nitzArgs = (Object[])ar.result;
+ String nitzString = (String)nitzArgs[0];
+ long nitzReceiveTimeMs = ((Long)nitzArgs[1]).longValue();
+ long ageMs = 0;
+ if (nitzArgs.length >= 3) {
+ ageMs = ((Long)nitzArgs[2]).longValue();
+ }
- setTimeFromNITZString(nitzString, nitzReceiveTime);
+ setTimeFromNITZString(nitzString, nitzReceiveTimeMs, ageMs);
break;
-
- case EVENT_SIGNAL_STRENGTH_UPDATE:
- // This is a notification from CommandsInterface.setOnSignalStrengthUpdate
-
- ar = (AsyncResult) msg.obj;
-
- // The radio is telling us about signal strength changes
- // we don't have to ask it
- mDontPollSignalStrength = true;
-
- onSignalStrengthResult(ar);
- break;
+ }
case EVENT_SIM_RECORDS_LOADED:
log("EVENT_SIM_RECORDS_LOADED: what=" + msg.what);
@@ -2343,7 +2257,7 @@
&& ServiceState.isPsOnlyTech(newDataRat))
|| (ServiceState.isPsOnlyTech(oldDataRAT)
&& ServiceState.isCdma(newDataRat))) {
- mCi.getSignalStrength(obtainMessage(EVENT_GET_SIGNAL_STRENGTH));
+ mPhone.getSignalStrengthController().getSignalStrengthFromCi();
}
// voice roaming state in done while handling EVENT_POLL_STATE_REGISTRATION_CDMA
@@ -2354,7 +2268,8 @@
mNewSS.setDataRoamingFromRegistration(isDataRoaming);
}
- updateServiceStateArfcnRsrpBoost(mNewSS, networkRegState.getCellIdentity());
+ mPhone.getSignalStrengthController().updateServiceStateArfcnRsrpBoost(mNewSS,
+ networkRegState.getCellIdentity());
break;
}
@@ -3329,7 +3244,7 @@
switch (mCi.getRadioState()) {
case TelephonyManager.RADIO_POWER_UNAVAILABLE:
mNewSS.setStateOutOfService();
- setSignalStrengthDefaultValues();
+ mPhone.getSignalStrengthController().setSignalStrengthDefaultValues();
mLastNitzData = null;
mNitzState.handleNetworkUnavailable();
pollStateDone();
@@ -3337,7 +3252,7 @@
case TelephonyManager.RADIO_POWER_OFF:
mNewSS.setStateOff();
- setSignalStrengthDefaultValues();
+ mPhone.getSignalStrengthController().setSignalStrengthDefaultValues();
mLastNitzData = null;
mNitzState.handleNetworkUnavailable();
// don't poll when device is shutting down or the poll was not modemTrigged
@@ -3567,6 +3482,8 @@
boolean hasCssIndicatorChanged = (mSS.getCssIndicator() != mNewSS.getCssIndicator());
+ boolean hasBandwidthChanged = mSS.getCellBandwidths() != mNewSS.getCellBandwidths();
+
boolean has4gHandoff = false;
boolean hasMultiApnSupport = false;
boolean hasLostMultiApnSupport = false;
@@ -3610,6 +3527,7 @@
+ " hasCssIndicatorChanged = " + hasCssIndicatorChanged
+ " hasNrFrequencyRangeChanged = " + hasNrFrequencyRangeChanged
+ " hasNrStateChanged = " + hasNrStateChanged
+ + " hasBandwidthChanged = " + hasBandwidthChanged
+ " hasAirplaneModeOnlChanged = " + hasAirplaneModeOnChanged);
}
@@ -3686,6 +3604,10 @@
mCssIndicatorChangedRegistrants.notifyRegistrants();
}
+ if (hasBandwidthChanged) {
+ mBandwidthChangedRegistrants.notifyRegistrants();
+ }
+
if (hasRejectCauseChanged) {
setNotification(CS_REJECT_CAUSE_ENABLED);
}
@@ -3781,13 +3703,15 @@
if (hasRilVoiceRadioTechnologyChanged) {
shouldLogRatChange = true;
- notifySignalStrength();
+ // TODO(b/178429976): Remove the dependency on SSC. Double check if the SS broadcast
+ // is really needed when CS/PS RAT change.
+ mPhone.getSignalStrengthController().notifySignalStrength();
}
for (int transport : mTransportManager.getAvailableTransports()) {
if (hasRilDataRadioTechnologyChanged.get(transport)) {
shouldLogRatChange = true;
- notifySignalStrength();
+ mPhone.getSignalStrengthController().notifySignalStrength();
}
if (hasDataRegStateChanged.get(transport)
@@ -3818,7 +3742,8 @@
// because the signal strength might come earlier RAT and radio state
// changed.
if (hasAirplaneModeOffChanged) {
- mCi.getSignalStrength(obtainMessage(EVENT_GET_SIGNAL_STRENGTH));
+ // TODO(b/178429976): Remove the dependency on SSC. This should be done in SSC.
+ mPhone.getSignalStrengthController().getSignalStrengthFromCi();
}
if (shouldLogAttachedChange) {
@@ -4413,20 +4338,24 @@
}
/**
- * nitzReceiveTime is time_t that the NITZ time was posted
+ * Handle the NITZ string from the modem
+ *
+ * @param nitzString NITZ time string in the form "yy/mm/dd,hh:mm:ss(+/-)tz,dt"
+ * @param nitzReceiveTimeMs time according to {@link android.os.SystemClock#elapsedRealtime()}
+ * when the RIL sent the NITZ time to the framework
+ * @param ageMs time in milliseconds indicating how long NITZ was cached in RIL and modem
*/
- private void setTimeFromNITZString(String nitzString, long nitzReceiveTime) {
+ private void setTimeFromNITZString(String nitzString, long nitzReceiveTimeMs, long ageMs) {
long start = SystemClock.elapsedRealtime();
if (DBG) {
- Rlog.d(LOG_TAG, "NITZ: " + nitzString + "," + nitzReceiveTime
- + " start=" + start + " delay=" + (start - nitzReceiveTime));
+ Rlog.d(LOG_TAG, "NITZ: " + nitzString + "," + nitzReceiveTimeMs + ", ageMs=" + ageMs
+ + " start=" + start + " delay=" + (start - nitzReceiveTimeMs));
}
NitzData newNitzData = NitzData.parse(nitzString);
mLastNitzData = newNitzData;
if (newNitzData != null) {
try {
- TimestampedValue<NitzData> nitzSignal =
- new TimestampedValue<>(nitzReceiveTime, newNitzData);
+ NitzSignal nitzSignal = new NitzSignal(nitzReceiveTimeMs, newNitzData, ageMs);
mNitzState.handleNitzReceived(nitzSignal);
} finally {
if (DBG) {
@@ -4673,28 +4602,7 @@
}
private void queueNextSignalStrengthPoll() {
- if (mDontPollSignalStrength) {
- // The radio is telling us about signal strength changes
- // we don't have to ask it
- return;
- }
-
- // if there is no SIM present, do not poll signal strength
- UiccCard uiccCard = UiccController.getInstance().getUiccCard(getPhoneId());
- if (uiccCard == null || uiccCard.getCardState() == CardState.CARDSTATE_ABSENT) {
- log("Not polling signal strength due to absence of SIM");
- return;
- }
-
- Message msg;
-
- msg = obtainMessage();
- msg.what = EVENT_POLL_SIGNAL_STRENGTH;
-
- long nextTime;
-
- // TODO Don't poll signal strength if screen is off
- sendMessageDelayed(msg, POLL_PERIOD_MILLIS);
+ mPhone.getSignalStrengthController().queueNextSignalStrengthPoll();
}
private void notifyCdmaSubscriptionInfoReady() {
@@ -5036,76 +4944,6 @@
}
}
- /**
- * Checks if the provided earfcn falls withing the range of earfcns.
- *
- * return int index in earfcnPairList if earfcn falls within the provided range; -1 otherwise.
- */
- private int containsEarfcnInEarfcnRange(ArrayList<Pair<Integer, Integer>> earfcnPairList,
- int earfcn) {
- int index = 0;
- if (earfcnPairList != null) {
- for (Pair<Integer, Integer> earfcnPair : earfcnPairList) {
- if ((earfcn >= earfcnPair.first) && (earfcn <= earfcnPair.second)) {
- return index;
- }
- index++;
- }
- }
-
- return -1;
- }
-
- /**
- * Convert the earfcnStringArray to list of pairs.
- *
- * Format of the earfcnsList is expected to be {"erafcn1_start-earfcn1_end",
- * "earfcn2_start-earfcn2_end" ... }
- */
- ArrayList<Pair<Integer, Integer>> convertEarfcnStringArrayToPairList(String[] earfcnsList) {
- ArrayList<Pair<Integer, Integer>> earfcnPairList = new ArrayList<Pair<Integer, Integer>>();
-
- if (earfcnsList != null) {
- int earfcnStart;
- int earfcnEnd;
- for (int i = 0; i < earfcnsList.length; i++) {
- try {
- String[] earfcns = earfcnsList[i].split("-");
- if (earfcns.length != 2) {
- if (VDBG) {
- log("Invalid earfcn range format");
- }
- return null;
- }
-
- earfcnStart = Integer.parseInt(earfcns[0]);
- earfcnEnd = Integer.parseInt(earfcns[1]);
-
- if (earfcnStart > earfcnEnd) {
- if (VDBG) {
- log("Invalid earfcn range format");
- }
- return null;
- }
-
- earfcnPairList.add(new Pair<Integer, Integer>(earfcnStart, earfcnEnd));
- } catch (PatternSyntaxException pse) {
- if (VDBG) {
- log("Invalid earfcn range format");
- }
- return null;
- } catch (NumberFormatException nfe) {
- if (VDBG) {
- log("Invalid earfcn number format");
- }
- return null;
- }
- }
- }
-
- return earfcnPairList;
- }
-
private void onCarrierConfigChanged() {
PersistableBundle config = getCarrierConfig();
log("CarrierConfigChange " + config);
@@ -5116,8 +4954,10 @@
mCdnr.updateEfForEri(getOperatorNameFromEri());
}
- updateArfcnLists(config);
+ // TODO(b/178429976): Listen config change in SSC and remove logic here
+ mPhone.getSignalStrengthController().updateArfcnLists(config);
mPhone.getSignalStrengthController().updateReportingCriteria(config);
+
updateOperatorNamePattern(config);
mCdnr.updateEfFromCarrierConfig(config);
mPhone.notifyCallForwardingIndicator();
@@ -5128,93 +4968,6 @@
pollStateInternal(false);
}
- private void updateArfcnLists(PersistableBundle config) {
- synchronized (mRsrpBoostLock) {
- mLteRsrpBoost = config.getInt(CarrierConfigManager.KEY_LTE_EARFCNS_RSRP_BOOST_INT, 0);
- String[] earfcnsStringArrayForRsrpBoost = config.getStringArray(
- CarrierConfigManager.KEY_BOOSTED_LTE_EARFCNS_STRING_ARRAY);
- mEarfcnPairListForRsrpBoost = convertEarfcnStringArrayToPairList(
- earfcnsStringArrayForRsrpBoost);
-
- mNrRsrpBoost = config.getIntArray(
- CarrierConfigManager.KEY_NRARFCNS_RSRP_BOOST_INT_ARRAY);
- String[] nrarfcnsStringArrayForRsrpBoost = config.getStringArray(
- CarrierConfigManager.KEY_BOOSTED_NRARFCNS_STRING_ARRAY);
- mNrarfcnRangeListForRsrpBoost = convertEarfcnStringArrayToPairList(
- nrarfcnsStringArrayForRsrpBoost);
-
- if ((mNrRsrpBoost == null && mNrarfcnRangeListForRsrpBoost != null)
- || (mNrRsrpBoost != null && mNrarfcnRangeListForRsrpBoost == null)
- || (mNrRsrpBoost != null && mNrarfcnRangeListForRsrpBoost != null
- && mNrRsrpBoost.length != mNrarfcnRangeListForRsrpBoost.size())) {
- loge("Invalid parameters for NR RSRP boost");
- mNrRsrpBoost = null;
- mNrarfcnRangeListForRsrpBoost = null;
- }
- }
- }
-
- private void updateServiceStateArfcnRsrpBoost(ServiceState serviceState,
- CellIdentity cellIdentity) {
- int rsrpBoost = 0;
- int arfcn;
-
- synchronized (mRsrpBoostLock) {
- switch (cellIdentity.getType()) {
- case CellInfo.TYPE_LTE:
- arfcn = ((CellIdentityLte) cellIdentity).getEarfcn();
- if (arfcn != INVALID_ARFCN
- && containsEarfcnInEarfcnRange(mEarfcnPairListForRsrpBoost,
- arfcn) != -1) {
- rsrpBoost = mLteRsrpBoost;
- }
- break;
- case CellInfo.TYPE_NR:
- arfcn = ((CellIdentityNr) cellIdentity).getNrarfcn();
- if (arfcn != INVALID_ARFCN) {
- int index = containsEarfcnInEarfcnRange(mNrarfcnRangeListForRsrpBoost,
- arfcn);
- if (index != -1) {
- rsrpBoost = mNrRsrpBoost[index];
- }
- }
- break;
- default:
- break;
- }
- }
- serviceState.setArfcnRsrpBoost(rsrpBoost);
- }
-
- /**
- * send signal-strength-changed notification if changed Called both for
- * solicited and unsolicited signal strength updates
- *
- * @return true if the signal strength changed and a notification was sent.
- */
- protected boolean onSignalStrengthResult(AsyncResult ar) {
-
- // This signal is used for both voice and data radio signal so parse
- // all fields
- // Under power off, let's suppress valid signal strength report, which is
- // beneficial to avoid icon flickering.
- if ((ar.exception == null) && (ar.result != null)
- && mSS.getState() != ServiceState.STATE_POWER_OFF) {
- mSignalStrength = (SignalStrength) ar.result;
-
- PersistableBundle config = getCarrierConfig();
- mSignalStrength.updateLevel(config, mSS);
- } else {
- log("onSignalStrengthResult() Exception from RIL : " + ar.exception);
- mSignalStrength = new SignalStrength();
- }
- mSignalStrengthUpdatedTime = System.currentTimeMillis();
-
- boolean ssChanged = notifySignalStrength();
-
- return ssChanged;
- }
-
/**
* Hang up all voice call and turn off radio. Implemented by derived class.
*/
@@ -5338,50 +5091,6 @@
}
/**
- * @return signal strength
- */
- public SignalStrength getSignalStrength() {
- if (shouldRefreshSignalStrength()) {
- log("SST.getSignalStrength() refreshing signal strength.");
- obtainMessage(EVENT_POLL_SIGNAL_STRENGTH).sendToTarget();
- }
- return mSignalStrength;
- }
-
- private boolean shouldRefreshSignalStrength() {
- long curTime = System.currentTimeMillis();
-
- // If last signal strength is older than 10 seconds, or somehow if curTime is smaller
- // than mSignalStrengthUpdatedTime (system time update), it's considered stale.
- boolean isStale = (mSignalStrengthUpdatedTime > curTime)
- || (curTime - mSignalStrengthUpdatedTime > SIGNAL_STRENGTH_REFRESH_THRESHOLD_IN_MS);
- if (!isStale) return false;
-
- List<SubscriptionInfo> subInfoList = SubscriptionController.getInstance()
- .getActiveSubscriptionInfoList(mPhone.getContext().getOpPackageName(),
- mPhone.getContext().getAttributionTag());
-
- if (!ArrayUtils.isEmpty(subInfoList)) {
- for (SubscriptionInfo info : subInfoList) {
- // If we have an active opportunistic subscription whose data is IN_SERVICE,
- // we need to get signal strength to decide data switching threshold. In this case,
- // we poll latest signal strength from modem.
- if (info.isOpportunistic()) {
- TelephonyManager tm = TelephonyManager.from(mPhone.getContext())
- .createForSubscriptionId(info.getSubscriptionId());
- ServiceState ss = tm.getServiceState();
- if (ss != null
- && ss.getDataRegistrationState() == ServiceState.STATE_IN_SERVICE) {
- return true;
- }
- }
- }
- }
-
- return false;
- }
-
- /**
* Registration point for subscription info ready
* @param h handler to notify
* @param what what code of message when delivered
@@ -5432,25 +5141,6 @@
}
}
- private void dumpEarfcnPairList(PrintWriter pw, ArrayList<Pair<Integer, Integer>> pairList,
- String name) {
- pw.print(" " + name + "={");
- if (pairList != null) {
- int i = pairList.size();
- for (Pair<Integer, Integer> earfcnPair : pairList) {
- pw.print("(");
- pw.print(earfcnPair.first);
- pw.print(",");
- pw.print(earfcnPair.second);
- pw.print(")");
- if ((--i) != 0) {
- pw.print(",");
- }
- }
- }
- pw.println("}");
- }
-
private void dumpCellInfoList(PrintWriter pw) {
pw.print(" mLastCellInfoList={");
if(mLastCellInfoList != null) {
@@ -5476,9 +5166,6 @@
pw.println(" mPollingContext=" + mPollingContext + " - " +
(mPollingContext != null ? mPollingContext[0] : ""));
pw.println(" mDesiredPowerState=" + mDesiredPowerState);
- pw.println(" mDontPollSignalStrength=" + mDontPollSignalStrength);
- pw.println(" mSignalStrength=" + mSignalStrength);
- pw.println(" mLastSignalStrength=" + mLastSignalStrength);
pw.println(" mRestrictedState=" + mRestrictedState);
pw.println(" mPendingRadioPowerOffAfterDataOff=" + mPendingRadioPowerOffAfterDataOff);
pw.println(" mPendingRadioPowerOffAfterDataOffTag=" + mPendingRadioPowerOffAfterDataOffTag);
@@ -5533,12 +5220,8 @@
pw.println(" mRadioDisabledByCarrier" + mRadioDisabledByCarrier);
pw.println(" mDeviceShuttingDown=" + mDeviceShuttingDown);
pw.println(" mSpnUpdatePending=" + mSpnUpdatePending);
- pw.println(" mLteRsrpBoost=" + mLteRsrpBoost);
- pw.println(" mNrRsrpBoost=" + Arrays.toString(mNrRsrpBoost));
pw.println(" mCellInfoMinIntervalMs=" + mCellInfoMinIntervalMs);
pw.println(" mEriManager=" + mEriManager);
- dumpEarfcnPairList(pw, mEarfcnPairListForRsrpBoost, "mEarfcnPairListForRsrpBoost");
- dumpEarfcnPairList(pw, mNrarfcnRangeListForRsrpBoost, "mNrarfcnRangeListForRsrpBoost");
mLocaleTracker.dump(fd, pw, args);
IndentingPrintWriter ipw = new IndentingPrintWriter(pw, " ");
@@ -5736,12 +5419,6 @@
}
}
- @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
- private void setSignalStrengthDefaultValues() {
- mSignalStrength = new SignalStrength();
- mSignalStrengthUpdatedTime = System.currentTimeMillis();
- }
-
protected String getHomeOperatorNumeric() {
String numeric = ((TelephonyManager) mPhone.getContext().
getSystemService(Context.TELEPHONY_SERVICE)).
@@ -6090,6 +5767,25 @@
}
/**
+ * Registers for cell bandwidth changed.
+ * @param h handler to notify
+ * @param what what code of message when delivered
+ * @param obj placed in Message.obj
+ */
+ public void registerForBandwidthChanged(Handler h, int what, Object obj) {
+ Registrant r = new Registrant(h, what, obj);
+ mBandwidthChangedRegistrants.add(r);
+ }
+
+ /**
+ * Unregisters for cell bandwidth changed.
+ * @param h handler to notify
+ */
+ public void unregisterForBandwidthChanged(Handler h) {
+ mBandwidthChangedRegistrants.remove(h);
+ }
+
+ /**
* Get the NR data connection context ids.
*
* @return data connection context ids.
diff --git a/src/java/com/android/internal/telephony/SignalStrengthController.java b/src/java/com/android/internal/telephony/SignalStrengthController.java
index 48d91c7..d99f4fc 100644
--- a/src/java/com/android/internal/telephony/SignalStrengthController.java
+++ b/src/java/com/android/internal/telephony/SignalStrengthController.java
@@ -27,41 +27,96 @@
import android.os.RemoteException;
import android.telephony.AccessNetworkConstants;
import android.telephony.CarrierConfigManager;
+import android.telephony.CellIdentity;
+import android.telephony.CellIdentityLte;
+import android.telephony.CellIdentityNr;
+import android.telephony.CellInfo;
import android.telephony.CellSignalStrengthLte;
import android.telephony.CellSignalStrengthNr;
+import android.telephony.ServiceState;
+import android.telephony.SignalStrength;
import android.telephony.SignalStrengthUpdateRequest;
import android.telephony.SignalThresholdInfo;
+import android.telephony.SubscriptionInfo;
+import android.telephony.SubscriptionManager;
+import android.telephony.TelephonyManager;
import android.util.Pair;
import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.telephony.uicc.IccCardStatus;
+import com.android.internal.telephony.uicc.UiccCard;
+import com.android.internal.telephony.uicc.UiccController;
+import com.android.internal.telephony.util.ArrayUtils;
import com.android.internal.util.IndentingPrintWriter;
import com.android.telephony.Rlog;
import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;
+import java.util.concurrent.TimeUnit;
+import java.util.regex.PatternSyntaxException;
/**
* SignalStrengthController handles signal polling request and unsolicited signal strength update.
*/
public class SignalStrengthController extends Handler {
- protected static final boolean DBG = false; /* STOPSHIP if true */
- protected static final String TAG = "SSCtr";
+ private static final boolean DBG = false; /* STOPSHIP if true */
+ private static final String TAG = "SSCtr";
- private static final int EVENT_SET_SIGNAL_STRENGTH_UPDATE_REQUEST = 1;
- private static final int EVENT_CLEAR_SIGNAL_STRENGTH_UPDATE_REQUEST = 2;
- private static final int EVENT_ON_DEVICE_IDLE_STATE_CHANGED = 3;
- private static final int EVENT_RIL_CONNECTED = 4;
- private static final int EVENT_RADIO_AVAILABLE = 5;
+ private static final long SIGNAL_STRENGTH_REFRESH_THRESHOLD_IN_MS =
+ TimeUnit.SECONDS.toMillis(10);
+ /** Signal strength poll rate. */
+ private static final long POLL_PERIOD_MILLIS = TimeUnit.SECONDS.toMillis(20);
+ private static final int INVALID_ARFCN = -1;
+ private static final int EVENT_SET_SIGNAL_STRENGTH_UPDATE_REQUEST = 1;
+ private static final int EVENT_CLEAR_SIGNAL_STRENGTH_UPDATE_REQUEST = 2;
+ private static final int EVENT_ON_DEVICE_IDLE_STATE_CHANGED = 3;
+ private static final int EVENT_RIL_CONNECTED = 4;
+ private static final int EVENT_RADIO_AVAILABLE = 5;
+ private static final int EVENT_GET_SIGNAL_STRENGTH = 6;
+ private static final int EVENT_POLL_SIGNAL_STRENGTH = 7;
+ private static final int EVENT_SIGNAL_STRENGTH_UPDATE = 8;
private final Phone mPhone;
private final CommandsInterface mCi;
+ /**
+ * By default, strength polling is enabled. However, if we're
+ * getting unsolicited signal strength updates from the radio, set
+ * value to true and don't bother polling any more.
+ */
+ private boolean mDontPollSignalStrength = false;
+ @NonNull
+ private SignalStrength mSignalStrength;
+ private long mSignalStrengthUpdatedTime;
+ private SignalStrength mLastSignalStrength = null;
+
+ /**
+ * List of LTE EARFCNs (E-UTRAN Absolute Radio Frequency Channel Number,
+ * Reference: 3GPP TS 36.104 5.4.3)
+ * inclusive ranges for which the lte rsrp boost is applied
+ */
+ private ArrayList<Pair<Integer, Integer>> mEarfcnPairListForRsrpBoost = null;
+ /**
+ * Offset which is reduced from the rsrp threshold while calculating signal strength level.
+ */
+ private int mLteRsrpBoost = 0;
+ /**
+ * Ranges of NR ARFCNs (5G Absolute Radio Frequency Channel Number,
+ * Reference: 3GPP TS 38.104)
+ * inclusive ranges for which the corresponding nr rsrp boost is applied
+ */
+ private ArrayList<Pair<Integer, Integer>> mNrarfcnRangeListForRsrpBoost = null;
+ @Nullable
+ private int[] mNrRsrpBoost = null;
+ private final Object mRsrpBoostLock = new Object();
+
private final List<SignalRequestRecord> mSignalRequestRecords = new ArrayList<>();
public SignalStrengthController(Phone phone) {
@@ -70,11 +125,14 @@
mCi.registerForRilConnected(this, EVENT_RIL_CONNECTED, null);
mCi.registerForAvailable(this, EVENT_RADIO_AVAILABLE, null);
+ mCi.setOnSignalStrengthUpdate(this, EVENT_SIGNAL_STRENGTH_UPDATE, null);
+ setSignalStrengthDefaultValues();
}
@Override
public void handleMessage(Message msg) {
if (DBG) log("received event " + msg.what);
+ AsyncResult ar;
switch (msg.what) {
case EVENT_RIL_CONNECTED: // fall through
@@ -147,30 +205,154 @@
break;
}
+ case EVENT_GET_SIGNAL_STRENGTH: {
+ // This callback is called when signal strength is polled
+ // all by itself
+
+ if (!(mCi.getRadioState() == TelephonyManager.RADIO_POWER_ON)) {
+ // Polling will continue when radio turns back on
+ return;
+ }
+ ar = (AsyncResult) msg.obj;
+ onSignalStrengthResult(ar);
+ queueNextSignalStrengthPoll();
+
+ break;
+ }
+
+ case EVENT_POLL_SIGNAL_STRENGTH: {
+ // Just poll signal strength...not part of pollState()
+
+ mCi.getSignalStrength(obtainMessage(EVENT_GET_SIGNAL_STRENGTH));
+ break;
+ }
+
+ case EVENT_SIGNAL_STRENGTH_UPDATE: {
+ // This is a notification from CommandsInterface.setOnSignalStrengthUpdate
+
+ ar = (AsyncResult) msg.obj;
+
+ // The radio is telling us about signal strength changes
+ // we don't have to ask it
+ mDontPollSignalStrength = true;
+
+ onSignalStrengthResult(ar);
+ break;
+ }
+
default:
log("Unhandled message with number: " + msg.what);
break;
}
}
- /**
- * Set a new request to update the signal strength thresholds.
- */
- public void setSignalStrengthUpdateRequest(int subId, int callingUid,
- SignalStrengthUpdateRequest request, @NonNull Message onCompleted) {
- SignalRequestRecord record = new SignalRequestRecord(subId, callingUid, request);
- sendMessage(obtainMessage(EVENT_SET_SIGNAL_STRENGTH_UPDATE_REQUEST,
- new Pair<SignalRequestRecord, Message>(record, onCompleted)));
+ void dispose() {
+ mCi.unSetOnSignalStrengthUpdate(this);
}
/**
- * Clear the previously set request.
+ * Called when RIL is connected during boot up or after modem restart. Set the default criteria
+ * so that modem can start with default state before updated criteria is ready.
*/
- public void clearSignalStrengthUpdateRequest(int subId, int callingUid,
- SignalStrengthUpdateRequest request, @Nullable Message onCompleted) {
- SignalRequestRecord record = new SignalRequestRecord(subId, callingUid, request);
- sendMessage(obtainMessage(EVENT_CLEAR_SIGNAL_STRENGTH_UPDATE_REQUEST,
- new Pair<SignalRequestRecord, Message>(record, onCompleted)));
+ private void onReset() {
+ setDefaultSignalStrengthReportingCriteria();
+ }
+
+ void getSignalStrengthFromCi() {
+ mCi.getSignalStrength(obtainMessage(EVENT_GET_SIGNAL_STRENGTH));
+ }
+
+ /**
+ * send signal-strength-changed notification if changed Called both for
+ * solicited and unsolicited signal strength updates
+ *
+ * @return true if the signal strength changed and a notification was sent.
+ */
+ private boolean onSignalStrengthResult(AsyncResult ar) {
+
+ // This signal is used for both voice and data radio signal so parse
+ // all fields
+
+ if ((ar.exception == null) && (ar.result != null)) {
+ mSignalStrength = (SignalStrength) ar.result;
+
+ PersistableBundle config = getCarrierConfig();
+ if (mPhone.getServiceStateTracker() != null) {
+ mSignalStrength.updateLevel(config, mPhone.getServiceStateTracker().mSS);
+ }
+ } else {
+ log("onSignalStrengthResult() Exception from RIL : " + ar.exception);
+ mSignalStrength = new SignalStrength();
+ }
+ mSignalStrengthUpdatedTime = System.currentTimeMillis();
+
+ boolean ssChanged = notifySignalStrength();
+
+ return ssChanged;
+ }
+
+ /**
+ * @return signal strength
+ */
+ public SignalStrength getSignalStrength() {
+ if (shouldRefreshSignalStrength()) {
+ log("getSignalStrength() refreshing signal strength.");
+ obtainMessage(EVENT_POLL_SIGNAL_STRENGTH).sendToTarget();
+ }
+ return mSignalStrength;
+ }
+
+ private boolean shouldRefreshSignalStrength() {
+ long curTime = System.currentTimeMillis();
+
+ // If last signal strength is older than 10 seconds, or somehow if curTime is smaller
+ // than mSignalStrengthUpdatedTime (system time update), it's considered stale.
+ boolean isStale = (mSignalStrengthUpdatedTime > curTime)
+ || (curTime - mSignalStrengthUpdatedTime > SIGNAL_STRENGTH_REFRESH_THRESHOLD_IN_MS);
+ if (!isStale) return false;
+
+ List<SubscriptionInfo> subInfoList = SubscriptionController.getInstance()
+ .getActiveSubscriptionInfoList(mPhone.getContext().getOpPackageName(),
+ mPhone.getContext().getAttributionTag());
+
+ if (!ArrayUtils.isEmpty(subInfoList)) {
+ for (SubscriptionInfo info : subInfoList) {
+ // If we have an active opportunistic subscription whose data is IN_SERVICE,
+ // we need to get signal strength to decide data switching threshold. In this case,
+ // we poll latest signal strength from modem.
+ if (info.isOpportunistic()) {
+ TelephonyManager tm = TelephonyManager.from(mPhone.getContext())
+ .createForSubscriptionId(info.getSubscriptionId());
+ ServiceState ss = tm.getServiceState();
+ if (ss != null
+ && ss.getDataRegistrationState() == ServiceState.STATE_IN_SERVICE) {
+ return true;
+ }
+ }
+ }
+ }
+
+ return false;
+ }
+
+ void queueNextSignalStrengthPoll() {
+ if (mDontPollSignalStrength) {
+ // The radio is telling us about signal strength changes
+ // we don't have to ask it
+ return;
+ }
+
+ // if there is no SIM present, do not poll signal strength
+ UiccCard uiccCard = UiccController.getInstance().getUiccCard(
+ mPhone != null ? mPhone.getPhoneId() : SubscriptionManager.DEFAULT_PHONE_INDEX);
+ if (uiccCard == null
+ || uiccCard.getCardState() == IccCardStatus.CardState.CARDSTATE_ABSENT) {
+ log("Not polling signal strength due to absence of SIM");
+ return;
+ }
+
+ // TODO Don't poll signal strength if screen is off
+ sendMessageDelayed(obtainMessage(EVENT_POLL_SIGNAL_STRENGTH), POLL_PERIOD_MILLIS);
}
/**
@@ -223,6 +405,65 @@
}
}
+ private void setDefaultSignalStrengthReportingCriteria() {
+ mPhone.setSignalStrengthReportingCriteria(SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_RSSI,
+ AccessNetworkThresholds.GERAN, AccessNetworkConstants.AccessNetworkType.GERAN,
+ true);
+ mPhone.setSignalStrengthReportingCriteria(SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_RSCP,
+ AccessNetworkThresholds.UTRAN, AccessNetworkConstants.AccessNetworkType.UTRAN,
+ true);
+ mPhone.setSignalStrengthReportingCriteria(SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_RSRP,
+ AccessNetworkThresholds.EUTRAN_RSRP,
+ AccessNetworkConstants.AccessNetworkType.EUTRAN, true);
+ mPhone.setSignalStrengthReportingCriteria(SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_RSSI,
+ AccessNetworkThresholds.CDMA2000, AccessNetworkConstants.AccessNetworkType.CDMA2000,
+ true);
+ if (mPhone.getHalVersion().greaterOrEqual(RIL.RADIO_HAL_VERSION_1_5)) {
+ mPhone.setSignalStrengthReportingCriteria(
+ SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_RSRQ,
+ AccessNetworkThresholds.EUTRAN_RSRQ,
+ AccessNetworkConstants.AccessNetworkType.EUTRAN, false);
+ mPhone.setSignalStrengthReportingCriteria(
+ SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_RSSNR,
+ AccessNetworkThresholds.EUTRAN_RSSNR,
+ AccessNetworkConstants.AccessNetworkType.EUTRAN, true);
+
+ // Defaultly we only need SSRSRP for NGRAN signal criteria reporting
+ mPhone.setSignalStrengthReportingCriteria(
+ SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_SSRSRP,
+ AccessNetworkThresholds.NGRAN_RSRSRP,
+ AccessNetworkConstants.AccessNetworkType.NGRAN, true);
+ mPhone.setSignalStrengthReportingCriteria(
+ SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_SSRSRQ,
+ AccessNetworkThresholds.NGRAN_RSRSRQ,
+ AccessNetworkConstants.AccessNetworkType.NGRAN, false);
+ mPhone.setSignalStrengthReportingCriteria(
+ SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_SSSINR,
+ AccessNetworkThresholds.NGRAN_SSSINR,
+ AccessNetworkConstants.AccessNetworkType.NGRAN, false);
+ }
+ }
+
+ void setSignalStrengthDefaultValues() {
+ mSignalStrength = new SignalStrength();
+ mSignalStrengthUpdatedTime = System.currentTimeMillis();
+ }
+
+ boolean notifySignalStrength() {
+ boolean notified = false;
+ if (!mSignalStrength.equals(mLastSignalStrength)) {
+ try {
+ mPhone.notifySignalStrength();
+ notified = true;
+ mLastSignalStrength = mSignalStrength;
+ } catch (NullPointerException ex) {
+ log("updateSignalStrength() Phone already destroyed: " + ex
+ + "SignalStrength not notified");
+ }
+ }
+ return notified;
+ }
+
/**
* Print the SignalStrengthController states into the given stream.
*
@@ -233,11 +474,57 @@
public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, " ");
ipw.increaseIndent();
- pw.println("mSignalRequestRecords: " + mSignalRequestRecords);
+ pw.println("mSignalRequestRecords=" + mSignalRequestRecords);
+ pw.println(" mLastSignalStrength=" + mLastSignalStrength);
+ pw.println(" mSignalStrength=" + mSignalStrength);
+ pw.println(" mDontPollSignalStrength=" + mDontPollSignalStrength);
+ pw.println(" mLteRsrpBoost=" + mLteRsrpBoost);
+ pw.println(" mNrRsrpBoost=" + Arrays.toString(mNrRsrpBoost));
+ dumpEarfcnPairList(pw, mEarfcnPairListForRsrpBoost, "mEarfcnPairListForRsrpBoost");
+ dumpEarfcnPairList(pw, mNrarfcnRangeListForRsrpBoost, "mNrarfcnRangeListForRsrpBoost");
ipw.decreaseIndent();
ipw.flush();
}
+ private void dumpEarfcnPairList(PrintWriter pw, ArrayList<Pair<Integer, Integer>> pairList,
+ String name) {
+ pw.print(" " + name + "={");
+ if (pairList != null) {
+ int i = pairList.size();
+ for (Pair<Integer, Integer> earfcnPair : pairList) {
+ pw.print("(");
+ pw.print(earfcnPair.first);
+ pw.print(",");
+ pw.print(earfcnPair.second);
+ pw.print(")");
+ if ((--i) != 0) {
+ pw.print(",");
+ }
+ }
+ }
+ pw.println("}");
+ }
+
+ /**
+ * Set a new request to update the signal strength thresholds.
+ */
+ public void setSignalStrengthUpdateRequest(int subId, int callingUid,
+ SignalStrengthUpdateRequest request, @NonNull Message onCompleted) {
+ SignalRequestRecord record = new SignalRequestRecord(subId, callingUid, request);
+ sendMessage(obtainMessage(EVENT_SET_SIGNAL_STRENGTH_UPDATE_REQUEST,
+ new Pair<SignalRequestRecord, Message>(record, onCompleted)));
+ }
+
+ /**
+ * Clear the previously set request.
+ */
+ public void clearSignalStrengthUpdateRequest(int subId, int callingUid,
+ SignalStrengthUpdateRequest request, @Nullable Message onCompleted) {
+ SignalRequestRecord record = new SignalRequestRecord(subId, callingUid, request);
+ sendMessage(obtainMessage(EVENT_CLEAR_SIGNAL_STRENGTH_UPDATE_REQUEST,
+ new Pair<SignalRequestRecord, Message>(record, onCompleted)));
+ }
+
/**
* Align all the qualified thresholds set from applications to the {@code systemThresholds}
* and consolidate a new thresholds array, follow rules below:
@@ -334,43 +621,203 @@
return false;
}
- private void setDefaultSignalStrengthReportingCriteria() {
- mPhone.setSignalStrengthReportingCriteria(SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_RSSI,
- AccessNetworkThresholds.GERAN, AccessNetworkConstants.AccessNetworkType.GERAN,
- true);
- mPhone.setSignalStrengthReportingCriteria(SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_RSCP,
- AccessNetworkThresholds.UTRAN, AccessNetworkConstants.AccessNetworkType.UTRAN,
- true);
- mPhone.setSignalStrengthReportingCriteria(SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_RSRP,
- AccessNetworkThresholds.EUTRAN_RSRP,
- AccessNetworkConstants.AccessNetworkType.EUTRAN, true);
- mPhone.setSignalStrengthReportingCriteria(SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_RSSI,
- AccessNetworkThresholds.CDMA2000, AccessNetworkConstants.AccessNetworkType.CDMA2000,
- true);
- if (mPhone.getHalVersion().greaterOrEqual(RIL.RADIO_HAL_VERSION_1_5)) {
- mPhone.setSignalStrengthReportingCriteria(
- SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_RSRQ,
- AccessNetworkThresholds.EUTRAN_RSRQ,
- AccessNetworkConstants.AccessNetworkType.EUTRAN, false);
- mPhone.setSignalStrengthReportingCriteria(
- SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_RSSNR,
- AccessNetworkThresholds.EUTRAN_RSSNR,
- AccessNetworkConstants.AccessNetworkType.EUTRAN, true);
+ private static boolean isRanAndSignalMeasurementTypeMatch(
+ @AccessNetworkConstants.RadioAccessNetworkType int ran,
+ @SignalThresholdInfo.SignalMeasurementType int measurement,
+ SignalThresholdInfo info) {
+ return ran == info.getRadioAccessNetworkType()
+ && measurement == info.getSignalMeasurementType();
+ }
- // Defaultly we only need SSRSRP for NGRAN signal criteria reporting
- mPhone.setSignalStrengthReportingCriteria(
- SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_SSRSRP,
- AccessNetworkThresholds.NGRAN_RSRSRP,
- AccessNetworkConstants.AccessNetworkType.NGRAN, true);
- mPhone.setSignalStrengthReportingCriteria(
- SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_SSRSRQ,
- AccessNetworkThresholds.NGRAN_RSRSRQ,
- AccessNetworkConstants.AccessNetworkType.NGRAN, false);
- mPhone.setSignalStrengthReportingCriteria(
- SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_SSSINR,
- AccessNetworkThresholds.NGRAN_SSSINR,
- AccessNetworkConstants.AccessNetworkType.NGRAN, false);
+ private static boolean isSignalReportRequestedWhileIdle(SignalStrengthUpdateRequest request) {
+ return request.isSystemThresholdReportingRequestedWhileIdle()
+ || request.isReportingRequestedWhileIdle();
+ }
+
+ /**
+ * Gets the carrier configuration values for a particular subscription.
+ *
+ * @return A {@link PersistableBundle} containing the config for the given subId,
+ * or default values for an invalid subId.
+ */
+ @NonNull
+ private PersistableBundle getCarrierConfig() {
+ CarrierConfigManager configManager = (CarrierConfigManager) mPhone.getContext()
+ .getSystemService(Context.CARRIER_CONFIG_SERVICE);
+ if (configManager != null) {
+ // If an invalid subId is used, this bundle will contain default values.
+ PersistableBundle config = configManager.getConfigForSubId(mPhone.getSubId());
+ if (config != null) {
+ return config;
+ }
}
+ // Return static default defined in CarrierConfigManager.
+ return CarrierConfigManager.getDefaultConfig();
+ }
+
+ private class SignalRequestRecord implements IBinder.DeathRecipient {
+ final int mSubId; // subId the request originally applied to
+ final int mCallingUid;
+ final SignalStrengthUpdateRequest mRequest;
+
+ SignalRequestRecord(int subId, int uid, @NonNull SignalStrengthUpdateRequest request) {
+ this.mCallingUid = uid;
+ this.mSubId = subId;
+ this.mRequest = request;
+ }
+
+ @Override
+ public void binderDied() {
+ clearSignalStrengthUpdateRequest(mSubId, mCallingUid, mRequest, null /*onCompleted*/);
+ }
+
+ @Override
+ public String toString() {
+ StringBuffer sb = new StringBuffer("SignalRequestRecord {");
+ sb.append("mSubId=").append(mSubId);
+ sb.append(" mCallingUid=").append(mCallingUid);
+ sb.append(" mRequest=").append(mRequest).append("}");
+ return sb.toString();
+ }
+ }
+
+ private void updateAlwaysReportSignalStrength() {
+ final int curSubId = mPhone.getSubId();
+ boolean alwaysReport = mSignalRequestRecords.stream().anyMatch(
+ srr -> srr.mSubId == curSubId && isSignalReportRequestedWhileIdle(srr.mRequest));
+
+ // TODO(b/177924721): TM#setAlwaysReportSignalStrength will be removed and we will not
+ // worry about unset flag which was set by other client.
+ mPhone.setAlwaysReportSignalStrength(alwaysReport);
+ }
+
+ void updateArfcnLists(PersistableBundle config) {
+ synchronized (mRsrpBoostLock) {
+ mLteRsrpBoost = config.getInt(CarrierConfigManager.KEY_LTE_EARFCNS_RSRP_BOOST_INT, 0);
+ String[] earfcnsStringArrayForRsrpBoost = config.getStringArray(
+ CarrierConfigManager.KEY_BOOSTED_LTE_EARFCNS_STRING_ARRAY);
+ mEarfcnPairListForRsrpBoost = convertEarfcnStringArrayToPairList(
+ earfcnsStringArrayForRsrpBoost);
+
+ mNrRsrpBoost = config.getIntArray(
+ CarrierConfigManager.KEY_NRARFCNS_RSRP_BOOST_INT_ARRAY);
+ String[] nrarfcnsStringArrayForRsrpBoost = config.getStringArray(
+ CarrierConfigManager.KEY_BOOSTED_NRARFCNS_STRING_ARRAY);
+ mNrarfcnRangeListForRsrpBoost = convertEarfcnStringArrayToPairList(
+ nrarfcnsStringArrayForRsrpBoost);
+
+ if ((mNrRsrpBoost == null && mNrarfcnRangeListForRsrpBoost != null)
+ || (mNrRsrpBoost != null && mNrarfcnRangeListForRsrpBoost == null)
+ || (mNrRsrpBoost != null && mNrarfcnRangeListForRsrpBoost != null
+ && mNrRsrpBoost.length != mNrarfcnRangeListForRsrpBoost.size())) {
+ loge("Invalid parameters for NR RSRP boost");
+ mNrRsrpBoost = null;
+ mNrarfcnRangeListForRsrpBoost = null;
+ }
+ }
+ }
+
+ void updateServiceStateArfcnRsrpBoost(ServiceState serviceState,
+ CellIdentity cellIdentity) {
+ int rsrpBoost = 0;
+ int arfcn;
+
+ synchronized (mRsrpBoostLock) {
+ switch (cellIdentity.getType()) {
+ case CellInfo.TYPE_LTE:
+ arfcn = ((CellIdentityLte) cellIdentity).getEarfcn();
+ if (arfcn != INVALID_ARFCN
+ && containsEarfcnInEarfcnRange(mEarfcnPairListForRsrpBoost,
+ arfcn) != -1) {
+ rsrpBoost = mLteRsrpBoost;
+ }
+ break;
+ case CellInfo.TYPE_NR:
+ arfcn = ((CellIdentityNr) cellIdentity).getNrarfcn();
+ if (arfcn != INVALID_ARFCN) {
+ int index = containsEarfcnInEarfcnRange(mNrarfcnRangeListForRsrpBoost,
+ arfcn);
+ if (index != -1) {
+ rsrpBoost = mNrRsrpBoost[index];
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ serviceState.setArfcnRsrpBoost(rsrpBoost);
+ }
+
+ /**
+ * Checks if the provided earfcn falls within the range of earfcns.
+ *
+ * return int index in earfcnPairList if earfcn falls within the provided range; -1 otherwise.
+ */
+ private static int containsEarfcnInEarfcnRange(ArrayList<Pair<Integer, Integer>> earfcnPairList,
+ int earfcn) {
+ int index = 0;
+ if (earfcnPairList != null) {
+ for (Pair<Integer, Integer> earfcnPair : earfcnPairList) {
+ if ((earfcn >= earfcnPair.first) && (earfcn <= earfcnPair.second)) {
+ return index;
+ }
+ index++;
+ }
+ }
+
+ return -1;
+ }
+
+ /**
+ * Convert the earfcnStringArray to list of pairs.
+ *
+ * Format of the earfcnsList is expected to be {"erafcn1_start-earfcn1_end",
+ * "earfcn2_start-earfcn2_end" ... }
+ */
+ private static ArrayList<Pair<Integer, Integer>> convertEarfcnStringArrayToPairList(
+ String[] earfcnsList) {
+ ArrayList<Pair<Integer, Integer>> earfcnPairList = new ArrayList<Pair<Integer, Integer>>();
+
+ if (earfcnsList != null) {
+ int earfcnStart;
+ int earfcnEnd;
+ for (int i = 0; i < earfcnsList.length; i++) {
+ try {
+ String[] earfcns = earfcnsList[i].split("-");
+ if (earfcns.length != 2) {
+ if (DBG) {
+ log("Invalid earfcn range format");
+ }
+ return null;
+ }
+
+ earfcnStart = Integer.parseInt(earfcns[0]);
+ earfcnEnd = Integer.parseInt(earfcns[1]);
+
+ if (earfcnStart > earfcnEnd) {
+ if (DBG) {
+ log("Invalid earfcn range format");
+ }
+ return null;
+ }
+
+ earfcnPairList.add(new Pair<Integer, Integer>(earfcnStart, earfcnEnd));
+ } catch (PatternSyntaxException pse) {
+ if (DBG) {
+ log("Invalid earfcn range format");
+ }
+ return null;
+ } catch (NumberFormatException nfe) {
+ if (DBG) {
+ log("Invalid earfcn number format");
+ }
+ return null;
+ }
+ }
+ }
+
+ return earfcnPairList;
}
/**
@@ -486,85 +933,11 @@
};
}
- private static boolean isRanAndSignalMeasurementTypeMatch(
- @AccessNetworkConstants.RadioAccessNetworkType int ran,
- @SignalThresholdInfo.SignalMeasurementType int measurement,
- SignalThresholdInfo info) {
- return ran == info.getRadioAccessNetworkType()
- && measurement == info.getSignalMeasurementType();
- }
-
- private static boolean isSignalReportRequestedWhileIdle(SignalStrengthUpdateRequest request) {
- return request.isSystemThresholdReportingRequestedWhileIdle()
- || request.isReportingRequestedWhileIdle();
- }
-
- /**
- * Gets the carrier configuration values for a particular subscription.
- *
- * @return A {@link PersistableBundle} containing the config for the given subId,
- * or default values for an invalid subId.
- */
- @NonNull
- private PersistableBundle getCarrierConfig() {
- CarrierConfigManager configManager = (CarrierConfigManager) mPhone.getContext()
- .getSystemService(Context.CARRIER_CONFIG_SERVICE);
- if (configManager != null) {
- // If an invalid subId is used, this bundle will contain default values.
- PersistableBundle config = configManager.getConfigForSubId(mPhone.getSubId());
- if (config != null) {
- return config;
- }
- }
- // Return static default defined in CarrierConfigManager.
- return CarrierConfigManager.getDefaultConfig();
- }
-
- private class SignalRequestRecord implements IBinder.DeathRecipient {
- final int mSubId; // subId the request originally applied to
- final int mCallingUid;
- final SignalStrengthUpdateRequest mRequest;
-
- SignalRequestRecord(int subId, int uid, @NonNull SignalStrengthUpdateRequest request) {
- this.mCallingUid = uid;
- this.mSubId = subId;
- this.mRequest = request;
- }
-
- @Override
- public void binderDied() {
- clearSignalStrengthUpdateRequest(mSubId, mCallingUid, mRequest, null /*onCompleted*/);
- }
-
- @Override
- public String toString() {
- StringBuffer sb = new StringBuffer("SignalRequestRecord {");
- sb.append("mSubId=").append(mSubId);
- sb.append(" mCallingUid=").append(mCallingUid);
- sb.append(" mRequest=").append(mRequest).append("}");
- return sb.toString();
- }
- }
-
- private void updateAlwaysReportSignalStrength() {
- final int curSubId = mPhone.getSubId();
- boolean alwaysReport = mSignalRequestRecords.stream().anyMatch(
- srr -> srr.mSubId == curSubId && isSignalReportRequestedWhileIdle(srr.mRequest));
-
- // TODO(b/177924721): TM#setAlwaysReportSignalStrength will be removed and we will not
- // worry about unset flag which was set by other client.
- mPhone.setAlwaysReportSignalStrength(alwaysReport);
- }
-
- /**
- * Called when RIL is connected during boot up or after modem restart. Set the default criteria
- * so that modem can start with default state before updated criteria is ready.
- */
- private void onReset() {
- setDefaultSignalStrengthReportingCriteria();
- }
-
- private void log(String msg) {
+ private static void log(String msg) {
if (DBG) Rlog.d(TAG, msg);
}
+
+ private static void loge(String msg) {
+ Rlog.e(TAG, msg);
+ }
}
diff --git a/src/java/com/android/internal/telephony/SubscriptionInfoUpdater.java b/src/java/com/android/internal/telephony/SubscriptionInfoUpdater.java
index 36751a3..d05ef12 100644
--- a/src/java/com/android/internal/telephony/SubscriptionInfoUpdater.java
+++ b/src/java/com/android/internal/telephony/SubscriptionInfoUpdater.java
@@ -597,6 +597,10 @@
}
private void updateCarrierServices(int phoneId, String simState) {
+ if (!SubscriptionManager.isValidPhoneId(phoneId)) {
+ logd("Ignore updateCarrierServices request with invalid phoneId " + phoneId);
+ return;
+ }
CarrierConfigManager configManager =
(CarrierConfigManager) sContext.getSystemService(Context.CARRIER_CONFIG_SERVICE);
configManager.updateConfigForPhoneId(phoneId, simState);
diff --git a/src/java/com/android/internal/telephony/dataconnection/DataConnection.java b/src/java/com/android/internal/telephony/dataconnection/DataConnection.java
index 631bbdd..85d3974 100644
--- a/src/java/com/android/internal/telephony/dataconnection/DataConnection.java
+++ b/src/java/com/android/internal/telephony/dataconnection/DataConnection.java
@@ -1660,6 +1660,7 @@
if (!uplinkUpdated) {
mUplinkBandwidth = values.second;
}
+ mUplinkBandwidth = Math.min(mUplinkBandwidth, mDownlinkBandwidth);
}
}
diff --git a/src/java/com/android/internal/telephony/dataconnection/LinkBandwidthEstimator.java b/src/java/com/android/internal/telephony/dataconnection/LinkBandwidthEstimator.java
index 833cf86..3ab6ddf 100644
--- a/src/java/com/android/internal/telephony/dataconnection/LinkBandwidthEstimator.java
+++ b/src/java/com/android/internal/telephony/dataconnection/LinkBandwidthEstimator.java
@@ -133,6 +133,7 @@
// Used to derive byte count threshold from avg BW
private static final int LOW_BW_TO_AVG_BW_RATIO_NUM = 3;
private static final int LOW_BW_TO_AVG_BW_RATIO_DEN = 8;
+ private static final int MAX_BW_TO_STATIC_BW_RATIO = 15;
private static final int BYTE_DELTA_THRESHOLD_MIN_KB = 10;
private static final int MAX_ERROR_PERCENT = 100 * 100;
private static final String[] AVG_BW_PER_RAT = {
@@ -606,7 +607,8 @@
return;
}
long linkBandwidthLongKbps = bytesDelta * 8 / timeDeltaMs * 1000 / 1024;
- if (linkBandwidthLongKbps > Integer.MAX_VALUE || linkBandwidthLongKbps < 0) {
+ if (linkBandwidthLongKbps > (long) mStaticBwKbps * MAX_BW_TO_STATIC_BW_RATIO
+ || linkBandwidthLongKbps < 0) {
return;
}
int linkBandwidthKbps = (int) linkBandwidthLongKbps;
@@ -691,6 +693,45 @@
return -1;
}
+ private int getAvgUsedBandwidthAdjacentThreeLevelKbps() {
+ String dataRatName = getDataRatName(mDataRat);
+ NetworkBandwidth network = lookupNetwork(mPlmn, dataRatName);
+
+ int bandwidthAtLow = getAvgUsedBandwidthAtLevel(network, mSignalLevel - 1);
+ int bandwidthAtHigh = getAvgUsedBandwidthAtLevel(network, mSignalLevel + 1);
+ if (bandwidthAtLow > 0 && bandwidthAtHigh > 0) {
+ return (bandwidthAtLow + bandwidthAtHigh) / 2;
+ }
+
+ int count = 0;
+ long value = 0;
+ for (int i = -1; i <= 1; i++) {
+ int currLevel = mSignalLevel + i;
+ if (currLevel < 0 || currLevel >= NUM_SIGNAL_LEVEL) {
+ continue;
+ }
+ count += network.getCount(mLink, currLevel);
+ value += network.getValue(mLink, currLevel);
+ }
+
+ if (count >= BW_STATS_COUNT_THRESHOLD) {
+ return (int) (value / count);
+ }
+ return -1;
+ }
+
+ private int getAvgUsedBandwidthAtLevel(NetworkBandwidth network,
+ int signalLevel) {
+ if (signalLevel < 0 || signalLevel >= NUM_SIGNAL_LEVEL) {
+ return -1;
+ }
+ int count = network.getCount(mLink, signalLevel);
+ if (count >= BW_STATS_COUNT_THRESHOLD) {
+ return (int) (network.getValue(mLink, signalLevel) / count);
+ }
+ return -1;
+ }
+
private int getCurrentCount() {
String dataRatName = getDataRatName(mDataRat);
NetworkBandwidth network = lookupNetwork(mPlmn, dataRatName);
@@ -703,6 +744,10 @@
if (mAvgUsedKbps > 0) {
return mAvgUsedKbps;
}
+ mAvgUsedKbps = getAvgUsedBandwidthAdjacentThreeLevelKbps();
+ if (mAvgUsedKbps > 0) {
+ return mAvgUsedKbps;
+ }
// Fall back to static value
return mStaticBwKbps;
}
diff --git a/src/java/com/android/internal/telephony/imsphone/ImsPhoneConnection.java b/src/java/com/android/internal/telephony/imsphone/ImsPhoneConnection.java
index 3ee7dba..0745d93 100755
--- a/src/java/com/android/internal/telephony/imsphone/ImsPhoneConnection.java
+++ b/src/java/com/android/internal/telephony/imsphone/ImsPhoneConnection.java
@@ -59,6 +59,8 @@
import com.android.internal.telephony.metrics.TelephonyMetrics;
import com.android.telephony.Rlog;
+import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Collections;
import java.util.Objects;
import java.util.Set;
@@ -1318,7 +1320,11 @@
return;
}
if (extras.containsKey(ImsCallProfile.EXTRA_FORWARDED_NUMBER)) {
- mForwardedNumber = extras.getStringArrayList(ImsCallProfile.EXTRA_FORWARDED_NUMBER);
+ String[] forwardedNumberArray =
+ extras.getStringArray(ImsCallProfile.EXTRA_FORWARDED_NUMBER);
+ if (forwardedNumberArray != null) {
+ mForwardedNumber = new ArrayList<String>(Arrays.asList(forwardedNumberArray));
+ }
}
}
diff --git a/src/java/com/android/internal/telephony/metrics/CallQualityMetrics.java b/src/java/com/android/internal/telephony/metrics/CallQualityMetrics.java
index cf98acb..208aff6 100644
--- a/src/java/com/android/internal/telephony/metrics/CallQualityMetrics.java
+++ b/src/java/com/android/internal/telephony/metrics/CallQualityMetrics.java
@@ -25,7 +25,7 @@
import android.util.Pair;
import com.android.internal.telephony.Phone;
-import com.android.internal.telephony.ServiceStateTracker;
+import com.android.internal.telephony.SignalStrengthController;
import com.android.internal.telephony.nano.TelephonyProto.TelephonyCallSession;
import com.android.internal.telephony.util.TelephonyUtils;
import com.android.telephony.Rlog;
@@ -215,13 +215,13 @@
// Returns the LTE signal to noise ratio, or 0 if unavailable
private Integer getLteSnr() {
- ServiceStateTracker sst = mPhone.getDefaultPhone().getServiceStateTracker();
- if (sst == null) {
- Rlog.e(TAG, "getLteSnr: unable to get SST for phone " + mPhone.getPhoneId());
+ SignalStrengthController ssc = mPhone.getDefaultPhone().getSignalStrengthController();
+ if (ssc == null) {
+ Rlog.e(TAG, "getLteSnr: unable to get SSC for phone " + mPhone.getPhoneId());
return CellInfo.UNAVAILABLE;
}
- SignalStrength ss = sst.getSignalStrength();
+ SignalStrength ss = ssc.getSignalStrength();
if (ss == null) {
Rlog.e(TAG, "getLteSnr: unable to get SignalStrength for phone " + mPhone.getPhoneId());
return CellInfo.UNAVAILABLE;
diff --git a/src/java/com/android/internal/telephony/metrics/VoiceCallSessionStats.java b/src/java/com/android/internal/telephony/metrics/VoiceCallSessionStats.java
index d2f740c..be3c492 100644
--- a/src/java/com/android/internal/telephony/metrics/VoiceCallSessionStats.java
+++ b/src/java/com/android/internal/telephony/metrics/VoiceCallSessionStats.java
@@ -415,6 +415,12 @@
// internal fields for tracking
proto.setupBeginMillis = getTimeMillis();
+ // audio codec might have already been set
+ int codec = audioQualityToCodec(bearer, conn.getAudioCodec());
+ if (codec != AudioCodec.AUDIO_CODEC_UNKNOWN) {
+ proto.codecBitmask = (1L << codec);
+ }
+
proto.concurrentCallCountAtStart = mCallProtos.size();
mCallProtos.put(id, proto);
diff --git a/src/java/com/android/internal/telephony/nitz/NitzSignalInputFilterPredicateFactory.java b/src/java/com/android/internal/telephony/nitz/NitzSignalInputFilterPredicateFactory.java
index aa72722..965cd41 100644
--- a/src/java/com/android/internal/telephony/nitz/NitzSignalInputFilterPredicateFactory.java
+++ b/src/java/com/android/internal/telephony/nitz/NitzSignalInputFilterPredicateFactory.java
@@ -21,10 +21,10 @@
import android.content.Context;
import android.os.PowerManager;
import android.os.PowerManager.WakeLock;
-import android.os.TimestampedValue;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.telephony.NitzData;
+import com.android.internal.telephony.NitzSignal;
import com.android.internal.telephony.NitzStateMachine.DeviceState;
import com.android.internal.telephony.nitz.NitzStateMachineImpl.NitzSignalInputFilterPredicate;
import com.android.telephony.Rlog;
@@ -84,8 +84,8 @@
*/
@Nullable
Boolean mustProcessNitzSignal(
- @Nullable TimestampedValue<NitzData> previousSignal,
- @NonNull TimestampedValue<NitzData> newSignal);
+ @Nullable NitzSignal previousSignal,
+ @NonNull NitzSignal newSignal);
}
/**
@@ -132,8 +132,9 @@
// Acquire the wake lock as we are reading the elapsed realtime clock below.
wakeLock.acquire();
- long elapsedRealtime = deviceState.elapsedRealtime();
- long millisSinceNitzReceived = elapsedRealtime - newSignal.getReferenceTimeMillis();
+ long elapsedRealtime = deviceState.elapsedRealtimeMillis();
+ long millisSinceNitzReceived =
+ elapsedRealtime - newSignal.getReceiptElapsedRealtimeMillis();
if (millisSinceNitzReceived < 0 || millisSinceNitzReceived > Integer.MAX_VALUE) {
if (DBG) {
Rlog.d(LOG_TAG, "mustProcessNitzSignal: Not processing NITZ signal"
@@ -178,15 +179,15 @@
@Override
@NonNull
public Boolean mustProcessNitzSignal(
- @NonNull TimestampedValue<NitzData> previousSignal,
- @NonNull TimestampedValue<NitzData> newSignal) {
+ @NonNull NitzSignal previousSignal,
+ @NonNull NitzSignal newSignal) {
Objects.requireNonNull(newSignal);
- Objects.requireNonNull(newSignal.getValue());
+ Objects.requireNonNull(newSignal.getNitzData());
Objects.requireNonNull(previousSignal);
- Objects.requireNonNull(previousSignal.getValue());
+ Objects.requireNonNull(previousSignal.getNitzData());
- NitzData newNitzData = newSignal.getValue();
- NitzData previousNitzData = previousSignal.getValue();
+ NitzData newNitzData = newSignal.getNitzData();
+ NitzData previousNitzData = previousSignal.getNitzData();
// Compare the discrete NitzData fields associated with local time offset. Any
// difference and we should process the signal regardless of how recent the last one
@@ -195,26 +196,36 @@
return true;
}
- // Now check the continuous NitzData field (time) to see if it is sufficiently
- // different.
+ // Check the time-related NitzData fields to see if they are sufficiently different.
+
+ // See if the NITZ signals have been received sufficiently far apart. If yes, we
+ // want to process the new one.
int nitzUpdateSpacing = deviceState.getNitzUpdateSpacingMillis();
+ long elapsedRealtimeSinceLastSaved = newSignal.getReceiptElapsedRealtimeMillis()
+ - previousSignal.getReceiptElapsedRealtimeMillis();
+ if (elapsedRealtimeSinceLastSaved > nitzUpdateSpacing) {
+ return true;
+ }
+
+ // See if the NITZ signals have sufficiently different encoded UTC times. If yes,
+ // then we want to process the new one.
int nitzUpdateDiff = deviceState.getNitzUpdateDiffMillis();
- // Calculate the elapsed time between the new signal and the last signal.
- long elapsedRealtimeSinceLastSaved = newSignal.getReferenceTimeMillis()
- - previousSignal.getReferenceTimeMillis();
-
- // Calculate the UTC difference between the time the two signals hold.
+ // Calculate the UTC difference between the time the two signals hold, accounting
+ // for any difference in receipt time and age.
long utcTimeDifferenceMillis = newNitzData.getCurrentTimeInMillis()
- previousNitzData.getCurrentTimeInMillis();
+ long ageAdjustedElapsedRealtimeDifferenceMillis =
+ newSignal.getAgeAdjustedElapsedRealtimeMillis()
+ - previousSignal.getAgeAdjustedElapsedRealtimeMillis();
- // Ideally the difference between elapsedRealtimeSinceLastSaved and
- // utcTimeDifferenceMillis would be zero.
- long millisGainedOrLost = Math
- .abs(utcTimeDifferenceMillis - elapsedRealtimeSinceLastSaved);
-
- if (elapsedRealtimeSinceLastSaved > nitzUpdateSpacing
- || millisGainedOrLost > nitzUpdateDiff) {
+ // In ideal conditions, the difference between
+ // ageAdjustedElapsedRealtimeSinceLastSaved and utcTimeDifferenceMillis will be zero
+ // if two NITZ signals are consistent and if the elapsed realtime clock is ticking
+ // at the correct rate.
+ long millisGainedOrLost = Math.abs(
+ utcTimeDifferenceMillis - ageAdjustedElapsedRealtimeDifferenceMillis);
+ if (millisGainedOrLost > nitzUpdateDiff) {
return true;
}
@@ -256,8 +267,8 @@
}
@Override
- public boolean mustProcessNitzSignal(@Nullable TimestampedValue<NitzData> oldSignal,
- @NonNull TimestampedValue<NitzData> newSignal) {
+ public boolean mustProcessNitzSignal(@Nullable NitzSignal oldSignal,
+ @NonNull NitzSignal newSignal) {
Objects.requireNonNull(newSignal);
for (TrivalentPredicate component : mComponents) {
diff --git a/src/java/com/android/internal/telephony/nitz/NitzStateMachineImpl.java b/src/java/com/android/internal/telephony/nitz/NitzStateMachineImpl.java
index a36eb4f..7a53491 100644
--- a/src/java/com/android/internal/telephony/nitz/NitzStateMachineImpl.java
+++ b/src/java/com/android/internal/telephony/nitz/NitzStateMachineImpl.java
@@ -25,6 +25,7 @@
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.telephony.NitzData;
+import com.android.internal.telephony.NitzSignal;
import com.android.internal.telephony.NitzStateMachine;
import com.android.internal.telephony.Phone;
import com.android.internal.util.IndentingPrintWriter;
@@ -68,8 +69,8 @@
* See {@link NitzSignalInputFilterPredicate}.
*/
boolean mustProcessNitzSignal(
- @Nullable TimestampedValue<NitzData> oldSignal,
- @NonNull TimestampedValue<NitzData> newSignal);
+ @Nullable NitzSignal oldSignal,
+ @NonNull NitzSignal newSignal);
}
/**
@@ -89,7 +90,7 @@
@NonNull
TelephonyTimeZoneSuggestion getTimeZoneSuggestion(
int slotIndex, @Nullable String countryIsoCode,
- @Nullable TimestampedValue<NitzData> nitzSignal);
+ @Nullable NitzSignal nitzSignal);
}
static final String LOG_TAG = "NewNitzStateMachineImpl";
@@ -114,7 +115,7 @@
* needs to be recalculated when something else has changed.
*/
@Nullable
- private TimestampedValue<NitzData> mLatestNitzSignal;
+ private NitzSignal mLatestNitzSignal;
// Time Zone detection state.
@@ -227,14 +228,14 @@
}
@Override
- public void handleNitzReceived(@NonNull TimestampedValue<NitzData> nitzSignal) {
+ public void handleNitzReceived(@NonNull NitzSignal nitzSignal) {
if (DBG) {
Rlog.d(LOG_TAG, "handleNitzReceived: nitzSignal=" + nitzSignal);
}
Objects.requireNonNull(nitzSignal);
// Perform input filtering to filter bad data and avoid processing signals too often.
- TimestampedValue<NitzData> previousNitzSignal = mLatestNitzSignal;
+ NitzSignal previousNitzSignal = mLatestNitzSignal;
if (!mNitzSignalInputFilter.mustProcessNitzSignal(previousNitzSignal, nitzSignal)) {
return;
}
@@ -278,7 +279,8 @@
* Perform a round of time zone detection and notify the time zone detection service as needed.
*/
private void doTimeZoneDetection(
- @Nullable String countryIsoCode, @Nullable TimestampedValue<NitzData> nitzSignal,
+ @Nullable String countryIsoCode, @Nullable NitzSignal
+ nitzSignal,
@NonNull String reason) {
try {
Objects.requireNonNull(reason);
@@ -306,7 +308,7 @@
/**
* Perform a round of time detection and notify the time detection service as needed.
*/
- private void doTimeDetection(@Nullable TimestampedValue<NitzData> nitzSignal,
+ private void doTimeDetection(@Nullable NitzSignal nitzSignal,
@NonNull String reason) {
try {
Objects.requireNonNull(reason);
@@ -317,9 +319,7 @@
builder.addDebugInfo("Clearing time suggestion"
+ " reason=" + reason);
} else {
- TimestampedValue<Long> newNitzTime = new TimestampedValue<>(
- nitzSignal.getReferenceTimeMillis(),
- nitzSignal.getValue().getCurrentTimeInMillis());
+ TimestampedValue<Long> newNitzTime = nitzSignal.createTimeSignal();
builder.setUtcTime(newNitzTime);
builder.addDebugInfo("Sending new time suggestion"
+ " nitzSignal=" + nitzSignal
@@ -350,6 +350,6 @@
@Nullable
public NitzData getCachedNitzData() {
- return mLatestNitzSignal != null ? mLatestNitzSignal.getValue() : null;
+ return mLatestNitzSignal != null ? mLatestNitzSignal.getNitzData() : null;
}
}
diff --git a/src/java/com/android/internal/telephony/nitz/TimeZoneSuggesterImpl.java b/src/java/com/android/internal/telephony/nitz/TimeZoneSuggesterImpl.java
index 48491df..342705b 100644
--- a/src/java/com/android/internal/telephony/nitz/TimeZoneSuggesterImpl.java
+++ b/src/java/com/android/internal/telephony/nitz/TimeZoneSuggesterImpl.java
@@ -21,12 +21,12 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.timezonedetector.TelephonyTimeZoneSuggestion;
-import android.os.TimestampedValue;
import android.text.TextUtils;
import android.timezone.CountryTimeZones.OffsetResult;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.telephony.NitzData;
+import com.android.internal.telephony.NitzSignal;
import com.android.internal.telephony.NitzStateMachine.DeviceState;
import com.android.internal.telephony.nitz.NitzStateMachineImpl.TimeZoneSuggester;
import com.android.internal.telephony.nitz.TimeZoneLookupHelper.CountryResult;
@@ -55,12 +55,12 @@
@Override
@NonNull
public TelephonyTimeZoneSuggestion getTimeZoneSuggestion(int slotIndex,
- @Nullable String countryIsoCode, @Nullable TimestampedValue<NitzData> nitzSignal) {
+ @Nullable String countryIsoCode, @Nullable NitzSignal nitzSignal) {
try {
// Check for overriding NITZ-based signals from Android running in an emulator.
TelephonyTimeZoneSuggestion overridingSuggestion = null;
if (nitzSignal != null) {
- NitzData nitzData = nitzSignal.getValue();
+ NitzData nitzData = nitzSignal.getNitzData();
if (nitzData.getEmulatorHostTimeZone() != null) {
TelephonyTimeZoneSuggestion.Builder builder =
new TelephonyTimeZoneSuggestion.Builder(slotIndex)
@@ -135,9 +135,9 @@
*/
@NonNull
private TelephonyTimeZoneSuggestion findTimeZoneForTestNetwork(
- int slotIndex, @NonNull TimestampedValue<NitzData> nitzSignal) {
+ int slotIndex, @NonNull NitzSignal nitzSignal) {
Objects.requireNonNull(nitzSignal);
- NitzData nitzData = Objects.requireNonNull(nitzSignal.getValue());
+ NitzData nitzData = Objects.requireNonNull(nitzSignal.getNitzData());
TelephonyTimeZoneSuggestion.Builder suggestionBuilder =
new TelephonyTimeZoneSuggestion.Builder(slotIndex);
@@ -166,7 +166,7 @@
@NonNull
private TelephonyTimeZoneSuggestion findTimeZoneFromCountryAndNitz(
int slotIndex, @NonNull String countryIsoCode,
- @NonNull TimestampedValue<NitzData> nitzSignal) {
+ @NonNull NitzSignal nitzSignal) {
Objects.requireNonNull(countryIsoCode);
Objects.requireNonNull(nitzSignal);
@@ -175,7 +175,7 @@
suggestionBuilder.addDebugInfo("findTimeZoneFromCountryAndNitz:"
+ " countryIsoCode=" + countryIsoCode
+ ", nitzSignal=" + nitzSignal);
- NitzData nitzData = Objects.requireNonNull(nitzSignal.getValue());
+ NitzData nitzData = Objects.requireNonNull(nitzSignal.getNitzData());
if (isNitzSignalOffsetInfoBogus(countryIsoCode, nitzData)) {
suggestionBuilder.addDebugInfo(
"findTimeZoneFromCountryAndNitz: NITZ signal looks bogus");
diff --git a/tests/telephonytests/src/com/android/internal/telephony/NetworkTypeControllerTest.java b/tests/telephonytests/src/com/android/internal/telephony/NetworkTypeControllerTest.java
index be23df8..ac5facd 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/NetworkTypeControllerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/NetworkTypeControllerTest.java
@@ -114,6 +114,7 @@
mPhone).getCachedAllowedNetworkTypesBitmask();
doReturn(false).when(mTelephonyManager).isRadioInterfaceCapabilitySupported(
TelephonyManager.CAPABILITY_PHYSICAL_CHANNEL_CONFIG_1_6_SUPPORTED);
+ doReturn(new int[] {0}).when(mServiceState).getCellBandwidths();
mNetworkTypeController = new NetworkTypeController(mPhone, mDisplayInfoController);
processAllMessages();
}
@@ -1186,4 +1187,49 @@
}
doReturn(lastPhysicalChannelConfigList).when(mSST).getPhysicalChannelConfigList();
}
+
+ @Test
+ public void testTransitionToCurrentStateNrConnectedWithLowBandwidth() throws Exception {
+ assertEquals("DefaultState", getCurrentState().getName());
+ doReturn(TelephonyManager.NETWORK_TYPE_LTE).when(mServiceState).getDataNetworkType();
+ doReturn(NetworkRegistrationInfo.NR_STATE_CONNECTED).when(mServiceState).getNrState();
+ doReturn(ServiceState.FREQUENCY_RANGE_MMWAVE).when(mServiceState).getNrFrequencyRange();
+ doReturn(new int[] {19999}).when(mServiceState).getCellBandwidths();
+ mBundle.putInt(CarrierConfigManager.KEY_NR_ADVANCED_THRESHOLD_BANDWIDTH_KHZ_INT, 20000);
+ broadcastCarrierConfigs();
+
+ mNetworkTypeController.sendMessage(NetworkTypeController.EVENT_UPDATE);
+ processAllMessages();
+ assertEquals("connected", getCurrentState().getName());
+ }
+
+ @Test
+ public void testTransitionToCurrentStateNrConnectedWithHighBandwidth() throws Exception {
+ assertEquals("DefaultState", getCurrentState().getName());
+ doReturn(TelephonyManager.NETWORK_TYPE_LTE).when(mServiceState).getDataNetworkType();
+ doReturn(NetworkRegistrationInfo.NR_STATE_CONNECTED).when(mServiceState).getNrState();
+ doReturn(ServiceState.FREQUENCY_RANGE_MMWAVE).when(mServiceState).getNrFrequencyRange();
+ doReturn(new int[] {20001}).when(mServiceState).getCellBandwidths();
+ mBundle.putInt(CarrierConfigManager.KEY_NR_ADVANCED_THRESHOLD_BANDWIDTH_KHZ_INT, 20000);
+ broadcastCarrierConfigs();
+
+ mNetworkTypeController.sendMessage(NetworkTypeController.EVENT_UPDATE);
+ processAllMessages();
+ assertEquals("connected_mmwave", getCurrentState().getName());
+ }
+
+ @Test
+ public void testNrAdvancedDisabledWhileRoaming() throws Exception {
+ assertEquals("DefaultState", getCurrentState().getName());
+ doReturn(TelephonyManager.NETWORK_TYPE_LTE).when(mServiceState).getDataNetworkType();
+ doReturn(true).when(mServiceState).getDataRoaming();
+ doReturn(NetworkRegistrationInfo.NR_STATE_CONNECTED).when(mServiceState).getNrState();
+ doReturn(ServiceState.FREQUENCY_RANGE_MMWAVE).when(mServiceState).getNrFrequencyRange();
+ mBundle.putBoolean(CarrierConfigManager.KEY_ENABLE_NR_ADVANCED_WHILE_ROAMING_BOOL, false);
+ broadcastCarrierConfigs();
+
+ mNetworkTypeController.sendMessage(NetworkTypeController.EVENT_UPDATE);
+ processAllMessages();
+ assertEquals("connected", getCurrentState().getName());
+ }
}
diff --git a/tests/telephonytests/src/com/android/internal/telephony/NitzSignalTest.java b/tests/telephonytests/src/com/android/internal/telephony/NitzSignalTest.java
new file mode 100644
index 0000000..352a9aa
--- /dev/null
+++ b/tests/telephonytests/src/com/android/internal/telephony/NitzSignalTest.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright 2021 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 com.android.internal.telephony;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
+
+import org.junit.Test;
+
+public class NitzSignalTest {
+
+ /** Sample cases for equals() and hashCode(). Not exhaustive. */
+ @Test
+ public void testEqualsAndHashCode() {
+ long receiptElapsedMillis1 = 1111;
+ NitzData nitzData1 = NitzData.createForTests(0, 0, 1234, null);
+ long ageMillis1 = 11;
+ NitzSignal nitzSignal1 = new NitzSignal(receiptElapsedMillis1, nitzData1, ageMillis1);
+ assertEquals(nitzSignal1, nitzSignal1);
+ assertEquals(nitzSignal1.hashCode(), nitzSignal1.hashCode());
+
+ NitzSignal nitzSignal1v2 = new NitzSignal(receiptElapsedMillis1, nitzData1, ageMillis1);
+ assertEquals(nitzSignal1, nitzSignal1v2);
+ assertEquals(nitzSignal1v2, nitzSignal1);
+ assertEquals(nitzSignal1.hashCode(), nitzSignal1v2.hashCode());
+
+ long receiptElapsedMillis2 = 2222;
+ NitzData nitzData2 = NitzData.createForTests(0, 0, 2345, null);
+ long ageMillis2 = 11;
+ NitzSignal nitzSignal2 = new NitzSignal(receiptElapsedMillis2, nitzData2, ageMillis2);
+ assertNotEquals(nitzSignal1, nitzSignal2);
+ assertNotEquals(nitzSignal2, nitzSignal1);
+ }
+
+ @Test
+ public void testGetAgeAdjustedRealtimeMillis_zeroAge() {
+ NitzData nitzData = NitzData.createForTests(0, 0, 1234, null);
+ long receiptElapsedRealtimeMillis = 1111;
+ long ageMillis = 0;
+ NitzSignal nitzSignal =
+ new NitzSignal(receiptElapsedRealtimeMillis, nitzData, ageMillis);
+ assertEquals(receiptElapsedRealtimeMillis,
+ nitzSignal.getReceiptElapsedRealtimeMillis());
+ assertEquals(ageMillis, nitzSignal.getAgeMillis());
+ assertEquals(receiptElapsedRealtimeMillis - ageMillis,
+ nitzSignal.getAgeAdjustedElapsedRealtimeMillis());
+ }
+
+ @Test
+ public void testGetAgeAdjustedRealtimeMillis_withAge() {
+ NitzData nitzData = NitzData.createForTests(0, 0, 1234, null);
+ long receiptElapsedRealtimeMillis = 1111;
+ long ageMillis = 5000;
+ NitzSignal nitzSignal =
+ new NitzSignal(receiptElapsedRealtimeMillis, nitzData, ageMillis);
+ assertEquals(receiptElapsedRealtimeMillis,
+ nitzSignal.getReceiptElapsedRealtimeMillis());
+ assertEquals(ageMillis, nitzSignal.getAgeMillis());
+ assertEquals(receiptElapsedRealtimeMillis - ageMillis,
+ nitzSignal.getAgeAdjustedElapsedRealtimeMillis());
+ }
+}
diff --git a/tests/telephonytests/src/com/android/internal/telephony/ServiceStateTrackerTest.java b/tests/telephonytests/src/com/android/internal/telephony/ServiceStateTrackerTest.java
index a425b25..5cfff52 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/ServiceStateTrackerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/ServiceStateTrackerTest.java
@@ -56,7 +56,6 @@
import android.os.PersistableBundle;
import android.os.Process;
import android.os.SystemClock;
-import android.os.TimestampedValue;
import android.os.UserHandle;
import android.os.WorkSource;
import android.telephony.AccessNetworkConstants;
@@ -70,13 +69,7 @@
import android.telephony.CellIdentityWcdma;
import android.telephony.CellInfo;
import android.telephony.CellInfoGsm;
-import android.telephony.CellSignalStrength;
-import android.telephony.CellSignalStrengthCdma;
import android.telephony.CellSignalStrengthGsm;
-import android.telephony.CellSignalStrengthLte;
-import android.telephony.CellSignalStrengthNr;
-import android.telephony.CellSignalStrengthTdscdma;
-import android.telephony.CellSignalStrengthWcdma;
import android.telephony.INetworkService;
import android.telephony.LteVopsSupportInfo;
import android.telephony.NetworkRegistrationInfo;
@@ -84,7 +77,6 @@
import android.telephony.NrVopsSupportInfo;
import android.telephony.PhysicalChannelConfig;
import android.telephony.ServiceState;
-import android.telephony.SignalStrength;
import android.telephony.SubscriptionInfo;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
@@ -142,8 +134,7 @@
// SST now delegates all signal strength operations to SSC
// Add Mock SSC as the dependency to avoid NPE
- @Mock
- private SignalStrengthController mSignalStrengthController;
+ private SignalStrengthController mSsc;
private ServiceStateTracker sst;
private ServiceStateTrackerTestHandler mSSTTestHandler;
@@ -194,8 +185,8 @@
@Override
public void onLooperPrepared() {
- mSignalStrengthController = new SignalStrengthController(mPhone);
- doReturn(mSignalStrengthController).when(mPhone).getSignalStrengthController();
+ mSsc = new SignalStrengthController(mPhone);
+ doReturn(mSsc).when(mPhone).getSignalStrengthController();
sst = new ServiceStateTracker(mPhone, mSimulatedCommands);
sst.setServiceStateStats(mServiceStateStats);
@@ -705,58 +696,6 @@
verify(mPhone, times(1)).notifyServiceStateChanged(any(ServiceState.class));
}
- private void sendSignalStrength(SignalStrength ss) {
- mSimulatedCommands.setSignalStrength(ss);
- mSimulatedCommands.notifySignalStrength();
- waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
- }
-
- @Test
- @MediumTest
- public void testSignalStrength() {
- // Send in GSM Signal Strength Info and expect isGsm == true
- SignalStrength ss = new SignalStrength(
- new CellSignalStrengthCdma(),
- new CellSignalStrengthGsm(-53, 0, SignalStrength.INVALID),
- new CellSignalStrengthWcdma(),
- new CellSignalStrengthTdscdma(),
- new CellSignalStrengthLte(),
- new CellSignalStrengthNr());
-
- sendSignalStrength(ss);
- assertEquals(sst.getSignalStrength(), ss);
- assertEquals(sst.getSignalStrength().isGsm(), true);
-
- // Send in CDMA+LTE Signal Strength Info and expect isGsm == true
- ss = new SignalStrength(
- new CellSignalStrengthCdma(-90, -12,
- SignalStrength.INVALID, SignalStrength.INVALID, SignalStrength.INVALID),
- new CellSignalStrengthGsm(),
- new CellSignalStrengthWcdma(),
- new CellSignalStrengthTdscdma(),
- new CellSignalStrengthLte(
- -110, -114, -5, 0, SignalStrength.INVALID, SignalStrength.INVALID),
- new CellSignalStrengthNr());
-
- sendSignalStrength(ss);
- assertEquals(sst.getSignalStrength(), ss);
- assertEquals(sst.getSignalStrength().isGsm(), true);
-
- // Send in CDMA-only Signal Strength Info and expect isGsm == false
- ss = new SignalStrength(
- new CellSignalStrengthCdma(-90, -12,
- SignalStrength.INVALID, SignalStrength.INVALID, SignalStrength.INVALID),
- new CellSignalStrengthGsm(),
- new CellSignalStrengthWcdma(),
- new CellSignalStrengthTdscdma(),
- new CellSignalStrengthLte(),
- new CellSignalStrengthNr());
-
- sendSignalStrength(ss);
- assertEquals(sst.getSignalStrength(), ss);
- assertEquals(sst.getSignalStrength().isGsm(), false);
- }
-
private void sendCarrierConfigUpdate() {
CarrierConfigManager mockConfigManager = Mockito.mock(CarrierConfigManager.class);
when(mContext.getSystemService(Context.CARRIER_CONFIG_SERVICE))
@@ -770,182 +709,6 @@
}
@Test
- public void testLteSignalStrengthReportingCriteria() {
- SignalStrength ss = new SignalStrength(
- new CellSignalStrengthCdma(),
- new CellSignalStrengthGsm(),
- new CellSignalStrengthWcdma(),
- new CellSignalStrengthTdscdma(),
- new CellSignalStrengthLte(
- -110, /* rssi */
- -114, /* rsrp */
- -5, /* rsrq */
- 0, /* rssnr */
- SignalStrength.INVALID, /* cqi */
- SignalStrength.INVALID /* ta */),
- new CellSignalStrengthNr());
-
- mBundle.putBoolean(CarrierConfigManager.KEY_USE_ONLY_RSRP_FOR_LTE_SIGNAL_BAR_BOOL,
- true);
-
- sendCarrierConfigUpdate();
-
- mSimulatedCommands.setSignalStrength(ss);
- mSimulatedCommands.notifySignalStrength();
- waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
- // Default thresholds are POOR=-115 MODERATE=-105 GOOD=-95 GREAT=-85
- assertEquals(CellSignalStrength.SIGNAL_STRENGTH_POOR, sst.getSignalStrength().getLevel());
-
- int[] lteThresholds = {
- -130, // SIGNAL_STRENGTH_POOR
- -120, // SIGNAL_STRENGTH_MODERATE
- -110, // SIGNAL_STRENGTH_GOOD
- -100, // SIGNAL_STRENGTH_GREAT
- };
- mBundle.putIntArray(CarrierConfigManager.KEY_LTE_RSRP_THRESHOLDS_INT_ARRAY,
- lteThresholds);
- sendCarrierConfigUpdate();
-
- mSimulatedCommands.setSignalStrength(ss);
- mSimulatedCommands.notifySignalStrength();
- waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
- assertEquals(sst.getSignalStrength().getLevel(),
- CellSignalStrength.SIGNAL_STRENGTH_MODERATE);
- }
-
- @Test
- public void test5gNrSignalStrengthReportingCriteria_UseSsRsrp() {
- SignalStrength ss = new SignalStrength(
- new CellSignalStrengthCdma(),
- new CellSignalStrengthGsm(),
- new CellSignalStrengthWcdma(),
- new CellSignalStrengthTdscdma(),
- new CellSignalStrengthLte(),
- new CellSignalStrengthNr(
- -139, /** csiRsrp NONE */
- -20, /** csiRsrq NONE */
- -23, /** CsiSinr NONE */
- -44, /** SsRsrp SIGNAL_STRENGTH_GREAT */
- -20, /** SsRsrq NONE */
- -23) /** SsSinr NONE */
- );
-
- // SSRSRP = 1 << 0
- mBundle.putInt(CarrierConfigManager.KEY_PARAMETERS_USE_FOR_5G_NR_SIGNAL_BAR_INT,
- CellSignalStrengthNr.USE_SSRSRP);
- sendCarrierConfigUpdate();
- mSimulatedCommands.setSignalStrength(ss);
- mSimulatedCommands.notifySignalStrength();
- waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
- assertEquals(CellSignalStrength.SIGNAL_STRENGTH_GREAT, sst.getSignalStrength().getLevel());
- }
-
- @Test
- public void test5gNrSignalStrengthReportingCriteria_UseSsRsrpAndSsRsrq() {
- SignalStrength ss = new SignalStrength(
- new CellSignalStrengthCdma(),
- new CellSignalStrengthGsm(),
- new CellSignalStrengthWcdma(),
- new CellSignalStrengthTdscdma(),
- new CellSignalStrengthLte(),
- new CellSignalStrengthNr(
- -139, /** csiRsrp NONE */
- -20, /** csiRsrq NONE */
- -23, /** CsiSinr NONE */
- -44, /** SsRsrp SIGNAL_STRENGTH_GREAT */
- -32, /** SsRsrq NONE */
- -23) /** SsSinr NONE */
- );
-
- // SSRSRP = 1 << 0 | SSSINR = 1 << 2
- mBundle.putInt(CarrierConfigManager.KEY_PARAMETERS_USE_FOR_5G_NR_SIGNAL_BAR_INT,
- CellSignalStrengthNr.USE_SSRSRP | CellSignalStrengthNr.USE_SSRSRQ);
- sendCarrierConfigUpdate();
- mSimulatedCommands.setSignalStrength(ss);
- mSimulatedCommands.notifySignalStrength();
- waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
- assertEquals(CellSignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN,
- sst.getSignalStrength().getLevel());
- }
-
- @Test
- public void test5gNrSignalStrengthReportingCriteria_ConfiguredThresholds() {
- SignalStrength ss = new SignalStrength(
- new CellSignalStrengthCdma(),
- new CellSignalStrengthGsm(),
- new CellSignalStrengthWcdma(),
- new CellSignalStrengthTdscdma(),
- new CellSignalStrengthLte(),
- new CellSignalStrengthNr(
- -139, /** csiRsrp NONE */
- -20, /** csiRsrq NONE */
- -23, /** CsiSinr NONE */
- -44, /** SsRsrp SIGNAL_STRENGTH_GREAT */
- -20, /** SsRsrq NONE */
- -23) /** SsSinr NONE */
- );
-
- // SSRSRP = 1 << 0
- mBundle.putInt(CarrierConfigManager.KEY_PARAMETERS_USE_FOR_5G_NR_SIGNAL_BAR_INT,
- CellSignalStrengthNr.USE_SSRSRP);
- sendCarrierConfigUpdate();
- mSimulatedCommands.setSignalStrength(ss);
- mSimulatedCommands.notifySignalStrength();
- waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
- assertEquals(CellSignalStrength.SIGNAL_STRENGTH_GREAT, sst.getSignalStrength().getLevel());
-
- int[] nrSsRsrpThresholds = {
- -45, // SIGNAL_STRENGTH_POOR
- -40, // SIGNAL_STRENGTH_MODERATE
- -37, // SIGNAL_STRENGTH_GOOD
- -34, // SIGNAL_STRENGTH_GREAT
- };
- mBundle.putIntArray(CarrierConfigManager.KEY_5G_NR_SSRSRP_THRESHOLDS_INT_ARRAY,
- nrSsRsrpThresholds);
- mBundle.putInt(CarrierConfigManager.KEY_PARAMETERS_USE_FOR_5G_NR_SIGNAL_BAR_INT,
- CellSignalStrengthNr.USE_SSRSRP);
- sendCarrierConfigUpdate();
- mSimulatedCommands.setSignalStrength(ss);
- mSimulatedCommands.notifySignalStrength();
- waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
- assertEquals(CellSignalStrength.SIGNAL_STRENGTH_POOR,
- sst.getSignalStrength().getLevel());
- }
-
- @Test
- public void testWcdmaSignalStrengthReportingCriteria() {
- SignalStrength ss = new SignalStrength(
- new CellSignalStrengthCdma(),
- new CellSignalStrengthGsm(),
- new CellSignalStrengthWcdma(-79, 0, -85, -5),
- new CellSignalStrengthTdscdma(),
- new CellSignalStrengthLte(),
- new CellSignalStrengthNr());
-
- mSimulatedCommands.setSignalStrength(ss);
- mSimulatedCommands.notifySignalStrength();
- waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
- assertEquals(sst.getSignalStrength().getLevel(), CellSignalStrength.SIGNAL_STRENGTH_GOOD);
-
- int[] wcdmaThresholds = {
- -110, // SIGNAL_STRENGTH_POOR
- -100, // SIGNAL_STRENGTH_MODERATE
- -90, // SIGNAL_STRENGTH_GOOD
- -80 // SIGNAL_STRENGTH_GREAT
- };
- mBundle.putIntArray(CarrierConfigManager.KEY_WCDMA_RSCP_THRESHOLDS_INT_ARRAY,
- wcdmaThresholds);
- mBundle.putString(
- CarrierConfigManager.KEY_WCDMA_DEFAULT_SIGNAL_STRENGTH_MEASUREMENT_STRING,
- "rscp");
- sendCarrierConfigUpdate();
- mSimulatedCommands.setSignalStrength(ss);
- mSimulatedCommands.notifySignalStrength();
- waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
- assertEquals(sst.getSignalStrength().getLevel(), CellSignalStrength.SIGNAL_STRENGTH_GOOD);
- }
-
- @Test
@MediumTest
// TODO(nharold): we probably should remove support for this procedure (GET_LOC)
public void testGsmCellLocation() {
@@ -2047,7 +1810,7 @@
@Test
@SmallTest
- public void testSetTimeFromNITZStr() throws Exception {
+ public void testSetTimeFromNITZStr_withoutAge() throws Exception {
{
// Mock sending incorrect nitz str from RIL
mSimulatedCommands.triggerNITZupdate("38/06/20,00:00:00+0");
@@ -2055,21 +1818,55 @@
verify(mNitzStateMachine, times(0)).handleNitzReceived(any());
}
{
- // Mock sending correct nitz str from RIL
+ // Mock sending correct nitz str from RIL with a zero ageMs
String nitzStr = "15/06/20,00:00:00+0";
NitzData expectedNitzData = NitzData.parse(nitzStr);
mSimulatedCommands.triggerNITZupdate(nitzStr);
waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
- ArgumentCaptor<TimestampedValue<NitzData>> argumentsCaptor =
- ArgumentCaptor.forClass(TimestampedValue.class);
+ ArgumentCaptor<NitzSignal> argumentsCaptor =
+ ArgumentCaptor.forClass(NitzSignal.class);
verify(mNitzStateMachine, times(1))
.handleNitzReceived(argumentsCaptor.capture());
// Confirm the argument was what we expected.
- TimestampedValue<NitzData> actualNitzSignal = argumentsCaptor.getValue();
- assertEquals(expectedNitzData, actualNitzSignal.getValue());
- assertTrue(actualNitzSignal.getReferenceTimeMillis() <= SystemClock.elapsedRealtime());
+ NitzSignal actualNitzSignal = argumentsCaptor.getValue();
+ assertEquals(expectedNitzData, actualNitzSignal.getNitzData());
+ assertTrue(actualNitzSignal.getReceiptElapsedRealtimeMillis()
+ <= SystemClock.elapsedRealtime());
+ assertEquals(actualNitzSignal.getAgeMillis(), 0);
+ }
+ }
+
+ @Test
+ @SmallTest
+ public void testSetTimeFromNITZStr_withAge() throws Exception {
+ {
+ // Mock sending incorrect nitz str from RIL with a non-zero ageMs
+ long ageMs = 60 * 1000;
+ mSimulatedCommands.triggerNITZupdate("38/06/20,00:00:00+0", ageMs);
+ waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
+ verify(mNitzStateMachine, times(0)).handleNitzReceived(any());
+ }
+ {
+ // Mock sending correct nitz str from RIL with a non-zero ageMs
+ String nitzStr = "21/08/15,00:00:00+0";
+ long ageMs = 60 * 1000;
+ NitzData expectedNitzData = NitzData.parse(nitzStr);
+ mSimulatedCommands.triggerNITZupdate(nitzStr, ageMs);
+ waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
+
+ ArgumentCaptor<NitzSignal> argumentsCaptor =
+ ArgumentCaptor.forClass(NitzSignal.class);
+ verify(mNitzStateMachine, times(1))
+ .handleNitzReceived(argumentsCaptor.capture());
+
+ // Confirm the argument was what we expected.
+ NitzSignal actualNitzSignal = argumentsCaptor.getValue();
+ assertEquals(expectedNitzData, actualNitzSignal.getNitzData());
+ assertTrue(actualNitzSignal.getReceiptElapsedRealtimeMillis()
+ <= SystemClock.elapsedRealtime());
+ assertEquals(actualNitzSignal.getAgeMillis(), ageMs);
}
}
@@ -2526,6 +2323,7 @@
doReturn(true).when(mPhone).isPhoneTypeCdmaLte();
doReturn(CdmaSubscriptionSourceManager.SUBSCRIPTION_FROM_RUIM).when(mCdmaSSM)
.getCdmaSubscriptionSource();
+ doReturn(PHONE_ID).when(mPhone).getPhoneId();
logd("Calling updatePhoneType");
// switch to CDMA
diff --git a/tests/telephonytests/src/com/android/internal/telephony/SignalStrengthControllerTest.java b/tests/telephonytests/src/com/android/internal/telephony/SignalStrengthControllerTest.java
index 0f2fc95..1f22352 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/SignalStrengthControllerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/SignalStrengthControllerTest.java
@@ -21,22 +21,39 @@
import static com.google.common.truth.Truth.assertThat;
+import static org.junit.Assert.assertEquals;
+import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
+import android.content.Context;
+import android.content.Intent;
import android.os.Handler;
-import android.os.HandlerThread;
import android.os.Message;
+import android.os.PersistableBundle;
import android.telephony.AccessNetworkConstants;
+import android.telephony.CarrierConfigManager;
+import android.telephony.CellSignalStrength;
+import android.telephony.CellSignalStrengthCdma;
+import android.telephony.CellSignalStrengthGsm;
+import android.telephony.CellSignalStrengthLte;
+import android.telephony.CellSignalStrengthNr;
+import android.telephony.CellSignalStrengthTdscdma;
+import android.telephony.CellSignalStrengthWcdma;
+import android.telephony.SignalStrength;
import android.telephony.SignalStrengthUpdateRequest;
import android.telephony.SignalThresholdInfo;
+import android.test.suitebuilder.annotation.MediumTest;
import android.testing.AndroidTestingRunner;
+import android.testing.TestableLooper;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.Mockito;
import java.util.ArrayList;
import java.util.List;
@@ -46,6 +63,7 @@
* Unit test for {@link SignalStrengthUpdateRequest}.
*/
@RunWith(AndroidTestingRunner.class)
+@TestableLooper.RunWithLooper
public class SignalStrengthControllerTest extends TelephonyTest {
private static final String TAG = "SignalStrengthControllerTest";
@@ -53,47 +71,60 @@
private static final int ACTIVE_SUB_ID = 0;
private static final int INVALID_SUB_ID = 1000;
private static final int CALLING_UID = 12345;
+ private static final int PHONE_ID = 0;
+ private static final String HOME_PLMN = "310260";
+ private static final String PLMN1 = "480123";
+ private static final String PLMN2 = "586111";
+ private static final String HOME_PNN = "home pnn";
+ private static final String[] CARRIER_CONFIG_SPDI = new String[] {HOME_PLMN, PLMN2};
+ private static final String[] CARRIER_CONFIG_EHPLMN = new String[] {HOME_PLMN, PLMN1};
+ private static final String[] CARRIER_CONFIG_PNN = new String[] {
+ String.format("%s,%s", HOME_PNN, "short"), "f2,s2"
+ };
- private SignalStrengthController mSignalStrengthController;
- private TestHandlerThread mTestHandlerThread;
+ @Mock
private Handler mHandler;
- private class TestHandlerThread extends HandlerThread {
- private TestHandlerThread(String name) {
- super(name);
- }
-
- @Override
- protected void onLooperPrepared() {
- mSignalStrengthController = new SignalStrengthController(mPhone);
- when(mPhone.getSignalStrengthController()).thenReturn(mSignalStrengthController);
- setReady(true);
- }
- }
+ private SignalStrengthController mSsc;
+ private PersistableBundle mBundle;
@Before
public void setUp() throws Exception {
- logd("SignalStrengthControllerTest setUp.");
super.setUp(TAG);
when(mPhone.getSubId()).thenReturn(ACTIVE_SUB_ID);
+ mSsc = new SignalStrengthController(mPhone);
+ replaceInstance(Handler.class, "mLooper", mHandler, mSsc.getLooper());
+ replaceInstance(Phone.class, "mLooper", mPhone, mSsc.getLooper());
- mTestHandlerThread = new TestHandlerThread(TAG);
- mTestHandlerThread.start();
- mHandler = mTestHandlerThread.getThreadHandler();
- waitUntilReady();
- waitForLastHandlerAction(mHandler);
+ mBundle = mContextFixture.getCarrierConfigBundle();
+ mBundle.putIntArray(CarrierConfigManager.KEY_5G_NR_SSRSRP_THRESHOLDS_INT_ARRAY,
+ new int[] {
+ -110, /* SIGNAL_STRENGTH_POOR */
+ -90, /* SIGNAL_STRENGTH_MODERATE */
+ -80, /* SIGNAL_STRENGTH_GOOD */
+ -65, /* SIGNAL_STRENGTH_GREAT */
+ });
+ mBundle.putIntArray(CarrierConfigManager.KEY_5G_NR_SSRSRQ_THRESHOLDS_INT_ARRAY,
+ new int[] {
+ -31, /* SIGNAL_STRENGTH_POOR */
+ -19, /* SIGNAL_STRENGTH_MODERATE */
+ -7, /* SIGNAL_STRENGTH_GOOD */
+ 6 /* SIGNAL_STRENGTH_GREAT */
+ });
+ mBundle.putIntArray(CarrierConfigManager.KEY_5G_NR_SSSINR_THRESHOLDS_INT_ARRAY,
+ new int[] {
+ -5, /* SIGNAL_STRENGTH_POOR */
+ 5, /* SIGNAL_STRENGTH_MODERATE */
+ 15, /* SIGNAL_STRENGTH_GOOD */
+ 30 /* SIGNAL_STRENGTH_GREAT */
+ });
+ processAllMessages();
}
-
@After
public void tearDown() throws Exception {
- mSignalStrengthController = null;
- if (mTestHandlerThread != null) {
- mTestHandlerThread.quit();
- mTestHandlerThread.join();
- }
-
+ mSsc = null;
super.tearDown();
}
@@ -109,9 +140,9 @@
true /* shouldReportSystemWhileIdle */
);
- mSignalStrengthController.setSignalStrengthUpdateRequest(INVALID_SUB_ID, CALLING_UID,
+ mSsc.setSignalStrengthUpdateRequest(INVALID_SUB_ID, CALLING_UID,
request, Message.obtain(mHandler));
- waitForLastHandlerAction(mHandler);
+ processAllMessages();
verify(mPhone).setAlwaysReportSignalStrength(eq(false));
}
@@ -128,9 +159,9 @@
false /* shouldReportSystemWhileIdle */
);
- mSignalStrengthController.setSignalStrengthUpdateRequest(ACTIVE_SUB_ID, CALLING_UID,
+ mSsc.setSignalStrengthUpdateRequest(ACTIVE_SUB_ID, CALLING_UID,
request, Message.obtain(mHandler));
- waitForLastHandlerAction(mHandler);
+ processAllMessages();
verify(mPhone).setAlwaysReportSignalStrength(eq(true));
}
@@ -147,9 +178,9 @@
true /* shouldReportSystemWhileIdle */
);
- mSignalStrengthController.setSignalStrengthUpdateRequest(ACTIVE_SUB_ID, CALLING_UID,
+ mSsc.setSignalStrengthUpdateRequest(ACTIVE_SUB_ID, CALLING_UID,
request, Message.obtain(mHandler));
- waitForLastHandlerAction(mHandler);
+ processAllMessages();
verify(mPhone).setAlwaysReportSignalStrength(eq(true));
}
@@ -161,7 +192,7 @@
public void shouldHonorSystemThresholds_deviceIsHighPowered_returnTrue() {
when(mPhone.isDeviceIdle()).thenReturn(false);
- assertThat(mSignalStrengthController.shouldHonorSystemThresholds()).isTrue();
+ assertThat(mSsc.shouldHonorSystemThresholds()).isTrue();
}
/**
@@ -172,7 +203,7 @@
public void shouldHonorSystemThresholds_deviceIdle_noSignalRequest_returnTrue() {
when(mPhone.isDeviceIdle()).thenReturn(true);
- assertThat(mSignalStrengthController.shouldHonorSystemThresholds()).isFalse();
+ assertThat(mSsc.shouldHonorSystemThresholds()).isFalse();
}
/**
@@ -188,11 +219,11 @@
false /* shouldReportWhileIdle*/,
true /* shouldReportSystemWhileIdle */
);
- mSignalStrengthController.setSignalStrengthUpdateRequest(ACTIVE_SUB_ID, CALLING_UID,
+ mSsc.setSignalStrengthUpdateRequest(ACTIVE_SUB_ID, CALLING_UID,
request, Message.obtain(mHandler));
- waitForLastHandlerAction(mHandler);
+ processAllMessages();
- assertThat(mSignalStrengthController.shouldHonorSystemThresholds()).isTrue();
+ assertThat(mSsc.shouldHonorSystemThresholds()).isTrue();
}
/**
@@ -201,7 +232,7 @@
*/
@Test
public void shouldEnableSignalThresholdForAppRequest_noRequest_returnFalse() {
- assertThat(mSignalStrengthController.shouldEnableSignalThresholdForAppRequest(
+ assertThat(mSsc.shouldEnableSignalThresholdForAppRequest(
AccessNetworkConstants.AccessNetworkType.GERAN,
SIGNAL_MEASUREMENT_TYPE_RSSI,
ACTIVE_SUB_ID,
@@ -220,11 +251,11 @@
false /* shouldReportWhileIdle*/,
false /* shouldReportSystemWhileIdle */
);
- mSignalStrengthController.setSignalStrengthUpdateRequest(ACTIVE_SUB_ID, CALLING_UID,
+ mSsc.setSignalStrengthUpdateRequest(ACTIVE_SUB_ID, CALLING_UID,
request, Message.obtain(mHandler));
- waitForLastHandlerAction(mHandler);
+ processAllMessages();
- assertThat(mSignalStrengthController.shouldEnableSignalThresholdForAppRequest(
+ assertThat(mSsc.shouldEnableSignalThresholdForAppRequest(
AccessNetworkConstants.AccessNetworkType.GERAN,
SIGNAL_MEASUREMENT_TYPE_RSSI,
ACTIVE_SUB_ID,
@@ -244,11 +275,11 @@
false /* shouldReportWhileIdle*/,
false /* shouldReportSystemWhileIdle */
);
- mSignalStrengthController.setSignalStrengthUpdateRequest(ACTIVE_SUB_ID, CALLING_UID,
+ mSsc.setSignalStrengthUpdateRequest(ACTIVE_SUB_ID, CALLING_UID,
request, Message.obtain(mHandler));
- waitForLastHandlerAction(mHandler);
+ processAllMessages();
- assertThat(mSignalStrengthController.shouldEnableSignalThresholdForAppRequest(
+ assertThat(mSsc.shouldEnableSignalThresholdForAppRequest(
AccessNetworkConstants.AccessNetworkType.GERAN,
SIGNAL_MEASUREMENT_TYPE_RSSI,
ACTIVE_SUB_ID,
@@ -268,11 +299,11 @@
true /* shouldReportWhileIdle*/,
false /* shouldReportSystemWhileIdle */
);
- mSignalStrengthController.setSignalStrengthUpdateRequest(ACTIVE_SUB_ID, CALLING_UID,
+ mSsc.setSignalStrengthUpdateRequest(ACTIVE_SUB_ID, CALLING_UID,
request, Message.obtain(mHandler));
- waitForLastHandlerAction(mHandler);
+ processAllMessages();
- assertThat(mSignalStrengthController.shouldEnableSignalThresholdForAppRequest(
+ assertThat(mSsc.shouldEnableSignalThresholdForAppRequest(
AccessNetworkConstants.AccessNetworkType.GERAN,
SIGNAL_MEASUREMENT_TYPE_RSSI,
ACTIVE_SUB_ID,
@@ -292,11 +323,11 @@
false /* shouldReportWhileIdle*/,
true /* shouldReportSystemWhileIdle */
);
- mSignalStrengthController.setSignalStrengthUpdateRequest(ACTIVE_SUB_ID, CALLING_UID,
+ mSsc.setSignalStrengthUpdateRequest(ACTIVE_SUB_ID, CALLING_UID,
request, Message.obtain(mHandler));
- waitForLastHandlerAction(mHandler);
+ processAllMessages();
- assertThat(mSignalStrengthController.shouldEnableSignalThresholdForAppRequest(
+ assertThat(mSsc.shouldEnableSignalThresholdForAppRequest(
AccessNetworkConstants.AccessNetworkType.GERAN,
SIGNAL_MEASUREMENT_TYPE_RSSI,
ACTIVE_SUB_ID,
@@ -337,22 +368,262 @@
false /* shouldReportWhileIdle*/,
false /* shouldReportSystemWhileIdle */
);
- mSignalStrengthController.setSignalStrengthUpdateRequest(ACTIVE_SUB_ID, CALLING_UID,
+ mSsc.setSignalStrengthUpdateRequest(ACTIVE_SUB_ID, CALLING_UID,
request, Message.obtain(mHandler));
- waitForLastHandlerAction(mHandler);
+ processAllMessages();
- assertThat(mSignalStrengthController.getConsolidatedSignalThresholds(
+ assertThat(mSsc.getConsolidatedSignalThresholds(
ran, measurement, systemThresholds, hysteresis
)).isEqualTo(target);
// Each pair in the Map is tested separately (instead of cumulatively).
// Remove the request once it is done.
- mSignalStrengthController.clearSignalStrengthUpdateRequest(ACTIVE_SUB_ID, CALLING_UID,
+ mSsc.clearSignalStrengthUpdateRequest(ACTIVE_SUB_ID, CALLING_UID,
request, Message.obtain(mHandler));
- waitForLastHandlerAction(mHandler);
+ processAllMessages();
}
}
+ @Test
+ @MediumTest
+ public void testSignalStrength() {
+ // Send in GSM Signal Strength Info and expect isGsm == true
+ SignalStrength ss = new SignalStrength(
+ new CellSignalStrengthCdma(),
+ new CellSignalStrengthGsm(-53, 0, SignalStrength.INVALID),
+ new CellSignalStrengthWcdma(),
+ new CellSignalStrengthTdscdma(),
+ new CellSignalStrengthLte(),
+ new CellSignalStrengthNr());
+
+ sendSignalStrength(ss);
+ assertEquals(mSsc.getSignalStrength(), ss);
+ assertEquals(mSsc.getSignalStrength().isGsm(), true);
+
+ // Send in CDMA+LTE Signal Strength Info and expect isGsm == true
+ ss = new SignalStrength(
+ new CellSignalStrengthCdma(-90, -12,
+ SignalStrength.INVALID, SignalStrength.INVALID, SignalStrength.INVALID),
+ new CellSignalStrengthGsm(),
+ new CellSignalStrengthWcdma(),
+ new CellSignalStrengthTdscdma(),
+ new CellSignalStrengthLte(
+ -110, -114, -5, 0, SignalStrength.INVALID, SignalStrength.INVALID),
+ new CellSignalStrengthNr());
+
+ sendSignalStrength(ss);
+ assertEquals(mSsc.getSignalStrength(), ss);
+ assertEquals(mSsc.getSignalStrength().isGsm(), true);
+
+ // Send in CDMA-only Signal Strength Info and expect isGsm == false
+ ss = new SignalStrength(
+ new CellSignalStrengthCdma(-90, -12,
+ SignalStrength.INVALID, SignalStrength.INVALID, SignalStrength.INVALID),
+ new CellSignalStrengthGsm(),
+ new CellSignalStrengthWcdma(),
+ new CellSignalStrengthTdscdma(),
+ new CellSignalStrengthLte(),
+ new CellSignalStrengthNr());
+
+ sendSignalStrength(ss);
+ assertEquals(mSsc.getSignalStrength(), ss);
+ assertEquals(mSsc.getSignalStrength().isGsm(), false);
+ }
+
+ @Test
+ public void testLteSignalStrengthReportingCriteria() {
+ SignalStrength ss = new SignalStrength(
+ new CellSignalStrengthCdma(),
+ new CellSignalStrengthGsm(),
+ new CellSignalStrengthWcdma(),
+ new CellSignalStrengthTdscdma(),
+ new CellSignalStrengthLte(
+ -110, /* rssi */
+ -114, /* rsrp */
+ -5, /* rsrq */
+ 0, /* rssnr */
+ SignalStrength.INVALID, /* cqi */
+ SignalStrength.INVALID /* ta */),
+ new CellSignalStrengthNr());
+
+ mBundle.putBoolean(CarrierConfigManager.KEY_USE_ONLY_RSRP_FOR_LTE_SIGNAL_BAR_BOOL,
+ true);
+
+ sendCarrierConfigUpdate();
+
+ mSimulatedCommands.setSignalStrength(ss);
+ mSimulatedCommands.notifySignalStrength();
+ processAllMessages();
+ // Default thresholds are POOR=-115 MODERATE=-105 GOOD=-95 GREAT=-85
+ assertEquals(CellSignalStrength.SIGNAL_STRENGTH_POOR, mSsc.getSignalStrength().getLevel());
+
+ int[] lteThresholds = {
+ -130, // SIGNAL_STRENGTH_POOR
+ -120, // SIGNAL_STRENGTH_MODERATE
+ -110, // SIGNAL_STRENGTH_GOOD
+ -100, // SIGNAL_STRENGTH_GREAT
+ };
+ mBundle.putIntArray(CarrierConfigManager.KEY_LTE_RSRP_THRESHOLDS_INT_ARRAY,
+ lteThresholds);
+ sendCarrierConfigUpdate();
+
+ mSimulatedCommands.setSignalStrength(ss);
+ mSimulatedCommands.notifySignalStrength();
+ processAllMessages();
+ assertEquals(mSsc.getSignalStrength().getLevel(),
+ CellSignalStrength.SIGNAL_STRENGTH_MODERATE);
+ }
+
+ @Test
+ public void test5gNrSignalStrengthReportingCriteria_UseSsRsrp() {
+ SignalStrength ss = new SignalStrength(
+ new CellSignalStrengthCdma(),
+ new CellSignalStrengthGsm(),
+ new CellSignalStrengthWcdma(),
+ new CellSignalStrengthTdscdma(),
+ new CellSignalStrengthLte(),
+ new CellSignalStrengthNr(
+ -139, /** csiRsrp NONE */
+ -20, /** csiRsrq NONE */
+ -23, /** CsiSinr NONE */
+ -44, /** SsRsrp SIGNAL_STRENGTH_GREAT */
+ -20, /** SsRsrq NONE */
+ -23) /** SsSinr NONE */
+ );
+
+ // SSRSRP = 1 << 0
+ mBundle.putInt(CarrierConfigManager.KEY_PARAMETERS_USE_FOR_5G_NR_SIGNAL_BAR_INT,
+ CellSignalStrengthNr.USE_SSRSRP);
+ sendCarrierConfigUpdate();
+ mSimulatedCommands.setSignalStrength(ss);
+ mSimulatedCommands.notifySignalStrength();
+ processAllMessages();
+ assertEquals(CellSignalStrength.SIGNAL_STRENGTH_GREAT, mSsc.getSignalStrength().getLevel());
+ }
+
+ @Test
+ public void test5gNrSignalStrengthReportingCriteria_UseSsRsrpAndSsRsrq() {
+ SignalStrength ss = new SignalStrength(
+ new CellSignalStrengthCdma(),
+ new CellSignalStrengthGsm(),
+ new CellSignalStrengthWcdma(),
+ new CellSignalStrengthTdscdma(),
+ new CellSignalStrengthLte(),
+ new CellSignalStrengthNr(
+ -139, /** csiRsrp NONE */
+ -20, /** csiRsrq NONE */
+ -23, /** CsiSinr NONE */
+ -44, /** SsRsrp SIGNAL_STRENGTH_GREAT */
+ -32, /** SsRsrq NONE */
+ -23) /** SsSinr NONE */
+ );
+
+ // SSRSRP = 1 << 0 | SSSINR = 1 << 2
+ mBundle.putInt(CarrierConfigManager.KEY_PARAMETERS_USE_FOR_5G_NR_SIGNAL_BAR_INT,
+ CellSignalStrengthNr.USE_SSRSRP | CellSignalStrengthNr.USE_SSRSRQ);
+ sendCarrierConfigUpdate();
+ mSimulatedCommands.setSignalStrength(ss);
+ mSimulatedCommands.notifySignalStrength();
+ processAllMessages();
+ assertEquals(CellSignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN,
+ mSsc.getSignalStrength().getLevel());
+ }
+
+ @Test
+ public void test5gNrSignalStrengthReportingCriteria_ConfiguredThresholds() {
+ SignalStrength ss = new SignalStrength(
+ new CellSignalStrengthCdma(),
+ new CellSignalStrengthGsm(),
+ new CellSignalStrengthWcdma(),
+ new CellSignalStrengthTdscdma(),
+ new CellSignalStrengthLte(),
+ new CellSignalStrengthNr(
+ -139, /** csiRsrp NONE */
+ -20, /** csiRsrq NONE */
+ -23, /** CsiSinr NONE */
+ -44, /** SsRsrp SIGNAL_STRENGTH_GREAT */
+ -20, /** SsRsrq NONE */
+ -23) /** SsSinr NONE */
+ );
+
+ // SSRSRP = 1 << 0
+ mBundle.putInt(CarrierConfigManager.KEY_PARAMETERS_USE_FOR_5G_NR_SIGNAL_BAR_INT,
+ CellSignalStrengthNr.USE_SSRSRP);
+ sendCarrierConfigUpdate();
+ mSimulatedCommands.setSignalStrength(ss);
+ mSimulatedCommands.notifySignalStrength();
+ processAllMessages();
+ assertEquals(CellSignalStrength.SIGNAL_STRENGTH_GREAT, mSsc.getSignalStrength().getLevel());
+
+ int[] nrSsRsrpThresholds = {
+ -45, // SIGNAL_STRENGTH_POOR
+ -40, // SIGNAL_STRENGTH_MODERATE
+ -37, // SIGNAL_STRENGTH_GOOD
+ -34, // SIGNAL_STRENGTH_GREAT
+ };
+ mBundle.putIntArray(CarrierConfigManager.KEY_5G_NR_SSRSRP_THRESHOLDS_INT_ARRAY,
+ nrSsRsrpThresholds);
+ mBundle.putInt(CarrierConfigManager.KEY_PARAMETERS_USE_FOR_5G_NR_SIGNAL_BAR_INT,
+ CellSignalStrengthNr.USE_SSRSRP);
+ sendCarrierConfigUpdate();
+ mSimulatedCommands.setSignalStrength(ss);
+ mSimulatedCommands.notifySignalStrength();
+ processAllMessages();
+ assertEquals(CellSignalStrength.SIGNAL_STRENGTH_POOR,
+ mSsc.getSignalStrength().getLevel());
+ }
+
+ @Test
+ public void testWcdmaSignalStrengthReportingCriteria() {
+ SignalStrength ss = new SignalStrength(
+ new CellSignalStrengthCdma(),
+ new CellSignalStrengthGsm(),
+ new CellSignalStrengthWcdma(-79, 0, -85, -5),
+ new CellSignalStrengthTdscdma(),
+ new CellSignalStrengthLte(),
+ new CellSignalStrengthNr());
+
+ mSimulatedCommands.setSignalStrength(ss);
+ mSimulatedCommands.notifySignalStrength();
+ processAllMessages();
+ assertEquals(mSsc.getSignalStrength().getLevel(), CellSignalStrength.SIGNAL_STRENGTH_GOOD);
+
+ int[] wcdmaThresholds = {
+ -110, // SIGNAL_STRENGTH_POOR
+ -100, // SIGNAL_STRENGTH_MODERATE
+ -90, // SIGNAL_STRENGTH_GOOD
+ -80 // SIGNAL_STRENGTH_GREAT
+ };
+ mBundle.putIntArray(CarrierConfigManager.KEY_WCDMA_RSCP_THRESHOLDS_INT_ARRAY,
+ wcdmaThresholds);
+ mBundle.putString(
+ CarrierConfigManager.KEY_WCDMA_DEFAULT_SIGNAL_STRENGTH_MEASUREMENT_STRING,
+ "rscp");
+ sendCarrierConfigUpdate();
+ mSimulatedCommands.setSignalStrength(ss);
+ mSimulatedCommands.notifySignalStrength();
+ processAllMessages();
+ assertEquals(mSsc.getSignalStrength().getLevel(), CellSignalStrength.SIGNAL_STRENGTH_GOOD);
+ }
+
+ private void sendCarrierConfigUpdate() {
+ CarrierConfigManager mockConfigManager = Mockito.mock(CarrierConfigManager.class);
+ when(mContext.getSystemService(Context.CARRIER_CONFIG_SERVICE))
+ .thenReturn(mockConfigManager);
+ when(mockConfigManager.getConfigForSubId(anyInt())).thenReturn(mBundle);
+
+ Intent intent = new Intent().setAction(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED);
+ intent.putExtra(CarrierConfigManager.EXTRA_SLOT_INDEX, PHONE_ID);
+ mContext.sendBroadcast(intent);
+ processAllMessages();
+ }
+
+ private void sendSignalStrength(SignalStrength ss) {
+ mSimulatedCommands.setSignalStrength(ss);
+ mSimulatedCommands.notifySignalStrength();
+ processAllMessages();
+ }
+
private SignalThresholdInfo createTestSignalThresholdInfo() {
SignalThresholdInfo info = new SignalThresholdInfo.Builder()
.setRadioAccessNetworkType(AccessNetworkConstants.AccessNetworkType.GERAN)
diff --git a/tests/telephonytests/src/com/android/internal/telephony/SimulatedCommands.java b/tests/telephonytests/src/com/android/internal/telephony/SimulatedCommands.java
index b35cdd1..8dd6a81 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/SimulatedCommands.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/SimulatedCommands.java
@@ -1189,6 +1189,13 @@
}
}
+ public void triggerNITZupdate(String NITZStr, long ageMs) {
+ if (NITZStr != null) {
+ mNITZTimeRegistrant.notifyRegistrant(new AsyncResult (null, new Object[]{NITZStr,
+ SystemClock.elapsedRealtime(), ageMs}, null));
+ }
+ }
+
@Override
public void setupDataCall(int accessNetworkType, DataProfile dataProfile, boolean isRoaming,
boolean allowRoaming, int reason, LinkProperties linkProperties, int pduSessionId,
diff --git a/tests/telephonytests/src/com/android/internal/telephony/TelephonyRegistryTest.java b/tests/telephonytests/src/com/android/internal/telephony/TelephonyRegistryTest.java
index 1d5bce6..c04bcfb 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/TelephonyRegistryTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/TelephonyRegistryTest.java
@@ -724,4 +724,67 @@
processAllMessages();
assertEquals(lceList, mLinkCapacityEstimateList);
}
+
+ @Test
+ public void testPreciseDataConnectionStateChangedForInvalidSubId() {
+ //set dual sim
+ doReturn(2).when(mTelephonyManager).getActiveModemCount();
+ mContext.sendBroadcast(new Intent(ACTION_MULTI_SIM_CONFIG_CHANGED));
+ // set default slot
+ mContext.sendBroadcast(new Intent(ACTION_DEFAULT_SUBSCRIPTION_CHANGED)
+ .putExtra(SubscriptionManager.EXTRA_SUBSCRIPTION_INDEX, 2)
+ .putExtra(SubscriptionManager.EXTRA_SLOT_INDEX, 0));
+ processAllMessages();
+
+ final int subId = 1;
+ int[] events = {TelephonyCallback.EVENT_PRECISE_DATA_CONNECTION_STATE_CHANGED};
+ doReturn(mMockSubInfo).when(mSubscriptionManager).getActiveSubscriptionInfo(anyInt());
+ doReturn(1).when(mMockSubInfo).getSimSlotIndex();
+
+ mTelephonyRegistry.listenWithEventList(subId, mContext.getOpPackageName(),
+ mContext.getAttributionTag(), mTelephonyCallback.callback, events, true);
+ processAllMessages();
+
+ // notify data connection with invalid sub id and default phone id
+ mTelephonyRegistry.notifyDataConnectionForSubscriber(
+ /*default phoneId*/ 0, /*invalid subId*/ -1,
+ new PreciseDataConnectionState.Builder()
+ .setTransportType(AccessNetworkConstants.TRANSPORT_TYPE_WWAN)
+ .setId(1)
+ .setState(TelephonyManager.DATA_CONNECTED)
+ .setNetworkType(TelephonyManager.NETWORK_TYPE_LTE)
+ .setApnSetting(new ApnSetting.Builder()
+ .setApnTypeBitmask(ApnSetting.TYPE_IMS)
+ .setApnName("ims")
+ .setEntryName("ims")
+ .build())
+ .setLinkProperties(new LinkProperties())
+ .setFailCause(0)
+ .build());
+
+ processAllMessages();
+
+ assertEquals(0, mTelephonyCallback.invocationCount.get());
+
+ // notify data connection with invalid sub id and default phone id
+ mTelephonyRegistry.notifyDataConnectionForSubscriber(
+ /*target phoneId*/ 1, /*invalid subId*/ -1,
+ new PreciseDataConnectionState.Builder()
+ .setTransportType(AccessNetworkConstants.TRANSPORT_TYPE_WWAN)
+ .setId(2)
+ .setState(TelephonyManager.DATA_SUSPENDED)
+ .setNetworkType(TelephonyManager.NETWORK_TYPE_LTE)
+ .setApnSetting(new ApnSetting.Builder()
+ .setApnTypeBitmask(ApnSetting.TYPE_IMS)
+ .setApnName("ims")
+ .setEntryName("ims")
+ .build())
+ .setLinkProperties(new LinkProperties())
+ .setFailCause(0)
+ .build());
+
+ processAllMessages();
+
+ assertEquals(1, mTelephonyCallback.invocationCount.get());
+ }
}
diff --git a/tests/telephonytests/src/com/android/internal/telephony/dataconnection/LinkBandwidthEstimatorTest.java b/tests/telephonytests/src/com/android/internal/telephony/dataconnection/LinkBandwidthEstimatorTest.java
index 80fe817..3467f3f 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/dataconnection/LinkBandwidthEstimatorTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/dataconnection/LinkBandwidthEstimatorTest.java
@@ -105,6 +105,7 @@
when(mTelephonyFacade.getMobileTxBytes()).thenReturn(0L);
when(mTelephonyFacade.getMobileTxBytes()).thenReturn(0L);
when(mPhone.getCurrentCellIdentity()).thenReturn(mCellIdentity);
+ // Note that signal level is 0 before 1st MSG_SIGNAL_STRENGTH_CHANGED
when(mPhone.getSubId()).thenReturn(1);
when(mSignalStrength.getDbm()).thenReturn(-100);
when(mSignalStrength.getLevel()).thenReturn(1);
@@ -330,17 +331,43 @@
verifyUpdateBandwidth(-1, 19_597);
- addTxBytes(20_000L);
- addRxBytes(50_000L);
+ when(mSignalStrength.getLevel()).thenReturn(1);
when(mSignalStrength.getDbm()).thenReturn(-110);
mLBE.obtainMessage(MSG_SIGNAL_STRENGTH_CHANGED, mSignalStrength).sendToTarget();
addElapsedTime(6000);
moveTimeForward(6000);
processAllMessages();
+ verifyUpdateBandwidth(-1, 19_535);
+ when(mSignalStrength.getLevel()).thenReturn(2);
+ when(mSignalStrength.getDbm()).thenReturn(-90);
+ mLBE.obtainMessage(MSG_SIGNAL_STRENGTH_CHANGED, mSignalStrength).sendToTarget();
+ addElapsedTime(6000);
+ moveTimeForward(6000);
+ processAllMessages();
verifyUpdateBandwidth(-1, -1);
+
+ for (int i = 0; i < BW_STATS_COUNT_THRESHOLD + 2; i++) {
+ addTxBytes(10_000L);
+ addRxBytes(1000_000L);
+ addElapsedTime(5_100);
+ moveTimeForward(5_100);
+ processAllMessages();
+ mLBE.obtainMessage(MSG_MODEM_ACTIVITY_RETURNED, new ModemActivityInfo(
+ i * 5_100L, 0, 0, TX_TIME_2_MS, i * RX_TIME_2_MS)).sendToTarget();
+ processAllMessages();
+ }
+
+ when(mSignalStrength.getLevel()).thenReturn(1);
+ when(mSignalStrength.getDbm()).thenReturn(-110);
+ mLBE.obtainMessage(MSG_SIGNAL_STRENGTH_CHANGED, mSignalStrength).sendToTarget();
+ addElapsedTime(6000);
+ moveTimeForward(6000);
+ processAllMessages();
+ verifyUpdateBandwidth(-1, 30_821);
}
+
@Test
public void testAvgBwForAllPossibleRat() throws Exception {
Pair<Integer, Integer> values = mLBE.getStaticAvgBw(TelephonyManager.NETWORK_TYPE_GPRS);
@@ -401,7 +428,6 @@
addRxBytes(19_000L);
when(mServiceState.getNrState()).thenReturn(NetworkRegistrationInfo.NR_STATE_CONNECTED);
when(mServiceState.getNrFrequencyRange()).thenReturn(ServiceState.FREQUENCY_RANGE_MMWAVE);
- when(mSignalStrength.getLevel()).thenReturn(2);
mLBE.obtainMessage(MSG_NR_FREQUENCY_CHANGED).sendToTarget();
addElapsedTime(6000);
moveTimeForward(6000);
@@ -634,7 +660,7 @@
@Test
- public void testVeryHighByteCountReturnNonNegativeValue() throws Exception {
+ public void testVeryHighRxLinkBandwidthEstimationIgnored() throws Exception {
mLBE.obtainMessage(MSG_SCREEN_STATE_CHANGED, true).sendToTarget();
processAllMessages();
mLBE.obtainMessage(MSG_SIGNAL_STRENGTH_CHANGED, mSignalStrength).sendToTarget();
@@ -650,11 +676,12 @@
processAllMessages();
}
+ // This will result in link bandwidth estimation value 128Gbps which is too high for LTE.
+ // So it will be ignored by the estimator.
LinkBandwidthEstimator.NetworkBandwidth network = mLBE.lookupNetwork("310260", 366, "LTE");
- assertEquals(BW_STATS_COUNT_THRESHOLD + 4, network.getCount(LINK_RX, 1));
+ assertEquals(0, network.getCount(LINK_RX, 1));
assertEquals(0, network.getValue(LINK_TX, 1));
- assertEquals(16_000_000_000L * 8 / 1024 * (BW_STATS_COUNT_THRESHOLD + 4),
- network.getValue(LINK_RX, 1));
+ assertEquals(0, network.getValue(LINK_RX, 1));
}
}
diff --git a/tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsPhoneConnectionTest.java b/tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsPhoneConnectionTest.java
index 5e98e50..84f2672 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsPhoneConnectionTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsPhoneConnectionTest.java
@@ -72,6 +72,7 @@
import java.lang.reflect.Field;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
@@ -433,15 +434,14 @@
@SmallTest
public void testSetRedirectingAddress() {
mConnectionUT = new ImsPhoneConnection(mImsPhone, mImsCall, mImsCT, mForeGroundCall, false);
- ArrayList<String> forwardedNumber = new ArrayList<String>();
- forwardedNumber.add("11111");
- forwardedNumber.add("22222");
- forwardedNumber.add("33333");
+ String[] forwardedNumber = new String[]{"11111", "22222", "33333"};
+ ArrayList<String> forwardedNumberList =
+ new ArrayList<String>(Arrays.asList(forwardedNumber));
assertEquals(mConnectionUT.getForwardedNumber(), null);
- mBundle.putStringArrayList(ImsCallProfile.EXTRA_FORWARDED_NUMBER, forwardedNumber);
+ mBundle.putStringArray(ImsCallProfile.EXTRA_FORWARDED_NUMBER, forwardedNumber);
assertTrue(mConnectionUT.update(mImsCall, Call.State.ACTIVE));
- assertEquals(forwardedNumber, mConnectionUT.getForwardedNumber());
+ assertEquals(forwardedNumberList, mConnectionUT.getForwardedNumber());
}
@Test
diff --git a/tests/telephonytests/src/com/android/internal/telephony/metrics/CallQualityMetricsTest.java b/tests/telephonytests/src/com/android/internal/telephony/metrics/CallQualityMetricsTest.java
index e530425..a0341b7 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/metrics/CallQualityMetricsTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/metrics/CallQualityMetricsTest.java
@@ -28,15 +28,20 @@
import android.telephony.CellSignalStrengthWcdma;
import android.telephony.SignalStrength;
+import com.android.internal.telephony.SignalStrengthController;
import com.android.internal.telephony.TelephonyTest;
import com.android.internal.telephony.nano.TelephonyProto.TelephonyCallSession.Event.CallQualitySummary;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
+import org.mockito.Mock;
public class CallQualityMetricsTest extends TelephonyTest {
+ @Mock
+ SignalStrengthController mSsc;
+
private CallQualityMetrics mCallQualityMetrics;
@Before
@@ -48,6 +53,7 @@
// default phone from the ImsPhone and uses that to get the ServiceStateTracker, therefore
// we need to mock the default phone as well.
when(mPhone.getDefaultPhone()).thenReturn(mPhone);
+ when(mPhone.getSignalStrengthController()).thenReturn(mSsc);
}
@After
@@ -264,7 +270,7 @@
new CellSignalStrengthTdscdma(),
lteSs1,
new CellSignalStrengthNr());
- when(mSST.getSignalStrength()).thenReturn(ss1);
+ when(mSsc.getSignalStrength()).thenReturn(ss1);
mCallQualityMetrics.saveCallQuality(cq1);
// save good quality with low rssnr
@@ -280,7 +286,7 @@
new CellSignalStrengthTdscdma(),
lteSs2,
new CellSignalStrengthNr());
- when(mSST.getSignalStrength()).thenReturn(ss2);
+ when(mSsc.getSignalStrength()).thenReturn(ss2);
mCallQualityMetrics.saveCallQuality(cq1);
CallQualitySummary dlSummary = mCallQualityMetrics.getCallQualitySummaryDl();
diff --git a/tests/telephonytests/src/com/android/internal/telephony/metrics/VoiceCallSessionStatsTest.java b/tests/telephonytests/src/com/android/internal/telephony/metrics/VoiceCallSessionStatsTest.java
index 9651741..988e252 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/metrics/VoiceCallSessionStatsTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/metrics/VoiceCallSessionStatsTest.java
@@ -1311,9 +1311,9 @@
expectedCall.ratSwitchCount = 1L;
expectedCall.setupFailed = true;
expectedCall.ratAtConnected = TelephonyManager.NETWORK_TYPE_UNKNOWN;
- expectedCall.codecBitmask = 1L << AudioCodec.AUDIO_CODEC_AMR;
+ expectedCall.codecBitmask = 0L;
expectedCall.mainCodecQuality =
- VOICE_CALL_SESSION__MAIN_CODEC_QUALITY__CODEC_QUALITY_NARROWBAND;
+ VOICE_CALL_SESSION__MAIN_CODEC_QUALITY__CODEC_QUALITY_UNKNOWN;
VoiceCallRatUsage expectedRatUsageLte =
makeRatUsageProto(
CARRIER_ID_SLOT_0, TelephonyManager.NETWORK_TYPE_LTE, 2000L, 3000L, 1L);
@@ -1331,8 +1331,6 @@
mVoiceCallSessionStats0.setTimeMillis(3000L);
setServiceState(mServiceState, TelephonyManager.NETWORK_TYPE_UMTS);
mVoiceCallSessionStats0.onServiceStateChanged(mServiceState);
- mVoiceCallSessionStats0.setTimeMillis(3100L);
- mVoiceCallSessionStats0.onAudioCodecChanged(mGsmConnection0, DriverCall.AUDIO_QUALITY_AMR);
mVoiceCallSessionStats0.setTimeMillis(15000L);
doReturn(DisconnectCause.LOST_SIGNAL).when(mGsmConnection0).getDisconnectCause();
mVoiceCallSessionStats0.onRilCallListChanged(List.of(mGsmConnection0));
@@ -1435,7 +1433,8 @@
expectedCall.setupFailed = true;
expectedCall.ratAtConnected = TelephonyManager.NETWORK_TYPE_UNKNOWN;
expectedCall.bandAtEnd = 0;
- expectedCall.codecBitmask = 1L << AudioCodec.AUDIO_CODEC_AMR;
+ expectedCall.codecBitmask =
+ (1L << AudioCodec.AUDIO_CODEC_AMR) | (1L << AudioCodec.AUDIO_CODEC_AMR_WB);
expectedCall.mainCodecQuality =
VOICE_CALL_SESSION__MAIN_CODEC_QUALITY__CODEC_QUALITY_NARROWBAND;
VoiceCallRatUsage expectedRatUsage =
@@ -1448,10 +1447,12 @@
mVoiceCallSessionStats0.setTimeMillis(2500L);
doReturn(Call.State.INCOMING).when(mCsCall0).getState();
doReturn(Call.State.INCOMING).when(mGsmConnection0).getState();
+ doReturn(DriverCall.AUDIO_QUALITY_AMR_WB).when(mGsmConnection0).getAudioCodec();
doReturn(DisconnectCause.NOT_DISCONNECTED).when(mGsmConnection0).getDisconnectCause();
mVoiceCallSessionStats0.onRilCallListChanged(List.of(mGsmConnection0));
mVoiceCallSessionStats0.setTimeMillis(3000L);
mVoiceCallSessionStats0.onAudioCodecChanged(mGsmConnection0, DriverCall.AUDIO_QUALITY_AMR);
+ doReturn(DriverCall.AUDIO_QUALITY_AMR).when(mGsmConnection0).getAudioCodec();
mVoiceCallSessionStats0.setTimeMillis(15000L);
doReturn(DisconnectCause.NORMAL).when(mGsmConnection0).getDisconnectCause();
doReturn(PreciseDisconnectCause.CALL_REJECTED)
diff --git a/tests/telephonytests/src/com/android/internal/telephony/nitz/NitzSignalInputFilterPredicateFactoryTest.java b/tests/telephonytests/src/com/android/internal/telephony/nitz/NitzSignalInputFilterPredicateFactoryTest.java
index 2339f08..1997114 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/nitz/NitzSignalInputFilterPredicateFactoryTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/nitz/NitzSignalInputFilterPredicateFactoryTest.java
@@ -19,16 +19,17 @@
import static com.android.internal.telephony.nitz.NitzSignalInputFilterPredicateFactory.createBogusElapsedRealtimeCheck;
import static com.android.internal.telephony.nitz.NitzSignalInputFilterPredicateFactory.createIgnoreNitzPropertyCheck;
import static com.android.internal.telephony.nitz.NitzSignalInputFilterPredicateFactory.createRateLimitCheck;
+import static com.android.internal.telephony.nitz.NitzStateMachineTestSupport.ARBITRARY_AGE;
import static com.android.internal.telephony.nitz.NitzStateMachineTestSupport.UNIQUE_US_ZONE_SCENARIO1;
+import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
-import android.os.TimestampedValue;
-
import com.android.internal.telephony.NitzData;
+import com.android.internal.telephony.NitzSignal;
import com.android.internal.telephony.TelephonyTest;
import com.android.internal.telephony.nitz.NitzSignalInputFilterPredicateFactory.NitzSignalInputFilterPredicateImpl;
import com.android.internal.telephony.nitz.NitzSignalInputFilterPredicateFactory.TrivalentPredicate;
@@ -57,8 +58,8 @@
@Test
public void testNitzSignalInputFilterPredicateImpl_nullSecondArgumentRejected() {
Scenario scenario = UNIQUE_US_ZONE_SCENARIO1;
- TimestampedValue<NitzData> nitzSignal =
- scenario.createNitzSignal(mFakeDeviceState.elapsedRealtime());
+ NitzSignal nitzSignal =
+ scenario.createNitzSignal(mFakeDeviceState.elapsedRealtimeMillis(), ARBITRARY_AGE);
TrivalentPredicate[] triPredicates = {};
NitzSignalInputFilterPredicateImpl impl =
new NitzSignalInputFilterPredicateImpl(triPredicates);
@@ -72,8 +73,8 @@
@Test
public void testNitzSignalInputFilterPredicateImpl_defaultIsTrue() {
Scenario scenario = UNIQUE_US_ZONE_SCENARIO1;
- TimestampedValue<NitzData> nitzSignal = scenario
- .createNitzSignal(mFakeDeviceState.elapsedRealtime());
+ NitzSignal nitzSignal =
+ scenario.createNitzSignal(mFakeDeviceState.elapsedRealtimeMillis(), ARBITRARY_AGE);
NitzSignalInputFilterPredicateImpl impl =
new NitzSignalInputFilterPredicateImpl(new TrivalentPredicate[0]);
assertTrue(impl.mustProcessNitzSignal(null, nitzSignal));
@@ -82,8 +83,8 @@
@Test
public void testNitzSignalInputFilterPredicateImpl_nullIsIgnored() {
Scenario scenario = UNIQUE_US_ZONE_SCENARIO1;
- TimestampedValue<NitzData> nitzSignal =
- scenario.createNitzSignal(mFakeDeviceState.elapsedRealtime());
+ NitzSignal nitzSignal =
+ scenario.createNitzSignal(mFakeDeviceState.elapsedRealtimeMillis(), ARBITRARY_AGE);
TrivalentPredicate nullPredicate = (x, y) -> null;
TrivalentPredicate[] triPredicates = { nullPredicate };
NitzSignalInputFilterPredicateImpl impl =
@@ -94,8 +95,8 @@
@Test
public void testNitzSignalInputFilterPredicateImpl_trueIsHonored() {
Scenario scenario = UNIQUE_US_ZONE_SCENARIO1;
- TimestampedValue<NitzData> nitzSignal =
- scenario.createNitzSignal(mFakeDeviceState.elapsedRealtime());
+ NitzSignal nitzSignal =
+ scenario.createNitzSignal(mFakeDeviceState.elapsedRealtimeMillis(), ARBITRARY_AGE);
TrivalentPredicate nullPredicate = (x, y) -> null;
TrivalentPredicate truePredicate = (x, y) -> true;
TrivalentPredicate exceptionPredicate = (x, y) -> {
@@ -114,8 +115,8 @@
@Test
public void testNitzSignalInputFilterPredicateImpl_falseIsHonored() {
Scenario scenario = UNIQUE_US_ZONE_SCENARIO1;
- TimestampedValue<NitzData> nitzSignal =
- scenario.createNitzSignal(mFakeDeviceState.elapsedRealtime());
+ NitzSignal nitzSignal =
+ scenario.createNitzSignal(mFakeDeviceState.elapsedRealtimeMillis(), ARBITRARY_AGE);
TrivalentPredicate nullPredicate = (x, y) -> null;
TrivalentPredicate falsePredicate = (x, y) -> false;
TrivalentPredicate exceptionPredicate = (x, y) -> {
@@ -145,24 +146,42 @@
@Test
public void testTrivalentPredicate_bogusElapsedRealtimeCheck() {
Scenario scenario = UNIQUE_US_ZONE_SCENARIO1;
- long elapsedRealtimeClock = mFakeDeviceState.elapsedRealtime();
- TimestampedValue<NitzData> nitzSignal = scenario.createNitzSignal(elapsedRealtimeClock);
+ long elapsedRealtimeMillis = mFakeDeviceState.elapsedRealtimeMillis();
+ NitzSignal baseNitzSignal =
+ scenario.createNitzSignal(elapsedRealtimeMillis, ARBITRARY_AGE);
TrivalentPredicate triPredicate =
createBogusElapsedRealtimeCheck(mContext, mFakeDeviceState);
- assertNull(triPredicate.mustProcessNitzSignal(null, nitzSignal));
+ assertNull(triPredicate.mustProcessNitzSignal(null, baseNitzSignal));
// Any signal that claims to be from the future must be rejected.
- TimestampedValue<NitzData> bogusNitzSignal = new TimestampedValue<>(
- elapsedRealtimeClock + 1, nitzSignal.getValue());
- assertFalse(triPredicate.mustProcessNitzSignal(null, bogusNitzSignal));
+ {
+ long receiptElapsedMillis = elapsedRealtimeMillis + 1;
+ long ageMillis = 0;
+ NitzSignal bogusNitzSignal = new NitzSignal(
+ receiptElapsedMillis, baseNitzSignal.getNitzData(), ageMillis);
+ assertFalse(triPredicate.mustProcessNitzSignal(null, bogusNitzSignal));
+ }
+
+ // Age should be ignored: the predicate is intended to check receipt time isn't obviously
+ // corrupt / fabricated to be in the future. Larger ages could imply that the NITZ was
+ // received by the modem before the elapsed realtime clock started ticking, but we don't
+ // currently check for that.
+ {
+ long receiptElapsedMillis = elapsedRealtimeMillis + 1;
+ long ageMillis = 10000;
+ NitzSignal bogusNitzSignal = new NitzSignal(
+ receiptElapsedMillis, baseNitzSignal.getNitzData(), ageMillis);
+
+ assertFalse(triPredicate.mustProcessNitzSignal(null, bogusNitzSignal));
+ }
}
@Test
public void testTrivalentPredicate_noOldSignalCheck() {
Scenario scenario = UNIQUE_US_ZONE_SCENARIO1;
- TimestampedValue<NitzData> nitzSignal =
- scenario.createNitzSignal(mFakeDeviceState.elapsedRealtime());
+ NitzSignal nitzSignal =
+ scenario.createNitzSignal(mFakeDeviceState.elapsedRealtimeMillis(), ARBITRARY_AGE);
TrivalentPredicate triPredicate =
NitzSignalInputFilterPredicateFactory.createNoOldSignalCheck();
@@ -171,36 +190,108 @@
}
@Test
- public void testTrivalentPredicate_rateLimitCheck_elapsedRealtime() {
+ public void testTrivalentPredicate_rateLimitCheck_elapsedRealtime_zeroAge() {
Scenario scenario = UNIQUE_US_ZONE_SCENARIO1;
int nitzSpacingThreshold = mFakeDeviceState.getNitzUpdateSpacingMillis();
- NitzData baseNitzData = scenario.createNitzData();
+ // Change the other setting that can affect the predicate behavior so it is not a factor in
+ // the test.
+ mFakeDeviceState.setNitzUpdateDiffMillis(Integer.MAX_VALUE);
TrivalentPredicate triPredicate = createRateLimitCheck(mFakeDeviceState);
- long baseElapsedRealtimeMillis = mFakeDeviceState.elapsedRealtime();
- TimestampedValue<NitzData> baseSignal =
- new TimestampedValue<>(baseElapsedRealtimeMillis, baseNitzData);
+ long baseElapsedRealtimeMillis = mFakeDeviceState.elapsedRealtimeMillis();
+ NitzData baseNitzData = scenario.createNitzData();
+ int baseAgeMillis = 0;
+ NitzSignal baseNitzSignal =
+ new NitzSignal(baseElapsedRealtimeMillis, baseNitzData, baseAgeMillis);
// Two identical signals: no spacing so the new signal should not be processed.
- {
- assertFalse(triPredicate.mustProcessNitzSignal(baseSignal, baseSignal));
- }
+ assertFalse(triPredicate.mustProcessNitzSignal(baseNitzSignal, baseNitzSignal));
- // Two signals not spaced apart enough: the new signal should not processed.
+ // Two signals not spaced apart enough in receipt time: the new signal should not be
+ // processed.
{
- int elapsedTimeIncrement = nitzSpacingThreshold - 1;
- TimestampedValue<NitzData> newSignal =
- createIncrementedNitzSignal(baseSignal, elapsedTimeIncrement);
- assertFalse(triPredicate.mustProcessNitzSignal(baseSignal, newSignal));
+ int timeAdjustment = nitzSpacingThreshold - 1;
+ int utcAdjustment = 0;
+ long ageAdjustment = 0;
+ NitzSignal newSignal = createAdjustedNitzSignal(
+ baseNitzSignal, timeAdjustment, utcAdjustment, ageAdjustment);
+ assertFalse(triPredicate.mustProcessNitzSignal(baseNitzSignal, newSignal));
}
// Two signals spaced apart: the new signal should be processed.
{
- int elapsedTimeIncrement = nitzSpacingThreshold + 1;
- TimestampedValue<NitzData> newSignal =
- createIncrementedNitzSignal(baseSignal, elapsedTimeIncrement);
- assertTrue(triPredicate.mustProcessNitzSignal(baseSignal, newSignal));
+ int timeAdjustment = nitzSpacingThreshold + 1;
+ int utcAdjustment = 0;
+ long ageAdjustment = 0;
+ NitzSignal newSignal = createAdjustedNitzSignal(
+ baseNitzSignal, timeAdjustment, utcAdjustment, ageAdjustment);
+ assertTrue(triPredicate.mustProcessNitzSignal(baseNitzSignal, newSignal));
+ }
+ }
+
+ @Test
+ public void testTrivalentPredicate_rateLimitCheck_elapsedRealtime_withAge() {
+ Scenario scenario = UNIQUE_US_ZONE_SCENARIO1;
+ int nitzSpacingThreshold = 60000;
+ mFakeDeviceState.setNitzUpdateSpacingMillis(nitzSpacingThreshold);
+
+ // Change the other setting that can affect the predicate behavior so it is not a factor in
+ // the test.
+ mFakeDeviceState.setNitzUpdateDiffMillis(Integer.MAX_VALUE);
+
+ TrivalentPredicate triPredicate = createRateLimitCheck(mFakeDeviceState);
+
+ // Create a NITZ signal to be the first of two NITZ signals received.
+ long baseElapsedRealtimeMillis = mFakeDeviceState.elapsedRealtimeMillis();
+ NitzData baseNitzData = scenario.createNitzData();
+ int baseAgeMillis = 20000;
+ NitzSignal baseNitzSignal =
+ new NitzSignal(baseElapsedRealtimeMillis, baseNitzData, baseAgeMillis);
+
+ // Two identical signals: no spacing so the new signal should not be processed.
+ assertFalse(triPredicate.mustProcessNitzSignal(baseNitzSignal, baseNitzSignal));
+
+ // Two signals not spaced apart enough: the new signal should not be processed.
+ // The age is changed to prove it doesn't affect this check.
+ {
+ int elapsedRealtimeAdjustment = nitzSpacingThreshold - 1;
+ int utcAdjustment = 0;
+ long ageAdjustment = 10000;
+ NitzSignal newSignal = createAdjustedNitzSignal(
+ baseNitzSignal, elapsedRealtimeAdjustment, utcAdjustment, ageAdjustment);
+ assertFalse(triPredicate.mustProcessNitzSignal(baseNitzSignal, newSignal));
+ }
+
+ // Two signals not spaced apart enough: the new signal should not be processed.
+ // The age is changed to prove it doesn't affect this check.
+ {
+ int elapsedRealtimeAdjustment = nitzSpacingThreshold - 1;
+ int utcAdjustment = 0;
+ long ageAdjustment = -10000;
+ NitzSignal newSignal = createAdjustedNitzSignal(
+ baseNitzSignal, elapsedRealtimeAdjustment, utcAdjustment, ageAdjustment);
+ assertFalse(triPredicate.mustProcessNitzSignal(baseNitzSignal, newSignal));
+ }
+
+ // Two signals spaced far enough apart: the new signal should be processed.
+ {
+ int elapsedRealtimeAdjustment = nitzSpacingThreshold + 1;
+ int utcAdjustment = 0;
+ long ageAdjustment = 10000;
+ NitzSignal newSignal = createAdjustedNitzSignal(
+ baseNitzSignal, elapsedRealtimeAdjustment, utcAdjustment, ageAdjustment);
+ assertTrue(triPredicate.mustProcessNitzSignal(baseNitzSignal, newSignal));
+ }
+
+ // Two signals spaced far enough apart: the new signal should be processed.
+ {
+ int elapsedRealtimeAdjustment = nitzSpacingThreshold + 1;
+ int utcAdjustment = 0;
+ long ageAdjustment = -10000;
+ NitzSignal newSignal = createAdjustedNitzSignal(
+ baseNitzSignal, elapsedRealtimeAdjustment, utcAdjustment, ageAdjustment);
+ assertTrue(triPredicate.mustProcessNitzSignal(baseNitzSignal, newSignal));
}
}
@@ -208,20 +299,23 @@
public void testTrivalentPredicate_rateLimitCheck_offsetDifference() {
Scenario scenario = UNIQUE_US_ZONE_SCENARIO1;
int nitzSpacingThreshold = mFakeDeviceState.getNitzUpdateSpacingMillis();
- NitzData baseNitzData = scenario.createNitzData();
TrivalentPredicate triPredicate = createRateLimitCheck(mFakeDeviceState);
- long baseElapsedRealtimeMillis = mFakeDeviceState.elapsedRealtime();
- TimestampedValue<NitzData> baseSignal =
- new TimestampedValue<>(baseElapsedRealtimeMillis, baseNitzData);
+ long baseElapsedRealtimeMillis = mFakeDeviceState.elapsedRealtimeMillis();
+ NitzData baseNitzData = scenario.createNitzData();
+ long baseAgeMillis = 0;
+ NitzSignal baseNitzSignal = new NitzSignal(
+ baseElapsedRealtimeMillis, baseNitzData, baseAgeMillis);
- // Create a new NitzSignal that should be filtered.
- int elapsedTimeIncrement = nitzSpacingThreshold - 1;
- TimestampedValue<NitzData> intermediateNitzSignal =
- createIncrementedNitzSignal(baseSignal, elapsedTimeIncrement);
- NitzData intermediateNitzData = intermediateNitzSignal.getValue();
- assertFalse(triPredicate.mustProcessNitzSignal(baseSignal, intermediateNitzSignal));
+ // Create a new NitzSignal that would normally be filtered.
+ int timeAdjustment = nitzSpacingThreshold - 1;
+ long ageAdjustment = 0;
+ NitzSignal intermediateNitzSignal = createAdjustedNitzSignal(
+ baseNitzSignal, timeAdjustment, timeAdjustment, ageAdjustment);
+ NitzData intermediateNitzData = intermediateNitzSignal.getNitzData();
+ assertAgeAdjustedUtcTimeIsIdentical(baseNitzSignal, intermediateNitzSignal);
+ assertFalse(triPredicate.mustProcessNitzSignal(baseNitzSignal, intermediateNitzSignal));
// Two signals spaced apart so that the second would be filtered, but they contain different
// offset information so should be detected as "different" and processed.
@@ -232,102 +326,181 @@
intermediateNitzData.getDstAdjustmentMillis(),
intermediateNitzData.getCurrentTimeInMillis(),
intermediateNitzData.getEmulatorHostTimeZone());
- TimestampedValue<NitzData> differentOffsetSignal = new TimestampedValue<>(
- baseSignal.getReferenceTimeMillis() + elapsedTimeIncrement,
- differentOffsetNitzData);
- assertTrue(triPredicate.mustProcessNitzSignal(baseSignal, differentOffsetSignal));
+ NitzSignal differentOffsetSignal = new NitzSignal(
+ baseNitzSignal.getReceiptElapsedRealtimeMillis() + timeAdjustment,
+ differentOffsetNitzData,
+ baseNitzSignal.getAgeMillis());
+ assertAgeAdjustedUtcTimeIsIdentical(baseNitzSignal, differentOffsetSignal);
+ assertTrue(triPredicate.mustProcessNitzSignal(baseNitzSignal, differentOffsetSignal));
}
}
@Test
- public void testTrivalentPredicate_rateLimitCheck_utcTimeDifferences() {
+ public void testTrivalentPredicate_rateLimitCheck_utcTimeDifferences_withZeroAge() {
Scenario scenario = UNIQUE_US_ZONE_SCENARIO1;
- int nitzSpacingThreshold = mFakeDeviceState.getNitzUpdateSpacingMillis();
+ // Change the other setting that can affect the predicate behavior so it is not a factor in
+ // the test.
+ mFakeDeviceState.setNitzUpdateSpacingMillis(Integer.MAX_VALUE);
int nitzUtcDiffThreshold = mFakeDeviceState.getNitzUpdateDiffMillis();
- NitzData baseNitzData = scenario.createNitzData();
TrivalentPredicate triPredicate = createRateLimitCheck(mFakeDeviceState);
- long baseElapsedRealtimeMillis = mFakeDeviceState.elapsedRealtime();
- TimestampedValue<NitzData> baseSignal =
- new TimestampedValue<>(baseElapsedRealtimeMillis, baseNitzData);
+ long baseElapsedRealtimeMillis = mFakeDeviceState.elapsedRealtimeMillis();
+ NitzData baseNitzData = scenario.createNitzData();
+ int baseAgeMillis = 0;
+ NitzSignal baseNitzSignal =
+ new NitzSignal(baseElapsedRealtimeMillis, baseNitzData, baseAgeMillis);
- // Create a new NitzSignal that should be filtered.
- int elapsedTimeIncrement = nitzSpacingThreshold - 1;
- TimestampedValue<NitzData> intermediateSignal =
- createIncrementedNitzSignal(baseSignal, elapsedTimeIncrement);
- NitzData intermediateNitzData = intermediateSignal.getValue();
- assertFalse(triPredicate.mustProcessNitzSignal(baseSignal, intermediateSignal));
-
- // Two signals spaced apart so that the second would normally be filtered and it contains
- // a UTC time that is not sufficiently different.
+ // Two signals spaced contain UTC times that are not sufficiently different and so should be
+ // filtered.
{
- NitzData incrementedUtcTimeNitzData = NitzData.createForTests(
- intermediateNitzData.getLocalOffsetMillis(),
- intermediateNitzData.getDstAdjustmentMillis(),
- intermediateNitzData.getCurrentTimeInMillis() + nitzUtcDiffThreshold - 1,
- intermediateNitzData.getEmulatorHostTimeZone());
-
- TimestampedValue<NitzData> incrementedNitzSignal = new TimestampedValue<>(
- intermediateSignal.getReferenceTimeMillis(), incrementedUtcTimeNitzData);
- assertFalse(triPredicate.mustProcessNitzSignal(baseSignal, incrementedNitzSignal));
+ int elapsedRealtimeAdjustment = 0;
+ int utcAdjustment = nitzUtcDiffThreshold - 1;
+ long ageAdjustment = 0;
+ NitzSignal nitzSignal = createAdjustedNitzSignal(baseNitzSignal,
+ elapsedRealtimeAdjustment, utcAdjustment, ageAdjustment);
+ assertFalse(triPredicate.mustProcessNitzSignal(baseNitzSignal, nitzSignal));
}
- // Two signals spaced apart so that the second would normally be filtered but it contains
- // a UTC time that is sufficiently different.
+ // Two signals spaced contain UTC times that are not sufficiently different and so should be
+ // filtered.
{
- NitzData incrementedUtcTimeNitzData = NitzData.createForTests(
- intermediateNitzData.getLocalOffsetMillis(),
- intermediateNitzData.getDstAdjustmentMillis(),
- intermediateNitzData.getCurrentTimeInMillis() + nitzUtcDiffThreshold + 1,
- intermediateNitzData.getEmulatorHostTimeZone());
-
- TimestampedValue<NitzData> incrementedNitzSignal = new TimestampedValue<>(
- intermediateSignal.getReferenceTimeMillis(), incrementedUtcTimeNitzData);
- assertTrue(triPredicate.mustProcessNitzSignal(baseSignal, incrementedNitzSignal));
+ int elapsedRealtimeAdjustment = 0;
+ int utcAdjustment = -(nitzUtcDiffThreshold - 1);
+ long ageAdjustment = 0;
+ NitzSignal nitzSignal = createAdjustedNitzSignal(baseNitzSignal,
+ elapsedRealtimeAdjustment, utcAdjustment, ageAdjustment);
+ assertFalse(triPredicate.mustProcessNitzSignal(baseNitzSignal, nitzSignal));
}
- // Two signals spaced apart so that the second would normally be filtered and it contains
- // a UTC time that is not sufficiently different.
+ // Two signals spaced contain UTC times that are sufficiently different and so should not be
+ // filtered.
{
- NitzData decrementedUtcTimeNitzData = NitzData.createForTests(
- intermediateNitzData.getLocalOffsetMillis(),
- intermediateNitzData.getDstAdjustmentMillis(),
- intermediateNitzData.getCurrentTimeInMillis() - nitzUtcDiffThreshold + 1,
- intermediateNitzData.getEmulatorHostTimeZone());
-
- TimestampedValue<NitzData> decrementedNitzSignal = new TimestampedValue<>(
- intermediateSignal.getReferenceTimeMillis(), decrementedUtcTimeNitzData);
- assertFalse(triPredicate.mustProcessNitzSignal(baseSignal, decrementedNitzSignal));
+ int elapsedRealtimeAdjustment = 0;
+ int utcAdjustment = nitzUtcDiffThreshold + 1;
+ long ageAdjustment = 0;
+ NitzSignal nitzSignal = createAdjustedNitzSignal(baseNitzSignal,
+ elapsedRealtimeAdjustment, utcAdjustment, ageAdjustment);
+ assertTrue(triPredicate.mustProcessNitzSignal(baseNitzSignal, nitzSignal));
}
- // Two signals spaced apart so that the second would normally be filtered but it contains
- // a UTC time that is sufficiently different.
+ // Two signals spaced contain UTC times that are sufficiently different and so should not be
+ // filtered.
{
- NitzData decrementedUtcTimeNitzData = NitzData.createForTests(
- intermediateNitzData.getLocalOffsetMillis(),
- intermediateNitzData.getDstAdjustmentMillis(),
- intermediateNitzData.getCurrentTimeInMillis() + nitzUtcDiffThreshold + 1,
- intermediateNitzData.getEmulatorHostTimeZone());
+ int elapsedRealtimeAdjustment = 0;
+ int utcAdjustment = -(nitzUtcDiffThreshold + 1);
+ long ageAdjustment = 0;
+ NitzSignal nitzSignal = createAdjustedNitzSignal(baseNitzSignal,
+ elapsedRealtimeAdjustment, utcAdjustment, ageAdjustment);
+ assertTrue(triPredicate.mustProcessNitzSignal(baseNitzSignal, nitzSignal));
+ }
+ }
- TimestampedValue<NitzData> decrementedNitzSignal = new TimestampedValue<>(
- intermediateSignal.getReferenceTimeMillis(), decrementedUtcTimeNitzData);
- assertTrue(triPredicate.mustProcessNitzSignal(baseSignal, decrementedNitzSignal));
+ @Test
+ public void testTrivalentPredicate_rateLimitCheck_utcTimeDifferences_withAge() {
+ Scenario scenario = UNIQUE_US_ZONE_SCENARIO1;
+ // Change the other setting that can affect the predicate behavior so it is not a factor in
+ // the test.
+ mFakeDeviceState.setNitzUpdateSpacingMillis(Integer.MAX_VALUE);
+ int nitzUtcDiffThreshold = mFakeDeviceState.getNitzUpdateDiffMillis();
+
+ TrivalentPredicate triPredicate = createRateLimitCheck(mFakeDeviceState);
+
+ long baseElapsedRealtimeMillis = mFakeDeviceState.elapsedRealtimeMillis();
+ NitzData baseNitzData = scenario.createNitzData();
+ int baseAgeMillis = 20000;
+ NitzSignal baseNitzSignal =
+ new NitzSignal(baseElapsedRealtimeMillis, baseNitzData, baseAgeMillis);
+
+ // This is another NitzSignal that represents the same time as baseNitzSignal, but it has
+ // been cached by the modem for a different amount of time, so has different values even
+ // though it encodes for the same UTC time. Used to construct test signals below.
+ int intermediateSignalAgeAdjustment = -10000;
+ int intermediateUtcAdjustment = 0;
+ NitzSignal intermediateNitzSignal = createAdjustedNitzSignal(baseNitzSignal,
+ intermediateSignalAgeAdjustment, intermediateUtcAdjustment,
+ intermediateSignalAgeAdjustment);
+ assertAgeAdjustedUtcTimeIsIdentical(baseNitzSignal, intermediateNitzSignal);
+
+ // Two signals spaced contain UTC times that are not sufficiently different and so should be
+ // filtered.
+ {
+ int elapsedRealtimeAdjustment = 0;
+ int utcAdjustment = nitzUtcDiffThreshold - 1;
+ long ageAdjustment = 0;
+ NitzSignal nitzSignal = createAdjustedNitzSignal(intermediateNitzSignal,
+ elapsedRealtimeAdjustment, utcAdjustment, ageAdjustment);
+ assertFalse(triPredicate.mustProcessNitzSignal(baseNitzSignal, nitzSignal));
+ }
+
+ // Two signals spaced contain UTC times that are not sufficiently different and so should be
+ // filtered.
+ {
+ int elapsedRealtimeAdjustment = 0;
+ int utcAdjustment = -(nitzUtcDiffThreshold - 1);
+ long ageAdjustment = 0;
+ NitzSignal nitzSignal = createAdjustedNitzSignal(intermediateNitzSignal,
+ elapsedRealtimeAdjustment, utcAdjustment, ageAdjustment);
+ assertFalse(triPredicate.mustProcessNitzSignal(baseNitzSignal, nitzSignal));
+ }
+
+ // Two signals spaced contain UTC times that are sufficiently different and so should not be
+ // filtered.
+ {
+ int elapsedRealtimeAdjustment = 0;
+ int utcAdjustment = nitzUtcDiffThreshold + 1;
+ long ageAdjustment = 0;
+ NitzSignal nitzSignal = createAdjustedNitzSignal(intermediateNitzSignal,
+ elapsedRealtimeAdjustment, utcAdjustment, ageAdjustment);
+ assertTrue(triPredicate.mustProcessNitzSignal(baseNitzSignal, nitzSignal));
+ }
+
+ // Two signals spaced contain UTC times that are sufficiently different and so should not be
+ // filtered.
+ {
+ int elapsedRealtimeAdjustment = 0;
+ int utcAdjustment = -(nitzUtcDiffThreshold + 1);
+ long ageAdjustment = 0;
+ NitzSignal nitzSignal = createAdjustedNitzSignal(intermediateNitzSignal,
+ elapsedRealtimeAdjustment, utcAdjustment, ageAdjustment);
+ assertTrue(triPredicate.mustProcessNitzSignal(baseNitzSignal, nitzSignal));
}
}
/**
- * Creates an NITZ signal based on the the supplied signal but with all the fields related to
- * elapsed time incremented by the specified number of milliseconds.
+ * Creates an NITZ signal based on the supplied signal but with all the fields associated with
+ * the time (receipt time, UTC and age) adjusted by the specified amounts.
*/
- private static TimestampedValue<NitzData> createIncrementedNitzSignal(
- TimestampedValue<NitzData> baseSignal, int incrementMillis) {
- NitzData baseData = baseSignal.getValue();
- return new TimestampedValue<>(baseSignal.getReferenceTimeMillis() + incrementMillis,
- NitzData.createForTests(
- baseData.getLocalOffsetMillis(),
- baseData.getDstAdjustmentMillis(),
- baseData.getCurrentTimeInMillis() + incrementMillis,
- baseData.getEmulatorHostTimeZone()));
+ private static NitzSignal createAdjustedNitzSignal(
+ NitzSignal baseNitzSignal, int elapsedRealtimeMillisAdjustment, int utcMillisAdjustment,
+ long ageMillisAdjustment) {
+ long adjustedReceiptElapsedMillis =
+ baseNitzSignal.getReceiptElapsedRealtimeMillis() + elapsedRealtimeMillisAdjustment;
+ NitzData adjustedNitzData =
+ createAdjustedNitzData(baseNitzSignal.getNitzData(), utcMillisAdjustment);
+ long adjustedAgeMillis = baseNitzSignal.getAgeMillis() + ageMillisAdjustment;
+ return new NitzSignal(adjustedReceiptElapsedMillis, adjustedNitzData, adjustedAgeMillis);
+ }
+
+ /** Creates a new NitzData by adjusting the UTC time in the supplied NitzData */
+ private static NitzData createAdjustedNitzData(NitzData baseData, int utcMillisAdjustment) {
+ return NitzData.createForTests(
+ baseData.getLocalOffsetMillis(),
+ baseData.getDstAdjustmentMillis(),
+ baseData.getCurrentTimeInMillis() + utcMillisAdjustment,
+ baseData.getEmulatorHostTimeZone());
+ }
+
+ /**
+ * Used during tests to confirm that two NitzSignal test objects represent the same UTC time,
+ * even though their receipt times and ages may differ.
+ */
+ private static void assertAgeAdjustedUtcTimeIsIdentical(
+ NitzSignal signal1, NitzSignal signal2) {
+ long referenceTimeDifference = signal2.getAgeAdjustedElapsedRealtimeMillis()
+ - signal1.getAgeAdjustedElapsedRealtimeMillis();
+ long utcTimeDifference = signal2.getNitzData().getCurrentTimeInMillis()
+ - signal1.getNitzData().getCurrentTimeInMillis();
+ assertEquals(referenceTimeDifference, utcTimeDifference);
}
}
diff --git a/tests/telephonytests/src/com/android/internal/telephony/nitz/NitzStateMachineImplTest.java b/tests/telephonytests/src/com/android/internal/telephony/nitz/NitzStateMachineImplTest.java
index c433bd0..3f2e4d5 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/nitz/NitzStateMachineImplTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/nitz/NitzStateMachineImplTest.java
@@ -19,6 +19,7 @@
import static android.app.timezonedetector.TelephonyTimeZoneSuggestion.MATCH_TYPE_TEST_NETWORK_OFFSET_ONLY;
import static android.app.timezonedetector.TelephonyTimeZoneSuggestion.QUALITY_MULTIPLE_ZONES_WITH_SAME_OFFSET;
+import static com.android.internal.telephony.nitz.NitzStateMachineTestSupport.ARBITRARY_AGE;
import static com.android.internal.telephony.nitz.NitzStateMachineTestSupport.ARBITRARY_SYSTEM_CLOCK_TIME;
import static com.android.internal.telephony.nitz.NitzStateMachineTestSupport.UNIQUE_US_ZONE_SCENARIO1;
import static com.android.internal.telephony.nitz.NitzStateMachineTestSupport.UNITED_KINGDOM_SCENARIO;
@@ -35,10 +36,9 @@
import android.app.timedetector.TelephonyTimeSuggestion;
import android.app.timezonedetector.TelephonyTimeZoneSuggestion;
-import android.os.TimestampedValue;
import com.android.internal.telephony.IndentingPrintWriter;
-import com.android.internal.telephony.NitzData;
+import com.android.internal.telephony.NitzSignal;
import com.android.internal.telephony.TelephonyTest;
import com.android.internal.telephony.nitz.NitzStateMachineImpl.NitzSignalInputFilterPredicate;
import com.android.internal.telephony.nitz.NitzStateMachineTestSupport.FakeDeviceState;
@@ -105,8 +105,8 @@
public void test_countryThenNitz() throws Exception {
Scenario scenario = UNIQUE_US_ZONE_SCENARIO1;
String networkCountryIsoCode = scenario.getNetworkCountryIsoCode();
- TimestampedValue<NitzData> nitzSignal =
- scenario.createNitzSignal(mFakeDeviceState.elapsedRealtime());
+ NitzSignal nitzSignal =
+ scenario.createNitzSignal(mFakeDeviceState.elapsedRealtimeMillis(), ARBITRARY_AGE);
// Capture expected results from the real suggester and confirm we can tell the difference
// between them.
@@ -140,14 +140,14 @@
expectedTimeSuggestion, expectedTimeZoneSuggestion2);
// Check NitzStateMachine exposed state.
- assertEquals(nitzSignal.getValue(), mNitzStateMachineImpl.getCachedNitzData());
+ assertEquals(nitzSignal.getNitzData(), mNitzStateMachineImpl.getCachedNitzData());
}
@Test
public void test_nitzThenCountry() throws Exception {
Scenario scenario = UNIQUE_US_ZONE_SCENARIO1;
- TimestampedValue<NitzData> nitzSignal =
- scenario.createNitzSignal(mFakeDeviceState.elapsedRealtime());
+ NitzSignal nitzSignal =
+ scenario.createNitzSignal(mFakeDeviceState.elapsedRealtimeMillis(), ARBITRARY_AGE);
String networkCountryIsoCode = scenario.getNetworkCountryIsoCode();
@@ -175,21 +175,21 @@
expectedTimeSuggestion, expectedTimeZoneSuggestion1);
// Check NitzStateMachine exposed state.
- assertEquals(nitzSignal.getValue(), mNitzStateMachineImpl.getCachedNitzData());
+ assertEquals(nitzSignal.getNitzData(), mNitzStateMachineImpl.getCachedNitzData());
// Simulate country being known and verify the behavior.
script.countryReceived(networkCountryIsoCode)
.verifyOnlyTimeZoneWasSuggestedAndReset(expectedTimeZoneSuggestion2);
// Check NitzStateMachine exposed state.
- assertEquals(nitzSignal.getValue(), mNitzStateMachineImpl.getCachedNitzData());
+ assertEquals(nitzSignal.getNitzData(), mNitzStateMachineImpl.getCachedNitzData());
}
@Test
public void test_emptyCountryString_countryReceivedFirst() throws Exception {
Scenario scenario = UNIQUE_US_ZONE_SCENARIO1;
- TimestampedValue<NitzData> nitzSignal =
- scenario.createNitzSignal(mFakeDeviceState.elapsedRealtime());
+ NitzSignal nitzSignal =
+ scenario.createNitzSignal(mFakeDeviceState.elapsedRealtimeMillis(), ARBITRARY_AGE);
Script script = new Script()
.initializeSystemClock(ARBITRARY_SYSTEM_CLOCK_TIME)
@@ -224,14 +224,14 @@
expectedTimeSuggestion, expectedTimeZoneSuggestion);
// Check NitzStateMachine exposed state.
- assertEquals(nitzSignal.getValue(), mNitzStateMachineImpl.getCachedNitzData());
+ assertEquals(nitzSignal.getNitzData(), mNitzStateMachineImpl.getCachedNitzData());
}
@Test
public void test_emptyCountryStringUsTime_nitzReceivedFirst() throws Exception {
Scenario scenario = UNIQUE_US_ZONE_SCENARIO1;
- TimestampedValue<NitzData> nitzSignal =
- scenario.createNitzSignal(mFakeDeviceState.elapsedRealtime());
+ NitzSignal nitzSignal =
+ scenario.createNitzSignal(mFakeDeviceState.elapsedRealtimeMillis(), ARBITRARY_AGE);
Script script = new Script()
.initializeSystemClock(ARBITRARY_SYSTEM_CLOCK_TIME)
@@ -248,7 +248,7 @@
expectedTimeSuggestion, EMPTY_TIME_ZONE_SUGGESTION);
// Check NitzStateMachine exposed state.
- assertEquals(nitzSignal.getValue(), mNitzStateMachineImpl.getCachedNitzData());
+ assertEquals(nitzSignal.getNitzData(), mNitzStateMachineImpl.getCachedNitzData());
// Simulate an empty country being set.
script.countryReceived("");
@@ -267,7 +267,7 @@
script.verifyOnlyTimeZoneWasSuggestedAndReset(expectedTimeZoneSuggestion);
// Check NitzStateMachine exposed state.
- assertEquals(nitzSignal.getValue(), mNitzStateMachineImpl.getCachedNitzData());
+ assertEquals(nitzSignal.getNitzData(), mNitzStateMachineImpl.getCachedNitzData());
}
@Test
@@ -281,8 +281,8 @@
// Pre-flight: Simulate a device receiving signals that allow it to detect time and time
// zone.
- TimestampedValue<NitzData> preFlightNitzSignal =
- scenario.createNitzSignal(mFakeDeviceState.elapsedRealtime());
+ NitzSignal preFlightNitzSignal =
+ scenario.createNitzSignal(mFakeDeviceState.elapsedRealtimeMillis(), ARBITRARY_AGE);
TelephonyTimeSuggestion expectedPreFlightTimeSuggestion =
createTimeSuggestionFromNitzSignal(SLOT_INDEX, preFlightNitzSignal);
String preFlightCountryIsoCode = scenario.getNetworkCountryIsoCode();
@@ -299,7 +299,7 @@
expectedPreFlightTimeSuggestion, expectedPreFlightTimeZoneSuggestion);
// Check state that NitzStateMachine must expose.
- assertEquals(preFlightNitzSignal.getValue(), mNitzStateMachineImpl.getCachedNitzData());
+ assertEquals(preFlightNitzSignal.getNitzData(), mNitzStateMachineImpl.getCachedNitzData());
// Boarded flight: Airplane mode turned on / time zone detection still enabled.
// The NitzStateMachine must lose all state and stop having an opinion about time zone.
@@ -347,8 +347,8 @@
// Simulate the device receiving NITZ signal and country again after the flight. Now the
// NitzStateMachine should be opinionated again.
- TimestampedValue<NitzData> postFlightNitzSignal =
- scenario.createNitzSignal(mFakeDeviceState.elapsedRealtime());
+ NitzSignal postFlightNitzSignal =
+ scenario.createNitzSignal(mFakeDeviceState.elapsedRealtimeMillis(), ARBITRARY_AGE);
String postFlightCountryCode = scenario.getNetworkCountryIsoCode();
script.countryReceived(postFlightCountryCode)
.nitzReceived(postFlightNitzSignal);
@@ -363,7 +363,7 @@
expectedPostFlightTimeSuggestion, expectedPostFlightTimeZoneSuggestion);
// Check state that NitzStateMachine must expose.
- assertEquals(postFlightNitzSignal.getValue(), mNitzStateMachineImpl.getCachedNitzData());
+ assertEquals(postFlightNitzSignal.getNitzData(), mNitzStateMachineImpl.getCachedNitzData());
}
/**
@@ -380,8 +380,8 @@
.networkAvailable();
// Simulate a device receiving signals that allow it to detect time and time zone.
- TimestampedValue<NitzData> initialNitzSignal =
- scenario.createNitzSignal(mFakeDeviceState.elapsedRealtime());
+ NitzSignal initialNitzSignal =
+ scenario.createNitzSignal(mFakeDeviceState.elapsedRealtimeMillis(), ARBITRARY_AGE);
TelephonyTimeSuggestion expectedInitialTimeSuggestion =
createTimeSuggestionFromNitzSignal(SLOT_INDEX, initialNitzSignal);
@@ -397,7 +397,7 @@
expectedInitialTimeSuggestion, expectedInitialTimeZoneSuggestion);
// Check state that NitzStateMachine must expose.
- assertEquals(initialNitzSignal.getValue(), mNitzStateMachineImpl.getCachedNitzData());
+ assertEquals(initialNitzSignal.getNitzData(), mNitzStateMachineImpl.getCachedNitzData());
// Simulate the passage of time and update the device realtime clock.
scenario.incrementTime(timeStepMillis);
@@ -433,8 +433,8 @@
// Simulate the device receiving NITZ signal again. Now the NitzStateMachine should be
// opinionated again.
- TimestampedValue<NitzData> finalNitzSignal =
- scenario.createNitzSignal(mFakeDeviceState.elapsedRealtime());
+ NitzSignal finalNitzSignal =
+ scenario.createNitzSignal(mFakeDeviceState.elapsedRealtimeMillis(), ARBITRARY_AGE);
script.nitzReceived(finalNitzSignal);
// Verify the state machine did the right thing.
@@ -447,14 +447,14 @@
expectedFinalTimeSuggestion, expectedFinalTimeZoneSuggestion);
// Check state that NitzStateMachine must expose.
- assertEquals(finalNitzSignal.getValue(), mNitzStateMachineImpl.getCachedNitzData());
+ assertEquals(finalNitzSignal.getNitzData(), mNitzStateMachineImpl.getCachedNitzData());
}
@Test
public void test_countryUnavailableClearsTimeZoneSuggestion() throws Exception {
Scenario scenario = UNIQUE_US_ZONE_SCENARIO1;
- TimestampedValue<NitzData> nitzSignal =
- scenario.createNitzSignal(mFakeDeviceState.elapsedRealtime());
+ NitzSignal nitzSignal =
+ scenario.createNitzSignal(mFakeDeviceState.elapsedRealtimeMillis(), ARBITRARY_AGE);
Script script = new Script()
.initializeSystemClock(ARBITRARY_SYSTEM_CLOCK_TIME)
@@ -478,7 +478,7 @@
expectedTimeSuggestion, expectedTimeZoneSuggestion2);
// Check state that NitzStateMachine must expose.
- assertEquals(nitzSignal.getValue(), mNitzStateMachineImpl.getCachedNitzData());
+ assertEquals(nitzSignal.getNitzData(), mNitzStateMachineImpl.getCachedNitzData());
// Simulate the country becoming unavailable and verify the state machine does the right
// thing.
@@ -489,7 +489,7 @@
script.verifyOnlyTimeZoneWasSuggestedAndReset(expectedTimeZoneSuggestion3);
// Check state that NitzStateMachine must expose.
- assertEquals(nitzSignal.getValue(), mNitzStateMachineImpl.getCachedNitzData());
+ assertEquals(nitzSignal.getNitzData(), mNitzStateMachineImpl.getCachedNitzData());
}
/**
@@ -524,7 +524,7 @@
return this;
}
- Script nitzReceived(TimestampedValue<NitzData> nitzSignal) {
+ Script nitzReceived(NitzSignal nitzSignal) {
mNitzStateMachineImpl.handleNitzReceived(nitzSignal);
return this;
}
diff --git a/tests/telephonytests/src/com/android/internal/telephony/nitz/NitzStateMachineTestSupport.java b/tests/telephonytests/src/com/android/internal/telephony/nitz/NitzStateMachineTestSupport.java
index ed1c98b..6458517 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/nitz/NitzStateMachineTestSupport.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/nitz/NitzStateMachineTestSupport.java
@@ -23,9 +23,9 @@
import android.icu.util.Calendar;
import android.icu.util.GregorianCalendar;
import android.icu.util.TimeZone;
-import android.os.TimestampedValue;
import com.android.internal.telephony.NitzData;
+import com.android.internal.telephony.NitzSignal;
import com.android.internal.telephony.NitzStateMachine;
import com.android.internal.telephony.NitzStateMachine.DeviceState;
@@ -34,9 +34,12 @@
*/
final class NitzStateMachineTestSupport {
+ /** Used to indicate that a NitzSignal ageMillis is unimportant for the test. */
+ static final int ARBITRARY_AGE = 54321;
+
// Values used to when initializing device state but where the value isn't important.
static final long ARBITRARY_SYSTEM_CLOCK_TIME = createUtcTime(1977, 1, 1, 12, 0, 0);
- static final long ARBITRARY_REALTIME_MILLIS = 123456789L;
+ static final long ARBITRARY_ELAPSED_REALTIME = 123456789L;
static final String ARBITRARY_DEBUG_INFO = "Test debug info";
// A country with a single zone : the zone can be guessed from the country.
@@ -120,9 +123,11 @@
mNetworkCountryIsoCode = countryIsoCode;
}
- /** Creates an NITZ signal to match the scenario. */
- TimestampedValue<NitzData> createNitzSignal(long elapsedRealtimeClock) {
- return new TimestampedValue<>(elapsedRealtimeClock, createNitzData());
+ /**
+ * Creates an NITZ signal to match the scenario with the specified receipt / age properties.
+ */
+ NitzSignal createNitzSignal(long receiptElapsedMillis, long ageMillis) {
+ return new NitzSignal(receiptElapsedMillis, createNitzData(), ageMillis);
}
/** Creates an NITZ signal to match the scenario. */
@@ -214,7 +219,7 @@
ignoreNitz = false;
nitzUpdateDiffMillis = 2000;
nitzUpdateSpacingMillis = 1000 * 60 * 10;
- elapsedRealtime = ARBITRARY_REALTIME_MILLIS;
+ elapsedRealtime = ARBITRARY_ELAPSED_REALTIME;
}
@Override
@@ -222,18 +227,26 @@
return nitzUpdateSpacingMillis;
}
+ public void setNitzUpdateSpacingMillis(int nitzUpdateSpacingMillis) {
+ this.nitzUpdateSpacingMillis = nitzUpdateSpacingMillis;
+ }
+
@Override
public int getNitzUpdateDiffMillis() {
return nitzUpdateDiffMillis;
}
+ public void setNitzUpdateDiffMillis(int nitzUpdateDiffMillis) {
+ this.nitzUpdateDiffMillis = nitzUpdateDiffMillis;
+ }
+
@Override
public boolean getIgnoreNitz() {
return ignoreNitz;
}
@Override
- public long elapsedRealtime() {
+ public long elapsedRealtimeMillis() {
return elapsedRealtime;
}
@@ -275,20 +288,13 @@
}
static TelephonyTimeSuggestion createTimeSuggestionFromNitzSignal(
- int slotIndex, TimestampedValue<NitzData> nitzSignal) {
+ int slotIndex, NitzSignal nitzSignal) {
return new TelephonyTimeSuggestion.Builder(slotIndex)
- .setUtcTime(createTimeSignalFromNitzSignal(nitzSignal))
+ .setUtcTime(nitzSignal.createTimeSignal())
.addDebugInfo("Test")
.build();
}
- private static TimestampedValue<Long> createTimeSignalFromNitzSignal(
- TimestampedValue<NitzData> nitzSignal) {
- return new TimestampedValue<>(
- nitzSignal.getReferenceTimeMillis(),
- nitzSignal.getValue().getCurrentTimeInMillis());
- }
-
private static TimeZone zone(String zoneId) {
TimeZone timeZone = TimeZone.getFrozenTimeZone(zoneId);
if (timeZone.getID().equals(TimeZone.UNKNOWN_ZONE_ID)) {
diff --git a/tests/telephonytests/src/com/android/internal/telephony/nitz/TimeZoneSuggesterImplTest.java b/tests/telephonytests/src/com/android/internal/telephony/nitz/TimeZoneSuggesterImplTest.java
index 708d3de..5d59426 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/nitz/TimeZoneSuggesterImplTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/nitz/TimeZoneSuggesterImplTest.java
@@ -24,7 +24,8 @@
import static android.app.timezonedetector.TelephonyTimeZoneSuggestion.QUALITY_MULTIPLE_ZONES_WITH_SAME_OFFSET;
import static android.app.timezonedetector.TelephonyTimeZoneSuggestion.QUALITY_SINGLE_ZONE;
-import static com.android.internal.telephony.nitz.NitzStateMachineTestSupport.ARBITRARY_REALTIME_MILLIS;
+import static com.android.internal.telephony.nitz.NitzStateMachineTestSupport.ARBITRARY_AGE;
+import static com.android.internal.telephony.nitz.NitzStateMachineTestSupport.ARBITRARY_ELAPSED_REALTIME;
import static com.android.internal.telephony.nitz.NitzStateMachineTestSupport.CZECHIA_SCENARIO;
import static com.android.internal.telephony.nitz.NitzStateMachineTestSupport.NEW_ZEALAND_COUNTRY_DEFAULT_ZONE_ID;
import static com.android.internal.telephony.nitz.NitzStateMachineTestSupport.NEW_ZEALAND_DEFAULT_SCENARIO;
@@ -40,9 +41,9 @@
import static org.junit.Assert.assertTrue;
import android.app.timezonedetector.TelephonyTimeZoneSuggestion;
-import android.os.TimestampedValue;
import com.android.internal.telephony.NitzData;
+import com.android.internal.telephony.NitzSignal;
import com.android.internal.telephony.TelephonyTest;
import com.android.internal.telephony.nitz.NitzStateMachineImpl.TimeZoneSuggester;
import com.android.internal.telephony.nitz.NitzStateMachineTestSupport.FakeDeviceState;
@@ -95,8 +96,8 @@
@Test
public void test_emptySuggestionForNullCountryWithNitz() throws Exception {
Scenario scenario = UNIQUE_US_ZONE_SCENARIO1;
- TimestampedValue<NitzData> nitzSignal =
- scenario.createNitzSignal(ARBITRARY_REALTIME_MILLIS);
+ NitzSignal nitzSignal =
+ scenario.createNitzSignal(ARBITRARY_ELAPSED_REALTIME, ARBITRARY_AGE);
assertEquals(EMPTY_TIME_ZONE_SUGGESTION,
mTimeZoneSuggester.getTimeZoneSuggestion(
SLOT_INDEX, null /* countryIsoCode */, nitzSignal));
@@ -137,9 +138,10 @@
// NITZ with a "" country code is interpreted as a test network so only offset is used
// to get a match.
{
+ NitzSignal nitzSignal = scenario.createNitzSignal(
+ mFakeDeviceState.elapsedRealtimeMillis(), ARBITRARY_AGE);
TelephonyTimeZoneSuggestion actualSuggestion = mTimeZoneSuggester.getTimeZoneSuggestion(
- SLOT_INDEX, "" /* countryIsoCode */,
- scenario.createNitzSignal(mFakeDeviceState.elapsedRealtime()));
+ SLOT_INDEX, "" /* countryIsoCode */, nitzSignal);
assertEquals(SLOT_INDEX, actualSuggestion.getSlotIndex());
assertEquals(MATCH_TYPE_TEST_NETWORK_OFFSET_ONLY, actualSuggestion.getMatchType());
assertEquals(QUALITY_MULTIPLE_ZONES_WITH_SAME_OFFSET, actualSuggestion.getQuality());
@@ -147,9 +149,10 @@
// NITZ alone is not enough to get a result when the country is not available.
{
+ NitzSignal nitzSignal = scenario.createNitzSignal(
+ mFakeDeviceState.elapsedRealtimeMillis(), ARBITRARY_AGE);
TelephonyTimeZoneSuggestion actualSuggestion = mTimeZoneSuggester.getTimeZoneSuggestion(
- SLOT_INDEX, null /* countryIsoCode */,
- scenario.createNitzSignal(mFakeDeviceState.elapsedRealtime()));
+ SLOT_INDEX, null /* countryIsoCode */, nitzSignal);
assertEquals(EMPTY_TIME_ZONE_SUGGESTION, actualSuggestion);
}
@@ -161,9 +164,10 @@
.setMatchType(MATCH_TYPE_NETWORK_COUNTRY_AND_OFFSET)
.setQuality(QUALITY_SINGLE_ZONE)
.build();
+ NitzSignal nitzSignal = scenario.createNitzSignal(
+ mFakeDeviceState.elapsedRealtimeMillis(), ARBITRARY_AGE);
TelephonyTimeZoneSuggestion actualSuggestion = mTimeZoneSuggester.getTimeZoneSuggestion(
- SLOT_INDEX, scenario.getNetworkCountryIsoCode(),
- scenario.createNitzSignal(mFakeDeviceState.elapsedRealtime()));
+ SLOT_INDEX, scenario.getNetworkCountryIsoCode(), nitzSignal);
assertEquals(expectedTimeZoneSuggestion, actualSuggestion);
}
@@ -171,12 +175,11 @@
// since there are multiple zones to choose from.
{
// We use an NITZ from CZ to generate an NITZ signal with a bad offset.
- TimestampedValue<NitzData> badNitzSignal =
- CZECHIA_SCENARIO.createNitzSignal(mFakeDeviceState.elapsedRealtime());
+ NitzSignal badNitzSignal = CZECHIA_SCENARIO.createNitzSignal(
+ mFakeDeviceState.elapsedRealtimeMillis(), ARBITRARY_AGE);
TelephonyTimeZoneSuggestion expectedTimeZoneSuggestion = EMPTY_TIME_ZONE_SUGGESTION;
TelephonyTimeZoneSuggestion actualSuggestion = mTimeZoneSuggester.getTimeZoneSuggestion(
- SLOT_INDEX, scenario.getNetworkCountryIsoCode(),
- badNitzSignal);
+ SLOT_INDEX, scenario.getNetworkCountryIsoCode(), badNitzSignal);
assertEquals(expectedTimeZoneSuggestion, actualSuggestion);
}
}
@@ -209,9 +212,10 @@
// NITZ with a "" country code is interpreted as a test network so only offset is used
// to get a match.
{
+ NitzSignal nitzSignal = scenario.createNitzSignal(
+ mFakeDeviceState.elapsedRealtimeMillis(), ARBITRARY_AGE);
TelephonyTimeZoneSuggestion actualSuggestion = mTimeZoneSuggester.getTimeZoneSuggestion(
- SLOT_INDEX, "" /* countryIsoCode */,
- scenario.createNitzSignal(mFakeDeviceState.elapsedRealtime()));
+ SLOT_INDEX, "" /* countryIsoCode */, nitzSignal);
assertEquals(SLOT_INDEX, actualSuggestion.getSlotIndex());
assertEquals(MATCH_TYPE_TEST_NETWORK_OFFSET_ONLY, actualSuggestion.getMatchType());
assertEquals(QUALITY_MULTIPLE_ZONES_WITH_SAME_OFFSET, actualSuggestion.getQuality());
@@ -219,17 +223,19 @@
// NITZ alone is not enough to get a result when the country is not available.
{
+ NitzSignal nitzSignal = scenario.createNitzSignal(
+ mFakeDeviceState.elapsedRealtimeMillis(), ARBITRARY_AGE);
TelephonyTimeZoneSuggestion actualSuggestion = mTimeZoneSuggester.getTimeZoneSuggestion(
- SLOT_INDEX, null /* countryIsoCode */,
- scenario.createNitzSignal(mFakeDeviceState.elapsedRealtime()));
+ SLOT_INDEX, null /* countryIsoCode */, nitzSignal);
assertEquals(EMPTY_TIME_ZONE_SUGGESTION, actualSuggestion);
}
// Country + NITZ is not enough for a unique time zone detection result for this scenario.
{
+ NitzSignal nitzSignal = scenario.createNitzSignal(
+ mFakeDeviceState.elapsedRealtimeMillis(), ARBITRARY_AGE);
TelephonyTimeZoneSuggestion actualSuggestion = mTimeZoneSuggester.getTimeZoneSuggestion(
- SLOT_INDEX, scenario.getNetworkCountryIsoCode(),
- scenario.createNitzSignal(mFakeDeviceState.elapsedRealtime()));
+ SLOT_INDEX, scenario.getNetworkCountryIsoCode(), nitzSignal);
assertEquals(SLOT_INDEX, actualSuggestion.getSlotIndex());
assertEquals(MATCH_TYPE_NETWORK_COUNTRY_AND_OFFSET, actualSuggestion.getMatchType());
assertEquals(QUALITY_MULTIPLE_ZONES_WITH_SAME_OFFSET, actualSuggestion.getQuality());
@@ -241,12 +247,11 @@
// since there are multiple zones to choose from.
{
// We use an NITZ from CZ to generate an NITZ signal with a bad offset.
- TimestampedValue<NitzData> badNitzSignal =
- CZECHIA_SCENARIO.createNitzSignal(mFakeDeviceState.elapsedRealtime());
+ NitzSignal badNitzSignal = CZECHIA_SCENARIO.createNitzSignal(
+ mFakeDeviceState.elapsedRealtimeMillis(), ARBITRARY_AGE);
TelephonyTimeZoneSuggestion expectedTimeZoneSuggestion = EMPTY_TIME_ZONE_SUGGESTION;
TelephonyTimeZoneSuggestion actualSuggestion = mTimeZoneSuggester.getTimeZoneSuggestion(
- SLOT_INDEX, scenario.getNetworkCountryIsoCode(),
- badNitzSignal);
+ SLOT_INDEX, scenario.getNetworkCountryIsoCode(), badNitzSignal);
assertEquals(expectedTimeZoneSuggestion, actualSuggestion);
}
}
@@ -278,9 +283,10 @@
// NITZ with a "" country code is interpreted as a test network so only offset is used
// to get a match.
{
+ NitzSignal nitzSignal = scenario.createNitzSignal(
+ mFakeDeviceState.elapsedRealtimeMillis(), ARBITRARY_AGE);
TelephonyTimeZoneSuggestion actualSuggestion = mTimeZoneSuggester.getTimeZoneSuggestion(
- SLOT_INDEX, "" /* countryIsoCode */,
- scenario.createNitzSignal(mFakeDeviceState.elapsedRealtime()));
+ SLOT_INDEX, "" /* countryIsoCode */, nitzSignal);
assertEquals(SLOT_INDEX, actualSuggestion.getSlotIndex());
assertEquals(MATCH_TYPE_TEST_NETWORK_OFFSET_ONLY, actualSuggestion.getMatchType());
assertEquals(QUALITY_MULTIPLE_ZONES_WITH_SAME_OFFSET, actualSuggestion.getQuality());
@@ -289,9 +295,10 @@
// NITZ alone is not enough to get a result when the country is not available.
{
+ NitzSignal nitzSignal = scenario.createNitzSignal(
+ mFakeDeviceState.elapsedRealtimeMillis(), ARBITRARY_AGE);
TelephonyTimeZoneSuggestion actualSuggestion = mTimeZoneSuggester.getTimeZoneSuggestion(
- SLOT_INDEX, null /* countryIsoCode */,
- scenario.createNitzSignal(mFakeDeviceState.elapsedRealtime()));
+ SLOT_INDEX, null /* countryIsoCode */, nitzSignal);
assertEquals(EMPTY_TIME_ZONE_SUGGESTION, actualSuggestion);
}
@@ -304,9 +311,10 @@
.setQuality(QUALITY_SINGLE_ZONE)
.build();
+ NitzSignal nitzSignal = scenario.createNitzSignal(
+ mFakeDeviceState.elapsedRealtimeMillis(), ARBITRARY_AGE);
TelephonyTimeZoneSuggestion actualSuggestion = mTimeZoneSuggester.getTimeZoneSuggestion(
- SLOT_INDEX, scenario.getNetworkCountryIsoCode(),
- scenario.createNitzSignal(mFakeDeviceState.elapsedRealtime()));
+ SLOT_INDEX, scenario.getNetworkCountryIsoCode(), nitzSignal);
assertEquals(expectedTimeZoneSuggestion, actualSuggestion);
}
@@ -314,8 +322,8 @@
// there's only one zone.
{
// We use an NITZ from Czechia to generate an NITZ signal with a bad offset.
- TimestampedValue<NitzData> badNitzSignal =
- CZECHIA_SCENARIO.createNitzSignal(mFakeDeviceState.elapsedRealtime());
+ NitzSignal badNitzSignal = CZECHIA_SCENARIO.createNitzSignal(
+ mFakeDeviceState.elapsedRealtimeMillis(), ARBITRARY_AGE);
TelephonyTimeZoneSuggestion expectedTimeZoneSuggestion =
new TelephonyTimeZoneSuggestion.Builder(SLOT_INDEX)
.setZoneId(scenario.getTimeZoneId())
@@ -324,8 +332,7 @@
.build();
TelephonyTimeZoneSuggestion actualSuggestion = mTimeZoneSuggester.getTimeZoneSuggestion(
- SLOT_INDEX, scenario.getNetworkCountryIsoCode(),
- badNitzSignal);
+ SLOT_INDEX, scenario.getNetworkCountryIsoCode(), badNitzSignal);
assertEquals(expectedTimeZoneSuggestion, actualSuggestion);
}
}
@@ -356,21 +363,22 @@
// NITZ with a "" country code is interpreted as a test network so only offset is used
// to get a match.
{
+ NitzSignal nitzSignal = scenario.createNitzSignal(
+ mFakeDeviceState.elapsedRealtimeMillis(), ARBITRARY_AGE);
TelephonyTimeZoneSuggestion actualSuggestion =
mTimeZoneSuggester.getTimeZoneSuggestion(
- SLOT_INDEX, "" /* countryIsoCode */,
- scenario.createNitzSignal(mFakeDeviceState.elapsedRealtime()));
+ SLOT_INDEX, "" /* countryIsoCode */, nitzSignal);
assertEquals(SLOT_INDEX, actualSuggestion.getSlotIndex());
assertEquals(MATCH_TYPE_TEST_NETWORK_OFFSET_ONLY, actualSuggestion.getMatchType());
assertEquals(QUALITY_MULTIPLE_ZONES_WITH_SAME_OFFSET, actualSuggestion.getQuality());
-
}
// NITZ alone is not enough to get a result when the country is not available.
{
+ NitzSignal nitzSignal = scenario.createNitzSignal(
+ mFakeDeviceState.elapsedRealtimeMillis(), ARBITRARY_AGE);
TelephonyTimeZoneSuggestion actualSuggestion = mTimeZoneSuggester.getTimeZoneSuggestion(
- SLOT_INDEX, null /* countryIsoCode */,
- scenario.createNitzSignal(mFakeDeviceState.elapsedRealtime()));
+ SLOT_INDEX, null /* countryIsoCode */, nitzSignal);
assertEquals(EMPTY_TIME_ZONE_SUGGESTION, actualSuggestion);
}
@@ -383,9 +391,10 @@
.setQuality(QUALITY_SINGLE_ZONE)
.build();
+ NitzSignal nitzSignal = scenario.createNitzSignal(
+ mFakeDeviceState.elapsedRealtimeMillis(), ARBITRARY_AGE);
TelephonyTimeZoneSuggestion actualSuggestion = mTimeZoneSuggester.getTimeZoneSuggestion(
- SLOT_INDEX, scenario.getNetworkCountryIsoCode(),
- scenario.createNitzSignal(mFakeDeviceState.elapsedRealtime()));
+ SLOT_INDEX, scenario.getNetworkCountryIsoCode(), nitzSignal);
assertEquals(expectedTimeZoneSuggestion, actualSuggestion);
}
@@ -393,8 +402,8 @@
// there's only one zone.
{
// We use an NITZ from the US to generate an NITZ signal with a bad offset.
- TimestampedValue<NitzData> badNitzSignal =
- UNIQUE_US_ZONE_SCENARIO1.createNitzSignal(mFakeDeviceState.elapsedRealtime());
+ NitzSignal badNitzSignal = UNIQUE_US_ZONE_SCENARIO1.createNitzSignal(
+ mFakeDeviceState.elapsedRealtimeMillis(), ARBITRARY_AGE);
TelephonyTimeZoneSuggestion expectedTimeZoneSuggestion =
new TelephonyTimeZoneSuggestion.Builder(SLOT_INDEX)
.setZoneId(scenario.getTimeZoneId())
@@ -403,8 +412,7 @@
.build();
TelephonyTimeZoneSuggestion actualSuggestion = mTimeZoneSuggester.getTimeZoneSuggestion(
- SLOT_INDEX, scenario.getNetworkCountryIsoCode(),
- badNitzSignal);
+ SLOT_INDEX, scenario.getNetworkCountryIsoCode(), badNitzSignal);
assertEquals(expectedTimeZoneSuggestion, actualSuggestion);
}
}
@@ -430,14 +438,15 @@
// NITZ + bogus NITZ is not enough to get a result.
{
// Create a corrupted NITZ signal, where the offset information has been lost.
- TimestampedValue<NitzData> goodNitzSignal =
- scenario.createNitzSignal(mFakeDeviceState.elapsedRealtime());
+ NitzSignal goodNitzSignal = scenario.createNitzSignal(
+ mFakeDeviceState.elapsedRealtimeMillis(), ARBITRARY_AGE);
NitzData bogusNitzData = NitzData.createForTests(
0 /* UTC! */, null /* dstOffsetMillis */,
- goodNitzSignal.getValue().getCurrentTimeInMillis(),
+ goodNitzSignal.getNitzData().getCurrentTimeInMillis(),
null /* emulatorHostTimeZone */);
- TimestampedValue<NitzData> badNitzSignal = new TimestampedValue<>(
- goodNitzSignal.getReferenceTimeMillis(), bogusNitzData);
+ NitzSignal badNitzSignal = new NitzSignal(
+ goodNitzSignal.getReceiptElapsedRealtimeMillis(), bogusNitzData,
+ goodNitzSignal.getAgeMillis());
TelephonyTimeZoneSuggestion actualSuggestion = mTimeZoneSuggester.getTimeZoneSuggestion(
SLOT_INDEX, scenario.getNetworkCountryIsoCode(), badNitzSignal);
@@ -466,14 +475,15 @@
// NITZ + bogus NITZ is not enough to get a result.
{
// Create a corrupted NITZ signal, where the offset information has been lost.
- TimestampedValue<NitzData> goodNitzSignal =
- scenario.createNitzSignal(mFakeDeviceState.elapsedRealtime());
+ NitzSignal goodNitzSignal = scenario.createNitzSignal(
+ mFakeDeviceState.elapsedRealtimeMillis(), ARBITRARY_AGE);
NitzData bogusNitzData = NitzData.createForTests(
0 /* UTC! */, null /* dstOffsetMillis */,
- goodNitzSignal.getValue().getCurrentTimeInMillis(),
+ goodNitzSignal.getNitzData().getCurrentTimeInMillis(),
null /* emulatorHostTimeZone */);
- TimestampedValue<NitzData> badNitzSignal = new TimestampedValue<>(
- goodNitzSignal.getReferenceTimeMillis(), bogusNitzData);
+ NitzSignal badNitzSignal = new NitzSignal(
+ goodNitzSignal.getReceiptElapsedRealtimeMillis(), bogusNitzData,
+ goodNitzSignal.getAgeMillis());
TelephonyTimeZoneSuggestion actualSuggestion = mTimeZoneSuggester.getTimeZoneSuggestion(
SLOT_INDEX, scenario.getNetworkCountryIsoCode(), badNitzSignal);
@@ -485,11 +495,11 @@
public void test_emulatorNitzExtensionUsedForTimeZone() throws Exception {
Scenario scenario = UNIQUE_US_ZONE_SCENARIO1;
- TimestampedValue<NitzData> originalNitzSignal =
- scenario.createNitzSignal(mFakeDeviceState.elapsedRealtime());
+ NitzSignal originalNitzSignal = scenario.createNitzSignal(
+ mFakeDeviceState.elapsedRealtimeMillis(), ARBITRARY_AGE);
// Create an NITZ signal with an explicit time zone (as can happen on emulators).
- NitzData originalNitzData = originalNitzSignal.getValue();
+ NitzData originalNitzData = originalNitzSignal.getNitzData();
// A time zone that is obviously not in the US, but because the explicit value is present it
// should not be questioned.
@@ -499,8 +509,9 @@
originalNitzData.getDstAdjustmentMillis(),
originalNitzData.getCurrentTimeInMillis(),
java.util.TimeZone.getTimeZone(emulatorTimeZoneId) /* emulatorHostTimeZone */);
- TimestampedValue<NitzData> emulatorNitzSignal = new TimestampedValue<>(
- originalNitzSignal.getReferenceTimeMillis(), emulatorNitzData);
+ NitzSignal emulatorNitzSignal = new NitzSignal(
+ originalNitzSignal.getReceiptElapsedRealtimeMillis(), emulatorNitzData,
+ originalNitzSignal.getAgeMillis());
TelephonyTimeZoneSuggestion expectedTimeZoneSuggestion =
new TelephonyTimeZoneSuggestion.Builder(SLOT_INDEX)
@@ -535,8 +546,8 @@
// Confirm what happens when NITZ is correct for the country default.
{
Scenario scenario = NEW_ZEALAND_DEFAULT_SCENARIO;
- TimestampedValue<NitzData> nitzSignal =
- scenario.createNitzSignal(mFakeDeviceState.elapsedRealtime());
+ NitzSignal nitzSignal = scenario.createNitzSignal(
+ mFakeDeviceState.elapsedRealtimeMillis(), ARBITRARY_AGE);
TelephonyTimeZoneSuggestion expectedSuggestion =
new TelephonyTimeZoneSuggestion.Builder(SLOT_INDEX)
.setZoneId(scenario.getTimeZoneId())
@@ -552,8 +563,8 @@
// A valid NITZ signal for the non-default zone should still be correctly detected.
{
Scenario scenario = NEW_ZEALAND_OTHER_SCENARIO;
- TimestampedValue<NitzData> nitzSignal =
- scenario.createNitzSignal(mFakeDeviceState.elapsedRealtime());
+ NitzSignal nitzSignal = scenario.createNitzSignal(
+ mFakeDeviceState.elapsedRealtimeMillis(), ARBITRARY_AGE);
TelephonyTimeZoneSuggestion expectedSuggestion =
new TelephonyTimeZoneSuggestion.Builder(SLOT_INDEX)
.setZoneId(scenario.getTimeZoneId())
@@ -571,8 +582,8 @@
{
Scenario scenario = NEW_ZEALAND_DEFAULT_SCENARIO;
// Use a scenario that has a different offset than NZ to generate the NITZ signal.
- TimestampedValue<NitzData> nitzSignal =
- CZECHIA_SCENARIO.createNitzSignal(mFakeDeviceState.elapsedRealtime());
+ NitzSignal nitzSignal = CZECHIA_SCENARIO.createNitzSignal(
+ mFakeDeviceState.elapsedRealtimeMillis(), ARBITRARY_AGE);
TelephonyTimeZoneSuggestion expectedSuggestion =
new TelephonyTimeZoneSuggestion.Builder(SLOT_INDEX)
.setZoneId(NEW_ZEALAND_COUNTRY_DEFAULT_ZONE_ID)
@@ -607,8 +618,8 @@
// Confirm what happens when NITZ is correct for the country default.
{
Scenario scenario = UNIQUE_US_ZONE_SCENARIO1;
- TimestampedValue<NitzData> nitzSignal =
- scenario.createNitzSignal(mFakeDeviceState.elapsedRealtime());
+ NitzSignal nitzSignal = scenario.createNitzSignal(
+ mFakeDeviceState.elapsedRealtimeMillis(), ARBITRARY_AGE);
TelephonyTimeZoneSuggestion expectedSuggestion =
new TelephonyTimeZoneSuggestion.Builder(SLOT_INDEX)
.setZoneId(scenario.getTimeZoneId())
@@ -624,8 +635,8 @@
// A valid NITZ signal for the non-default zone should still be correctly detected.
{
Scenario scenario = UNIQUE_US_ZONE_SCENARIO2;
- TimestampedValue<NitzData> nitzSignal =
- scenario.createNitzSignal(mFakeDeviceState.elapsedRealtime());
+ NitzSignal nitzSignal = scenario.createNitzSignal(
+ mFakeDeviceState.elapsedRealtimeMillis(), ARBITRARY_AGE);
TelephonyTimeZoneSuggestion expectedSuggestion =
new TelephonyTimeZoneSuggestion.Builder(SLOT_INDEX)
.setZoneId(scenario.getTimeZoneId())
@@ -644,8 +655,8 @@
// A scenario that has a different offset than US.
Scenario scenario = UNIQUE_US_ZONE_SCENARIO1;
// Use a scenario that has a different offset than the US to generate the NITZ signal.
- TimestampedValue<NitzData> nitzSignal =
- CZECHIA_SCENARIO.createNitzSignal(mFakeDeviceState.elapsedRealtime());
+ NitzSignal nitzSignal = CZECHIA_SCENARIO.createNitzSignal(
+ mFakeDeviceState.elapsedRealtimeMillis(), ARBITRARY_AGE);
TelephonyTimeZoneSuggestion expectedSuggestion = EMPTY_TIME_ZONE_SUGGESTION;
TelephonyTimeZoneSuggestion actualSuggestion = mTimeZoneSuggester.getTimeZoneSuggestion(
SLOT_INDEX, scenario.getNetworkCountryIsoCode(), nitzSignal);